OSDN Git Service

Version 0.6.221, Update the X.TextRange.
authoritozyun <itozyun@user.sourceforge.jp>
Sat, 12 Nov 2016 18:00:06 +0000 (03:00 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Sat, 12 Nov 2016 18:00:06 +0000 (03:00 +0900)
0.6.x/js/01_core/03_XScript.js
0.6.x/js/01_core/07_XString.js
0.6.x/js/01_core/15_XEventDispatcher.js
0.6.x/js/01_core/21_XViewPort.js
0.6.x/js/02_dom/03_XDomEvent.js
0.6.x/js/02_dom/05_XNodeAttr.js
0.6.x/js/02_dom/20_XNode.js
0.6.x/js/02_dom/30_XTextRange.js
0.6.x/js/05_util/01_XNinjaIframe.js
0.6.x/js/06_net/01_XNetXHR.js

index 753af82..f32a744 100644 (file)
@@ -62,6 +62,24 @@ if( X_Script_VBS_ENABLED ){
                        * */\r
                ].join( '\n' ) + '</script>' );\r
 \r
+       // http://space.geocities.jp/nequomame/others/excelvba/excelvba_01_03.html\r
+       // Document.ActiveElement に安全に触れるか?確認\r
+       // そういえば error は iframe 内で起きていた\r
+       // http://stackoverflow.com/questions/14378224/document-activeelement-in-iframe-shows-unspecified-error-in-ie-standards-mode\r
+       // document.activeElement in iframe shows unspecified error in IE standards mode\r
+       X_Script_gte15 || document.write( '<script type=text/vbscript>' +\r
+               [\r
+                       'Function vbs_testAE()',\r
+                               'On Error Resume Next',\r
+                               'Set ae = Document.ActiveElement',\r
+                               'If Err.Number Then',\r
+                                       'ae = 1',\r
+                               'End If',\r
+                               'Err.Clear',\r
+                               'vbs_testAE = ae',\r
+                       'End Function'\r
+               ].join( '\n' ) + '</script>' );\r
+\r
        // TODO Object のメンバを辿る vba\r
        // byte Array を扱う vba\r
 };\r
