OSDN Git Service

Version 0.6.213, add X.Node.TextRange.
authoritozyun <itozyun@user.sourceforge.jp>
Fri, 26 Feb 2016 08:17:01 +0000 (17:17 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Fri, 26 Feb 2016 08:17:01 +0000 (17:17 +0900)
0.6.x/js/01_core/07_XString.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/04_XBoxModel.js
0.6.x/js/02_dom/08_XNodeSelector.js
0.6.x/js/02_dom/10_XNodeAnime.js
0.6.x/js/02_dom/20_XNode.js
0.6.x/js/02_dom/30_XTextRange.js [new file with mode: 0644]
0.6.x/js/05_util/04_XXML.js
0.6.x/js/07_audio/02_XHTMLAudio.js
0.6.x/js/import.js

index 6f99ff2..788654d 100644 (file)
@@ -2,7 +2,7 @@
 // ------------------------------------------------------------------------- //\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 ),\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 ae083d7..1dc98e9 100644 (file)
@@ -270,6 +270,7 @@ X[ 'ViewPort' ] = {
                // http://orera.g.hatena.ne.jp/edvakf/20100515/1273908051
        //http://onozaty.hatenablog.com/entry/20060803/p1
        // Safari2.0.4では標準・互換どちらも document.body
+       // http://hisasann.com/housetect/2008/08/jqueryheightwidthopera95.html このdocument.body[ "client" + name ]はおそらくOpera9.5未満のバージョンで有効なんじゃないかな?
                
                X_Node_updateTimerID && X_Node_startUpdate();
                /*X_UA[ 'Opera' ] ?
index 7c94b06..bc7abf0 100644 (file)
@@ -19,6 +19,11 @@ var X_Dom_Event_devicePixelRatio = window.devicePixelRatio || ( window.screen.de
                '3' : 'pen',\r
                '4' : 'mouse'\r
        }; */\r
+       /*\r
+        * https://github.com/markleusink/ios-html5-drag-drop-shim/blob/master/ios-drag-drop.js\r
+        */\r
+       X_Dom_Event_coordinateSystemForElementFromPoint = X_UA[ 'iOS' ] < 5 ? 'page' : 'client', // iOS4 以下は clientX が undeifned...\r
+       \r
        X_Dom_Event_CANCEL_MOUSE = {},\r
        X_DomEvent;\r
 \r
@@ -31,9 +36,10 @@ if( X_Dom_Event_devicePixelRatio !== 1 ){
 if( !X_UA[ 'IE' ] || 9 <= X_UA[ 'IE' ] ){\r
        X_DomEvent = function( e, xnode ){\r
                var originalType = e.type,\r
+                       isNum = X_Type_isNumber,\r
                        type, pointerEventType,\r
                        touches, events,\r
-                       altKey, ctrlKey, metaKey, shiftKey, target, related, force,\r
+                       altKey, ctrlKey, metaKey, shiftKey, target, xtarget, offset, related, force,\r
                        elm, i, n, time, touch, ev;\r
                \r
                //this._event        = e;\r
@@ -63,11 +69,13 @@ if( !X_UA[ 'IE' ] || 9 <= X_UA[ 'IE' ] ){
                //console.log( 'original : ' + originalType + ' > ' + type );\r
                // http://msdn.microsoft.com/ja-jp/library/ie/dn304886%28v=vs.85%29.aspx\r
                // ポインター イベントの更新\r
-               if( e.pointerType ){\r
+               if( e.pointerType ||\r
+                       // IE11 の IE10 モードで click イベントの pointerType が undefined\r
+                       ( X_UA[ 'IE' ] === 10 && type === 'click' && ( e.pointerType = 'mouse' ) ) ){\r
                        // PointerEvent;\r
                        if( X_Dom_Event_convertMSPointerType ){\r
                                this[ 'pointerType' ]   = X_Dom_Event_convertMSPointerType[ e.pointerType ];\r
-                               this[ 'pressure' ]      = e.pressure || ( e.button !== -1 ? 0.5 : 0 );\r
+                               this[ 'pressure' ]      = isNum( e.pressure ) ? e.pressure : ( e.button !== -1 ? 0.5 : 0 );\r
                                // ポインターの接触形状の スクリーン ピクセル単位の幅と高さ なので変換。(多分、、、)\r
                                this[ 'width' ]         = e.width  / X_Dom_Event_devicePixelRatio;\r
                                this[ 'height' ]        = e.height / X_Dom_Event_devicePixelRatio;\r
@@ -139,11 +147,16 @@ if( !X_UA[ 'IE' ] || 9 <= X_UA[ 'IE' ] ){
                                for( i = touches.length; i; ){\r
                                        touch   = touches[ --i ];\r
                                        target  = touch.target;\r
+                                       target  = target.nodeType === 3 ? target.parentNode : target;\r
+                                       xtarget = X_Node_getXNode( target );\r
+                                       // https://developer.mozilla.org/en/docs/Web/API/Element/getBoundingClientRect\r
+                                       // Android 2+, iOS4+\r
+                                       offset  = X_UA[ 'iOS' ] < 5 ? xtarget.offset() : target.getBoundingClientRect();\r
                                        related = touch.relatedTarget;\r
                                        events[ i ] = {\r
                                                'type'          : pointerEventType,\r
                                                'pointerType'   : 'touch',\r
-                                               'target'        : X_Node_getXNode( target.nodeType === 3 ? target.parentNode : target ),// defeat Safari bug // xnodetouch.target,\r
+                                               'target'        : xtarget,// defeat Safari bug // xnodetouch.target,\r
                                                'currentTarget' : xnode,\r
                                                'relatedTarget' : related && X_Node_getXNode( related.nodeType === 3 ? related.parentNode : related ), // xnode iOS3 には relatedTarget がない\r
                                                'isPrimary'     : true,\r
@@ -158,12 +171,17 @@ if( !X_UA[ 'IE' ] || 9 <= X_UA[ 'IE' ] ){
                                                'pointerId'     : touch.identifier + 2, // iOS4 は 変換が必要!\r
                                                //screenX       : touch.screenX,\r
                                                //screenY       : touch.screenY,\r
-                                               'clientX'       : touch.clientX || ( touch.pageX - X_ViewPort_scrollX ), // iOS4以下は clientX が undefined, コードでは入れ子のスクロールに対応できない\r
-                                               'clientY'       : touch.clientY || ( touch.pageY - X_ViewPort_scrollY ),\r
                                                'pageX'         : touch.pageX,\r
-                                               'pageY'         : touch.pageY,\r
-                                               'offsetX'       : touch.offsetX, // 要素上の座標を取得 \r
-                                               'offsetY'       : touch.offsetY,\r
+                                               'pageY'         : touch.pageY,                                          \r
+                                               // iOS4 以下では clientX が undef, pageX から scrollLeft を引く.\r
+                                               // TODO getter にする?\r
+                                               'clientX'       : isNum( touch.clientX ) ? touch.clientX : ( touch.pageX - X_ViewPort_scrollX ),\r
+                                               'clientY'       : isNum( touch.clientY ) ? touch.clientY : ( touch.pageY - X_ViewPort_scrollY ),\r
+                                               // 要素上の座標を取得\r
+                                               // iOS8 でも offsetX が undef, iOS4 以下では pageX - offset.x, iOS5 以上は clientX - getBCR.left\r
+                                               // TODO getter にする?\r
+                                               'offsetX'       : isNum( touch.offsetX ) ? touch.offsetX : touch[ X_Dom_Event_coordinateSystemForElementFromPoint + 'X' ] - ( offset.x || offset.left || 0 ), \r
+                                               'offsetY'       : isNum( touch.offsetY ) ? touch.offsetY : touch[ X_Dom_Event_coordinateSystemForElementFromPoint + 'Y' ] - ( offset.y || offset.top  || 0 ),\r
                                                'radiusX'       : touch.radiusX || 0,\r
                                                'radiusY'       : touch.radiusY || 0,\r
                                                'rotationAngle' : touch.rotationAngle || 0,\r
@@ -172,6 +190,7 @@ if( !X_UA[ 'IE' ] || 9 <= X_UA[ 'IE' ] ){
                                                'height'        : touch.height || 0\r
                                        };\r
                                        //console.log( 'e.pointerId = ' + touch.identifier );\r
+                                       //X_UA[ 'iOS' ] < 5 && console.log( pointerEventType + ':[' + events[ i ].pageX + ',' + events[ i ].pageY + ']' + events[ i ].pointerId );\r
                                };\r
                                return events.length === 1 ? events[ 0 ] : events;\r
                        } else {\r
@@ -206,8 +225,8 @@ if( !X_UA[ 'IE' ] || 9 <= X_UA[ 'IE' ] ){
                                this[ 'clientY' ]       = e.clientY;\r
                                this[ 'pageX' ]         = e.pageX;\r
                                this[ 'pageY' ]         = e.pageY;\r
-                               this[ 'offsetX' ]       = e.offsetX || e.layerX; // 要素上の座標を取得 \r
-                               this[ 'offsetY' ]       = e.offsetY || e.layerY;\r
+                               this[ 'offsetX' ]       = isNum( e.offsetX ) ? e.offsetX : e.layerX; // 要素上の座標を取得 \r
+                               this[ 'offsetY' ]       = isNum( e.offsetY ) ? e.offsetY : e.layerY;\r
                                \r
                        // http://www.programming-magic.com/20090127231544/\r
                        // Opera で button==2の場合、コンテキストメニューイベントを発火 「ツール」->「設定」->「詳細設定」->「コンテンツ」->「Javascriptオプション」で「右クリックを制御するスクリプトを許可する」\r
index d96d253..d62972b 100644 (file)
@@ -237,6 +237,8 @@ function X_Node_offset(){
 // エレメントの座標取得 ~スクロール要素~\r
 // http://n-yagi.0r2.net/script/2009/07/post_16.html\r
 \r
+// TODO getClientRects Safari2- ?\r
+\r
 //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\r
 //  エレメントの絶対座標を得たい\r
 //------------------------------------------------------------------------------\r
@@ -246,7 +248,7 @@ var X_Node_getPosition =
                (\r
                        document.compatMode === 'CSS1Compat' && !X_UA[ 'Webkit' ] ? function( el ){\r
                        var pos  = el.getBoundingClientRect(),\r
-                               html = document.documentElement;\r
+                               html = X_elmHtml;\r
                        return  {   x:(pos.left + html.scrollLeft - html.clientLeft)\r
                                ,   y:(pos.top  + html.scrollTop  - html.clientTop) };\r
                        } :\r
index 1208076..2c52acb 100644 (file)
@@ -611,6 +611,7 @@ function X_Node_Selector__parse( query, last ){
                var l = xnodes.length,\r
                        i = 0,\r
                        j, child, _xnodes;\r
+\r
                for( ; i < l; ++i ){\r
                        child = xnodes[ i ];\r
                        if( !child[ '_tag' ] ) continue;\r
@@ -635,7 +636,8 @@ function X_Node_Selector__parse( query, last ){
                var l      = xnodes.length,\r
                        i      = 0,\r
                        child, uid, _tag, _xnodes;\r
-               for( ; i < l; ++i ){\r
+\r
+               for( ; i < l; ++i ){ // for( ; child = xnodes[ ++i ]; )\r
                        child = xnodes[ i ];\r
                        uid   = child[ '_uid' ];\r
                        _tag  = child[ '_tag' ];\r
index 765dec7..8ae688e 100644 (file)
@@ -12,9 +12,7 @@ var X_NodeAnime_QUEUE           = [],
        /* Opera mobile で  translateZ(0) が有効だと XY が 0 0 になる */\r
        /* GPUレイヤーにいる間に要素のコンテンツを変更をすると transitionend が動かなくなるっぽい Mac safari と firefox */\r
        X_NodeAnime_translateZ      = X_Node_CSS_VENDER_PREFIX[ 'perspective' ] &&\r
-                                                                       !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] //&&\r
-                                                                       /* ハードウェアによると思うが IE11 と Win8.1 で画面(塗)が乱れる */\r
-                                                                       /* !( ( X_UA[ 'IE' ] === 11 || X_UA[ 'IEHost' ] === 11 ) && X_UA[ 'Windows' ] === 8.1 ) */ ? ' translateZ(0)' : '',\r
+                                                                       !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] ? ' translateZ(0)' : '',\r
 \r
 /*\r
  * phase:\r
@@ -354,7 +352,7 @@ function X_NodeAnime_updateAnimations( e ){
                now  = X_Timer_now(),\r
                c    = false,\r
                i, xnode, obj, _xnode,\r
-               rm, easing, lazy;\r
+               rm, progress, easing, lazy;\r
        \r
        if( X_NodeAnime_needsDetection ){\r
                X_NodeAnime_needsDetection = false;\r
@@ -384,8 +382,8 @@ function X_NodeAnime_updateAnimations( e ){
                switch( obj.phase ){\r
                        case 7 : // アニメーション中\r
                                if( now < obj.toTime ){\r
-                                       obj.progress = ( now - obj.fromTime ) / obj.duration;\r
-                                       easing      = obj.easing( obj.progress );\r
+                                       obj.progress = progress = ( now - obj.fromTime ) / obj.duration;\r
+                                       easing      = obj.easing( progress );\r
                                        obj.x       = ( obj.toX       - obj.fromX       ) * easing + obj.fromX;\r
                                        obj.y       = ( obj.toY       - obj.fromY       ) * easing + obj.fromY;\r
                                        obj.rotate  = ( obj.toRotate  - obj.fromRotate  ) * easing + obj.fromRotate;\r
@@ -396,7 +394,7 @@ function X_NodeAnime_updateAnimations( e ){
                                        obj.alpha   = ( obj.toAlpha   - obj.fromAlpha   ) * easing + obj.fromAlpha;\r
                                        obj.scrollX = ( obj.toScrollX - obj.fromScrollX ) * easing + obj.fromScrollX;\r
                                        obj.scrollY = ( obj.toScrollY - obj.fromScrollY ) * easing + obj.fromScrollY;\r
-                                       X_NodeAnime_updatePosition( xnode, obj, obj.progress, true );\r
+                                       X_NodeAnime_updatePosition( xnode, obj, progress, true );\r
                                        c = true;\r
                                        break;\r
                                };\r
index d80b855..db671a1 100644 (file)
@@ -253,6 +253,8 @@ var Node = X[ 'Node' ] = X_EventDispatcher[ 'inherits' ](
                
                'createTextAt'   : X_Node_createTextAt,
                
+               'createRange'    : X_Node_createRange,
+               
                'clone'          : X_Node_clone,
                
                'append'         : X_Node_append,
@@ -494,6 +496,15 @@ function X_Node_createTextAt( index, text ){
 };
 
 /**
+ * 選択されたテキストへの参照やテキスト座標情報
+ * @alias Node.prototype.createRange
+ * @return {TextRange} 新規作成されたテキストレンジ
+ */
+function X_Node_createRange( a, b, c ){
+       return X_TextRange( this, a, b, c );
+};
+
+/**
  * Node のクローンを作成し返す。id もクローンされる点に注意。イベントリスナはクローンされない。
  * http://d.hatena.ne.jp/think49/20110724/1311472811
  * http://d.hatena.ne.jp/uupaa/20100508/1273299874
diff --git a/0.6.x/js/02_dom/30_XTextRange.js b/0.6.x/js/02_dom/30_XTextRange.js
new file mode 100644 (file)
index 0000000..80ddf4c
--- /dev/null
@@ -0,0 +1,275 @@
+/*\r
+ * 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
+ * tr.text()\r
+ * \r
+ * naming は mozilla に寄せる\r
+ */\r
+\r
+var X_TextRange_range,\r
+       X_TextRange_range2,\r
+       X_TextRange_isW3C = !document.selection || 10 <= X_UA[ 'IE' ];\r
+\r
+/**\r
+ * ユーザーによって選択されたテキストへの参照や文字の座標の取得\r
+ * @alias X.TextRange\r
+ * @class TextRange テキストレンジ\r
+ * @extends {__ClassBase__}\r
+ */\r
+var X_TextRange = X_Class_create(\r
+       'X.TextRange',\r
+       \r
+       /** @lends X.TextRange.prototype */\r
+       {\r
+               xnode      : null,\r
+               createFrom : '',\r
+               v1         : 0,\r
+               v2         : 0,\r
+               \r
+               'Constructor' : function( xnode, arg2, arg3, arg4 ){\r
+                       if( !X_TextRange_range ){\r
+                               X_TextRange_range = X_TextRange_isW3C ? document.createRange() : X_elmBody.createTextRange();\r
+                               if( !X_TextRange_isW3C ) X_TextRange_range2 = X_elmBody.createTextRange();\r
+                       };\r
+                       \r
+                       this.xnode = xnode;\r
+                       \r
+                       switch( arg2 ){\r
+                               case 'selection' :\r
+                                       //break;\r
+                               case 'point' :\r
+                               case 'char' :\r
+                                       this.createFrom = arg2;\r
+                                       break;\r
+                               default :\r
+                                       arg4 = arg3;\r
+                                       arg3 = arg2;\r
+                       };\r
+                       \r
+                       if( arg2 !== 'selection' ){\r
+                               this.v1 = arg3 || 0;\r
+                               this.v2 = arg4 || 0;\r
+                       };\r
+               },\r
+               \r
+               'getRect'   : X_TextRange_getRect,\r
+               \r
+               'getOffset' : X_TextRange_getOffset,\r
+               \r
+               'text'      : X_TextRange_text\r
+       }\r
+);\r
+\r
+// TextNode を探して flat な配列に格納する\r
+function X_TextRange_collectTextNodes( elm, ary ){\r
+       var kids = elm.childNodes,\r
+               i, e;\r
+       \r
+       if( !kids || !kids.length ) return;\r
+       \r
+       for( i = 0; e = kids[ i ]; ++i ){\r
+               switch( e.nodeType ){\r
+                       case 1 :\r
+                               X_TextRange_collectTextNodes( e, ary );\r
+                               break;\r
+                       case 3 :\r
+                               ary[ ary.length ] = e;\r
+                               break;\r
+               };\r
+       };\r
+};\r
+\r
+function X_TextRange_getRawRange( tr ){\r
+       var xnode = tr.xnode,\r
+                               //\r
+               range = 10 <= X_UA[ 'IE' ] /* || X_UA[ 'iOS' ] */ ? document.createRange() :\r
+                               8 <= X_UA[ 'IE' ] ? X_elmBody.createTextRange() : X_TextRange_range,\r
+               elm, selection, isPoint,\r
+               texts, i, offset, j, l, x, y, rect;\r
+       \r
+       if( xnode[ '_flags' ] & X_NodeFlags_IN_TREE ){\r
+               \r
+               X_Node_updateTimerID && X_Node_startUpdate();\r
+               \r
+               elm = xnode[ '_rawObject' ];\r
+               \r
+               switch( tr.createFrom ){\r
+                       case 'selection' :\r
+                               if( X_TextRange_isW3C ){\r
+                                       selection = window.getSelection();\r
+                                       return selection.rangeCount && selection.getRangeAt( 0 );\r
+                               } else {\r
+                                       switch( document.selection.type ){\r
+                                               case 'text' :\r
+                                                       return document.selection.createRange();\r
+                                               case 'Control' :\r
+                                                       // TODO\r
+                                               case 'none' :\r
+                                       };\r
+                               };\r
+                               break;\r
+\r
+                       case 'point' :\r
+                               isPoint = true;\r
+                       case 'char' :\r
+                               if( X_TextRange_isW3C ){\r
+                                       // textarea で異なる\r
+\r
+                                       if( isPoint ){\r
+                                               // TextNode をフラットな配列に回収\r
+                                               X_TextRange_collectTextNodes( elm, texts = [] );                                                \r
+                                               \r
+                                               for( i = offset = 0; text = texts[ i ]; ++i ){\r
+                                                       range.selectNodeContents( text ); // selectNodeContents は TextNode のみ?? Firefox\r
+                                                       l = text.data.length;\r
+\r
+                                               for( j = 0, x = tr.v1, y = tr.v2; j < l; ++j ) {\r
+                                                       if( range ){\r
+                                                           range.setStart( text, j );\r
+                                                           range.setEnd( text, j + 1 );\r
+                                                           rect = range.getBoundingClientRect();                                               \r
+                                                       };\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
+                                                       };\r
+                                                   };\r
+                                               };\r
+                                               offset += l;                                                    \r
+                                               };\r
+                                               range = null;\r
+                                       } else {\r
+                                               // 未チェック!\r
+                                               range.setEnd( elm, l < tr.v2 ? l : tr.v2 );\r
+                                   range.setStart( elm, tr.v1 );\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
+                                       } else {\r
+                                               range.moveToElementText( elm );\r
+                                               //range.collapse( true );                                               \r
+                                               range.moveEnd( 'character', l < tr.v2 ? l : tr.v2 );\r
+                                               range.moveStart( 'character', tr.v1 );\r
+                                       };\r
+                               };\r
+                               return range;\r
+               };\r
+       };\r
+};\r
+\r
+function X_TextRange_getRect(){\r
+       var result = X_TextRange_getRawRange( this ),\r
+               rect, ret;\r
+       \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
+                       };\r
+                       //range.detach && range.detach();                       \r
+               } else {\r
+                       ret = {\r
+                               'x'      : result.boundingLeft,\r
+                               'y'      : result.boundingTop,\r
+                               'width'  : result.boundingWidth,\r
+                               'height' : result.boundingHeight // ie は right, bottom を持たない...\r
+                       };\r
+               };\r
+       };\r
+       return ret || { 'x' : 0, 'y' : 0, 'width' : 0, 'height' : 0 };\r
+};\r
+\r
+// X.Text を探して flat な配列に格納する\r
+function X_TextRange_collectXTexts( xnode, ary ){\r
+       var kids = xnode[ '_xnodes' ],\r
+               i;\r
+       \r
+       if( !kids || !kids.length ) return;\r
+       \r
+       for( i = -1; xnode = kids[ ++i ]; ){\r
+               if( xnode[ '_tag' ] ){\r
+                       X_TextRange_collectXTexts( xnode, ary );\r
+               } else {\r
+                       ary[ ary.length ] = xnode;\r
+               };\r
+       };\r
+};\r
+\r
+function X_TextRange_getOffset(){\r
+       var result = X_TextRange_getRawRange( this ),\r
+               range, ret, all, from, xtexts, n, i, l, xtext;\r
+       \r
+       if( result ){\r
+               if( X_TextRange_isW3C ){\r
+                       range = result.hitRange;\r
+                       ret = {\r
+                               'offset' : result.offset,\r
+                               'from'   : range.startOffset,\r
+                               'to'     : 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
+                       \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
+                       \r
+                       if( xtexts.length ){\r
+                               // 改行が入ると正しく startIndex を取ることができない...\r
+                               for( n = l = 0, i = -1; xtext = xtexts[ ++i ]; ){\r
+                                       l = xtext[ '_text' ].length;\r
+                                       if( from < n + l ){\r
+                                               break;\r
+                                       };\r
+                                       n += l;\r
+                               };\r
+                               \r
+                               ret = {\r
+                                       'offset' : n,\r
+                                       'from'   : from - n,\r
+                                       'to'     : from - n + result.text.length,\r
+                                       'text'   : xtext\r
+                               };                              \r
+                       };\r
+               };\r
+       };\r
+       \r
+       return ret || { 'from' : -1, 'to' : -1 };\r
+};\r
+\r
+function X_TextRange_text( v ){\r
+       if( v === undefined ){\r
+               \r
+       } else {\r
+               \r
+       };\r
+};\r
+\r
index 39859ce..7930433 100644 (file)
@@ -448,6 +448,7 @@ function XMLWrapper_val( queryString, type ){
                var l = xmlList.length,\r
                        i = 0,\r
                        j, child, _xmlList;\r
+\r
                for( ; i < l; ++i ){\r
                        child = xmlList[ i ];\r
                        //if( child.nodeType !== 1 ) continue;\r
@@ -473,6 +474,7 @@ function XMLWrapper_val( queryString, type ){
                        l      = xmlList.length,\r
                        i      = 0,\r
                        child;\r
+\r
                for( ; i < l; ++i ){\r
                        child = xmlList[ i ];\r
                        if( child.nodeType === 1 ){\r
index ac38571..b5abcd2 100644 (file)
@@ -280,7 +280,9 @@ if( X_Audio_constructor ){
                                                } else\r
                                                if( this.playing ){\r
                                                        end = X_Audio_getEndTime( this ) + this._shortPlayFixTime;\r
-                                                       //console.log( now + ' / ' + end );\r
+                                                       \r
+                                                       console.log( now + ' / ' + end );// Firefox44.0.2 で音声の再生開始に難あり...\r
+                                                       \r
                                                        if( ( 0 + end <= 0 + now ) || // 0+ なぜか iem9 で必要,,,\r
                                                                ( now < this._lastCurrentTime && now < 2000 ) ){\r
                                                                //( ( X_HTMLAudio_endedFixAOSP2 || X_HTMLAudio_endedFixAOSP4 ) && ( now < this._lastCurrentTime && now < 1000 ) ) ){\r
index 41c69a2..014ed63 100644 (file)
@@ -43,6 +43,7 @@ document.write( [
                'js/02_dom/10_XNodeAnime.js',\r
                'js/02_dom/20_XNode.js',\r
                'js/02_dom/22_XTreeBuilder.js',\r
+               'js/02_dom/30_XTextRange.js',\r
 \r
                'js/03_plugin/00_XPlugin.js',\r
 \r