OSDN Git Service

Version 0.6.179, fix X.Audio & X.AudioSprite.
authoritozyun <itozyun@user.sourceforge.jp>
Sun, 18 Oct 2015 15:13:30 +0000 (00:13 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Sun, 18 Oct 2015 15:13:30 +0000 (00:13 +0900)
19 files changed:
0.6.x/js/01_core/00_builtin.js
0.6.x/js/01_core/02_XUA.js
0.6.x/js/01_core/04_XObject.js
0.6.x/js/01_core/13_XClass.js
0.6.x/js/01_core/14_XEvent.js
0.6.x/js/01_core/16_XTimer.js
0.6.x/js/01_core/21_XViewPort.js
0.6.x/js/02_dom/02_XNodeFlags.js
0.6.x/js/02_dom/07_XNodeList.js
0.6.x/js/02_dom/09_XHTMLParser.js
0.6.x/js/02_dom/20_XNode.js
0.6.x/js/02_dom/22_XTreeBuilder.js
0.6.x/js/03_plugin/00_XPlugin.js
0.6.x/js/05_util/02_XJSON.js
0.6.x/js/05_util/04_XXML.js
0.6.x/js/06_net/01_XNetXHR.js
0.6.x/js/07_audio/01_XWebAudio.js
0.6.x/js/07_audio/02_XHTMLAudio.js
0.6.x/js/07_audio/10_XAudioSprite.js

index 17b1dc3..e483e4e 100644 (file)
@@ -274,82 +274,3 @@ if (window.ActiveXObject ? !Number.prototype.toFixed : (!navigator.taintEnabled
                };\r
        })(); */\r
        \r
-/*\r
- * Safari の JavaScript の不備 \r
- * http://nanto.asablo.jp/blog/2006/01/13/209495\r
- * \r
- * web.paulownia.jp - JavaScriptとクロージャ\r
- * https://web.archive.org/web/20070526063400/http://web.paulownia.jp/script/oop/closure.html\r
- * MacOSX 10.3のsafariにはhasOwnPropertyが実装されていないので、独自に追加する必要があります。\r
- * \r
- * prototype汚染問題でhasOwnPropertyを使わないクロスブラウザな方法\r
- * http://os0x.hatenablog.com/entry/20080901/1220272509\r
- */\r
-/*\r
-Object.prototype.hasOwnProperty || (Object.prototype.hasOwnProperty = function( p ){\r
-               var proto = this.constructor && this.constructor.prototype,\r
-                       __p__ = proto && proto.__proto__,\r
-                       v     = this[ p ],\r
-                       r     = false;\r
-               \r
-               if( __p__ ) proto.__proto__ = null;\r
-               \r
-               if( p in this ){\r
-                       if( v !== v ){\r
-                               if( proto && ( p in proto ) && proto[ p ] !== proto[ p ] ){ // proto[ p ] is NaN\r
-                                       proto[ p ] = 0; // different value\r
-                                       r = this[ p ] !== this[ p ]; // isNaN?\r
-                                       proto[ p ] = v; // set NaN\r
-                               } else {\r
-                                       r = true;\r
-                               };\r
-                       } else\r
-                       if( proto && p in proto && proto[ p ] === v ){\r
-                               // this と proto に同名で同値が書かれている可能性あり\r
-                               proto[ p ] = v + ' '; // different value\r
-                               r = v === this[ p ];\r
-                               proto[ p ] = v;\r
-                       } else {\r
-                               r = true;\r
-                       };\r
-               };\r
-               \r
-               if( __p__ ) proto.__proto__ = __p__;\r
-               \r
-               return r;\r
-  }); */\r
-/*\r
-Object.prototype.hasOwnProperty || (Object.prototype.hasOwnProperty = function( p ){\r
-               var proto = this.constructor && this.constructor.prototype,\r
-                       __p__ = proto && proto.__proto__,\r
-                       r     = false,//!!( __p__ && ( proto.__proto__ = null ) )\r
-                       _pro_, v, isNaN;\r
-               \r
-               if( __p__ ) proto.__proto__ = null;\r
-               if( this.__proto__ ){\r
-                       _pro_ = this.__proto__;\r
-                       this.__proto__ = null;\r
-               };\r
-               \r
-               if( p === '__proto__' ){\r
-                       r = !!_pro_;\r
-               } else {\r
-                       v     = this[ p ];\r
-                       isNaN = v !== v;                \r
-                       \r
-                       if( p in this ){\r
-                               if( proto && p in proto && ( proto[ p ] === v ) ^ isNaN ){ //true + false, false + true\r
-                                       // this と proto に同名で同値が書かれている可能性あり\r
-                                       proto[ p ] = v + ' '; // different value\r
-                                       r = ( v === this[ p ] ) ^ isNaN; // true + false, false + true\r
-                                       proto[ p ] = v;\r
-                               } else {\r
-                                       r = true;\r
-                               };\r
-                       };                      \r
-               };\r
-\r
-               if( __p__ ) proto.__proto__ = __p__;\r
-               if( _p_ ) this.__proto__ = _pro_;\r
-               return r;\r
-  }); */
\ No newline at end of file
index 0d03ee6..c639e70 100644 (file)
@@ -262,6 +262,10 @@ var X_UA = X[ 'UA' ] = {},
                         */\r
                        X_UA[ 'Android' ]  = X_UA[ 'AndroidMajor' ] + X_UA[ 'AndroidMinor' ] / 10;\r
                        console.log( '>> Android : ' + X_UA[ 'Android' ]  );\r
+               } else\r
+               if( dua.indexOf( 'Android;' ) !== -1 ){\r
+                       // Fennec 用\r
+                       X_UA[ 'Android' ] = 2;\r
                };\r
        };\r
        \r
@@ -338,12 +342,15 @@ var X_UA = X[ 'UA' ] = {},
                X_UA[ 'Trident' ]  = parseFloat(dav.split('Trident/')[1]) || 0;\r
                \r
                tridentToVer       = X_UA[ 'Trident' ] ? ( X_UA[ 'Trident' ] + 4 | 0 ) : X_UA[ '_IE' ];\r
-               /**\r
-                * IE10 以上の互換モードを使用している場合、そのバージョン\r
-                * @alias X.UA.IEHost\r
-                * @type {number}\r
-                */\r
-               if( tridentToVer !== X_UA[ '_IE' ] ) X_UA[ 'IEHost' ] = tridentToVer;\r
+\r
+               if( tridentToVer !== X_UA[ '_IE' ] ){\r
+                       /**\r
+                        * IE10 以上の互換モードを使用している場合、そのバージョン\r
+                        * @alias X.UA.IEHost\r
+                        * @type {number}\r
+                        */                     \r
+                       X_UA[ 'IEHost' ] = tridentToVer;\r
+               };\r
                /**\r
                 * documentモードを考慮したIEのバージョン\r
                 * @alias X.UA.IE\r
@@ -570,7 +577,7 @@ var X_UA = X[ 'UA' ] = {},
                };\r
                \r
                console.log( '>> Gecko : ' + X_UA[ 'Gecko' ] );\r
-       };\r
+       } else\r
        \r
        // Android 標準ブラウザ AOSP と ChromeWeb View, Sブラウザがある\r
        if( ( v = X_UA[ 'Android' ] ) &&\r
@@ -812,7 +819,9 @@ X_UA_ATagWrapDiv = (function( e, h ){
 \r
 console.log( 'HTML5? ' + X_UA_ATagWrapDiv ); */\r
 \r