@@ -75,6 +93,8 @@ if( X_Script_VBS_ENABLED ){
 function X_Script_try( func, args ){\r
        if( !X_Script_gte15 ){\r
                //return func.apply( {}, args );\r
+               // window.onerror = return true を設定\r
+               // vbs 側から呼び出し?\r
                return;\r
        };\r
        return X_Script_gte15( func, args || [] );\r
index 530bd9b..a1c9f1d 100644 (file)
@@ -1,8 +1,12 @@
+/*\r
+http://shimax.cocolog-nifty.com/search/2006/09/post_b296.html\r
+ここで、「String.fromCharCode(13,10)」というのは、「\r\n」のことであり、Windowsの改行コードです。もちろん、「\r\n」でも良いのですが、半角円マークが出現すると、LinuxのブラウザKonquerorで正しく動作しないことがあるため、半角円マークを使わないようにしています(参照:Konquerorとエスケープ文字(JavaScript謎のエラーを解く))。\r
+*/\r
 \r
 // ------------------------------------------------------------------------- //\r
 // ------------ local variables -------------------------------------------- //\r
 // ------------------------------------------------------------------------- //\r
-var X_String_CRLF = String.fromCharCode( 13 ) + String.fromCharCode( 10 ),\r
+var X_String_CRLF = String.fromCharCode( 13 ) + String.fromCharCode( 10 ), // String.fromCharCode( 13, 10 )\r
        X_String_CHAR_REFS = {"&iexcl;":161,"&cent;":162,"&pound;":163,"&curren;":164,"&yen;":165,"&brvbar;":166,"&sect;":167,"&uml;":168,"&copy;":169,\r
 "&ordf;":170,"&laquo;":171,\r
 "&not;":172,"&shy;":173,"&reg;":174,"&macr;":175,"&deg;":176,"&plusmn;":177,"&sup2;":178,"&sup3;":179,"&acute;":180,"&micro;":181,"&para;":182,\r
index 5a9864a..afa52c7 100644 (file)
@@ -733,7 +733,8 @@ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){
 \r
 \r
 // TODO ブラウザからの呼び出しの最後に登録された関数を呼び出す機能(例えば画面の更新)\r
-var X_EventDispatcher_CURRENT_EVENTS = [];\r
+var X_EventDispatcher_CURRENT_EVENTS    = [];\r
+var X_EventDispatcher_ignoreActualEvent = '';\r
 \r
 // handleEvent を拡張可能にするために、クロージャに移動した\r
 // Is this in regard to the Safari 1.x preventDefault bug on click/dblclick?\r
@@ -741,8 +742,16 @@ var X_EventDispatcher_CURRENT_EVENTS = [];
 var X_EventDispatcher_actualHandleEvent =\r
        X_UA_EVENT.IE4 || X_UA_EVENT.IE ? // ie45678 EVENT_IE & EVENT_DOM0 for ie4\r
                (function(){\r
-                       var e  = event, ret,\r
-                               ev = new X_DomEvent( e, this, this[ '_rawObject' ] );\r
+                       var e   = event,\r
+                               elm = this[ '_rawObject' ],\r
+                               ev, ret;\r
+                       \r
+                       /* if( e.type === X_EventDispatcher_ignoreActualEvent ){\r
+                               e.cancelBubble = true;\r
+                               return;\r
+                       }; */\r
+                       \r
+                       ev = new X_DomEvent( e, this, elm );\r
                        \r
                        X_EventDispatcher_CURRENT_EVENTS[ X_EventDispatcher_CURRENT_EVENTS.length ] = ev;\r
                        \r
@@ -754,16 +763,21 @@ var X_EventDispatcher_actualHandleEvent =
                                e.cancelBubble = true;\r
                        };\r
                        if( ret & X_CALLBACK_PREVENT_DEFAULT ){\r
-                               this[ '_tag' ] === 'A' && this[ '_rawObject' ].blur();\r
+                               this[ '_tag' ] === 'A' && elm.blur();\r
                                return e.returnValue = false;\r
                        };\r
                }) :\r
        //X_UA_EVENT.W3C || X_UA_EVENT.DOM0\r
                (function( e ){\r
-                       var ev  = new X_DomEvent( e, this ),\r
-                               ret = X_CALLBACK_NONE,\r
-                               i, l;\r
+                       var ret = X_CALLBACK_NONE,\r
+                               ev, i, l;\r
+                       \r
+                       /* if( e.type === X_EventDispatcher_ignoreActualEvent ){\r
+                               e.stopPropagation();\r
+                               return;\r
+                       }; */\r
                        \r
+                       ev  = new X_DomEvent( e, this );\r
                        X_EventDispatcher_CURRENT_EVENTS[ X_EventDispatcher_CURRENT_EVENTS.length ] = ev;\r
 \r
                        // touch event -> pointer\r
index 86682a8..54a07fe 100644 (file)
@@ -49,10 +49,9 @@ X_ViewPort = X_Class_override(
                                        //https://developer.mozilla.org/ja/docs/Web/JavaScript/A_re-introduction_to_JavaScript
                                        //Firefox 1.5 の bfcache が無効になりますので、他に理由がない限り Firefox では unload リスナを登録するべきではないことに注意してください。
                                        X_ViewPort[ 'dispatch' ]( X_EVENT_UNLOAD );
-                               //alert('unload');
+                                       //alert('unload');
                                        X_ViewPort_document[ 'kill' ]();
                                        X_ViewPort[ 'kill' ]();
-                                       
                                        //X_System[ 'dispatch' ]( X_EVENT_SHUT_DOWN );
                                        break;
 
@@ -75,8 +74,11 @@ X_ViewPort = X_Class_override(
        
                                case 'blur' :
                                case 'focusout' :
-                                       // TODO ie5...
-                                       if( 5.5 < X_UA[ 'IE' ] && X_UA[ 'IE' ] < 9 ){
+                                       if( ( 5.5 < X_UA[ 'IE' ] && X_UA[ 'IE' ] < 9 )
+                                                ||
+                                                // TODO ie5... activeElement に障るとエラーになるため VBS 経由で activeElement に触り安全確認する(未確認)
+                                                ( 5 <= X_UA[ 'IE' ] && X_UA[ 'IE' ] < 5.5 && !window[ 'vbs_testAE' ]() )
+                                        ){
                                                xnode = X_Node_getXNode( document.activeElement );
                                                if( xnode ){
                                                        xnode[ 'listenOnce' ]( [ 'focus', 'blur' ], X_ViewPort_detectFocusForIE );
index 4497267..7759a95 100644 (file)
@@ -299,14 +299,14 @@ if( !X_UA[ 'IE' ] || 9 <= X_UA[ 'IE' ] ){
                if( this[ 'target' ] && !this[ 'target' ][ '_tag' ] ) this[ 'target' ] = this[ 'target' ].parent; // ie4 の fake Textnode がヒットしていないか?\r
                this[ 'currentTarget' ] = xnode; // xnode\r
                this[ 'relatedTarget' ] = X_Node_getXNode( e.formElement || e.toElement ); // xnode\r
-               this[ 'relatedTarget' ] && console.dir( 'relatide...' );\r
+               //this[ 'relatedTarget' ] && console.dir( 'relatide...' );\r
                this[ 'eventPhase' ]    = e.srcElement === element ? 2: 3;\r
                \r
                this[ 'keyCode' ]       = e.keyCode;\r
                this[ 'charCode' ]      = e.keyCode;\r
                this[ 'altKey' ]        = e.altKey;\r
                this[ 'ctrlKey' ]       = e.ctrlKey;\r
-               this[ 'shiftKey' ]      = e.shiftKey;           \r
+               this[ 'shiftKey' ]      = e.shiftKey;\r
 \r
                \r
                switch( this[ 'type' ] ){\r
index 579f286..cdf19c6 100644 (file)
@@ -228,6 +228,10 @@ function X_Node_attr( nameOrObj /* v */ ){
                                        if( this[ '_newAttrs' ] && X_Object_inObject( nameOrObj, this[ '_newAttrs' ] ) ) return this[ '_newAttrs' ][ nameOrObj ];\r
                                        if( elm = X_UA_DOM.IE4 ? this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) : this[ '_rawObject' ] ){\r
                                                if( !attrs ) attrs = this[ '_attrs' ] = {};\r
+                                               \r
+                                               if( this[ '_tag' ] === 'TEXTAREA' && nameOrObj === 'value' && X_UA[ 'IE' ] < 9 ){\r
+                                                       return attrs[ nameOrObj ] = X_Node_Attr_getValueForIE( elm );\r
+                                               };\r
                                                return attrs[ nameOrObj ] = elm[ nameOrObj ]; // getAttribute( nameOrObj )?\r
                                        };\r
                                };\r
@@ -236,6 +240,16 @@ function X_Node_attr( nameOrObj /* v */ ){
                return attrs && attrs[ X_Node_Attr_renameForTag[ nameOrObj ] || nameOrObj ];\r
        };\r
 };\r
+\r
+\r
+               // ie8- 用に改行文字が \n の場合、 \r\n に変換しておく <- fromawork 内に移動\r
+               // http://qiita.com/hanoopy/items/71456afe32f207369d24\r
+function X_Node_Attr_getValueForIE( elm ){\r
+       // console.log( elm[ nameOrObj ].length + ' -> ' + elm[ nameOrObj ].split( '\r' ).join( '' ).length );\r
+       // IE は改行文字が /r/n になるがこれを /n に変換\r
+       return elm.value.split( '\r' ).join( '' );\r
+};\r
+\r
 function X_Node_Attr_setAttr( that, attrs, newAttrs, name, v ){\r
        switch( name ){\r
                case 'ns' :\r
index 6b67d04..bb392e3 100644 (file)
@@ -1382,7 +1382,7 @@ function X_Node_reserveUpdate(){
 var X_Node_updateReservedByReleaseGPU = false;
 
 function X_Node_startUpdate( time ){
-       var removal, i, xnodeOrElm, xnodesIEFilterFixAfter, xnode;
+       var removal, i, xnodeOrElm, xnodesIEFilterFixAfter, xnode, active;
        
        if( !X_Node_updateTimerID || X_ViewPort_readyState < X_EVENT_INIT ){
                return;
@@ -1422,17 +1422,24 @@ function X_Node_startUpdate( time ){
                removal.length = 0;
        };
        
-       //
-       X_UA[ 'IE5' ] && ( X_elmBody.style.visibility = 'hidden' );
-       
+       // 強制的に再描画を起こす, 但し activeElement からフォーカスが外れるため復帰する
+       // IE5mode win10 で 確認
+       if( X_UA[ 'IE5' ] ){
+               active = document.activeElement;
+               X_elmBody.style.visibility = 'hidden';
+       };
+
        if( X_Node_html[ '_flags' ] & X_Node_BitMask_IS_DIRTY ){
                X_Node__commitUpdate( X_Node_html, X_Node_html[ '_rawObject' ].parentNode, null, X_Node_html[ '_flags' ], 1, xnodesIEFilterFixAfter = [] );
        } else {
                X_Node__commitUpdate( X_Node_head, X_Node_head[ '_rawObject' ].parentNode, null, X_Node_head[ '_flags' ], 1, xnodesIEFilterFixAfter = [] );
                X_Node__commitUpdate( X_Node_body, X_Node_body[ '_rawObject' ].parentNode, null, X_Node_body[ '_flags' ], 1, xnodesIEFilterFixAfter = [] );
        };
-       
-       X_UA[ 'IE5' ] && ( X_elmBody.style.visibility = '' );
+
+       if( X_UA[ 'IE5' ] ){
+               X_elmBody.style.visibility = '';
+               active && active.parentNode && active.focus();
+       };
        
        if( X_Node_updateReservedByReleaseGPU ){
                X_Node_reserveUpdate();
@@ -1522,7 +1529,12 @@ var X_Node__commitUpdate =
                        if( !elm ){
                                if( !that[ '_tag' ] ){
                                        that[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
-                                       elm = document.createTextNode( X_String_chrReferanceTo( that[ '_text' ] ) );
+                                       if( X_UA[ 'IE' ] < 8 ){
+                                               // \n -> \r\n に変換しないと pre タグで開業されない  win10ie7(ie11 emu) で確認
+                                               elm = document.createTextNode( X_String_chrReferanceTo( that[ '_text' ] ).split( '\n' ).join( X_String_CRLF ) );
+                                       } else {
+                                               elm = document.createTextNode( X_String_chrReferanceTo( that[ '_text' ] ) );
+                                       };
                                        if( !X_UA[ 'IE' ] ){
                                                elm[ 'UID' ] = that[ '_uid' ];
                                        };
@@ -1798,7 +1810,12 @@ var X_Node__updateRawNode =
 
                        // textNode
                        if( !that[ '_tag' ] ){
-                               elm.data = X_String_chrReferanceTo( that[ '_text' ] );
+                               if( X_UA[ 'IE' ] < 8 ){
+                                       // \n -> \r\n に変換しないと pre タグで開業されない  win10ie7(ie11 emu) で確認
+                                       elm.data = X_String_chrReferanceTo( that[ '_text' ] ).split( '\n' ).join( X_String_CRLF );
+                               } else {
+                                       elm.data = X_String_chrReferanceTo( that[ '_text' ] );
+                               };
                                that[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
                                return;
                        };
index d6f8837..a2fc552 100644 (file)
@@ -2,13 +2,16 @@
  * tr = X.Doc.createRange('selection')\r
  *      X.Doc.createRange({from : num, to : num})\r
  * tr = xnode.createRange( from, to ),\r
- *        ( 'selection' ) docment の slection のうち xnode の配下のもの\r
- *     ( 'char', from, to )\r
- *     ( 'line', index ),\r
- *     ( 'point', x, y ) | ( 'point', e )\r
- * tr.move( startIndex, endIndex )\r
- * tr.getRect() { width, height, x, y }\r
- * tr.getOffset() { from, to }\r
+ *        ( 'selection' ) docment の slection のうち xnode の配下のもの, textarea, input, iframe[desineMode] の場合、選択範囲またはカーソル位置\r
+ *     ( 'select', from[, to] ) 選択する\r
+ *     ( 'char', from[, to] )\r
+ *     ( 'lineAt', index ),\r
+ *        ( 'line', x, y ), | ( 'line', pointerEvent )\r
+ *     ( 'point', x, y ) | ( 'point', pointerEvent )\r
+ * tr.move( from, to )\r
+ * tr.select( true | false )\r
+ * tr.getRect() { width, height, x, y } -> tr.mesure()\r
+ * tr.getOffset() { from, to } \r
  * tr.text()\r
  * \r
  * naming は mozilla に寄せる\r
@@ -27,6 +30,8 @@ var X_TextRange_range,
 var X_TextRange = X_Class_create(\r
        'X.TextRange',\r
        \r
+       // TODO コールバックの最後に破棄されるクラス 1刻みの間存在するクラス. X.XML も\r
+       \r
        /** @lends X.TextRange.prototype */\r
        {\r
                xnode      : null,\r
@@ -57,9 +62,15 @@ var X_TextRange = X_Class_create(
                        if( arg2 !== 'selection' ){\r
                                this.v1 = arg3 || 0;\r
                                this.v2 = arg4 || 0;\r
+                       } else {\r
+                               this[ 'getOffset' ]();\r
                        };\r
                },\r
                \r
+               'move'      : X_TextRange_move,\r
+               \r
+               'select'    : X_TextRange_select,\r
+               \r
                'getRect'   : X_TextRange_getRect,\r
                \r
                'getOffset' : X_TextRange_getOffset,\r
@@ -87,7 +98,7 @@ function X_TextRange_collectTextNodes( elm, ary ){
        };\r
 };\r
 \r
-function X_TextRange_getRawRange( tr ){\r
+function X_TextRange_getRawRange( tr, createFrom ){\r
        var xnode = tr.xnode,\r
                                //\r
                range = 10 <= X_UA[ 'IE' ] /* || X_UA[ 'iOS' ] */ ? document.createRange() :\r
@@ -101,11 +112,20 @@ function X_TextRange_getRawRange( tr ){
                \r
                elm = xnode[ '_rawObject' ];\r
                \r
-               switch( tr.createFrom ){\r
+               switch( createFrom || tr.createFrom ){\r
                        case 'selection' :\r
                                if( X_TextRange_isW3C ){\r
                                        selection = window.getSelection();\r
-                                       return selection.rangeCount && selection.getRangeAt( 0 );\r
+                                       \r
+                           if( selection.getRangeAt ){\r
+                               return selection.rangeCount && selection.getRangeAt( 0 );\r
+                           };\r
+                           // http://d.hatena.ne.jp/dayflower/20080423/1208941641\r
+                           // for Safari 1.3\r
+                           range = document.createRange();\r
+                           range.setStart( selection.anchorNode, selection.anchorOffset );\r
+                           range.setEnd( selection.focusNode, selection.focusOffset );\r
+                                       return range;\r
                                } else {\r
                                        switch( document.selection.type ){\r
                                                case 'text' :\r
@@ -139,10 +159,10 @@ function X_TextRange_getRawRange( tr ){
                                                        };\r
                                                    if( rect.left <= x && x <= rect.right && rect.top <= y && y <= rect.bottom ){\r
                                                        return {\r
-                                                               hitRange : range,\r
-                                                               rect     : rect,\r
-                                                               offset   : offset,\r
-                                                               text     : text\r
+                                                               'hitRange' : range,\r
+                                                               'rect'     : rect,\r
+                                                               'offset'   : offset,\r
+                                                               'text'     : text\r
                                                        };\r
                                                    };\r
                                                };\r
@@ -153,14 +173,14 @@ function X_TextRange_getRawRange( tr ){
                                                // 未チェック!\r
                                                range.setEnd( elm, l < tr.v2 ? l : tr.v2 );\r
                                    range.setStart( elm, tr.v1 );\r
-                                   return { hitRange : range };\r
+                                   return { 'hitRange' : range };\r
                                        };\r
                                } else {\r
                                        // !save && ( text = text.split( '\r\n' ).join( '\n' ) ); textarea用\r
                                        if( isPoint ){\r
                                                // ie11 の ie10モード で moveToPoint がないといわれる. よって isW3C:false で動作するのは ie9 以下\r
                                                range.moveToPoint( tr.v1, tr.v2 );\r
-                                               if( !range.expand( 'character' ) ) range = null;\r
+                                               if( !range.duplicate().expand( 'character' ) ) range = null;\r
                                        } else {\r
                                                range.moveToElementText( elm );\r
                                                //range.collapse( true );                                               \r
@@ -179,14 +199,16 @@ function X_TextRange_getRect(){
        \r
        if( result ){\r
                if( X_TextRange_isW3C ){\r
-                       rect = result.hitRange.getBoundingClientRect();\r
-                       ret = {\r
-                               'x'      : rect.left,\r
-                               'y'      : rect.top,\r
-                               'width'  : rect.width,\r
-                               'height' : rect.height\r
+                       if( result.hitRange ){\r
+                               rect = result.hitRange.getBoundingClientRect();\r
+                               ret = {\r
+                                       'x'      : rect.left,\r
+                                       'y'      : rect.top,\r
+                                       'width'  : rect.width,\r
+                                       'height' : rect.height\r
+                               };\r
+                               //range.detach && range.detach();\r
                        };\r
-                       //range.detach && range.detach();\r
                } else {\r
                        ret = {\r
                                'x'      : result.boundingLeft,\r
@@ -216,46 +238,68 @@ function X_TextRange_collectXTexts( xnode, ary ){
 };\r
 \r
 function X_TextRange_getOffset(){\r
-       var result = X_TextRange_getRawRange( this ),\r
-               range, ret, all, from, xtexts, n, i, l, xtext;\r
+       var xnode = this.xnode,\r
+               elm, result, range,\r
+               ret, from, xtexts, n, i, l, xtext;\r
        \r
-       if( result ){\r
+       if( xnode[ '_tag' ] === 'TEXTAREA' ){\r
+               elm = xnode[ '_rawObject' ];\r
+               \r
+               if( elm && xnode[ '_flags' ] & X_NodeFlags_IN_TREE ){\r
+                       if( X_UA[ 'IE' ] < 9 ){\r
+                               \r
+\r
+                               return cursorPosition.call( this, elm );\r
+\r
+                       } else if( elm.setSelectionRange ){\r
+                               if( X_UA[ 'IE' ] < 12 ){\r
+                                       l = elm.value.length;\r
+                                       ret = {\r
+                                               'from' : this.v1 = elm.selectionStart < l ? elm.selectionStart : l,\r
+                                               'to'   : this.v2 = elm.selectionEnd   < l ? elm.selectionEnd   : l\r
+                                       };\r
+                               } else {\r
+                                       ret = {\r
+                                               'from' : this.v1 = elm.selectionStart,\r
+                                               'to'   : this.v2 = elm.selectionEnd\r
+                                       };      \r
+                               };\r
+                       };\r
+               };\r
+       } else\r
+       if( result = X_TextRange_getRawRange( this ) ){\r
                if( X_TextRange_isW3C ){\r
                        range = result.hitRange;\r
                        ret = {\r
                                'offset' : result.offset,\r
-                               'from'   : range.startOffset,\r
-                               'to'     : range.endOffset,\r
+                               'from'   : this.v1 = range.startOffset,\r
+                               'to'     : this.v2 = range.endOffset,\r
                                'text'   : X_Node_getXNode( result.text )\r
                        };\r
                        // range.detach && range.detach();              \r
                } else {\r
                        // http://www.studio-freesky.net/programming/javascript/3/\r
-                       range = X_TextRange_range2;\r
-                       //var _rang = X_elmBody.createTextRange();\r
                        \r
+                       range = X_TextRange_range2;\r
+                       range.moveToElementText( xnode[ '_rawObject' ] );\r
+                       range.setEndPoint( 'EndToStart', result );\r
+                       from  = range.text.length;\r
                        \r
-                       //_rang.moveToElementText( this.xnode.getChildAt(1)[ '_rawObject' ] );\r
-                       range.moveToElementText( this.xnode[ '_rawObject' ] );\r
-                       range.setEndPoint( 'EndToStart', result ); //_rang )//\r
-                       from  = range.text.length;// - result.text.length;\r
-\r
-                       X_TextRange_collectXTexts( this.xnode, xtexts = [] );\r
+                       X_TextRange_collectXTexts( xnode, xtexts = [] );\r
                        \r
                        if( xtexts.length ){\r
-                               // 改行が入ると正しく startIndex を取ることができない...\r
-                               for( n = l = 0, i = -1; xtext = xtexts[ ++i ]; ){\r
-                                       l = xtext[ '_text' ].length;\r
+                               for( n = 0, i = -1; xtext = xtexts[ ++i ]; ){\r
+                                       l = xtext[ '_rawObject' ].data.length;\r
                                        if( from < n + l ){\r
                                                break;\r
                                        };\r
                                        n += l;\r
                                };\r
-                               \r
+\r
                                ret = {\r
-                                       'offset' : n,\r
-                                       'from'   : from - n,\r
-                                       'to'     : from - n + result.text.length,\r
+                                       'offset' : n, // elm の何個目の node か?\r
+                                       'from'   : this.v1 = from - n,\r
+                                       'to'     : this.v2 = from - n + result.text.length,\r
                                        'text'   : xtext\r
                                };                              \r
                        };\r
@@ -266,10 +310,222 @@ function X_TextRange_getOffset(){
 };\r
 \r
 function X_TextRange_text( v ){\r
+       var xnode = this.xnode, elm, val, offset, from, to;\r
+       \r
        if( v === undefined ){\r
                \r
        } else {\r
+               if( xnode[ '_tag' ] === 'TEXTAREA' ){\r
+                       elm = xnode[ '_rawObject' ];\r
+                       val = X_UA[ 'IE' ] < 9 ? X_Node_Attr_getValueForIE( elm ) : elm.value;\r
+                       \r
+                       if( this.createFrom === 'char' ){\r
+                               xnode.attr( {\r
+                                       'value' : val.substr( 0, this.v1 ) + v + val.substr( this.v2 )\r
+                               } );\r
+                       } else {\r
+                               offset = this[ 'getOffset' ]();\r
+                               \r
+                               from   = offset[ 'from' ];\r
+                               to     = offset[ 'to' ];\r
+\r
+                               if( X_UA[ 'IE' ] < 9 ){\r
+                                       range = document.selection.createRange();\r
+                                       // TODO check textarea\r
+                                       range.text = v;\r
+                                       // ここには range.text がいない https://msdn.microsoft.com/ja-jp/library/cc427934.aspx\r
+                               } else {\r
+                                       val = val.substr( 0, from ) + v + val.substr( to );\r
+                                       elm.value = val;\r
+                               };\r
+                                       \r
+                               if( to !== from ){\r
+                                       // カーソル位置を挿入した文字列の最後へ\r
+                                       to = from + v.length;\r
+                               } else {\r
+                                       // カーソル位置を挿入した文字列の後ろへ\r
+                                       to += v.length;\r
+                               };\r
+                               this.move( to, to );\r
+                       };\r
+               };\r
+       };\r
+};\r
+\r
+function X_TextRange_move( from, to ){\r
+       var xnode  = this.xnode,\r
+               elm    = xnode[ '_rawObject' ],\r
+               len, range;\r
+\r
+       if( 0 <= from ){\r
+               this.v1 = from;\r
+       } else {\r
+               this.v1 = this.v1 + from;\r
+               this.v1 < 0 && ( this.v1 = 0 );\r
+       };\r
+\r
+       if( X_Type_isNumber( to ) ){\r
+               if( 0 <= to ){\r
+                       this.v2 = to;\r
+               } else {\r
+                       this.v2 = this.v2 + to;\r
+                       this.v2 < this.v1 && ( this.v2 = this.v1 );\r
+               };\r
+       };\r
+       \r
+       if( xnode[ '_tag' ] === 'TEXTAREA' ){\r
+               // http://blog.enjoyxstudy.com/entry/20060305/p1\r
                \r
+               if( X_UA[ 'IE' ] < 9 || X_UA[ 'Opera' ] ){\r
+                       len = ( X_UA[ 'IE' ] < 9 ? X_Node_Attr_getValueForIE( elm ) : elm.value ).length;\r
+                       \r
+                       if( X_UA[ 'Opera' ] ){\r
+                               X_EventDispatcher_ignoreActualEvent = 'focus';\r
+                               elm.focus(); // Operaの為(IEでは無くても大丈夫)\r
+                               X_EventDispatcher_ignoreActualEvent = '';\r
+                       };\r
+\r
+                       range = elm.createTextRange();\r
+\r
+                       if( this.v1 === this.v2 && this.v1 === 0 ){\r
+                               range.collapse( true ); // 先頭に移動\r
+                       } else {\r
+                               if( this.v1 !== this.v2 || this.v1 < len ){\r
+                                       range.collapse(); // おまじない?\r
+\r
+                                       if( this.v1 === this.v2 ){\r
+                                               range.move( 'character', this.v1 );\r
+                                       } else {\r
+                                               range.moveEnd( 'character', this.v2 );\r
+                                               range.moveStart( 'character', this.v1 );\r
+                                       };\r
+                               } else {\r
+                                       range.collapse( false ); // 末美に移動\r
+                               };\r
+                       };\r
+                       range.select();\r
+\r
+               } else if( elm.setSelectionRange ){\r
+                       elm.setSelectionRange( this.v1, this.v2 );\r
+               };\r
        };\r
 };\r
 \r
+function X_TextRange_select( v ){\r
+       \r
+};\r
+\r
+// http://www.studio-freesky.net/programming/javascript/3/\r
+// それは、IEのTextRangeオブジェクトで取得した範囲にもしラストに改行コード¥r¥nがあった場合それが含まれないのです。(視覚的な選択範囲には含まれています)\r
+\r
+// https://web.archive.org/web/20090904134938/http://www.dedestruct.com/2008/03/22/howto-cross-browser-cursor-position-in-textareas/\r
+                                       // https://web.archive.org/web/20090904183807/http://www.dedestruct.com/cursorPosition.html\r
+                                       function cursorPosition( textarea ){\r
+\r
+                                               var selection_range = document.selection.createRange().duplicate();\r
+                                               \r
+\r
+                                               if (selection_range.parentElement() !== textarea) {\r
+                                                       // TODO 正しくはカーソル位置・選択範囲の復帰\r
+                                                       \r
+                                                       X_EventDispatcher_ignoreActualEvent = 'focus';\r
+                                                       textarea.focus();\r
+                                                       X_EventDispatcher_ignoreActualEvent = '';\r
+                                                               \r
+                                                       // BODY要素のテキスト範囲を作成する\r
+                                                       selection_range = X_elmBody.createTextRange();\r
+                                               \r
+                                                       // BODY要素のテキスト範囲をeのテキスト範囲に移動する\r
+                                                       // これはe.createTextRange()とほぼ同等\r
+                                                       selection_range.moveToElementText( textarea );\r
+                                                       \r
+                                                       selection_range.collapse( true ); // 末美に移動\r
+                                                       selection_range.select();\r
+                                               };\r
+\r
+                                               //if (selection_range.parentElement() == textarea) {// Check that the selection is actually in our textarea\r
+                                                       // Create three ranges, one containing all the text before the selection,\r
+                                                       // one containing all the text in the selection (this already exists), and one containing all\r
+                                                       // the text after the selection.\r
+                                                       var before_range = X_elmBody.createTextRange();\r
+                                                       before_range.moveToElementText(textarea);\r
+                                                       // Selects all the text\r
+                                                       before_range.setEndPoint('EndToStart', selection_range);\r
+                                                       // Moves the end where we need it\r
+                                               \r
+                                                       var after_range = X_elmBody.createTextRange();\r
+                                                       after_range.moveToElementText(textarea);\r
+                                                       // Selects all the text\r
+                                                       after_range.setEndPoint('StartToEnd', selection_range);\r
+                                                       // Moves the start where we need it\r
+                                               \r
+                                                       var before_finished = false, selection_finished = false, after_finished = false;\r
+                                                       var before_text, untrimmed_before_text, selection_text, untrimmed_selection_text, after_text, untrimmed_after_text;\r
+                                               \r
+                                                       // Load the text values we need to compare\r
+                                                       before_text = untrimmed_before_text = before_range.text;\r
+                                                       selection_text = untrimmed_selection_text = selection_range.text;\r
+                                                       after_text = untrimmed_after_text = after_range.text;\r
+                                               \r
+                                                       // Check each range for trimmed newlines by shrinking the range by 1 character and seeing\r
+                                                       // if the text property has changed.  If it has not changed then we know that IE has trimmed\r
+                                                       // a \r\n from the end.\r
+                                                       do {\r
+                                                               if (!before_finished) {\r
+                                                                       if (before_range.compareEndPoints('StartToEnd', before_range) == 0) {\r
+                                                                               before_finished = true;\r
+                                                                       } else {\r
+                                                                               before_range.moveEnd('character', -1);\r
+                                                                               if (before_range.text == before_text) {\r
+                                                                                       untrimmed_before_text += '\r\n';\r
+                                                                               } else {\r
+                                                                                       before_finished = true;\r
+                                                                               }\r
+                                                                       }\r
+                                                               }\r
+                                                               if (!selection_finished) {\r
+                                                                       if (selection_range.compareEndPoints('StartToEnd', selection_range) == 0) {\r
+                                                                               selection_finished = true;\r
+                                                                       } else {\r
+                                                                               selection_range.moveEnd('character', -1);\r
+                                                                               if (selection_range.text == selection_text) {\r
+                                                                                       untrimmed_selection_text += '\r\n';\r
+                                                                               } else {\r
+                                                                                       selection_finished = true;\r
+                                                                               }\r
+                                                                       }\r
+                                                               }\r
+                                                               if (!after_finished) {\r
+                                                                       if (after_range.compareEndPoints('StartToEnd', after_range) == 0) {\r
+                                                                               after_finished = true;\r
+                                                                       } else {\r
+                                                                               after_range.moveEnd('character', -1);\r
+                                                                               if (after_range.text == after_text) {\r
+                                                                                       untrimmed_after_text += '\r\n';\r
+                                                                               } else {\r
+                                                                                       after_finished = true;\r
+                                                                               }\r
+                                                                       }\r
+                                                               }\r
+                                               \r
+                                                       } while ((!before_finished || !selection_finished || !after_finished));\r
+                                               \r
+                                                       // Untrimmed success test to make sure our results match what is actually in the textarea\r
+                                                       // This can be removed once you're confident it's working correctly\r
+                                                       /*\r
+                                                       var untrimmed_text = untrimmed_before_text + untrimmed_selection_text + untrimmed_after_text;\r
+                                                       var untrimmed_successful = false;\r
+                                                       if (textarea.value == untrimmed_text) {\r
+                                                               untrimmed_successful = true;\r
+                                                       } */\r
+                                                       // ** END Untrimmed success test\r
+                                               \r
+                                                       var startPoint = untrimmed_before_text.split( '\r' ).join( '' ).length;\r
+                                                       // alert(startPoint);\r
+                                                       return {\r
+                                                               'from'   : this.v1 = startPoint,\r
+                                                               'to'     : this.v2 = startPoint + untrimmed_selection_text.split( '\r' ).join( '' ).length\r
+                                                       };\r
+                                               //}\r
+                                       }\r
+                                       \r
index 3bd2e4c..c0a77d1 100644 (file)
@@ -45,8 +45,6 @@ var X_NinjaIframe = X[ 'Util' ][ 'NinjaIframe' ] = Node[ 'inherits' ](
                        this._name = 'hidden-iframe-' + X_Timer_now();\r
                        // https://github.com/polygonplanet/Pot.js/blob/master/src/Worker.js\r
 \r
-                       X_Node_newByTag = true;\r
-\r
                        this[ 'Super' ](\r
                                'IFRAME',\r
                                {\r
index 2c1d73a..7faa80c 100644 (file)
@@ -211,7 +211,7 @@ if( X_XHR_w3c || X_XHR_msXML ){
                                                        break;\r
                                                case 'json' : // firefox9- は moz-json\r
                                                        raw.responseType = X_UA[ 'Gecko' ] < 10 ? 'moz-json' : X_UA[ 'Gecko' ] ? dataType : ''; // Iron 37 でエラー\r
-                                                       //X_XHR._dataType  = 'json';\r
+                                                       X_XHR._dataType  = 'json';\r
                                                        break;\r
                                                case 'document' :\r
                                                case 'xml' :\r