-var X_Script_VBS_ENABLED = X_UA[ 'Windows' ] && !X_UA[ 'WinCE' ] && !X_UA[ 'WinPhone' ] && X_UA[ 'IE' ] < 11;\r
+var X_Script_VBS_ENABLED = X_UA[ 'Windows' ] && !X_UA[ 'WinCE' ] && !X_UA[ 'WinPhone' ] && X_UA[ 'IE' ] < 11,\r
+       // 構文のサポート instanceof, in(for-in ではない), try-catch. JS version 1.5以上\r
+       X_Script_gte15       = !( X_UA[ 'IE' ] < 5.5 ) && ( new Function( 'f,a', 'try{return f.apply({},a)}catch(e){}' ) );\r
 \r
 /**\r
  * js バージョン間の際を吸収\r
@@ -824,51 +833,63 @@ X[ 'Script' ] = {
        'tryCatch' : X_Script_try\r
 };\r
 \r
-if( X_UA[ 'IE' ] < 9 && X_Script_VBS_ENABLED ){\r
-       (function( lines ){\r
-               var s = document.createElement( 'script' );\r
-               X_elmHead.appendChild( s );\r
-               s.type = 'text/vbscript';\r
-               s.text = lines.join( '\n' );\r
-               \r
-       })( [\r
-                               'Function vba_testAXO(v)',\r
-                                       'On Error Resume Next',\r
-                                       'Set ax = CreateObject(v)',\r
-                                       'If Err.Number Then',\r
-                                               'ax = 1',\r
-                                       'End If',\r
-                                       'Err.Clear',\r
-                                       'vba_testAXO = ax',\r
-                               'End Function' /*,\r
-                               \r
-                               'Function vba_try(jsFunc,a1,a2,a3,a4)',\r
-                                       'On Error Resume Next',\r
-                                       'Set rs = jsFunc(a1,a2,a3,a4)',\r
-                                       'If Err.Number != 0 Then',\r
-                                               'rs = 0',\r
-                                       'End If',\r
-                                       'Err.Clear',\r
-                                       'vba_try = rs',\r
-                               'End Function' */\r
-               ] );\r
-       \r
+if( X_Script_VBS_ENABLED ){\r
+       X_Script_gte15 || document.write( '<script type=text/vbscript>' +\r
+               [\r
+                       'Function vbs_testAXO(v)',\r
+                               'On Error Resume Next',\r
+                               'Set ax = CreateObject(v)',\r
+                               'If Err.Number Then',\r
+                                       'ax = 1',\r
+                               'End If',\r
+                               'Err.Clear',\r
+                               'vbs_testAXO = ax',\r
+                       'End Function' /*,\r
+                       \r
+                       'Function vbs_try(jsFunc,a1,a2,a3,a4)',\r
+                               'On Error Resume Next',\r
+                               'Set rs = jsFunc(a1,a2,a3,a4)',\r
+                               'If Err.Number != 0 Then',\r
+                                       'rs = 0',\r
+                               'End If',\r
+                               'Err.Clear',\r
+                               'vbs_try = rs',\r
+                       'End Function'\r
+                       \r
+                       // elementID .SRC = v\r
+                       'Function vbs_setValue(id,k,v)',\r
+                               'On Error Resume Next',\r
+                               'Set rs = 1',\r
+                               'Document.all[id][k]=v',\r
+                               'If Err.Number != 0 Then',\r
+                                       'rs = 0',\r
+                               'End If',\r
+                               'Err.Clear',\r
+                               'vbs_try = rs',\r
+                       'End Function'\r
+\r
+                       * \r
+                       * \r
+                       * */\r
+               ].join( '\n' ) + '</script>' );\r
+\r
        // TODO Object のメンバを辿る vba\r
+       // byte Array を扱う vba\r
 };\r
 \r
 function X_Script_try( func, args ){\r
-       if( X_UA[ 'IE' ] < 5.5 ){\r
+       if( !X_Script_gte15 ){\r
                //return func.apply( {}, args );\r
                return;\r
        };\r
-       return ( new Function( 'f,a', 'try{return f.apply({},a)}catch(e){}' ) )( func, args || [] );\r
+       return X_Script_gte15( func, args || [] );\r
 };\r
 \r
 function X_Script_createActiveXObjectSafty( name ){\r
-       if( X_UA[ 'IE' ] < 9 ){\r
+       if( !X_Script_gte15 ){\r
                if( X_Script_VBS_ENABLED ){\r
-                       console.log( window[ 'vba_testAXO' ]( name ) + ' ' + name );\r
-                       return !window[ 'vba_testAXO' ]( name ) && X_Script_createActiveXObject( name );\r
+                       // console.log( window[ 'vbs_testAXO' ]( name ) + ' ' + name );\r
+                       return !window[ 'vbs_testAXO' ]( name ) && X_Script_createActiveXObject( name );\r
                };\r
                return X_Script_createActiveXObject( name );\r
        };\r
@@ -880,18 +901,18 @@ function X_Script_createActiveXObject( name ){
        return new ActiveXObject( name );\r
 };\r
 \r
-// TODO 構文のサポート instanceof, in, try catch\r
-\r
-if( X_UA[ 'IE' ] < 7 ){ // error @ NN7.2\r
-       X_UA[ 'IE4' ] || X_UA[ 'IE5' ] || X_UA[ 'MacIE' ] ?\r
-               document.execCommand && document.execCommand( 'BackgroundImageCache', false, true ) :\r
-               (\r
-                       X_Script_try( function(){ document.execCommand( 'BackgroundImageCache', false, true ); return 1; } ) &&\r
-                               /**\r
-                                * ie7 以下で実行する document.execCommand( 'BackgroundImageCache', false, true ) の失敗。\r
-                                * bonus: hotfix for IE6 SP1 (bug KB823727)\r
-                                * multipleIEs IE6 standalone 版では不可, IE5.5 は可,,,\r
-                                * @alias X.UA.ieExeComError */                 \r
-                               ( X_UA[ 'ieExeComError' ] = true )\r
-               );\r
+/*\r
+ * http://archiva.jp/web/html-css/ie6_background_flickr.html\r
+ * hover時の背景画像ちらつきに対処する\r
+ * この問題はIE6固有の問題であり、他のモダンブラウザやIE5等では発現しない。\r
+ */\r
+if( X_UA[ 'IE6' ] && // error @ NN7.2\r
+       !X_Script_try( function(){ document.execCommand( 'BackgroundImageCache', false, true ); return 1; } ) ){\r
+               /**\r
+                * ie6 のみで実行する document.execCommand( 'BackgroundImageCache', false, true ) の失敗。\r
+                * bonus: hotfix for IE6 SP1 (bug KB823727)\r
+                * multipleIEs IE6 standalone 版では不可, IE5.5 は可,,,\r
+                * @alias X.UA.ieExeComError */\r
+               X_UA[ 'ieExeComError' ] = true;\r
 };\r
+\r
index 9ee8197..329973d 100644 (file)
@@ -7,12 +7,12 @@
  * @param {object} obj \r
  * @return {boolean} name が定義されている(値が undefined や null でも) -> true\r
  */\r
-var X_Object_inObject = X_UA[ 'IE' ] < 5.5 ? // TODO JScript で判定\r
-       (function( name, obj, p ){\r
-               if( obj[ name ] ) return true; // quick\r
+var X_Object_inObject = !X_Script_gte15 ? // TODO JScript で判定\r
+       (function( name, obj, _ ){\r
                name += ''; // 数値も許可\r
-               for( p in obj ){\r
-                       if( p === name ) return true;\r
+               if( obj[ name ] ) return true; // quick\r
+               for( _ in obj ){\r
+                       if( _ === name ) return true;\r
                };\r
                return false;\r
        }) :\r
@@ -170,3 +170,86 @@ function X_Object_find( obj, selector ){
        return obj;\r
 };\r
 \r
+// TODO X.Object.own( obj, name )\r
+/*\r
+ * Safari の JavaScript の不備 \r
+ * http://nanto.asablo.jp/blog/2006/01/13/209495\r
+ * \r
+ * web.paulownia.jp - JavaScriptとクロージャ\r
+ * https://web.archive.org/web/20070526063400/http://web.paulownia.jp/script/oop/closure.html\r
+ * MacOSX 10.3のsafariにはhasOwnPropertyが実装されていないので、独自に追加する必要があります。\r
+ * \r
+ * prototype汚染問題でhasOwnPropertyを使わないクロスブラウザな方法\r
+ * http://os0x.hatenablog.com/entry/20080901/1220272509\r
+ */\r
+/*\r
+Object.prototype.hasOwnProperty || (Object.prototype.hasOwnProperty = function( p ){\r
+               var proto = this.constructor && this.constructor.prototype,\r
+                       __p__ = proto && proto.__proto__,\r
+                       v     = this[ p ],\r
+                       r     = false;\r
+               \r
+               if( __p__ ) proto.__proto__ = null;\r
+               \r
+               if( p in this ){\r
+                       if( v !== v ){\r
+                               if( proto && ( p in proto ) && proto[ p ] !== proto[ p ] ){ // proto[ p ] is NaN\r
+                                       proto[ p ] = 0; // different value\r
+                                       r = this[ p ] !== this[ p ]; // isNaN?\r
+                                       proto[ p ] = v; // set NaN\r
+                               } else {\r
+                                       r = true;\r
+                               };\r
+                       } else\r
+                       if( proto && p in proto && proto[ p ] === v ){\r
+                               // this と proto に同名で同値が書かれている可能性あり\r
+                               proto[ p ] = v + ' '; // different value\r
+                               r = v === this[ p ];\r
+                               proto[ p ] = v;\r
+                       } else {\r
+                               r = true;\r
+                       };\r
+               };\r
+               \r
+               if( __p__ ) proto.__proto__ = __p__;\r
+               \r
+               return r;\r
+  }); */\r
+/*\r
+Object.prototype.hasOwnProperty || (Object.prototype.hasOwnProperty = function( p ){\r
+               var proto = this.constructor && this.constructor.prototype,\r
+                       __p__ = proto && proto.__proto__,\r
+                       r     = false,//!!( __p__ && ( proto.__proto__ = null ) )\r
+                       _pro_, v, isNaN;\r
+               \r
+               if( __p__ ) proto.__proto__ = null;\r
+               if( this.__proto__ ){\r
+                       _pro_ = this.__proto__;\r
+                       this.__proto__ = null;\r
+               };\r
+               \r
+               if( p === '__proto__' ){\r
+                       r = !!_pro_;\r
+               } else {\r
+                       v     = this[ p ];\r
+                       isNaN = v !== v;                \r
+                       \r
+                       if( p in this ){\r
+                               if( proto && p in proto && ( proto[ p ] === v ) ^ isNaN ){ //true + false, false + true\r
+                                       // this と proto に同名で同値が書かれている可能性あり\r
+                                       proto[ p ] = v + ' '; // different value\r
+                                       r = ( v === this[ p ] ) ^ isNaN; // true + false, false + true\r
+                                       proto[ p ] = v;\r
+                               } else {\r
+                                       r = true;\r
+                               };\r
+                       };                      \r
+               };\r
+\r
+               if( __p__ ) proto.__proto__ = __p__;\r
+               if( _p_ ) this.__proto__ = _pro_;\r
+               return r;\r
+  }); */\r
\r
\r
+\r
index bb0a857..f5cdc03 100644 (file)
@@ -584,6 +584,11 @@ function X_Class_actualConstructor( f, args ){
        \r
        def.live && def.live.push( instance );\r
 \r
+       if( ( X_UA[ 'AOSP' ] < 3 || X_UA[ 'iOS' ] < 5 ) && instance.constructor !== klass ){\r
+               console.log( '------- constructor の不一致!' ); // Android2.3.7\r
+               instance.constructor = klass;\r
+       };\r
+\r
        obj = def.Constructor ?\r
                        def.Constructor.apply( instance, args ) :\r
                def.SuperConstructor &&\r
@@ -593,6 +598,7 @@ function X_Class_actualConstructor( f, args ){
                instance[ 'kill' ]();\r
                return obj;\r
        };\r
+       \r
        return instance;\r
 };\r
 \r
index e2a5cda..0741a18 100644 (file)
@@ -110,7 +110,9 @@ var // 内部イベント
        \r
        X_EVENT_NEED_AUTH              = 49,\r
        \r
-       X_Event_last                   = 49;\r
+       X_EVENT_DEBUG                  = 50,\r
+       \r
+       X_Event_last                   = 50;\r
 \r
 // in_page_jump\r
 // on_screen_keyboard_show\r
@@ -221,7 +223,9 @@ X[ 'Event' ] = /** @lends X.Event */
        'MEDIA_WAITING'          : X_EVENT_MEDIA_WAITING,\r
        'MEDIA_SEEKING'          : X_EVENT_MEDIA_SEEKING,\r
        \r
-       'NEED_AUTH'              : X_EVENT_NEED_AUTH\r
+       'NEED_AUTH'              : X_EVENT_NEED_AUTH,\r
+       \r
+       'DEBUG'                  : X_EVENT_DEBUG\r
 };\r
 \r
 X_TEMP.onSystemReady.push(\r
index 681d5f8..2c00513 100644 (file)
@@ -44,9 +44,7 @@ var
         */\r
        X_Timer_now = Date.now || ( function(){ return +new Date; } ),\r
 \r
-       X_Timer_SET_TIMEOUT   = window.setTimeout,\r
-       X_Timer_CLEAR_TIMEOUT = window.clearTimeout,\r
-\r
+       // TODO X.AF.request, X.AF.cancel\r
        // http://uupaa.hatenablog.com/entry/2012/02/01/083607\r
        // Firefox 4 partial (request only), Mobile Firefox5 ready (request only), Firefox 11 ready (cancel impl)       \r
        X_Timer_REQ_ANIME_FRAME =\r
@@ -183,6 +181,8 @@ var
  * @alias X.Timer\r
  */ \r
 X[ 'Timer' ] = {\r
+       // TODO IE4 の resolution は 64ms\r
+       'RESOLUTION'   : X_Timer_INTERVAL_TIME,\r
 \r
        'now'          : X_Timer_now,\r
        \r
@@ -216,6 +216,7 @@ X[ 'Timer' ] = {
        function X_Timer_add( time, opt_count, args1, args2, args3 ){\r
                var list = X_Timer_TICKET_LIST,\r
                        hash, obj;\r
+\r
                time = time < X_Timer_INTERVAL_TIME ? 1 : time / X_Timer_INTERVAL_TIME | 0; // 正の数で使える「Math.floor(x)」を「(x | 0)」に;\r
                \r
                if( !X_Type_isNumber( opt_count ) ){\r
@@ -290,7 +291,7 @@ X[ 'Timer' ] = {
        };\r
 \r
 if( X_UA[ 'IE4' ] || X_UA[ 'MacIE' ] ){\r
-       X.Timer[ '_' ] = X_Timer_onTimeout;\r
+       X[ 'Timer' ][ '_' ] = X_Timer_onTimeout;\r
        X_Timer_onTimeout = 'X.Timer._()';\r
 };\r
 \r
@@ -368,7 +369,7 @@ function X_Timer_update(){
                i    = list.length,\r
                n;\r
        if( i === 0 ){\r
-               X_Timer_timerId && X_Timer_CLEAR_TIMEOUT( X_Timer_timerId );\r
+               X_Timer_timerId && clearTimeout( X_Timer_timerId );\r
                X_Timer_timerId = 0;\r
                return;\r
        };\r
@@ -379,12 +380,12 @@ function X_Timer_update(){
     \r
     if( n < X_Timer_waitTime || X_Timer_timerId === 0 ){\r
        if( X_Timer_timerId ){\r
-               X_Timer_CLEAR_TIMEOUT( X_Timer_timerId );\r
-               n -= ( X_Timer_now() - X_Timer_timeStamp ) / X_Timer_INTERVAL_TIME | 0;\r
+               clearTimeout( X_Timer_timerId );\r
+               n -= ( X_Timer_now() - X_Timer_timeStamp ) / X_Timer_INTERVAL_TIME;\r
                0 <= n || ( n = 0 ); // 負の数は 0 に\r
        };\r
        X_Timer_timeStamp = X_Timer_now();\r
-       X_Timer_timerId   = X_Timer_SET_TIMEOUT( X_Timer_onTimeout, X_Timer_INTERVAL_TIME * n );\r
+       X_Timer_timerId   = setTimeout( X_Timer_onTimeout, X_Timer_INTERVAL_TIME * n | 0 );\r
        X_Timer_waitTime  = n;\r
     };\r
 };\r
@@ -405,10 +406,10 @@ if( X_UA[ 'iOS' ] ){
        window.addEventListener( 'scroll', function(){\r
                var last, now;\r
                if( X_Timer_timerId ){\r
-                       X_Timer_CLEAR_TIMEOUT( X_Timer_timerId );\r
+                       clearTimeout( X_Timer_timerId );\r
                        now               = X_Timer_now();\r
                        last              = X_Timer_timeStamp + X_Timer_INTERVAL_TIME * X_Timer_waitTime - now;\r
-                       X_Timer_timerId   = X_Timer_SET_TIMEOUT( X_Timer_onTimeout, 0 < last ? last : 0 );\r
+                       X_Timer_timerId   = setTimeout( X_Timer_onTimeout, 0 < last ? last : 0 );\r
                        // 更新\r
                        X_Timer_timeStamp = now;\r
                        X_Timer_waitTime  = last / X_Timer_INTERVAL_TIME | 0;\r
index c83d9de..a89df05 100644 (file)
@@ -51,7 +51,7 @@ X_ViewPort = X_Class_override(
                                        X_ViewPort[ 'dispatch' ]( X_EVENT_UNLOAD );
                                //alert('unload');
                                        X_ViewPort_document[ 'kill' ]();
-                                       this[ 'kill' ]();
+                                       X_ViewPort[ 'kill' ]();
                                        
                                        //X_System[ 'dispatch' ]( X_EVENT_SHUT_DOWN );
                                        break;
@@ -415,7 +415,7 @@ X[ 'ViewPort' ] = {
                };
 
                X_TEMP.onDomContentLoaded = function(){
-                       var s, size, html, head, body;
+                       var html, head, body;
                        
                        console.log( '> X_TEMP.onDomContentLoaded rs:' + X_ViewPort_readyState );
                        
@@ -537,13 +537,10 @@ X[ 'ViewPort' ] = {
 console.log( '------------------->' );
 
                        if( document[ 'webkitHidden' ] !== undefined ){
-                               console.log( '--> has webkitvisibilitychange' );
                                X_EventDispatcher_systemListen( X_ViewPort_document, 'webkitvisibilitychange', X_ViewPort );
                        } else
                        if( document[ 'hidden' ] !== undefined ){// iOS 7+
-                               console.log( '--> has visibilitychange' );
                                X_EventDispatcher_systemListen( X_ViewPort_document, 'visibilitychange', X_ViewPort );
-                               document.onvisibilitychange = function(){ console.log( '!!!!!!!!!!!!!!!!' ) };
                        } else
                        if( document[ 'msHidden' ] !== undefined ){
                                X_EventDispatcher_systemListen( X_ViewPort_document, 'msvisibilitychange', X_ViewPort );
@@ -553,12 +550,10 @@ console.log( '------------------->' );
                        };
                        
                        if( window[ 'onpageshow' ] !== undefined ){
-                               console.log( '-------------------> pageshow, pagehide' );
                                X_EventDispatcher_systemListen( X_ViewPort, [ 'pageshow', 'pagehide' ] );
                        };
                        
                        if( document[ 'onfocusin' ] !== undefined ){
-                               console.log( '-------------------> focusin, focusout' );
                                // https://github.com/ai/visibilityjs/blob/master/lib/visibility.fallback.js
                                X_EventDispatcher_systemListen( X_ViewPort_document, [ 'focusin', 'focusout' ], X_ViewPort );
                        };
index 0a9fad8..c6faba9 100644 (file)
@@ -61,6 +61,8 @@ var X_NodeFlags_DESTROYED              = 0x0,
                                };\r
                                return 0;\r
                        })(),\r
+       \r
+       X_NodeFlags_SYSTEM_NODE     = 2 << 27,\r
 \r
        X_Node_BITMASK_RESET_STYLE  = ( ( 2 << 29 ) - 1 + ( 2 << 29 ) ) ^ (\r
                X_NodeFlags_STYLE_IS_DISPLAY_NONE |\r
index be45a3b..8e8702e 100644 (file)
@@ -53,15 +53,17 @@ X_NodeList.prototype[ 'each' ] = function( func /* opt_args... */ ){
 X_TEMP.onSystemReady.push( function( sys ){\r
        var target = X_NodeList.prototype,\r
                src    = Node.prototype,\r
-               p, v, multi;\r
+               p, v;\r
        for( p in src ){\r
                //if( X_EMPTY_OBJECT[ p ] ) continue;\r
                v = src[ p ];\r
                if( X_Type_isFunction( v ) && !target[ p ] ){\r
-                       target[ p ] = multi = new Function( [\r
+                       target[ p ] = new Function( [\r
                                'var a=arguments,f=X.Node.prototype.', p, ',t=this,i,l=t.length;',\r
                                'if(l)',\r
-                                       'for(i=0;i<l;++i)if(i===l-1)return f.apply(t[i],a);else f.apply(t[i],a);',\r
+                                       'for(i=0;i<l;++i)',\r
+                                               'if(i===l-1)return f.apply(t[i],a);',\r
+                                               'else f.apply(t[i],a);',\r
                                'return f.apply(t,a)'\r
                        ].join( '' ) );\r
                };\r
index 6aa4f7f..27f2164 100644 (file)
@@ -120,7 +120,7 @@ var X_HTMLParser_CHARS = {
                                return;\r
                        };\r
                        \r
-                       if( async && startTime + 15 <= X_Timer_now() && html ){\r
+                       if( async && startTime + X_Timer_INTERVAL_TIME <= X_Timer_now() && html ){\r
                                handler.progress( 1 - html.length / async[ 0 ] );\r
                                X_Timer_once( 0, X_HTMLParser_exec, [ html, handler, async ] );\r
                                return;\r
index 7fb2e40..b775d71 100644 (file)
@@ -1223,7 +1223,7 @@ function X_Node_call( name /*, opt_args... */ ){
        };
        
        if( name === 'inView' ){
-               body   = document.body;
+               body   = X_elmBody;
                child  = raw;
                visibleX = visibleY = visibleW = visibleH = 0;
                while( child !== body ){
@@ -1461,7 +1461,7 @@ var X_Node__commitUpdate =
                        if( !elm ){
                                if( !that[ '_tag' ] ){
                                        that[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
-                                       that[ '_rawObject' ] = elm = document.createTextNode( X_String_chrReferanceTo( that[ '_text' ] ) );
+                                       elm = document.createTextNode( X_String_chrReferanceTo( that[ '_text' ] ) );
                                        if( !X_UA[ 'IE' ] ){
                                                elm[ 'UID' ] = that[ '_uid' ];
                                        };
@@ -1469,7 +1469,7 @@ var X_Node__commitUpdate =
                                if( X_Node_strictElmCreation ){
                                        that[ '_flags' ] & X_NodeFlags_OLD_CSSTEXT && X_Node_CSS_objToCssText( that, true ); // OLD_CSSTEXT ??
                
-                                       that[ '_rawObject' ] = elm =
+                                       elm =
                                                document.createElement( [
                                                        '<', that[ '_tag' ],
                                                                ' UID="', that[ '_uid' ], '"',
@@ -1478,14 +1478,15 @@ var X_Node__commitUpdate =
                                                                X_Node_Attr_objToAttrText( that, true ),
                                                                that[ '_cssText' ] ? ' style="' + that[ '_cssText' ] + '"' : '',
                                                        '>' ].join( '' ) );
+                               } else
+                               if( that[ '_flags' ] & X_NodeFlags_IS_SVG ){
+                                       elm = document.createElementNS( 'http://www.w3.org/2000/svg', that[ '_tag' ].toLowerCase() );
                                } else {
-                                       if( that[ '_flags' ] & X_NodeFlags_IS_SVG ){
-                                               that[ '_rawObject' ] = elm = document.createElementNS( 'http://www.w3.org/2000/svg', that[ '_tag' ].toLowerCase() );
-                                       } else {
-                                               that[ '_rawObject' ] = elm = document.createElement( that[ '_tag' ] );
-                                       };
+                                       elm = document.createElement( that[ '_tag' ] );
                                };
                                
+                               that[ '_rawObject' ] = elm;
+                               
                                // IE には要素追加のタイミングで起こるメモリリークがありここで追加
                                if( !X_Node_addTreeAfterChildren ){
                                        nextElement ?
index 868261e..530b094 100644 (file)
@@ -41,12 +41,12 @@ if( X_UA[ 'MacIE' ] ){
                                e.appendChild( node );\r
                                parent.removeChild( e );\r
                                node.parentNode = null;\r
-                               document.body.appendChild( node );\r
+                               X_elmBody.appendChild( node );\r
                                parent.replaceChild( document.createComment( '' ), node ); */\r
-                               document.body.appendChild( node );\r
+                               X_elmBody.appendChild( node );\r
                                return;\r
                                /*\r
-                               if( parent.parentNode !== document.body ){\r
+                               if( parent.parentNode !== X_elmBody ){\r
                                        var clone = parent.cloneNode( true );\r
                                        for( var i = 0, l = parent.childNodes.length; i < l; ++i ){\r
                                                if( parent.childNodes[ i ] !== node ){\r
@@ -112,7 +112,7 @@ X_TEMP._onPreInit =
        X_UA_DOM.W3C ?\r
 (function(){\r
        var r    = X_Node_body,\r
-               body = r[ '_rawObject' ],\r
+               body = X_elmBody,\r
                copy, i, l, node, html,\r
                elmProgress;\r
        \r
@@ -124,7 +124,7 @@ X_TEMP._onPreInit =
        // textarea の内容を控えて、消す。xnode tree 構築後に復帰。でないと、html パースでこける\r
        //X_UA[ 'MacIE' ] && alert( body.innerHTML );\r
        // cleanup tree \r
-       function cleanUpTree( elm, skip, head ){\r
+       function cleanUpTree( elm, skip ){\r
                var nodes      = X_Array_copy( elm.childNodes ),\r
                        i          = 0,\r
                        l          = nodes.length,\r
@@ -135,8 +135,7 @@ X_TEMP._onPreInit =
                                case 1 :\r
                                        tag = node.tagName.toUpperCase();\r
                                        if( X_Dom_DTD_MOVE_TO_HEAD[ tag ] ){\r
-                                               head = head || document.getElementsByTagName( 'head' )[ 0 ];\r
-                                               head.appendChild( node );\r
+                                               X_elmHead.appendChild( node );\r
                                                continue;\r
                                        } else\r
                                        if( X_TEMP._isCleanupTarget( node ) ){\r
@@ -144,7 +143,7 @@ X_TEMP._onPreInit =
                                                continue;\r
                                        } else {\r
                                                // pre タグ以下はスペースの置換は行わない\r
-                                               node.childNodes && node.childNodes.length && cleanUpTree( node, skip || X_Dom_DTD_SKIP_CLEANUP_TAGS[ tag ], head );\r
+                                               node.childNodes && node.childNodes.length && cleanUpTree( node, skip || X_Dom_DTD_SKIP_CLEANUP_TAGS[ tag ] );\r
                                        };\r
                                        textNode = null;\r
                                        break;\r
@@ -198,8 +197,6 @@ X_TEMP._onPreInit =
        elmProgress.style.cssText = 'position:absolute;top:0;left:0;z-index:9999;width:0;height:0.5em;background:#00f;overflow:hidden;';\r
        elmProgress.setAttribute( 'style', 'position:absolute;top:0;left:0;z-index:9999;width:0;height:0.5em;background:#00f;overflow:hidden;' );\r
        \r
-       X_TEMP._body = body;\r
-       \r
        X_HTMLParser_asyncParse( html, true )\r
                [ 'listen' ]( X_EVENT_PROGRESS, X_TEMP._handleEvent )\r
                [ 'listenOnce' ]( X_EVENT_SUCCESS, X_TEMP._handleEvent );\r
@@ -224,8 +221,6 @@ X_TEMP._onPreInit =
        body.insertAdjacentHTML( 'BeforeEnd', '<div id="' + elmProgress + '" style="position:absolute;top:0;left:0;z-index:9999;width:0;height:0.5em;background:#00f;overflow:hidden;"></div>' );\r
        X_TEMP.elmProgress = document.all[ elmProgress ];\r
        \r
-       X_TEMP._body = body;\r
-       \r
        X_HTMLParser_asyncParse( html, true )\r
                [ 'listen' ]( X_EVENT_PROGRESS, X_TEMP._handleEvent )\r
                [ 'listenOnce' ]( X_EVENT_SUCCESS, X_TEMP._handleEvent );\r
@@ -247,10 +242,9 @@ X_TEMP._handleEvent = function( e ){
                        xnodes.push.apply( xnodes, e.xnodes );\r
                        elmProgress.style.width = '100%';\r
                        \r
-                       X_TEMP.asyncCreateTree( X_Node_body, X_TEMP._body.childNodes || X_TEMP._body.children, elmProgress );\r
+                       X_TEMP.asyncCreateTree( X_Node_body, X_elmBody.childNodes || X_elmBody.children, elmProgress );\r
                        \r
                        delete X_TEMP._onPreInit;\r
-                       delete X_TEMP._body;\r
                        delete X_TEMP.elmProgress;\r
                        break;\r
        };\r
@@ -298,7 +292,7 @@ X_TEMP.asyncCreateTree = function( parent, elems, elmProgress, async ){
                                        continue;\r
                                };\r
                                \r
-                               if( startTime + 16 <= X_Timer_now() ){\r
+                               if( startTime + X_Timer_INTERVAL_TIME <= X_Timer_now() ){\r
                                        current.i = i;\r
                                        if( async ){\r
                                                async.current = i < l && current;\r
index cac6fa8..3114a87 100644 (file)
@@ -25,10 +25,6 @@ var X_Pulgin_FLASH_VERSION =
                        })() :
                        0,
 
-       X_Pulgin_FLASH_ENABLED =
-               X_UA[ 'ActiveX' ] ? !!X_Pulgin_FLASH_VERSION :
-                       X_Object_find( navigator, 'mimeTypes>application/x-shockwave-flash>enabledPlugin' ),
-
 /*
  * ie11 の 互換モード(8,7)では、Silverlight が動作しない?
  */
@@ -36,7 +32,7 @@ var X_Pulgin_FLASH_VERSION =
                !X_UA[ 'IE' ] || !X_UA[ 'ActiveX' ] ? parseFloat( X_Object_find( navigator, 'plugins>Silverlight Plug-In>version' ) || 0 ) :
                X_UA[ 'ActiveX' ] && 6 <= X_UA[ 'IE' ] ? (function(){
                            var obj = X_Script_createActiveXObjectSafty( 'AgControl.AgControl' ),
-                               i = obj ? 5 : 0, f;
+                               i = obj ? 5 : 0;
 
                            for( ; i; --i ){
                                if( obj[ 'IsVersionSupported' ]( i + '.0' ) ) return i;
@@ -45,10 +41,6 @@ var X_Pulgin_FLASH_VERSION =
                        })() :
                        0,
 
-       X_Pulgin_SILVER_LIGHT_ENABLED =
-               X_UA[ 'ActiveX' ] ? !!X_Pulgin_SILVER_LIGHT_VERSION :
-                       X_Object_find( navigator, 'mimeTypes>application/x-silverlight>enabledPlugin' ),
-
 //http://docs.unity3d.ru/Manual/Detecting%20the%20Unity%20Web%20Player%20using%20browser%20scripting.html
        X_Pulgin_UNITY_VERSION =        
                !X_UA[ 'IE' ] || !X_UA[ 'ActiveX' ] ?
@@ -56,15 +48,11 @@ var X_Pulgin_FLASH_VERSION =
                !X_UA[ 'IE4' ] && !X_UA[ 'IE5' ] && X_UA[ 'ActiveX' ] ? (function(){
                            var obj = X_Script_createActiveXObjectSafty( 'UnityWebPlayer.UnityWebPlayer.1' );
                            
-                           console.log( obj && obj[ 'GetPluginVersion' ]() );
+                           //console.log( obj && obj[ 'GetPluginVersion' ]() );
                            return obj ? parseFloat( obj[ 'GetPluginVersion' ]() ) : 0;
                        })() :
                        0,
 
-       X_Pulgin_UNITY_ENABLED =
-               X_UA[ 'ActiveX' ] ? !!X_Pulgin_UNITY_VERSION :
-                       X_Object_find( navigator, 'mimeTypes>application/vnd.unity>enabledPlugin' ),
-
        X_Pulgin_GEARS_ENABLED =
                window.GearsFactory ||
                ( X_UA[ 'ActiveX' ] && 6 <= X_UA[ 'IE' ] ?
@@ -97,21 +85,15 @@ var X_Pulgin_FLASH_VERSION =
  */
 X[ 'Pulgin' ] = {
        
-       'Flash'              : X_Pulgin_FLASH_VERSION,
+       'Flash'       : X_Pulgin_FLASH_VERSION,
 
-       'FlashEnabled'       : X_Pulgin_FLASH_ENABLED,
-
-       'Silverlight'        : X_Pulgin_SILVER_LIGHT_VERSION,
-       
-       'SilverlightEnabled' : X_Pulgin_SILVER_LIGHT_ENABLED,
-       
-       'Unity'              : X_Pulgin_UNITY_VERSION,
+       'Silverlight' : X_Pulgin_SILVER_LIGHT_VERSION,
        
-       'UnityEnabled'       : X_Pulgin_UNITY_ENABLED,
+       'Unity'       : X_Pulgin_UNITY_VERSION,
        
        //'QuickTime'          : X_Pulgin_QUICKTIME_VERSION,
        
-       'GearsEnabled'       : !!X_Pulgin_GEARS_ENABLED
+       'Gears'       : !!X_Pulgin_GEARS_ENABLED
        
 };
 
index a99aa0e..5f86da6 100644 (file)
@@ -50,6 +50,7 @@ function X_JSON_stringify( obj ){
  * @alias X.JSON.parse\r
  */\r
 function X_JSON_parseTrustableString( jsonString ){\r
+       if( !jsonString ) return jsonString; // '' の場合エラ-になる\r
        return window.JSON ? JSON.parse( jsonString ) : eval( '(' + jsonString + ')' );\r
 };\r
 \r
index 34f50a4..44a020d 100644 (file)
@@ -1,7 +1,7 @@
 /*\r
  * XMLWrapper_find 周りの オリジナルコードに関する情報\r
  *  Original code by pettanR team\r
- *  - http://sourceforge.jp/projects/pettanr/scm/git/clientJs/blobs/master/0.6.x/js/01_dom/18_XDomQuery.js\r
+ *  - https://osdn.jp/projects/pettanr/scm/git/clientJs/blobs/master/0.6.x/js/02_dom/08_XNodeSelector.js\r
  *  and\r
  *  Original code by ofk ( kQuery, ksk )\r
  *  - http://d.hatena.ne.jp/ofk/comment/20090106/1231258010\r
@@ -23,11 +23,19 @@ function XMLWrapper( xml ){
        this._rawXML = xml;\r
 };\r
 \r
-XMLWrapper.prototype.length    = 1;\r
-XMLWrapper.prototype[ 'has' ]  = XMLWrapper_has;\r
-XMLWrapper.prototype[ 'get' ]  = XMLWrapper_get;\r
-XMLWrapper.prototype[ 'val' ]  = XMLWrapper_val;\r
-XMLWrapper.prototype[ 'find' ] = XMLWrapper_find;\r
+XMLWrapper.prototype.length      = 1;\r
+XMLWrapper.prototype[ 'parent' ] = XMLWrapper_parent;\r
+XMLWrapper.prototype[ 'has' ]    = XMLWrapper_has;\r
+XMLWrapper.prototype[ 'get' ]    = XMLWrapper_get;\r
+XMLWrapper.prototype[ 'val' ]    = XMLWrapper_val;\r
+XMLWrapper.prototype[ 'find' ]   = XMLWrapper_find;\r
+\r
+function XMLWrapper_parent(){\r
+       if( this.length === 1 ) return this._rawXML && this._rawXML.parentNode ? new XMLWrapper( this._rawXML.parentNode ) : null;\r
+       if( this.length === 0 ) return null;\r
+       \r
+       return this[ 0 ].parentNode ? ( new XMLWrapper( this[ 0 ].parentNode ) ) : null;\r
+};\r
 \r
 function XMLWrapper_has( queryString ){\r
        return !!this.find( queryString ).length;\r
@@ -45,7 +53,7 @@ function XMLWrapper_get( index ){
 };\r
 \r
 function XMLWrapper_val( queryString, type ){\r
-       var attr_textContent = X_UA[ 'IE' ] < 9 || X_UA[ 'Opera' ] ? 'innerText' : X_UA[ 'IE9' ] ? 'text' : 'textContent',\r
+       var //attr_textContent = X_UA[ 'IE' ] < 9 || X_UA[ 'Opera' ] ? 'innerText' : X_UA[ 'IE9' ] ? 'text' : 'textContent',\r
                wrapper, xml, v;\r
        \r
        switch( queryString ){\r
@@ -55,7 +63,7 @@ function XMLWrapper_val( queryString, type ){
                case 'string' :\r
                case undefined :\r
                        type = queryString;\r
-                       queryString = undefined;\r
+                       queryString = 0;\r
        };\r
                \r
        wrapper = queryString ? this.find( queryString ) : this;\r
@@ -83,7 +91,7 @@ function XMLWrapper_val( queryString, type ){
                case 'int' :\r
                        return parseFloat( v ) | 0;\r
                case 'boolean' :\r
-                       return v && v !== '0' && v !== 'false' && v !== 'null' && v !== 'undefined' && v !== 'NaN';\r
+                       return !!X_String_parse( v );\r
                //case 'string' :\r
                //default :     \r
        };\r
@@ -469,7 +477,7 @@ function XMLWrapper_val( queryString, type ){
                for( ; xnode = xmlList[ i ]; ++i ){\r
                        uid = xnode._uid;\r
                        tmp = checked[ uid ];\r
-                       if( tmp === void 0 ){\r
+                       if( tmp === undefined ){\r
                                for( c = 0, node = xnode.parentNode[ pointer ], tagName = flag_all || xnode.tagName; node; node = node[ sibling ] ){\r
                                        if( node.nodeType === 1 && ( flag_all || tagName === node.tagName ) ){\r
                                                ++c;\r
@@ -576,9 +584,10 @@ function XMLListWrapper( xmlList ){
 \r
 var XMLListWrapper_0 = new XMLListWrapper();\r
 \r
-XMLListWrapper.prototype.length    = 0;\r
-XMLListWrapper.prototype._wraps    = null;\r
-XMLListWrapper.prototype[ 'has' ]  = XMLWrapper_has;\r
-XMLListWrapper.prototype[ 'get' ]  = XMLWrapper_get;\r
-XMLListWrapper.prototype[ 'val' ]  = XMLWrapper_val;\r
-XMLListWrapper.prototype[ 'find' ] = XMLWrapper_find;\r
+XMLListWrapper.prototype.length      = 0;\r
+XMLListWrapper.prototype._wraps      = null;\r
+XMLListWrapper.prototype[ 'parent' ] = XMLWrapper_parent;\r
+XMLListWrapper.prototype[ 'has' ]    = XMLWrapper_has;\r
+XMLListWrapper.prototype[ 'get' ]    = XMLWrapper_get;\r
+XMLListWrapper.prototype[ 'val' ]    = XMLWrapper_val;\r
+XMLListWrapper.prototype[ 'find' ]   = XMLWrapper_find;\r
index 411de41..0094a05 100644 (file)
@@ -43,6 +43,17 @@ IE8 以下で xhr の失敗率が高い問題
 http://tkengo-totoro.blogspot.jp/2011/11/iexmlhttprequest.html\r
 TODO クライアント側にもリトライ機構を入れてみる\r
 \r
+\r
+TODO xml の取得には XMLDOM を使用する\r
+var activex = JKL.ParseXML.HTTP.ACTIVEX_XMLHTTP;    // IXMLHttpRequest\r
+if ( this.method == "GET" && ! this.textmode ) {\r
+    // use IXMLDOMElement to accept any mime types\r
+    // because overrideMimeType() is not available on IE6\r
+    activex = JKL.ParseXML.HTTP.ACTIVEX_XMLDOM;     // IXMLDOMElement\r
+};\r
+// debug.print( "new ActiveXObject( '"+activex+"' )" );\r
+this.req = new ActiveXObject( activex );\r
+\r
  */\r
 var // Opera7.6+, Safari1.2+, khtml3.?+, Gecko0.9.7+\r
        // ie9- ではローカルリソースには MSXML を使う\r
@@ -103,7 +114,7 @@ X[ 'XHR' ] = {
  * http://hakuhin.jp/as/javascript.html\r
  * Flash から JavaScript にアクセスする(3+)\r
  */\r
-       'FLASH'       : X_Pulgin_FLASH_ENABLED && 4 <= X_Pulgin_FLASH_VERSION ? 8 : 0,\r
+       'FLASH'       : 4 <= X_Pulgin_FLASH_VERSION ? 8 : 0,\r
        \r
        'GADGET'      : 5.5 <= X_UA[ 'IE' ] || !X_UA[ 'IE' ] ? 16 : 0,\r
 \r
@@ -424,7 +435,7 @@ if( X_XHR_w3c || X_XHR_msXML ){
                                                        headers = { 'Content-Type' : raw.contentType };\r
                                                } else\r
                                                if( ( X_XHR._isMsXML ? 3 <= X_XHR_msXMLVer : raw.setRequestHeader ) && ( headers = raw.getAllResponseHeaders() ) ){\r
-                                                       headers = X_NET_XHR_parseResponseHeaders( headers );\r
+                                                       headers = X_XHR_parseResponseHeaders( headers );\r
                                                };\r
                                                \r
                                                // https://code.google.com/p/fakeworker-js/source/browse/src/javascript/fakeworker.js\r
@@ -494,7 +505,45 @@ if( X_XHR_w3c || X_XHR_msXML ){
                                                break;\r
                                };\r
                        },\r
-                       \r
+\r
+/*\r
+ * http://www.kawa.net/works/js/jkl/parsexml.html\r
+ * \r
+// ================================================================\r
+//  method: documentElement()\r
+//  return: XML DOM in response body\r
+\r
+JKL.ParseXML.HTTP.prototype.documentElement = function() {\r
+    // debug.print( "documentElement: "+this.req );\r
+    if ( ! this.req ) return;\r
+    if ( this.req.responseXML ) {\r
+        return this.req.responseXML.documentElement;    // XMLHTTPRequest\r
+    } else {\r
+        return this.req.documentElement;                // IXMLDOMDocument\r
+    }\r
+};\r
+\r
+// ================================================================\r
+//  method: responseText()\r
+//  return: text string in response body\r
+\r
+JKL.ParseXML.HTTP.prototype.responseText = function() {\r
+    // debug.print( "responseText: "+this.req );\r
+    if ( ! this.req ) return;\r
+\r
+    //  Safari and Konqueror cannot understand the encoding of text files.\r
+    if ( navigator.appVersion.match( "KHTML" ) ) {\r
+        var esc = escape( this.req.responseText );\r
+//        debug.print( "escape: "+esc );\r
+        if ( ! esc.match("%u") && esc.match("%") ) {\r
+            return decodeURIComponent(esc);\r
+        }\r
+    }\r
+\r
+    return this.req.responseText;\r
+};\r
+ */\r
+               \r
                        onTimeout : function(){\r
                                var raw  = X_XHR[ '_rawObject' ],\r
                                        live = !X_XHR._canceled || !X_XHR._busy;\r
@@ -529,7 +578,7 @@ if( X_XHR_w3c || X_XHR_msXML ){
  * 複数の情報が存在する場合、改行で区切られています。\r
  */\r
 \r
-function X_NET_XHR_parseResponseHeaders( headerStr ){\r
+function X_XHR_parseResponseHeaders( headerStr ){\r
        var headers = {}, headerPairs, i = 0, l, headerPair, index, key, val;\r
        \r
        if( !headerStr ) return headers;\r
index 50cf05c..8e06469 100644 (file)
@@ -78,14 +78,15 @@ if( X_Audio_constructor ){
 };
 
 
-var X_WebAudio_context = !X_UA[ 'iPhone_4s' ]  && !X_UA[ 'iPad_2Mini1' ]  && !X_UA[ 'iPod_4' ]  &&
-                                                               // TODO なんで fennec を禁止?
+var X_WebAudio_context      = !X_UA[ 'iPhone_4s' ]  && !X_UA[ 'iPad_2Mini1' ]  && !X_UA[ 'iPod_4' ]  &&
+                                                               // Android2 + Gecko で WebAudio が極めて不安定
                                                                !( X_UA[ 'Gecko' ] && X_UA[ 'Android' ] ) &&
                                                                // Firefox40.0.5 + Windows8 で音声が途中から鳴らなくなる
                                                                // Firefox41.0.1 + Windows8 で音声が途中から鳴らなくなる
                                                                !( 40 <= X_UA[ 'Gecko' ] && X_UA[ 'Gecko' ] < 42 && X_UA[ 'Windows' ] ) &&
                                                                ( window[ 'AudioContext' ] || window[ 'webkitAudioContext' ] ),
-       X_WebAudio_BUFFER_LIST      = [],
+       X_WebAudio_BUFFER_LIST  = [],
+       X_WebAudio_need1stTouch = X_UA[ 'iOS' ],
        X_WebAudio,
        X_WebAudio_BufferLoader,
        X_WebAudio_fpsFix;
index 154e4ac..61f3ddd 100644 (file)
  * 8. BlinkOpera32 Win8 は HTMLAudio が壊れている、WebAudio は mp3 がデコードに失敗、ogg が動作\r
  * \r
  * memo\r
- * 1. Android4.1 iframe 内の Audio は親に focus が移っても再生を継続する\r
+ * 1. AOSP4.1 iframe 内の Audio は親に focus が移っても再生を継続する\r
+ * 2. AOSP4.2(Genymotion) どこかのタイミングでタッチによる play を行う\r
+ * 3. AOSP oggはシークが乱れる m4a, mp3 は優秀\r
  */\r
+       /*\r
+        * durationFix\r
+        *  duration が取得できるタイミングが遅くそれまでは infinity(PC Opera12), NaN(WP9), 0(Android 標準ブラウザ ChromeWebView) が入っている\r
+        * \r
+        *   1. touch が不要の場合、自動で再生を開始して duration を取得するまで再生する\r
+        *        -> 取得後に pause or 通常再生\r
+        *   2. touch が必要な場合、タッチイベント内の audio.play() で duration 取得\r
+        * \r
+        *  PC Opera12\r
+        *   1. loadeddata 等では duration が infinity で、再生後の durationchange 時に duration が判明する\r
+        *   2. duration 判明後には currentTime によるシークと、現在時間の取得が可能になる。\r
+        *   3. Opera12.17 Win32(XP) portable apps は勝手に再生が始まる、、、Win8+Opera では発生しない\r
+        *        -> その際には timeupdate が発行されない、、、 iframe+image+audio で使わないときは破棄する、とか。\r
+        *        -> opera11、10.54 WinXP はまとも、、、 portable が怪しい??\r
+        */\r
 \r
 var X_HTMLAudio_playTrigger =\r
-               6 <= X_UA[ 'iOS' ] ? 'loadeddata' :\r
-               X_UA[ 'iOS' ] < 5  ? 'stalled' :\r
-               X_UA[ 'iOS' ]      ? 'suspend' :\r
+               X_UA[ 'iOS' ] < 5    ? 'stalled' :\r
+               X_UA[ 'iOS' ] < 6    ? 'suspend' :\r
+               X_UA[ 'iOS' ] < 7    ? 'suspend' :\r
+               X_UA[ 'iOS' ]        ? 'loadeddata' :\r
                X_UA[ 'Safari' ] < 4 ? 'canplaythrough' :\r
                X_UA[ 'ChromeWV' ]   ? 'canplaythrough' :\r
                // Android 2.3.5(SBM101SH) では stalled は発生しない,,, ので必ず loadeddata もチェックする\r
-               X_UA[ 'AOSP' ] ? 'stalled' :\r
+               //X_UA[ 'AOSP' ] < 3 ? 'stalled' :\r
+               //X_UA[ 'AOSP' ] ? 'playing' :\r
                X_UA[ 'OperaMobile' ] || X_UA[ 'OperaTablet' ] ? 'loadeddata' :\r
                        'loadeddata', //'canplay',\r
        X_HTMLAudio,\r
@@ -37,7 +56,9 @@ var X_HTMLAudio_playTrigger =
        // Android 3.1 で ended 時に src='';src=src を実施。\r
        X_HTMLAudio_endedFixAOSP3   = !X_HTMLAudio_endedFixAOSP2 && X_UA[ 'AOSP' ] < 4,\r
        // ended 時に play() を実施, currentTime が duration に張り付き更新されなければ  src='';src=src を実施。\r
-       X_HTMLAudio_endedFixAOSP4   = 4 <= X_UA[ 'AOSP' ] || X_UA[ 'ChromeWV' ],\r
+       X_HTMLAudio_endedFixAOSP4   = 4 <= X_UA[ 'AOSP' ],\r
+       // ended 時に play() を実施\r
+       X_HTMLAudio_endedFixCWV     = X_UA[ 'ChromeWV' ],\r
        \r
        // Opera Mobile 12 は 2回目以降の currentTime へのセットで currentTime が更新されなくなるため、タイマーを使用する\r
        X_HTMLAudio_currentTimeFix  = !!X_UA[ 'OperaMobile' ] || !!X_UA[ 'OperaTablet' ],\r
@@ -51,25 +72,11 @@ var X_HTMLAudio_playTrigger =
        X_HTMLAudio_needPlayForSeek = X_UA[ 'Gecko' ],\r
        // \r
        X_HTMLAudio_pauseFix            = ( X_UA[ 'Windows' ] && 12 <= X_UA[ 'Opera' ] && 0 < ' XP XPSP2 2003|XP64'.indexOf( X_UA[ 'Windows' ] ) ), // XP + Opera12 のみ?\r
-       /*\r
-        * durationFix\r
-        *  duration が取得できるタイミングが遅くそれまでは infinity(PC Opera12), NaN(WP9), 0(Android 標準ブラウザ ChromeWebView) が入っている\r
-        * \r
-        *   1. touch が不要の場合、自動で再生を開始して duration を取得するまで再生する\r
-        *        -> 取得後に pause or 通常再生\r
-        *   2. touch が必要な場合、タッチイベント内の audio.play() で duration 取得\r
-        * \r
-        *  PC Opera12\r
-        *   1. loadeddata 等では duration が infinity で、再生後の durationchange 時に duration が判明する\r
-        *   2. duration 判明後には currentTime によるシークと、現在時間の取得が可能になる。\r
-        *   3. Opera12.17 Win32(XP) portable apps は勝手に再生が始まる、、、Win8+Opera では発生しない\r
-        *        -> その際には timeupdate が発行されない、、、 iframe+image+audio で使わないときは破棄する、とか。\r
-        *        -> opera11、10.54 WinXP はまとも、、、 portable が怪しい??\r
-        */\r
-       X_HTMLAudio_need1stTouch        = X_UA[ 'iOS' ] || X_UA[ 'ChromeWV' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ),       \r
-       X_HTMLAudio_durationFix     = ( X_UA[ 'Windows' ] && 12 <= X_UA[ 'Opera' ] ) || X_UA[ 'ChromeWV' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ),\r
+\r
+       X_HTMLAudio_need1stTouch        = X_UA[ 'iOS' ] || 4 <= X_UA[ 'AOSP' ] || X_UA[ 'ChromeWV' ] || X_UA[ 'WinPhone' ],     \r
+       X_HTMLAudio_durationFix     = X_UA[ 'iOS' ] || X_UA[ 'ChromeWV' ] || ( X_UA[ 'Windows' ] && 12 <= X_UA[ 'Opera' ] ) || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ),\r
        \r
-       X_HTMLAudio_shortPlayFix        = X_UA[ 'AOSP' ]; // Android 4.1.1 でも遭遇(ただしm4a, mp3は優秀, oggはシークが乱れる)\r
+       X_HTMLAudio_shortPlayFix        = X_UA[ 'AOSP' ]; // Android 4.1.1 でも遭遇\r
        \r
        \r
 \r
@@ -88,7 +95,7 @@ if( X_Audio_constructor ){
                        _currentFixBegin  : 0,\r
 \r
                        _durationFixPhase : X_HTMLAudio_durationFix ? 1 : 0,\r
-                       _durationFixSkip  : X_HTMLAudio_durationFix && !X_HTMLAudio_need1stTouch,                       \r
+                       _durationFixSkip  : X_HTMLAudio_durationFix && !X_HTMLAudio_need1stTouch,\r
                        _lastCurrentTime  : 0,\r
 \r
                        _shortPlayFixON   : false,\r
@@ -96,9 +103,6 @@ if( X_Audio_constructor ){
                        \r
                        _endedFixON               : false,\r
                        \r
-                       _kickTimerID      : false, // 処理が混み入ると AOSP で音声が再生されない\r
-                       _lastKickTime     : 0,\r
-                       \r
                        'Constructor' : function( disatcher, source, option ){\r
                                var raw;\r
                                \r
@@ -143,13 +147,31 @@ if( X_Audio_constructor ){
                                                'playing', 'waiting', 'seeking',\r
                                                'durationchange', 'timeupdate', 'ended' ] );\r
 \r
+\r
+                               this[ 'listen' ]( [\r
+                                               'loadstart', 'load',\r
+                                               'progress', 'error',\r
+                                               'suspend', 'abort', 'emptied', 'stalled',\r
+                                               'play', 'pause', 'seeked', 'ratechange', 'volumechange',\r
+                                               'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough',\r
+                                               'playing', 'waiting', 'seeking',\r
+                                               'durationchange', 'timeupdate', 'ended' ], this.onDebug );\r
+\r
                                if( X_TEMP.rawAudio ){\r
                                        raw.src = source;\r
-                                       raw.load(); // AOSP2 で必要\r
+                                       X_UA[ 'AOSP' ] < 3 && raw.load();\r
                                        delete X_TEMP.rawAudio;\r
                                };\r
                        },\r
                        \r
+                       onDebug : function( e ){\r
+                               this.disatcher[ 'dispatch' ]( {\r
+                                       type       : X_EVENT_DEBUG,\r
+                                       'rawEvent' : e.type,\r
+                                       current    : this.getActualCurrentTime() | 0,\r
+                                       duration   : this.duration | 0 } );\r
+                       },\r
+                       \r
                        handleEvent : function( e ){\r
                                var raw    = this[ '_rawObject' ],\r
                                        actualEnded = e.type === 'ended',\r
@@ -216,10 +238,10 @@ if( X_Audio_constructor ){
                                                if( this._durationFixPhase & 3 ){ // 1 or 2\r
                                                        duration = raw.duration;\r
                                                } else\r
-                                               if( raw.currentTime === this._lastCurrentTime ){\r
+                                               if( this.getActualCurrentTime() === this._lastCurrentTime ){\r
                                                        eventType = X_EVENT_MEDIA_WAITING;\r
                                                } else {\r
-                                                       this._lastCurrentTime = raw.currentTime;\r
+                                                       this._lastCurrentTime = this.getActualCurrentTime();\r
 \r
                                                        if( this.playing ){\r
                                                                end = X_Audio_getEndTime( this ) + this._shortPlayFixTime;\r
@@ -258,8 +280,8 @@ if( X_Audio_constructor ){
                                                if( X_HTMLAudio_volumeFix ){\r
                                                        raw.volume = this.gain;\r
                                                };\r
-                                               if( X_HTMLAudio_currentTimeFix ){\r
-                                                       this._currentFixStart = X_Timer_now(); // 正確な再生開始時間に補正\r
+                                               if( X_HTMLAudio_currentTimeFix && !this._currentFixStart ){\r
+                                                       //this._currentFixStart = X_Timer_now(); // 正確な再生開始時間に補正\r
                                                };\r
                                                eventType = !this._durationFixSkip && !this._endedFixON ? X_EVENT_MEDIA_PLAYING : X_EVENT_MEDIA_WAITING;\r
                                        //case 'play' :            //   再生が開始された。play()メソッドからの復帰後に発生する場合に発生\r
@@ -312,9 +334,9 @@ if( X_Audio_constructor ){
                                                if( !( this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_BEFORE_LOOP ) & X_CALLBACK_PREVENT_DEFAULT ) ){\r
                                                        this.looped = true;\r
                                                        this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_LOOPED );\r
-                                                       ( X_HTMLAudio_endedFixAOSP3 || X_HTMLAudio_endedFixAOSP4 || X_HTMLAudio_endedFixIOS ) && actualEnded && console.log( '☆★☆ 音声の継続用の play() @ended' );\r
+                                                       ( X_HTMLAudio_endedFixAOSP3 || X_HTMLAudio_endedFixAOSP4 || X_HTMLAudio_endedFixCWV || X_HTMLAudio_endedFixIOS ) && actualEnded && console.log( '☆★☆ 音声の継続用の play() @ended' );\r
                                                        this.actualPlay(\r
-                                                               ( X_HTMLAudio_endedFixAOSP4 || X_HTMLAudio_endedFixIOS ) && actualEnded,\r
+                                                               ( X_HTMLAudio_endedFixAOSP4 || X_HTMLAudio_endedFixCWV || X_HTMLAudio_endedFixIOS ) && actualEnded,\r
                                                                ( X_HTMLAudio_endedFixAOSP3 || X_HTMLAudio_endedFixAOSP2 ) && actualEnded );\r
                                                };\r
                                        } else {\r
@@ -325,8 +347,8 @@ if( X_Audio_constructor ){
                                } else\r
                                if( this._loaded && this.duration && !this._ready ){\r
                                        this._ready = true;\r
-                                       this.autoplay && X_Timer_once( 16, this, this.play );\r
                                        this.disatcher[ 'asyncDispatch' ]( X_EVENT_READY );\r
+                                       this.autoplay && !X_WebAudio_need1stTouch && X_Timer_once( 16, this, this.play );\r
                                        console.log( '> Audio Loaded!! ' + e.type + ' d:' + ( this.duration | 0 ) );\r
                                } else\r
                                if( eventType ){\r
@@ -382,10 +404,6 @@ if( X_Audio_constructor ){
                                                };\r
                                                raw.play();\r
                                                this.playing = true;\r
-                                               \r
-                                               if( X_UA[ 'AOSP' ] && !this._kickTimerID ){\r
-                                                       this._kickTimerID = X_Timer_add( 100, 0, this, this._kick );\r
-                                               };\r
                                        } else\r
                                        if( X_HTMLAudio_needPlayForSeek || forcePlay ){\r
                                                raw.play();\r
@@ -395,10 +413,9 @@ if( X_Audio_constructor ){
                                        //http://himaxoff.blog111.fc2.com/blog-entry-97.html\r
                                        //Firefox3.6では一度も play() していない状態で currentTime = 0 を実行するとエラーになる。\r
                                        //また、GoogleChrome7 では currentTime = 0 直後に play() すると、pause()した位置前後の音が混ざることがある。(少なくとも自分の環境では)                                                                        \r
-                                       raw.currentTime = this._lastKickTime = this._lastCurrentTime;\r
+                                       raw.currentTime = this._lastCurrentTime;\r
                                        console.log( '[HTMLAudio] play ' + begin + ' -> ' + end + ' crt:' + ( raw.currentTime | 0 ) + ' last:' + this._lastCurrentTime );\r
-                                       \r
-                                       // Android4.0.5 で ended イベント時に currentTime が duration に張り付いたまま変更できない\r
+\r
                                        if( forceReload || ( X_HTMLAudio_endedFixAOSP4 && raw.duration && raw.currentTime === raw.duration ) ){\r
                                                raw.src          = '';\r
                                                raw.src          = this._src;\r
@@ -408,7 +425,7 @@ if( X_Audio_constructor ){
                                                raw.currentTime  = this._lastCurrentTime;\r
                                                this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_WAITING );\r
                                                X_HTMLAudio_endedFixAOSP2 && raw.load();\r
-                                       };                                                      \r
+                                       };\r
                                };\r
 \r
                                if( X_HTMLAudio_currentTimeFix ){\r
@@ -417,20 +434,6 @@ if( X_Audio_constructor ){
                                };\r
                        },\r
                        \r
-                               _kick : function(){\r
-                                       var raw = this[ '_rawObject' ];\r
-                                       \r
-                                       console.log( ' >> KICK ? ct:' + ( raw.currentTime ) + ' lkt:' + this._lastKickTime );\r
-                                       if( this.playing && raw.currentTime === this._lastKickTime ){\r
-                                               this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_WAITING );\r
-                                               console.log( ' >> KICK !!' );\r
-                                               raw.play();\r
-                                       } else {\r
-                                               delete this._kickTimerID;\r
-                                               return X_CALLBACK_UN_LISTEN;\r
-                                       };\r
-                               },\r
-                       \r
                        actualPause : function(){\r
                                console.log( '[HTMLAudio] pause' );\r
                                \r
index 23ff7e5..cd91dc4 100644 (file)
@@ -8,10 +8,8 @@ var X_AudioSprite_shouldUse        = X_HTMLAudio && ( X_UA[ 'iOS' ] || X_UA[ 'AO
        X_AudioSprite_useVideoForMulti = //( 3.1 <= X_UA[ 'AOSP' ] < 4 ) || \r
                                                                          //( ( 4.2 <= X_UA[ 'AOSP' ] ),\r
                                                                          // ドスパラパッドはビデオのインライン再生が不可\r
-                                                                         false, //X_UA[ 'ChromeWV' ],\r
-       X_AudioSprite_needTouchAndroid = X_UA[ 'ChromeWV' ] && !X_WebAudio,\r
-       X_AudioSprite_needTouchFirst   = X_HTMLAudio_need1stTouch,\r
-       X_AudioSprite_disableMultiTrack = ( X_UA[ 'iOS' ] && !X_WebAudio_context ) || ( X_UA[ 'AOSP4' ] ) || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE' ] < 12 ),\r
+                                                                         false,\r
+       X_AudioSprite_disableMultiTrack = !X_WebAudio && ( X_UA[ 'iOS' ] || 4 <= X_UA[ 'AOSP' ] || X_UA[ 'ChromeWV' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ) ),\r
        X_AudioSprite_enableVolume     = X_HTMLAudio && ( !X_UA[ 'iOS' ] && !X_UA[ 'AOSP' ] && !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] ), // TODO fennec は 25以上\r
        // http://tukumemo.com/html5-audio-sp/\r
        // iOS6、Android4.1から同時再生が可能になりました。\r
@@ -110,7 +108,6 @@ X[ 'AudioSprite' ] = function( setting ){
 };\r
 \r
 X[ 'AudioSprite' ][ 'shouldUse'        ] = X_AudioSprite_shouldUse;\r
-X[ 'AudioSprite' ][ 'needTouchFirst'   ] = X_AudioSprite_needTouchFirst;\r
 X[ 'AudioSprite' ][ 'enableMultiTrack' ] = !X_AudioSprite_disableMultiTrack;\r
 \r
 // 再生が終わっているもの、終わりかけのものを探す\r
@@ -146,22 +143,14 @@ X_AudioSprite_members =
                /**\r
                 * モバイル用タッチイベント中に呼び出す\r
                 */\r
-               'load' : function(){\r
-                       var tracks = X_AudioSprite_TEMP.tracks,\r
-                               i = 0, l = tracks.length;\r
+               'on1stTouch' : function(){\r
+                       var i = 0, l = X_AudioSprite_TEMP.tracks.length;\r
 \r
                        for( ; i < l; ++i ){\r
-                               if( X_AudioSprite_needTouchAndroid ){\r
-                                       console.log( '[duration fix]開始 - ' + tracks[ i ][ '_rawObject' ].duration );\r
-                                       tracks[ i ]._durationFixPhase = 1;\r
-                                       tracks[ i ][ '_rawObject' ].play();\r
-                               } else\r
-                               if( X_UA[ 'WinPhone' ] ){\r
-                                       console.log( 'WinPhone : touch -> play()' );\r
-                                       //tracks[ i ].play( 0, X_AudioSprite_lengthSilence, true, 0, X_AudioSprite_lengthSilence ).seek( 0 );\r
-                                       this[ 'pause' ]( i );\r
+                               if( X_UA[ 'iOS' ] ){\r
+                                       X_AudioSprite_TEMP.tracks[ i ][ '_rawObject' ].load();\r
                                } else {\r
-                                       tracks[ i ][ '_rawObject' ].load();\r
+                                       X_AudioSprite_instance[ 'pause' ]( i );\r
                                };\r
                        };\r
                },\r
@@ -199,7 +188,7 @@ X_AudioSprite_members =
                                                track = X_AudioSprite_TEMP.bgmTrack = tracks[ 0 ];\r
                                        };\r
                                        \r
-                                       if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], this, X_AudioSprite_handleEvent ).playing ){\r
+                                       if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], X_AudioSprite_instance, X_AudioSprite_handleEvent ).playing ){\r
                                                track.setState({\r
                                                                'loop'          : true,\r
                                                                'looped'        : X_AudioSprite_TEMP.bgmLooped,\r
@@ -219,7 +208,7 @@ X_AudioSprite_members =
                                        if( 1 < tracks.length ){\r
                                                track = X_AudioSprite_getTrackEnded( X_AudioSprite_TEMP.bgmPlaying );\r
                                                track\r
-                                                       [ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], this, X_AudioSprite_handleEvent )\r
+                                                       [ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], X_AudioSprite_instance, X_AudioSprite_handleEvent )\r
                                                        .setState( { 'looped' : false } );\r
                                                track.play( preset[ 0 ], preset[ 1 ], true, 0, X_AudioSprite_lengthSilence );\r
                                        } else {\r
@@ -231,7 +220,7 @@ X_AudioSprite_members =
                                                };\r
                                                track = tracks[ 0 ];\r
                                        \r
-                                               if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], this, X_AudioSprite_handleEvent ).playing ){\r
+                                               if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], X_AudioSprite_instance, X_AudioSprite_handleEvent ).playing ){\r
                                                        track.setState({\r
                                                                        'loop'          : true,\r
                                                                        'looped'        : false,\r
@@ -267,8 +256,8 @@ X_AudioSprite_members =
                        };\r
                        track && track.play( 0, X_AudioSprite_lengthSilence, true, 0, X_AudioSprite_lengthSilence );\r
                        track && track.seek( 0 );\r
-                       this[ 'asyncDispatch' ]( X_EVENT_MEDIA_PAUSED );\r
-                       return this;\r
+                       X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_MEDIA_PAUSED );\r
+                       return X_AudioSprite_instance;\r
                },\r
                \r
                /**\r
@@ -286,7 +275,7 @@ X_AudioSprite_members =
                                start = X_Audio_getStartTime( track, end );\r
                                0 <= position && position <= ( end - start ) && track.seek( start + position );\r
                        };\r
-                       return this;\r
+                       return X_AudioSprite_instance;\r
                },\r
                \r
                /**\r
@@ -305,14 +294,14 @@ X_AudioSprite_members =
                                for( i = X_AudioSprite_TEMP.tracks.length; i; ){\r
                                        X_AudioSprite_TEMP.tracks[ --i ].volume( opt_volume );\r
                                };\r
-                               return this;\r
+                               return X_AudioSprite_instance;\r
                        };\r
                        track = X_AudioSprite_TEMP.tracks[ uid ];\r
                        if( opt_volume === undefined ){\r
                                return track ? track.gain : -1;\r
                        };\r
                        track && track.volume( opt_volume );\r
-                       return this;\r
+                       return X_AudioSprite_instance;\r
                },\r
                \r
                /**\r
@@ -340,12 +329,12 @@ X_AudioSprite_members =
                                return { 'volume' : X_AudioSprite_TEMP.volume, 'playing' : false };\r
                        };\r
                        track && track.setState( opt_obj );\r
-                       return this;\r
+                       return X_AudioSprite_instance;\r
                }\r
 };\r
 \r
 function X_AudioSprite_backendHandler( e ){\r
-       var i, backend, option, src, name, last, _e;\r
+       var i, backend, option, src, name, last, _e, touch;\r
        \r
        switch( e.type ){\r
                case X_EVENT_BACKEND_READY :\r
@@ -353,9 +342,9 @@ function X_AudioSprite_backendHandler( e ){
                        backend = X_Audio_BACKENDS[ e[ 'backendID' ] ];\r
                        option  = e[ 'option' ];\r
                        \r
-                       this[ 'unlisten' ]( X_EVENT_BACKEND_NONE, X_AudioSprite_backendHandler );\r
-                       this[ 'source' ]      = src = e[ 'source' ];\r
-                       this[ 'backendName' ] = name = backend.backendName;\r
+                       X_AudioSprite_instance[ 'unlisten' ]( X_EVENT_BACKEND_NONE, X_AudioSprite_backendHandler );\r
+                       X_AudioSprite_instance[ 'source' ]      = src = e[ 'source' ];\r
+                       X_AudioSprite_instance[ 'backendName' ] = name = backend.backendName;\r
                \r
                        //console.log( i + ' / ' + X_AudioSprite_numTracks );\r
                \r
@@ -365,11 +354,7 @@ function X_AudioSprite_backendHandler( e ){
                                        console.log( 'use video' );\r
                                };\r
                                // Audiobackend の owner として null を渡すとAudioBackend 自身へ dispatch する\r
-                               X_AudioSprite_TEMP.tracks.push( last = backend.klass( null, e[ 'source' ], option ) );\r
-                               \r
-                               \r
-                               //console.dir( backend );\r
-                               //console.dir( last );\r
+                               X_AudioSprite_TEMP.tracks.push( last = backend.klass( null, e[ 'source' ], option )[ 'listen' ]( X_EVENT_DEBUG, X_AudioSprite_instance, X_AudioSprite_handleEvent ) );\r
                        };\r
 \r
                        _e = {\r
@@ -377,45 +362,39 @@ function X_AudioSprite_backendHandler( e ){
                                'source'      : src,\r
                                'backendName' : name\r
                        };\r
+                       // touch 可能で backend ready\r
                        \r
-                       if( X_AudioSprite_needTouchFirst ){\r
-                               if( name === 'WebAudio' ){\r
-                                       _e[ 'needTouchForPlay' ] = true;\r
-                               } else {\r
-                                       _e[ 'needTouchForLoad' ] = true;\r
-                               };\r
+                       if( name === 'WebAudio' ){\r
+                               _e[ 'needTouchForPlay' ] = touch = X_WebAudio_need1stTouch;\r
+                       } else\r
+                       if( name === 'HTMLAudio' ){\r
+                               _e[ 'needTouchForLoad' ] = touch = X_HTMLAudio_need1stTouch;\r
                        };\r
-                       this[ 'asyncDispatch' ]( _e );\r
+\r
+                       X_AudioSprite_instance[ 'asyncDispatch' ]( _e );\r
                        \r
                        console.log( 'AudioSprite - X_EVENT_BACKEND_READY' );\r
                        \r
-                       last[ 'listenOnce' ]( X_EVENT_READY, this, X_AudioSprite_backendHandler );\r
+                       last[ 'listenOnce' ]( touch && !X_HTMLAudio_durationFix ? X_EVENT_MEDIA_PLAYING : X_EVENT_READY, X_AudioSprite_instance, X_AudioSprite_backendHandler );\r
 \r
                        // READY, needTouchForPlay, needTouchForLoad\r
-                       if( X_HTMLAudio_durationFix && !X_AudioSprite_needTouchFirst ){\r
+                       if( /* X_HTMLAudio_durationFix && */ !touch ){\r
                                for( i = 0; i < X_AudioSprite_TEMP.tracks.length; ++i ){\r
-                                       this[ 'pause' ]( i );\r
+                                       X_AudioSprite_instance[ 'pause' ]( i );\r
                                };\r
                        };\r
                        \r
                        return X_CALLBACK_STOP_NOW;\r
 \r
                case X_EVENT_BACKEND_NONE :\r
-                       this[ 'unlisten' ]( X_EVENT_BACKEND_READY, this, X_AudioSprite_backendHandler )\r
+                       X_AudioSprite_instance[ 'unlisten' ]( X_EVENT_BACKEND_READY, X_AudioSprite_instance, X_AudioSprite_backendHandler )\r
                                [ 'asyncDispatch' ]( X_EVENT_BACKEND_NONE );\r
                        return X_CALLBACK_STOP_NOW;\r
                \r
-               case X_EVENT_READY :\r
-                       if( X_AudioSprite_needTouchAndroid ){\r
-                               for( i = 0; i < X_AudioSprite_TEMP.tracks.length; ++i ){\r
-                                       this[ 'pause' ]( i );\r
-                               };\r
-                               e.target[ 'listenOnce' ]( X_EVENT_MEDIA_PLAYING, this, this[ 'asyncDispatch' ], [ X_EVENT_READY ] );\r
-                               return;\r
-                       };\r
-                       \r
+               case X_EVENT_READY :            \r
+               case X_EVENT_MEDIA_PLAYING :\r
                        console.log( 'X.AudioSprite - Ready!' );\r
-                       this[ 'asyncDispatch' ]( X_EVENT_READY );\r
+                       X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_READY );\r
                        break;\r
        };\r
 };\r
@@ -426,22 +405,22 @@ function X_AudioSprite_handleEvent( e ){
        \r
        switch( e.type ){\r
                case X_EVENT_MEDIA_PLAYING :\r
-                       ( e.target === X_AudioSprite_TEMP.bgmTrack || !e.target.looped ) && this[ 'asyncDispatch' ]( X_EVENT_MEDIA_PLAYING );\r
+                       ( e.target === X_AudioSprite_TEMP.bgmTrack || !e.target.looped ) &&  X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_MEDIA_PLAYING );\r
                        break;\r
                case X_EVENT_MEDIA_WAITING :\r
                case X_EVENT_MEDIA_SEEKING :\r
-                       ( e.target === X_AudioSprite_TEMP.bgmTrack || !e.target.looped ) && this[ 'asyncDispatch' ]( e.type );\r
+                       ( e.target === X_AudioSprite_TEMP.bgmTrack || !e.target.looped ) &&  X_AudioSprite_instance[ 'asyncDispatch' ]( e.type );\r
                        break;\r
                \r
                case X_EVENT_MEDIA_BEFORE_LOOP :\r
                        if( e.target === X_AudioSprite_TEMP.bgmTrack ){\r
                                X_AudioSprite_TEMP.bgmLooped = true;\r
-                               this[ 'asyncDispatch' ]( X_EVENT_MEDIA_LOOPED ); // TODO uid\r
+                                X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_MEDIA_LOOPED ); // TODO uid\r
                        } else {\r
                                if( e.target.looped ){\r
-                                       //this[ 'asyncDispatch' ]( X_EVENT_MEDIA_LOOPED ); // TODO uid\r
+                                       // X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_MEDIA_LOOPED ); // TODO uid\r
                                } else {\r
-                                       this[ 'asyncDispatch' ]( X_EVENT_MEDIA_ENDED ); // TODO uid\r
+                                        X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_MEDIA_ENDED ); // TODO uid\r
                                };\r
                                \r
                                //console.log( '[AudioSprite] bgmPlaying:' + X_AudioSprite_TEMP.bgmPlaying + ' ' + !X_AudioSprite_TEMP.bgmTrack );\r
@@ -449,12 +428,21 @@ function X_AudioSprite_handleEvent( e ){
                                // single track | iOS\r
                                if( X_AudioSprite_TEMP.bgmPlaying && !X_AudioSprite_TEMP.bgmTrack ){\r
                                        X_AudioSprite_TEMP.bgmTrack = e.target;\r
-                                       this.play( X_AudioSprite_TEMP.bgmName );\r
+                                        X_AudioSprite_instance.play( X_AudioSprite_TEMP.bgmName );\r
                                        return X_CALLBACK_PREVENT_DEFAULT;\r
                                };\r
                        };\r
                        break;\r
                \r
+               \r
+               case X_EVENT_DEBUG :\r
+                       i = X_AudioSprite_TEMP.tracks.indexOf( e.target );\r
+                       if( 0 <= i ){\r
+                               e[ 'trackID' ] = i;\r
+                               X_AudioSprite_instance[ 'dispatch' ]( e );\r
+                       };\r
+                       break;\r
+               \r
                // TODO Android Firefox で アクティブ検出できない!\r
                case X_EVENT_VIEW_ACTIVATE :\r
                        console.log( '■ アクティブ' );\r
@@ -493,7 +481,7 @@ function X_AudioSprite_handleEvent( e ){
                        X_AudioSprite_TEMP.bgmLooped   = false;\r
                        X_AudioSprite_TEMP.bgmPlaying  = false;\r
                        \r
-                       X_ViewPort[ 'unlisten' ]( [ X_EVENT_VIEW_ACTIVATE, X_EVENT_VIEW_DEACTIVATE ], this, X_AudioSprite_handleEvent );\r
+                       X_ViewPort[ 'unlisten' ]( [ X_EVENT_VIEW_ACTIVATE, X_EVENT_VIEW_DEACTIVATE ],  X_AudioSprite_instance, X_AudioSprite_handleEvent );\r
                        break;\r
        };\r
 };\r