From 1ed2190f012cf923f7e48d3c0d122aa56c56c5f3 Mon Sep 17 00:00:00 2001 From: itozyun Date: Tue, 6 Oct 2015 18:00:23 +0900 Subject: [PATCH] Version 0.6.176, add X.Script. --- 0.6.x/js/01_core/01_X.js | 1 - 0.6.x/js/01_core/02_XUA.js | 267 ++++++++++++++++--------- 0.6.x/js/01_core/03_XType.js | 2 +- 0.6.x/js/01_core/13_XClass.js | 2 +- 0.6.x/js/01_core/14_XEvent.js | 4 +- 0.6.x/js/01_core/15_XEventDispatcher.js | 6 +- 0.6.x/js/01_core/21_XViewPort.js | 30 +-- 0.6.x/js/02_dom/08_XNodeSelector.js | 6 +- 0.6.x/js/02_dom/09_XHTMLParser.js | 4 +- 0.6.x/js/02_dom/20_XNode.js | 4 +- 0.6.x/js/02_dom/22_XTreeBuilder.js | 3 +- 0.6.x/js/03_plugin/00_XPlugin.js | 21 +- 0.6.x/js/05_util/04_XXML.js | 18 +- 0.6.x/js/06_net/00_XNet.js | 4 +- 0.6.x/js/06_net/01_XNetXHR.js | 306 ++++++++++++++--------------- 0.6.x/js/06_net/03_XNetForm.js | 3 +- 0.6.x/js/06_net/05_XXHRGadget.js | 10 +- 0.6.x/js/06_net/10_XOAuth2.js | 7 +- 0.6.x/js/07_audio/01_XWebAudio.js | 9 +- 0.6.x/js/07_audio/02_XHTMLAudio.js | 8 +- 0.6.x/js/07_audio/03_XSilverlightAudio.js | 5 +- 0.6.x/js/07_audio/10_XAudioSprite.js | 313 +++++++++++++++++------------- 22 files changed, 582 insertions(+), 451 deletions(-) diff --git a/0.6.x/js/01_core/01_X.js b/0.6.x/js/01_core/01_X.js index 5c0ef3d..7a74113 100644 --- a/0.6.x/js/01_core/01_X.js +++ b/0.6.x/js/01_core/01_X.js @@ -73,4 +73,3 @@ X[ 'inHead' ] = (function( s ){ s = s.parentElement || s.parentNode || s;// s is for opera7.11 return s.tagName.toLowerCase() === 'head';// opera7.23 s.tagName is 'HTML' })( document.scripts || document.getElementsByTagName && document.getElementsByTagName( 'script' ) || document.all && document.all.tags( 'script' ) ); - diff --git a/0.6.x/js/01_core/02_XUA.js b/0.6.x/js/01_core/02_XUA.js index 426b486..c45d86e 100644 --- a/0.6.x/js/01_core/02_XUA.js +++ b/0.6.x/js/01_core/02_XUA.js @@ -243,12 +243,12 @@ var X_UA = X[ 'UA' ] = {}, * @alias X.UA.AndroidMinor * @type {number} */ - X_UA[ 'AndroidMinor' ] = parseFloat( v[ 1 ] ) || 0; + X_UA[ 'AndroidMinor' ] = parseFloat( v[ 1 ] ) || 0; /** * @alias X.UA.AndroidPatch * @type {number} */ - X_UA[ 'AndroidPatch' ] = parseFloat( v[ 2 ] ) || 0; + X_UA[ 'AndroidPatch' ] = parseFloat( v[ 2 ] ) || 0; /** * Firefox で Version が取れない! * http://bizmakoto.jp/bizid/articles/1207/31/news004.html @@ -331,8 +331,7 @@ var X_UA = X[ 'UA' ] = {}, */ X_UA[ '_IE' ] = parseFloat(dua.split('MSIE ')[1]) || parseFloat(dua.split('rv:')[1]) || parseFloat(dav.split('MSIE ')[1]) || 0; /** - * IE11 の互換モードの navigator.appVersion にも Trident/7.0 が書かれているため互換モードか?判定ができる - * 互換モードでは Silverlight でエラーが出る? + * IE11 の互換モードの navigator.appVersion にも Trident/7.0 が書かれているため互換モードか?判定ができるc * @alias X.UA.Trident * @type {number} */ @@ -351,71 +350,103 @@ var X_UA = X[ 'UA' ] = {}, * @type {number} */ X_UA[ 'IE' ] = v = document.documentMode || tridentToVer; - /** - * @alias X.UA.IE4 - * @type {boolean} - */ - if( v && v < 4.5 ) X_UA[ 'IE4' ] = true; - /** - * @alias X.UA.IE45 - * @type {boolean} - */ - if( v && 4.5 <= v && v < 5 ) X_UA[ 'IE45' ] = true; - /** - * @alias X.UA.IE4x - * @type {boolean} - */ - if( X_UA[ 'IE4' ] || X_UA[ 'IE45' ] ) X_UA[ 'IE4x' ] = true; - /** - * @alias X.UA.IE5 - * @type {boolean} - */ - if( 5 <= v && v < 5.5 ) X_UA[ 'IE5' ] = true; - /** - * @alias X.UA.IE55 - * @type {boolean} - */ - if( 5.5 <= v && v < 6 ) X_UA[ 'IE55' ] = true; - /** - * @alias X.UA.IE5x - * @type {boolean} - */ - if( X_UA[ 'IE5' ] || X_UA[ 'IE55' ] ) X_UA[ 'IE5x' ] = true; - /** - * @alias X.UA.IE6 - * @type {boolean} - */ - if( 6 <= v && v < 7 ) X_UA[ 'IE6' ] = true; - /** - * @alias X.UA.IE7 - * @type {boolean} - */ - if( 7 <= v && v < 8 ) X_UA[ 'IE7' ] = true; - /** - * @alias X.UA.IE8 - * @type {boolean} - */ - if( 8 <= v && v < 9 ) X_UA[ 'IE8' ] = true; - /** - * @alias X.UA.IE9 - * @type {boolean} - */ - if( 9 <= v && v < 10 ) X_UA[ 'IE9' ] = true; - /** - * @alias X.UA.MacIE - * @type {boolean} - */ - if( X_UA[ 'Mac' ] ) X_UA[ 'MacIE' ] = true; - /** - * @alias X.UA.IEMobile - * @type {boolean} - */ - if( dua.toLowerCase().indexOf( 'iemobile' ) !== -1 || X_UA[ 'WinCE' ] ) X_UA[ 'IEMobile' ] = true; - /** - * @alias X.UA.WinPhone - * @type {boolean} - */ - if( dua.toLowerCase().indexOf( 'windows phone' ) !== -1 || 0 < dav.indexOf( 'ZuneWP' ) ) X_UA[ 'WinPhone' ] = true; // ZuneWP は IEM のデスクトップモードで登場する + + if( v < 4.5 ){ + /** + * @alias X.UA.IE4 + * @type {boolean} + */ + X_UA[ 'IE4' ] = true; + } else + if( v < 5 ){ + /** + * @alias X.UA.IE45 + * @type {boolean} + */ + X_UA[ 'IE45' ] = true; + } else + if( v < 5.5 ){ + /** + * @alias X.UA.IE5 + * @type {boolean} + */ + X_UA[ 'IE5' ] = true; + } else + if( v < 6 ){ + /** + * @alias X.UA.IE55 + * @type {boolean} + */ + X_UA[ 'IE55' ] = true; + } else + if( v < 7 ){ + /** + * @alias X.UA.IE6 + * @type {boolean} + */ + X_UA[ 'IE6' ] = true; + } else + if( v < 8 ){ + /** + * @alias X.UA.IE7 + * @type {boolean} + */ + X_UA[ 'IE7' ] = true; + } else + if( v < 9 ){ + /** + * @alias X.UA.IE8 + * @type {boolean} + */ + X_UA[ 'IE8' ] = true; + } else + if( v < 10 ){ + /** + * @alias X.UA.IE9 + * @type {boolean} + */ + X_UA[ 'IE9' ] = true; + }; + + if( X_UA[ 'IE4' ] || X_UA[ 'IE45' ] ){ + /** + * @alias X.UA.IE4x + * @type {boolean} + */ + X_UA[ 'IE4x' ] = true; + }; + + if( X_UA[ 'IE5' ] || X_UA[ 'IE55' ] ){ + /** + * @alias X.UA.IE5x + * @type {boolean} + */ + X_UA[ 'IE5x' ] = true; + }; + + if( X_UA[ 'Mac' ] ){ + /** + * @alias X.UA.MacIE + * @type {boolean} + */ + X_UA[ 'MacIE' ] = true; + }; + + if( dua.toLowerCase().indexOf( 'iemobile' ) !== -1 || X_UA[ 'WinCE' ] ){ + /** + * @alias X.UA.IEMobile + * @type {boolean} + */ + X_UA[ 'IEMobile' ] = true; + }; + + if( dua.toLowerCase().indexOf( 'windows phone' ) !== -1 || 0 < dav.indexOf( 'ZuneWP' ) ){ + /** + * @alias X.UA.WinPhone + * @type {boolean} + */ + X_UA[ 'WinPhone' ] = true; // ZuneWP はデスクトップモードで登場する + }; console.log( '>> IE : ' + v + ' ActiveX : ' + X_UA[ 'ActiveX' ] + ' IEHost : ' + X_UA[ 'IEHost' ] ); // TODO XBox360, XBox1, Modern or Desktop, Standalone @@ -541,19 +572,19 @@ var X_UA = X[ 'UA' ] = {}, console.log( '>> Gecko : ' + X_UA[ 'Gecko' ] ); }; - if( ( dua.indexOf( 'Linux; U; Android ' ) !== -1 || dua.indexOf( 'Linux; Android ' ) !== -1 ) && + // Android 標準ブラウザ AOSP と ChromeWeb View, Sブラウザがある + if( X_UA[ 'Android' ] && ( dua.indexOf( 'Chrome\/' ) === -1 || dua.indexOf( 'Version\/' ) !== -1 ) ){ // Chrome/ を含まない または Version/ を含む - /* if( window.chrome ){ // Android3.1 のAOSPブラウザで .chrome がいた、、、 - //X_UA[ 'Blink' ] = X_UA[ 'ChromeWK' ] = tv; + /* if( window.chrome ){ // Android3.1 のAOSPブラウザで .chrome がいた、、、 } else */ if( dua.indexOf( 'Version\/' ) === -1 && ( v = parseFloat( dua.split( 'Chrome\/' )[ 1 ] ) ) ){ /** - * Android 標準ブラウザ Chrome Webkit ラップブラウザ - * @alias X.UA.ChromeWK + * Android 標準ブラウザ Chrome WebView ブラウザ + * @alias X.UA.ChromeWV * @type {number} */ - X_UA[ 'ChromeWK' ] = v; + X_UA[ 'ChromeWV' ] = v; } else // http://uupaa.hatenablog.com/entry/2014/04/15/163346 // Chrome WebView は Android 4.4 の時点では WebGL や WebAudio など一部の機能が利用できません(can i use)。 @@ -561,9 +592,9 @@ var X_UA = X[ 'UA' ] = {}, // http://caniuse.com/#compare=chrome+40,android+4.2-4.3,android+4.4,android+4.4.3-4.4.4,and_chr+45 // CustomElement の有無で判定 if( document[ 'registerElement' ] ){ - // UA が偽装された ChromeWK - X_UA[ 'ChromeWK' ] = tv; - alert( 'UA が偽装された Chrome Webkit' ); + // UA が偽装された Chrome WebView + X_UA[ 'ChromeWV' ] = tv; + alert( 'UA が偽装された Chrome WebView' ); } else { /** * Android 標準ブラウザ AOSP @@ -573,22 +604,14 @@ var X_UA = X[ 'UA' ] = {}, X_UA[ 'AOSP' ] = X_UA[ 'Android' ]; }; - i = parseFloat( dua.split( 'WebKit\/' )[ 1 ] ); - /** - * @alias X.UA.AndroidWebkit - * @type {number} - */ - X_UA[ 'AndroidWebkit' ] = i; - //alert( 'AudioSprite調査:Android標準ブラウザ Webkit Version ' + i ); - /* * http://www.flexfirm.jp/blog/article/402 - * Sブラウザ + * TODO Sブラウザ * SC-04E、SC-01F、SC-02F、 SC-04F、SCL22、SCL23など */ } else - // TODO Blink + // Blink Chrome & Blink Opera if( window.chrome ){ /** * @alias X.UA.Blink @@ -797,3 +820,71 @@ X_UA_ATagWrapDiv = (function( e, h ){ console.log( 'HTML5? ' + X_UA_ATagWrapDiv ); */ +var X_Script_VBS_ENABLED = X_UA[ 'Windows' ] && !X_UA[ 'WinCE' ] && !X_UA[ 'WinPhone' ] && X_UA[ 'IE' ] < 11; + +/** + * js バージョン間の際を吸収 + * @namespace X.Script + * @alias X.Script + * @type {object} + */ +X[ 'Script' ] = { + 'try' : X_Script_try +}; + +if( X_UA[ 'IE' ] < 9 && X_Script_VBS_ENABLED ){ + (function( lines ){ + var s = document.createElement( 'script' ); + document.getElementsByTagName("head")[ 0 ].appendChild( s ); + s.type = 'text/vbscript'; + s.text = lines.join( '\n' ); + + })( [ + 'Function vba_createAXO(v)', + 'On Error Resume Next', + 'Set ax = CreateObject(v)', + 'If Err.Number Then', + 'ax = 1', + 'End If', + 'Err.Clear', + 'vba_createAXO = ax', + 'End Function' /*, + + 'Function vba_try(jsFunc,a1,a2,a3,a4)', + 'On Error Resume Next', + 'Dim rs = jsFunc(a1,a2,a3,a4)', + 'If Err.Number != 0 Then', + 'rs = 0', + 'End If', + 'Err.Clear', + 'vba_try = rs', + 'End Function' */ + ] ); + + // TODO Object のメンバを辿る vba +}; + +function X_Script_try( func, args ){ + + if( X_UA[ 'IE' ] < 5.5 ){ + + } else { + return ( new Function( 'f,a', 'try{return f.apply({},a)}catch(e){}' ) )( func, args || [] ); + }; +}; + +function X_Script_createActiveXObjectSafty( name ){ + if( X_UA[ 'IE' ] < 9 ){ + if( X_Script_VBS_ENABLED ){ + return window[ 'vba_createAXO' ]( name ) ? null : X_Script_createActiveXObject( name ); + }; + return X_Script_createActiveXObject( name ); + } else { + return X_Script_try( X_Script_createActiveXObject, [ name ] ); + }; +}; + +function X_Script_createActiveXObject( name ){ + return new ActiveXObject( name ); +}; + diff --git a/0.6.x/js/01_core/03_XType.js b/0.6.x/js/01_core/03_XType.js index 84bca3d..2aada9e 100644 --- a/0.6.x/js/01_core/03_XType.js +++ b/0.6.x/js/01_core/03_XType.js @@ -113,7 +113,7 @@ X[ 'Type' ] = { }; - /* + /** * new Image した場合に HTMLImageElement が作られるブラウザと,そうでないブラウザ(IE8-)がある * @alias X.Type.isImage */ diff --git a/0.6.x/js/01_core/13_XClass.js b/0.6.x/js/01_core/13_XClass.js index 4438378..bb0a857 100644 --- a/0.6.x/js/01_core/13_XClass.js +++ b/0.6.x/js/01_core/13_XClass.js @@ -238,7 +238,7 @@ X_Class_CommonMethods = // --- interface ----------------------------------------------------------- // // ------------------------------------------------------------------------- // -/* +/** * @enum {number} * @const */ diff --git a/0.6.x/js/01_core/14_XEvent.js b/0.6.x/js/01_core/14_XEvent.js index e54199b..e2a5cda 100644 --- a/0.6.x/js/01_core/14_XEvent.js +++ b/0.6.x/js/01_core/14_XEvent.js @@ -12,8 +12,8 @@ var X_Event_Rename = {}, IFRAMEload_proxy : function( e ){ var raw = this[ '_rawObject' ]; - return raw.readyState === 'complete' || raw.readyState === 'loaded' ? - this[ 'dispatch' ]( 'load' ) : X_CALLBACK_PREVENT_DEFAULT, X_CALLBACK_STOP_PROPAGATION; + return ( raw.readyState === 'complete' || raw.readyState === 'loaded' ) ? + this[ 'dispatch' ]( 'load' ) : X_CALLBACK_PREVENT_DEFAULT | X_CALLBACK_STOP_PROPAGATION; }, // X_UA[ 'Opera' ] diff --git a/0.6.x/js/01_core/15_XEventDispatcher.js b/0.6.x/js/01_core/15_XEventDispatcher.js index 699c34b..d6140a4 100644 --- a/0.6.x/js/01_core/15_XEventDispatcher.js +++ b/0.6.x/js/01_core/15_XEventDispatcher.js @@ -44,11 +44,11 @@ var X_EventDispatcher_once = false, X_EventDispatcher_safariPreventDefault = false, // Safari3- - /* @const */ + /** @const */ X_EventDispatcher_EVENT_TARGET_OTHER = 0, - /* @const */ + /** @const */ X_EventDispatcher_EVENT_TARGET_XHR = 1, - /* @const */ + /** @const */ X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT = 2, X_EventDispatcher_LAZY_TIMERS = {}; // Object. number は timerID diff --git a/0.6.x/js/01_core/21_XViewPort.js b/0.6.x/js/01_core/21_XViewPort.js index c1a1760..7c29e7d 100644 --- a/0.6.x/js/01_core/21_XViewPort.js +++ b/0.6.x/js/01_core/21_XViewPort.js @@ -75,7 +75,7 @@ X_ViewPort = X_Class_override( case 'blur' : case 'focusout' : - if( X_UA[ 'IE' ] < 9 ){ + if( 5 < X_UA[ 'IE' ] && X_UA[ 'IE' ] < 9 ){ xnode = X_Node_getXNode( document.activeElement ); if( xnode ){ xnode[ 'listenOnce' ]( [ 'focus', 'blur' ], X_ViewPort_detectFocusForIE ); @@ -107,15 +107,23 @@ X_ViewPort = X_Class_override( ); function X_ViewPort_detectFocusForIE( e ){ - console.log( 'iefix! ' + e.type + ':' + this.attr( 'tag' ) + ' isActive?:' + ( this[ '_rawObject' ] === document.activeElement ) ); - + //console.log( 'iefix! ' + e.type + ':' + this.attr( 'tag' ) + ' isActive?:' + ( this[ '_rawObject' ] === document.activeElement ) ); + var elmActive = X_Script_try( X_Object_find, [ document, 'activeElement' ] ); X_ViewPort_active = e.type === 'focus'; - if( this[ '_rawObject' ] !== document.activeElement ){ + + if( elmActive && this[ '_rawObject' ] !== elmActive ){ this[ 'unlisten' ]( X_ViewPort_active ? 'blur' : 'focus', X_ViewPort_detectFocusForIE ); + console.log( '>>>>>> activeElement 取得 不一致 ' + this._tag ); + } else + if( !elmActive ){ + console.log( '******** activeElement 取得のエラー' ); + } else if( elmActive ){ + console.log( '>>>>>> activeElement 取得' ); }; + if( X_ViewPort_activeTimerID ){ - X_ViewPort_activeTimerID = X_Timer_remove( X_ViewPort_activeTimerID ); + X_Timer_remove( X_ViewPort_activeTimerID ); }; X_ViewPort_activeTimerID = X_Timer_once( 16, X_ViewPort_changeFocus ); @@ -251,8 +259,8 @@ X[ 'ViewPort' ] = { //(((t = document.documentElement) || (t = document.body.parentNode)) && typeof t.ScrollLeft == 'number' ? t : document.body).ScrollLeft; //(((t = document.documentElement) || (t = document.body.parentNode)) && typeof t.ScrollTop == 'number' ? t : document.body).ScrollTop - /* - * TODO X.Doc へ + // TODO X.Doc へ + /** * @alias X.ViewPort.getDocumentSize */ 'getDocumentSize' : function(){ @@ -595,12 +603,12 @@ if( X_UA_EVENT.W3C ){ } else if( 6 <= X_UA[ 'IE' ] && X[ 'inHead' ] && !X_UA[ 'ieExeComError' ] ){ // standalone の除外 -> && !X_UA[ 'ieExeComError' ] // if this script in Head - document.write( '' ); - X_TEMP._script = document.getElementById( '__ieonload' ); + //document.write( '' ); + //X_TEMP._script = document.getElementById( '__ieonload' ); // 上のコードはスタンドアローン版ie6でエラー - //X_TEMP._script = document.createElement( '' ) ; - //document.getElementsByTagName( 'head' )[ 0 ].appendChild( X_TEMP._script ); + X_TEMP._script = document.createElement( '' ) ; + document.getElementsByTagName( 'head' )[ 0 ].appendChild( X_TEMP._script ); X_TEMP._script.onreadystatechange = function(){ var s = X_TEMP._script; diff --git a/0.6.x/js/02_dom/08_XNodeSelector.js b/0.6.x/js/02_dom/08_XNodeSelector.js index 727ac95..ca7fcd5 100644 --- a/0.6.x/js/02_dom/08_XNodeSelector.js +++ b/0.6.x/js/02_dom/08_XNodeSelector.js @@ -281,7 +281,7 @@ function X_Node_Selector__parse( query, last ){ /*]@+debug*/ // 文字列以外は空で返す - if( typeof queryString !== 'string' ) return ret; + if( !X_Type_isString( queryString ) ) return ret; xnodes = []; @@ -293,7 +293,7 @@ function X_Node_Selector__parse( query, last ){ if( !parsed ){ parsed = X_Node_Selector__parse( queryString ); - if( typeof parsed === 'number' ){ + if( X_Type_isNumber( parsed ) ){ // error return []; }; @@ -499,7 +499,7 @@ function X_Node_Selector__parse( query, last ){ ); } else // filterが関数の場合 - if( typeof filter === 'function' ){ + if( X_Type_isFunction( filter ) ){ tmp = []; for( i = 0, n = -1; xnode = xnodes[ i ]; ++i ){ if( ( !!filter( xnode ) ) ^ isNot ) tmp[ ++n ] = xnode; diff --git a/0.6.x/js/02_dom/09_XHTMLParser.js b/0.6.x/js/02_dom/09_XHTMLParser.js index 11a3aa7..6aa4f7f 100644 --- a/0.6.x/js/02_dom/09_XHTMLParser.js +++ b/0.6.x/js/02_dom/09_XHTMLParser.js @@ -175,8 +175,8 @@ var X_HTMLParser_CHARS = { ( ( phase = 5 ) && ( attrName = html.substring( start, i ) ) ); break; case 5 : // 属性の = または次の属性または htmlタグの閉じ - ( whiteSpace[ chr ] & 16 ) ?// ie4 未対応の属性には cite = http:// となる - 1 : + !( whiteSpace[ chr ] & 16 ) &&// ie4 未対応の属性には cite = http:// となる + // 1 : ( alphabets[ chr ] & 3 ) ? ( ( phase = 4 ) && ( attrs[ attrs.length ] = attrName ) && ( start = i ) ) : chr === '=' ? diff --git a/0.6.x/js/02_dom/20_XNode.js b/0.6.x/js/02_dom/20_XNode.js index e7d85ec..7fb2e40 100644 --- a/0.6.x/js/02_dom/20_XNode.js +++ b/0.6.x/js/02_dom/20_XNode.js @@ -1497,10 +1497,10 @@ var X_Node__commitUpdate = X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰 that[ '_flags' ] |= X_NodeFlags_ACTUAL_LISTENING; - if( X_Node_documentFragment ){ + //if( X_Node_documentFragment ){ //( frg = X_Node_documentFragment ).appendChild( elm ); // 連続する要素の差し替えの場合に有効 - }; + //}; if( X_Node_strictElmCreation ){ that[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY; diff --git a/0.6.x/js/02_dom/22_XTreeBuilder.js b/0.6.x/js/02_dom/22_XTreeBuilder.js index 72eae6b..868261e 100644 --- a/0.6.x/js/02_dom/22_XTreeBuilder.js +++ b/0.6.x/js/02_dom/22_XTreeBuilder.js @@ -45,6 +45,7 @@ if( X_UA[ 'MacIE' ] ){ parent.replaceChild( document.createComment( '' ), node ); */ document.body.appendChild( node ); return; + /* if( parent.parentNode !== document.body ){ var clone = parent.cloneNode( true ); for( var i = 0, l = parent.childNodes.length; i < l; ++i ){ @@ -61,7 +62,7 @@ if( X_UA[ 'MacIE' ] ){ }; } else { // ignore - }; + }; */ }; //if( !node.ownerDocument ) alert( 'no owner' ); diff --git a/0.6.x/js/03_plugin/00_XPlugin.js b/0.6.x/js/03_plugin/00_XPlugin.js index 961f638..6be1a47 100644 --- a/0.6.x/js/03_plugin/00_XPlugin.js +++ b/0.6.x/js/03_plugin/00_XPlugin.js @@ -19,7 +19,7 @@ var X_Pulgin_FLASH_VERSION = !X_UA[ 'IE' ] || !X_UA[ 'ActiveX' ] ? parseFloat( X_Object_find( navigator, 'plugins>Shockwave Flash>version' ) || 0 ) : !X_UA[ 'IE4' ] && !X_UA[ 'IE5' ] && X_UA[ 'ActiveX' ] ? (function(){ - var obj = eval( 'var a,e;try{a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash")}catch(e){}a' ), + var obj = X_Script_createActiveXObjectSafty( 'ShockwaveFlash.ShockwaveFlash' ), ver = obj && obj[ 'GetVariable' ]( '$version' ).split( ' ' ).join( '.' ); return parseFloat( ver ) || 0; })() : @@ -35,7 +35,13 @@ var X_Pulgin_FLASH_VERSION = X_Pulgin_SILVER_LIGHT_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(){ - return eval( 'var a,i=0;try{a=new ActiveXObject("AgControl.AgControl");for(i=5;i;--i)if(a.IsVersionSupported(i+".0"))break;}catch(e){i=0}i' ); + var obj = X_Script_createActiveXObjectSafty( 'AgControl.AgControl' ), + i = obj ? 5 : 0, f; + + for( ; i; --i ){ + if( obj[ 'IsVersionSupported' ]( i + '.0' ) ) return i; + }; + return 0; })() : 0, @@ -48,7 +54,7 @@ var X_Pulgin_FLASH_VERSION = !X_UA[ 'IE' ] || !X_UA[ 'ActiveX' ] ? parseFloat( X_Object_find( navigator, 'plugins>Unity Player>version' ) || 0 ) : !X_UA[ 'IE4' ] && !X_UA[ 'IE5' ] && X_UA[ 'ActiveX' ] ? (function(){ - var obj = eval( 'var a,e;try{a=new ActiveXObject("UnityWebPlayer.UnityWebPlayer.1")}catch(e){}a' ); + var obj = X_Script_createActiveXObjectSafty( 'UnityWebPlayer.UnityWebPlayer.1' ); return obj ? parseFloat( obj[ 'GetPluginVersion' ]() ) : 0; })() : 0, @@ -61,10 +67,10 @@ var X_Pulgin_FLASH_VERSION = window.GearsFactory || ( X_UA[ 'ActiveX' ] && 6 <= X_UA[ 'IE' ] ? (function(){ - return eval( 'var a,e;try{a=new ActiveXObject("Gears.Factory")}catch(e){}!!a' ); + return X_Script_createActiveXObjectSafty( 'Gears.Factory' ); })() : X_Object_find( navigator, 'mimeTypes>application/x-googlegears>enabledPlugin' ) - ), + ); // QuickTime Plug-in 7.7.6 /* @@ -76,15 +82,12 @@ var X_Pulgin_FLASH_VERSION = return 0; })( navigator.plugins ) : !X_UA[ 'IE4' ] && !X_UA[ 'IE5' ] && X_UA[ 'ActiveX' ] ? (function(){ - var obj = eval( 'var a,e;try{a=new ActiveXObject("QuickTimeCheckObject.QuickTimeCheck.1")}catch(e){}a' ), + var obj = QuickTimeCheckObject.QuickTimeCheck.1' ), ver = obj && obj[ 'QuickTimeVersion' ].toString( 16 ); return ver ? parseFloat( ver.substr( 0, 3 ) ) / 100 : 0; })() : 0, */ - - X_Pulgin_VBS_ENABLED = - X_UA[ 'Windows' ] && !X_UA[ 'WinCE' ] && X_UA[ 'IE' ] < 11; /** diff --git a/0.6.x/js/05_util/04_XXML.js b/0.6.x/js/05_util/04_XXML.js index 39e2b0c..4f7ab2a 100644 --- a/0.6.x/js/05_util/04_XXML.js +++ b/0.6.x/js/05_util/04_XXML.js @@ -6,6 +6,8 @@ * Original code by ofk ( kQuery, ksk ) * - http://d.hatena.ne.jp/ofk/comment/20090106/1231258010 * - http://d.hatena.ne.jp/ofk/20090111/1231668170 + * + * TODO X.Class で作り、kill を強要する */ X[ 'XML' ] = XMLWrapper; @@ -480,6 +482,7 @@ function XMLWrapper_val( queryString, type ){ }; return res; }; + /* function XMLWrapper_funcSelectorProp( prop, flag, flags, xmlList ){ var res = [], flag_not = flag ? flags.not : !flags.not, @@ -488,7 +491,7 @@ function XMLWrapper_val( queryString, type ){ if( xnode.getAttributeNode( prop ) ^ flag_not ) res[ ++n ] = xnode; }; return res; - }; + }; */ var XMLWrapper_filter = { 'first-child' : { @@ -521,7 +524,7 @@ var XMLWrapper_filter = { 'nth-last-of-type' : { m : function( flags, xmlList, a, b ){ return XMLWrapper_funcSelectorNth( 'lastChild', 'previousSibling', false, flags, xmlList, a, b ); } }, - empty : { + 'empty' : { m : function( flags, xmlList ){ var res = [], flag_not = flags.not, @@ -539,19 +542,18 @@ var XMLWrapper_filter = { return res; } }, - contains : { + 'contains' : { m : function( flags, xmlList, arg ){ var res = [], flag_not = flags.not, - i = 0, n = -1, xnode, text = '', - // kquery - attr_textContent = X_UA[ 'IE' ] < 9 || X_UA[ 'Opera' ] ? 'innerText' : X_UA[ 'IE9' ] ? 'text' : 'textContent'; + i = 0, n = -1, xnode, text = ''; + for( ; xnode = xmlList[ i ]; ++i ){ switch( xnode.nodeType ){ case 1 : - text = xml.nodeType === 1 ? xml.innerText || xml.text || xml.textContent : xml.nodeValue;// xnode[ attr_textContent ]; + text = xml.nodeType === 1 ? xml.innerText || xml.text || xml.textContent : xml.nodeValue; break; - case 2 : + //case 2 : case 3 : text = xnode.nodeValue; break; diff --git a/0.6.x/js/06_net/00_XNet.js b/0.6.x/js/06_net/00_XNet.js index af64b4d..c693cc2 100644 --- a/0.6.x/js/06_net/00_XNet.js +++ b/0.6.x/js/06_net/00_XNet.js @@ -218,7 +218,7 @@ var X_NET_TYPE_XHR = 1, X_NET_QUEUE_LIST = [], - X_NET_XHRWrapper, + X_XHR, X_NET_JSONPWrapper, X_NET_FormWrapper, X_NET_ImageWrapper, @@ -320,7 +320,7 @@ function X_NET_shiftQueue(){ break; default : - X_NET_currentWrapper = X_NET_XHRWrapper || X_TEMP.X_Net_XHR_init(); + X_NET_currentWrapper = X_XHR || X_TEMP.X_XHR_init(); }; diff --git a/0.6.x/js/06_net/01_XNetXHR.js b/0.6.x/js/06_net/01_XNetXHR.js index d882cc1..411de41 100644 --- a/0.6.x/js/06_net/01_XNetXHR.js +++ b/0.6.x/js/06_net/01_XNetXHR.js @@ -46,51 +46,56 @@ TODO クライアント側にもリトライ機構を入れてみる */ var // Opera7.6+, Safari1.2+, khtml3.?+, Gecko0.9.7+ // ie9- ではローカルリソースには MSXML を使う - X_Net_XHR_createW3C = window[ 'XMLHttpRequest' ] && function(){ return X_Net_XHR_w3c || ( X_Net_XHR_w3c = new XMLHttpRequest() ); }, - X_Net_XHR_w3c = X_Net_XHR_createW3C && X_Net_XHR_createW3C(), - X_Net_XHR_cors = X_Net_XHR_w3c && X_Net_XHR_w3c.withCredentials !== undefined, - X_Net_XHR_progress = X_Net_XHR_w3c && X_Net_XHR_w3c.onprogress !== undefined, - X_Net_XHR_upload = X_Net_XHR_w3c && !!X_Net_XHR_w3c.upload, + X_XHR_createW3C = window[ 'XMLHttpRequest' ] && function(){ return X_XHR_w3c || ( X_XHR_w3c = new XMLHttpRequest() ); }, + X_XHR_w3c = X_XHR_createW3C && X_XHR_createW3C(), + X_XHR_cors = X_XHR_w3c && X_XHR_w3c.withCredentials !== undefined, + X_XHR_progress = X_XHR_w3c && X_XHR_w3c.onprogress !== undefined, + X_XHR_upload = X_XHR_w3c && !!X_XHR_w3c.upload, - X_Net_XHR_createXDR = window[ 'XDomainRequest' ] && function(){ return X_Net_XHR_xdr || ( X_Net_XHR_xdr = new XDomainRequest() ); }, - X_Net_XHR_xdr = X_Net_XHR_createXDR && X_Net_XHR_createXDR(), + X_XHR_createXDR = window[ 'XDomainRequest' ] && function(){ return X_XHR_xdr || ( X_XHR_xdr = new XDomainRequest() ); }, + X_XHR_xdr = X_XHR_createXDR && X_XHR_createXDR(), + X_XHR_msXMLVer = 0, + X_XHR_msXMLName = '', + X_XHR_msXML, + // ie11の互換モード(7,8)の msxml はいまいち動かない - X_Net_XHR_createMSXML = X_UA[ 'ActiveX' ] && ( X_UA[ 'IE5x' ] || X_UA[ 'IE6' ] || X_URL_IS_LOCAL ) && - ( new Function( 'f', [ - 'var x=".XMLHTTP",', - 'm="MSXML2"+x,', - 'n=[m+".6.0",m+".3.0",m+".5.0",m+".4.0",m,"Microsoft"+x],', - 'v=[6,3,5,4,2,1],', - 'a=ActiveXObject,', - 'i=-1;', - 'for(;i<5;){', - 'try{', - 'return f?[v[++i],new a(n[i])]:new a(n[i])', - '}catch(e){}', - '}' - ].join( '' ) ) ), - - X_Net_XHR_msXMLVer = 0, - X_Net_XHR_msXML = X_Net_XHR_createMSXML && X_Net_XHR_createMSXML( true ), + X_XHR_createMSXML = X_UA[ 'ActiveX' ] && ( X_UA[ 'IE5x' ] || X_UA[ 'IE6' ] || X_URL_IS_LOCAL ) && + function(){ return X_Script_createActiveXObjectSafty( X_XHR_msXMLName ); }, + + - X_Net_XHR_neverReuse = X_UA[ 'IE' ] < 9, // ie7,8 の xhr はリユース不可。msxml はリユース可能。 + X_XHR_neverReuse = X_UA[ 'IE' ] < 9, // ie7,8 の xhr はリユース不可。msxml はリユース可能。 - X_Net_XHR_TYPE_FLASH = 8, - X_Net_XHR_TYPE_GADGET = 16; - -if( X_Net_XHR_msXML ){ - X_Net_XHR_msXMLVer = X_Net_XHR_msXML[ 0 ]; - X_Net_XHR_msXML = X_Net_XHR_msXML[ 1 ]; -} else { - X_Net_XHR_createMSXML = null; + X_XHR_TYPE_FLASH = 8, + X_XHR_TYPE_GADGET = 16; + +if( X_XHR_createMSXML ){ + ( function(){ + var x = '.XMLHTTP', + m = 'MSXML2' + x, + n = [ m + ".6.0", m + ".3.0", m + ".5.0", m + ".4.0", m, "Microsoft" + x ], + v = [ 6, 3, 5, 4, 2, 1 ], + i = -1, + a; + for( ; i < 5; ){ + a = X_Script_createActiveXObjectSafty( n[ ++i ] ); + if( a ){ + X_XHR_msXMLVer = v[ i ]; + X_XHR_msXMLName = n[ i ]; + X_XHR_msXML = a; + return; + }; + }; + X_XHR_createMSXML = null; + })(); }; X[ 'XHR' ] = { - 'W3C' : X_Net_XHR_createW3C ? 1 : 0, - 'MSXML' : X_Net_XHR_createMSXML ? 2 : 0, - 'XDR' : X_Net_XHR_createXDR ? 4 : 0, + 'W3C' : X_XHR_createW3C ? 1 : 0, + 'MSXML' : X_XHR_createMSXML ? 2 : 0, + 'XDR' : X_XHR_createXDR ? 4 : 0, /* * http://hakuhin.jp/as/import.html @@ -106,30 +111,30 @@ X[ 'XHR' ] = { * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest * Progress Events Chrome7, firefox3.5, ie10, opera12, Safari?, Chrome for Android 0.16 */ - 'PROGRESS' : X_Net_XHR_progress, + 'PROGRESS' : X_XHR_progress, - 'UPLOAD_PROGRESS' : X_Net_XHR_upload, + 'UPLOAD_PROGRESS' : X_XHR_upload, // or gadget proxy or flash - 'CORS' : X_Net_XHR_xdr || X_Net_XHR_cors, + 'CORS' : X_XHR_xdr || X_XHR_cors, - 'BINARY' : X_Pulgin_VBS_ENABLED + 'BINARY' : X_Script_VBS_ENABLED }; -if( X_Net_XHR_msXMLVer ) X[ 'XHR' ][ 'MSXML_VERSION' ] = X_Net_XHR_msXMLVer; +if( X_XHR_msXMLVer ) X[ 'XHR' ][ 'MSXML_VERSION' ] = X_XHR_msXMLVer; -if( X_Net_XHR_w3c || X_Net_XHR_msXML ){ +if( X_XHR_w3c || X_XHR_msXML ){ -X_TEMP.X_Net_XHR_init = function(){ - X_NET_XHRWrapper = X_Class_override( X_EventDispatcher(), X_TEMP.X_Net_XHR_params, true ); - - delete X_TEMP.X_Net_XHR_init; - delete X_TEMP.X_Net_XHR_params; + X_TEMP.X_XHR_init = function(){ + X_XHR = X_Class_override( X_EventDispatcher(), X_TEMP.X_XHR_params, true ); + + delete X_TEMP.X_XHR_init; + delete X_TEMP.X_XHR_params; + + return X_XHR; + }; - return X_NET_XHRWrapper; -}; - -X_TEMP.X_Net_XHR_params = { + X_TEMP.X_XHR_params = { '_rawType' : X_EventDispatcher_EVENT_TARGET_XHR, @@ -145,7 +150,7 @@ X_TEMP.X_Net_XHR_params = { _timerID : 0, load : function( obj ){ - var raw = this[ '_rawObject' ], + var raw = X_XHR[ '_rawObject' ], method = obj[ 'method' ], url = obj[ 'url' ], async = obj[ 'async' ] !== false, @@ -158,43 +163,43 @@ X_TEMP.X_Net_XHR_params = { xDomain = !X_URL_isSameDomain( url ), isFile = X_URL_isLocal( url ), init, - tmp, p; + type, tmp, p; - this._dataType = obj[ 'dataType' ]; + X_XHR._dataType = obj[ 'dataType' ]; - if( !raw || xDomain !== this._isXDR || ( X_Net_XHR_createMSXML && isFile !== this._isMsXML ) ){ - raw && this[ 'unlisten' ]( [ 'load', 'readystatechange', 'progress', 'error', 'timeout' ] ); + if( !raw || xDomain !== X_XHR._isXDR || ( X_XHR_createMSXML && isFile !== X_XHR._isMsXML ) ){ + raw && X_XHR[ 'unlisten' ]( [ 'load', 'readystatechange', 'progress', 'error', 'timeout' ] ); init = true; - this[ '_rawObject' ] = raw = xDomain ? - ( X_Net_XHR_cors ? - X_Net_XHR_createW3C() : - X_Net_XHR_createXDR() + X_XHR[ '_rawObject' ] = raw = xDomain ? + ( X_XHR_cors ? + X_XHR_createW3C() : + X_XHR_createXDR() ) : isFile ? - ( X_Net_XHR_createMSXML ? - ( X_Net_XHR_msXML = X_Net_XHR_msXML || X_Net_XHR_createMSXML() ): - X_Net_XHR_createW3C() + ( X_XHR_createMSXML ? + ( X_XHR_msXML = X_XHR_msXML || X_XHR_createMSXML() ): + X_XHR_createW3C() ) : - X_Net_XHR_createW3C ? - X_Net_XHR_createW3C() : - ( X_Net_XHR_msXML = X_Net_XHR_msXML || X_Net_XHR_createMSXML() ); + X_XHR_createW3C ? + X_XHR_createW3C() : + ( X_XHR_msXML = X_XHR_msXML || X_XHR_createMSXML() ); // raw === XDR これは error になるのでフラグに控える - this._isXDR = X_Net_XHR_createXDR && xDomain; - this._isMsXML = !X_Net_XHR_createW3C || ( isFile && X_Net_XHR_createMSXML ); + X_XHR._isXDR = X_XHR_createXDR && xDomain; + X_XHR._isMsXML = !X_XHR_createW3C || ( isFile && X_XHR_createMSXML ); }; raw.open( method, url, async, username, password ); if( raw.responseType !== undefined ){ - switch( this._dataType ){ + switch( X_XHR._dataType ){ case '' : case 'text' : // js, css raw.responseType = 'text'; break; case 'json' : // firefox9- は moz-json - raw.responseType = X_UA[ 'Gecko' ] < 10 ? 'moz-json' : X_UA[ 'Gecko' ] ? this._dataType : ''; // Iron 37 でエラー + raw.responseType = X_UA[ 'Gecko' ] < 10 ? 'moz-json' : X_UA[ 'Gecko' ] ? X_XHR._dataType : ''; // Iron 37 でエラー break; case 'document' : case 'xml' : @@ -206,50 +211,43 @@ X_TEMP.X_Net_XHR_params = { case 'blob' : case 'arraybuffer' : // jpeg,jpg,png,gif,mp3,ogg... - raw.responseType = this._dataType; + raw.responseType = X_XHR._dataType; break; }; }; // http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_r_1.html - if( !this._isMsXML && raw.overrideMimeType ){ - switch( X_URL_getEXT( url ) || this._dataType ){ + if( !X_XHR._isMsXML && raw.overrideMimeType ){ + type = X_URL_getEXT( url ) || X_XHR._dataType; + switch( type ){ case 'html' : case 'htm' : case 'xml' : tmp = 'text/xml'; break; case 'json' : - tmp = 'application/json'; // 2015.6.29 + tmp = 'application/json'; break; - case 'mp3' : - tmp = 'audio/mpeg'; - break; + type = 'mpeg'; + case 'weba' : + type = type || 'webm'; case 'opus' : - case 'ogg' : - tmp = 'audio/ogg'; - break; - case 'wav' : - tmp = 'audio/wav'; - break; + type = type || 'ogg'; + case 'ogg' : + case 'wav' : case 'aac' : - tmp = 'audio/aac'; + tmp = 'audio/' + type; break; case 'm4a' : - tmp = 'audio/x-m4a"'; - break; case 'mp4' : - tmp = 'audio/x-mp4'; - break; - case 'weba' : - tmp = 'audio/webm'; + tmp = 'audio/x-' + type; break; }; if( tmp = obj[ 'mimeType' ] || tmp ) raw.overrideMimeType( tmp ); }; - if( !this._isXDR && ( this._isMsXML ? 3 <= X_Net_XHR_msXMLVer : raw.setRequestHeader ) ){ // msxml は setRequestHeader getter がいけない + if( !X_XHR._isXDR && ( X_XHR._isMsXML ? 3 <= X_XHR_msXMLVer : raw.setRequestHeader ) ){ // msxml は setRequestHeader getter がいけない /* if( noCache ){ @@ -260,7 +258,7 @@ X_TEMP.X_Net_XHR_params = { // http://nakigao.sitemix.jp/blog/?p=2040 // json 取得時に SafariでHTTP/412のエラー。但し相手が audio の場合この指定があるとロードに失敗する。 iOS8.2, iOS7.1 では遭遇せず - if( this._dataType === 'json' ){ + if( X_XHR._dataType === 'json' ){ headers[ 'If-Modified-Since' ] = ( new Date ).toUTCString(); }; @@ -275,65 +273,64 @@ X_TEMP.X_Net_XHR_params = { for( p in headers ){ - if( X_EMPTY_OBJECT[ p ] ) continue; + //if( X_EMPTY_OBJECT[ p ] ) continue; //console.log( headers[ p ] ); headers[ p ] !== undefined && raw.setRequestHeader( p, headers[ p ] + '' ); // Opera8.01+, MSXML3+ }; }; - if( !this._isMsXML && raw.timeout !== undefined ){ + if( !X_XHR._isMsXML && raw.timeout !== undefined ){ raw.timeout = timeout; } else { - this._timerID = X_Timer_once( timeout, this, this.onTimeout ); + X_XHR._timerID = X_Timer_once( timeout, X_XHR.onTimeout ); }; // send 前にフラグを立てる,回線が早いと raw.send() 内で onload -> _busy = false ののち、 _busy = true するため。 - this._busy = true; + X_XHR._busy = true; raw.send( X_Type_isString( postdata ) ? postdata : X_String_serialize( postdata ) ); if( !async || raw.readyState === 4 ){ - X_Timer_once( 32, this, this.handleEvent, [ { type : 'readystatechange' } ] ); + X_Timer_once( 32, X_XHR, [ { type : 'readystatechange' } ] ); } else if( init ){ - if( this._isMsXML ){ - raw[ 'onreadystatechange' ] = X_NET_XHRWrapper.handleEvent; + if( X_XHR._isMsXML ){ + raw[ 'onreadystatechange' ] = X_XHR.handleEvent; } else - if( X_Net_XHR_progress || this._isXDR ){ - this[ 'listen' ]( [ 'load', 'progress', 'error', 'timeout' ] ); //, 'abort' + if( X_XHR_progress || X_XHR._isXDR ){ + X_XHR[ 'listen' ]( [ 'load', 'progress', 'error', 'timeout' ] ); //, 'abort' } else if( X_UA[ 'IE8' ] ){ - this[ 'listen' ]( [ 'readystatechange', 'error', 'timeout' ] ); + X_XHR[ 'listen' ]( [ 'readystatechange', 'error', 'timeout' ] ); } else if( X_UA[ 'IE7' ] ){ - this[ 'listen' ]( [ 'readystatechange', 'error' ] ); - + X_XHR[ 'listen' ]( [ 'readystatechange', 'error' ] ); } else { - this[ 'listen' ]( [ 'load', 'readystatechange', 'error', 'timeout' ] ); //, 'abort' + X_XHR[ 'listen' ]( [ 'load', 'readystatechange', 'error', 'timeout' ] ); //, 'abort' }; - if( X_Net_XHR_upload ){ - raw.upload.addEventListener( 'progress', this.onUploadProgress ); + if( X_XHR_upload ){ + raw.upload.addEventListener( 'progress', X_XHR.onUploadProgress ); }; }; }, cancel : function(){ - /* this[ '_rawObject' ].abort && */ this[ '_rawObject' ].abort(); - this._canceled = true; + /* X_XHR[ '_rawObject' ].abort && */ X_XHR[ '_rawObject' ].abort(); + X_XHR._canceled = true; }, reset : function(){ - this._method = this._dataType = ''; - this._canceled = this._busy = this._error = false; - this._timerID && X_Timer_remove( this._timerID ); - this._percent = this._timerID = 0; + X_XHR._method = X_XHR._dataType = ''; + X_XHR._canceled = X_XHR._busy = X_XHR._error = false; + X_XHR._timerID && X_Timer_remove( X_XHR._timerID ); + X_XHR._percent = X_XHR._timerID = 0; // XMLHttpRequest の使い方 // http://webos-goodies.jp/archives/50548720.html // XMLHttpRequest オブジェクトを再利用する際も、 abort メソッドを呼び出す必要があるようです。 - /* this[ '_rawObject' ].abort && */ this[ '_rawObject' ].abort(); + /* X_XHR[ '_rawObject' ].abort && */ X_XHR[ '_rawObject' ].abort(); // XMLHttpRequest で順番にリソースを取得する // http://note.chiebukuro.yahoo.co.jp/detail/n16248 @@ -346,32 +343,32 @@ X_TEMP.X_Net_XHR_params = { // Timeout した Gecko の xhr.response に触るとエラー?? - if( this._error || ( X_Net_XHR_neverReuse && !this._isMsXML ) ){ + if( X_XHR._error || ( X_XHR_neverReuse && !X_XHR._isMsXML ) ){ - if( X_Net_XHR_upload ){ - X_Net_XHR_w3c.upload.removeEventListener( 'progress', this.onUploadProgress ); + if( X_XHR_upload ){ + X_XHR_w3c.upload.removeEventListener( 'progress', X_XHR.onUploadProgress ); }; // ie7 は xhr object を再利用できない。但し send のあとに alert を挟むと動いた、、、 // ie7モード(IE11) では再利用可能、、、 - X_EventDispatcher_toggleAllEvents( this, false ); - this[ '_rawObject' ] = null; + X_EventDispatcher_toggleAllEvents( X_XHR, false ); + X_XHR[ '_rawObject' ] = null; - if( this._isXDR ){ - X_Net_XHR_xdr = null; - delete this._isXDR; + if( X_XHR._isXDR ){ + X_XHR_xdr = null; + delete X_XHR._isXDR; } else { - X_Net_XHR_w3c = null; + X_XHR_w3c = null; }; - this[ 'unlisten' ]( [ 'load', 'readystatechange', 'progress', 'error', 'timeout' ] ); + X_XHR[ 'unlisten' ]( [ 'load', 'readystatechange', 'progress', 'error', 'timeout' ] ); }; }, handleEvent : function( e ){ - var raw = X_NET_XHRWrapper[ '_rawObject' ], - live = !X_NET_XHRWrapper._canceled, + var raw = X_XHR[ '_rawObject' ], + live = !X_XHR._canceled, headers, status, data; switch( e && e.type || 'readystatechange' ){ @@ -396,14 +393,14 @@ X_TEMP.X_Net_XHR_params = { case 1 : return; case 2 : // 0% ajaxstart - live && X_NET_XHRWrapper[ 'asyncDispatch' ]( { type : X_EVENT_PROGRESS, 'percent' : 0 } ); + live && X_XHR[ 'asyncDispatch' ]( { type : X_EVENT_PROGRESS, 'percent' : 0 } ); return; case 3 : - live && X_NET_XHRWrapper[ 'asyncDispatch' ]( { type : X_EVENT_PROGRESS, 'percent' : X_NET_XHRWrapper._percent < 99.9 ? 99.9 : ( X_NET_XHRWrapper._percent + 100 ) / 2 } ); + live && X_XHR[ 'asyncDispatch' ]( { type : X_EVENT_PROGRESS, 'percent' : X_XHR._percent < 99.9 ? 99.9 : ( X_XHR._percent + 100 ) / 2 } ); // 99.9% return; case 4 : - if( X_NET_XHRWrapper._percent === 100 ) return; // Opera8 readystatechange が2重に発生 + if( X_XHR._percent === 100 ) return; // Opera8 readystatechange が2重に発生 // 100% break; // load へ default : @@ -414,19 +411,19 @@ X_TEMP.X_Net_XHR_params = { case 'load' : - if( !X_NET_XHRWrapper._busy ) return; + if( !X_XHR._busy ) return; - X_NET_XHRWrapper._percent = 100; - X_NET_XHRWrapper._busy = false; + X_XHR._percent = 100; + X_XHR._busy = false; status = raw.status; // TODO GET_FULL_HEADERS // https://msdn.microsoft.com/en-us/library/ms766595%28v=vs.85%29.aspx // Implemented in: MSXML 3.0 and MSXML 6.0 - if( X_NET_XHRWrapper._isXDR ){ + if( X_XHR._isXDR ){ headers = { 'Content-Type' : raw.contentType }; } else - if( ( X_NET_XHRWrapper._isMsXML ? 3 <= X_Net_XHR_msXMLVer : raw.setRequestHeader ) && ( headers = raw.getAllResponseHeaders() ) ){ + if( ( X_XHR._isMsXML ? 3 <= X_XHR_msXMLVer : raw.setRequestHeader ) && ( headers = raw.getAllResponseHeaders() ) ){ headers = X_NET_XHR_parseResponseHeaders( headers ); }; @@ -445,7 +442,7 @@ X_TEMP.X_Net_XHR_params = { */ // parse json, html, xml, text, script, css - switch( X_NET_XHRWrapper._dataType ){ + switch( X_XHR._dataType ){ case '' : case 'text' : data = raw[ 'responseText' ]; @@ -470,56 +467,55 @@ X_TEMP.X_Net_XHR_params = { data = raw[ 'response' ] || raw[ 'responseText' ]; // とりあえず break; }; - X_NET_XHRWrapper[ 'asyncDispatch' ]( 32, { type : X_EVENT_SUCCESS, status : status || 200, response : data, 'headers' : headers || null } ); + X_XHR[ 'asyncDispatch' ]( 32, { type : X_EVENT_SUCCESS, status : status || 200, response : data, 'headers' : headers || null } ); } else { - X_NET_XHRWrapper[ 'asyncDispatch' ]( 32, { type : X_EVENT_ERROR, status : status || 400, 'headers' : headers || null } ); + X_XHR[ 'asyncDispatch' ]( 32, { type : X_EVENT_ERROR, status : status || 400, 'headers' : headers || null } ); }; break; case 'progress' : if( e.lengthComputable ){ - X_NET_XHRWrapper._percent = e.loaded / e.total * 100; - live && X_NET_XHRWrapper._percent < 100 && X_NET_XHRWrapper[ 'asyncDispatch' ]( { type : X_EVENT_PROGRESS, 'percent' : X_NET_XHRWrapper._percent } ); + X_XHR._percent = e.loaded / e.total * 100; + live && X_XHR._percent < 100 && X_XHR[ 'asyncDispatch' ]( { type : X_EVENT_PROGRESS, 'percent' : X_XHR._percent } ); }; break; case 'error' : //console.dir( e ); - X_NET_XHRWrapper._busy = false; - X_NET_XHRWrapper._error = X_UA[ 'Opera' ] || X_UA[ 'Webkit' ] ; - live && X_NET_XHRWrapper[ 'asyncDispatch' ]( 32, { type : X_EVENT_ERROR, status : raw.status } ); + X_XHR._busy = false; + X_XHR._error = X_UA[ 'Opera' ] || X_UA[ 'Webkit' ] ; + live && X_XHR[ 'asyncDispatch' ]( 32, { type : X_EVENT_ERROR, status : raw.status } ); break; case 'timeout' : // Gecko 12.0 https://developer.mozilla.org/ja/docs/XMLHttpRequest/Synchronous_and_Asynchronous_Requests - X_NET_XHRWrapper._busy = false; - X_NET_XHRWrapper._error = !!X_UA[ 'Gecko' ]; - X_NET_XHRWrapper[ 'asyncDispatch' ]( { type :X_EVENT_ERROR, 'timeout' : true, status : 408 } ); + X_XHR._busy = false; + X_XHR._error = !!X_UA[ 'Gecko' ]; + X_XHR[ 'asyncDispatch' ]( { type : X_EVENT_ERROR, 'timeout' : true, status : 408 } ); break; }; }, onTimeout : function(){ - var raw = this[ '_rawObject' ], - live = !X_NET_XHRWrapper._canceled || !this._busy; + var raw = X_XHR[ '_rawObject' ], + live = !X_XHR._canceled || !X_XHR._busy; if( live || raw.readyState < 3 ){ - this._busy = false; - live && this[ 'asyncDispatch' ]( { type : X_EVENT_ERROR, 'timeout' : true, status : 408 } ); + X_XHR._busy = false; + live && X_XHR[ 'asyncDispatch' ]( { type : X_EVENT_ERROR, 'timeout' : true, status : 408 } ); }; - this._timerID = 0; + X_XHR._timerID = 0; }, - onUploadProgress : X_Net_XHR_upload && function( e ){ - !X_NET_XHRWrapper._canceled && - X_NET_XHRWrapper[ 'asyncDispatch' ]( { + onUploadProgress : X_XHR_upload && function( e ){ + !X_XHR._canceled && + X_XHR[ 'asyncDispatch' ]( { type : X_EVENT_PROGRESS, - 'percent' : X_NET_XHRWrapper._percent, + 'percent' : X_XHR._percent, 'uploadPercent' : e.loaded / e.total * 100 } ); } }; // 同期リクエストでなければならない場合, unload, beforeunload時 - }; /* * https://gist.github.com/mmazer/5404301 diff --git a/0.6.x/js/06_net/03_XNetForm.js b/0.6.x/js/06_net/03_XNetForm.js index ce5021a..1bfd498 100644 --- a/0.6.x/js/06_net/03_XNetForm.js +++ b/0.6.x/js/06_net/03_XNetForm.js @@ -37,8 +37,7 @@ X_TEMP.X_NET_Form_params = { '
' ], - k; + '">' ]; if( target === '_top' || target === '_parent' ) this.isJump = true; if( 0 <= option[ 'timeout' ] ) this.timeout = option[ 'timeout' ]; diff --git a/0.6.x/js/06_net/05_XXHRGadget.js b/0.6.x/js/06_net/05_XXHRGadget.js index 16d83be..9b89fdc 100644 --- a/0.6.x/js/06_net/05_XXHRGadget.js +++ b/0.6.x/js/06_net/05_XXHRGadget.js @@ -31,8 +31,6 @@ var X_NET_GIMR_canUse = 5.5 <= X_UA[ 'IE' ] || !X_UA[ 'IE' ], // https://code.google.com/p/xssinterface/source/browse/trunk/js/xssinterface.js X_NET_GIMR_maxQueryLength = X_UA[ 'IE' ] ? 2000 : 6000, - X_NET_GIMR_detection = new Function( 'f,j,i', 'for(j=f.length;j;)try{i=f[--j];return i.location.hash}catch(e){}' ), - X_NET_GIMR_requestBatches, X_NET_GIMR_requestOriginal, @@ -48,13 +46,15 @@ var X_NET_GIMR_canUse = 5.5 <= X_UA[ 'IE' ] || !X_UA[ 'IE' ], function X_NET_GIMR_detectImageOverIframe(){ var raw = this[ '_rawObject' ], - iwin, ret, n; + iwin, ret, i, n; if( raw ){ iwin = raw.contentWindow || ( raw.contentDocument && raw.contentDocument.parentWindow ) || window.frames[ X_NET_GIMR_iframeName ]; - if( iwin && iwin.frames && iwin.frames.length ){ - ret = X_NET_GIMR_detection( iwin.frames ); + if( iwin && iwin.frames && ( i = iwin.frames.length ) ){ + for( ; i; ){ + if( ret = X_Script_try( X_Object_find, [ iwin.frames[ --i ], 'location.hash' ] ) ) break; + }; if( ret && ret !== X_NET_GIMR_lastHashString ){ X_NET_GIMR_lastHashString = ret; //console.log( ret.length ); diff --git a/0.6.x/js/06_net/10_XOAuth2.js b/0.6.x/js/06_net/10_XOAuth2.js index 86d1584..6d28665 100644 --- a/0.6.x/js/06_net/10_XOAuth2.js +++ b/0.6.x/js/06_net/10_XOAuth2.js @@ -1,7 +1,6 @@ //{+oauth2"OAuth2 サービスの定義"(OAuth2外部サービスを定義し、認可プロセス・xhrの署名を自動化します)[+xhr] -var X_NET_OAUTH2_detection = new Function( 'w', 'try{return w.location.search}catch(e){}' ), - X_NET_OAUTH2_authorizationWindow, +var X_NET_OAUTH2_authorizationWindow, X_NET_OAUTH2_authorizationTimerID; /** @@ -236,7 +235,7 @@ function X_Net_OAuth2_detectAuthPopup(){ this[ 'asyncDispatch' ]( X_EVENT_CANCELED ); } else - if( search = X_NET_OAUTH2_detection( X_NET_OAUTH2_authorizationWindow ) ){ + if( search = X_Script_try( X_Object_find, [ X_NET_OAUTH2_authorizationWindow, 'location>search' ] ) ){ pair = X_Pair_get( this ); pair.code = X_URL_paramToObj( search.slice( 1 ) )[ 'code' ]; @@ -394,7 +393,7 @@ function X_OAuth2_getAccessTokenExpiry( that ){ return parseInt( X_OAuth2_update function X_OAuth2_getAuthMechanism( that ){ // TODO use gadget | flash ... // IE's XDomainRequest doesn't support sending headers, so don't try. - return ( X_NET_currentWrapper === X_NET_XHRWrapper ) && X_Net_XHR_createXDR ? 'param' : X_OAuth2_updateLocalStorage( '', that, 'AuthMechanism' ); + return ( X_NET_currentWrapper === X_XHR ) && X_XHR_createXDR ? 'param' : X_OAuth2_updateLocalStorage( '', that, 'AuthMechanism' ); } function X_OAuth2_setAccessToken( that, value ){ X_OAuth2_updateLocalStorage( '+', that, 'accessToken' , value); } function X_OAuth2_setRefreshToken( that, value ){ X_OAuth2_updateLocalStorage( '+', that, 'refreshToken', value); } diff --git a/0.6.x/js/07_audio/01_XWebAudio.js b/0.6.x/js/07_audio/01_XWebAudio.js index bded21f..522443d 100644 --- a/0.6.x/js/07_audio/01_XWebAudio.js +++ b/0.6.x/js/07_audio/01_XWebAudio.js @@ -328,13 +328,14 @@ if( X_WebAudio_context ){ // おかしい、stop 前に外していても呼ばれる、、、@Firefox33.1 // 破棄された X.Callback が呼ばれて、obj.proxy() でエラーになる。Firefox では、onended は使わない - if( false && this.bufferSource.onended !== undefined ){ + // 多くのブラウザで onended は timer を使ったカウントより遅いので使わない + //if( this.bufferSource.onended !== undefined ){ //console.log( '> use onended' ); - this.bufferSource.onended = this._onended || ( this._onended = X_Closure_create( this, this._onEnded ) ); - } else { + //this.bufferSource.onended = this._onended || ( this._onended = X_Closure_create( this, this._onEnded ) ); + //} else { this._timerID && X_Timer_remove( this._timerID ); this._timerID = X_Timer_once( end - begin, this, this._onEnded ); - }; + //}; if( this.bufferSource.start ){ this.bufferSource.start( 0, begin / 1000, end / 1000 ); diff --git a/0.6.x/js/07_audio/02_XHTMLAudio.js b/0.6.x/js/07_audio/02_XHTMLAudio.js index a231e67..e792bcd 100644 --- a/0.6.x/js/07_audio/02_XHTMLAudio.js +++ b/0.6.x/js/07_audio/02_XHTMLAudio.js @@ -22,7 +22,7 @@ var X_HTMLAudio_playTrigger = X_UA[ 'iOS' ] < 5 ? 'stalled' : X_UA[ 'iOS' ] ? 'suspend' : X_UA[ 'Safari' ] < 4 ? 'canplaythrough' : - X_UA[ 'ChromeWK' ] ? 'canplaythrough' : + X_UA[ 'ChromeWV' ] ? 'canplaythrough' : // Android 2.3.5(SBM101SH) では stalled は発生しない,,, ので必ず loadeddata もチェックする X_UA[ 'AOSP' ] ? 'stalled' : X_UA[ 'OperaMobile' ] || X_UA[ 'OperaTablet' ] ? 'loadeddata' : @@ -52,7 +52,7 @@ var X_HTMLAudio_playTrigger = X_HTMLAudio_pauseFix = ( X_UA[ 'Windows' ] && 12 <= X_UA[ 'Opera' ] && 0 < ' XP XPSP2 2003|XP64'.indexOf( X_UA[ 'Windows' ] ) ), // XP + Opera12 のみ? /* * durationFix - * duration が取得できるタイミングが遅くそれまでは infinity(PC Opera12), NaN(WP9), 0(AOSP Chrome 系) が入っている + * duration が取得できるタイミングが遅くそれまでは infinity(PC Opera12), NaN(WP9), 0(Android 標準ブラウザ ChromeWebkit 系) が入っている * * 1. touch が不要の場合、自動で再生を開始して duration を取得するまで再生する * -> 取得後に pause or 通常再生 @@ -65,8 +65,8 @@ var X_HTMLAudio_playTrigger = * -> その際には timeupdate が発行されない、、、 iframe+image+audio で使わないときは破棄する、とか。 * -> opera11、10.54 WinXP はまとも、、、 portable が怪しい?? */ - X_HTMLAudio_need1stTouch = X_UA[ 'iOS' ] || X_UA[ 'ChromeWK' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ), - X_HTMLAudio_durationFix = ( X_UA[ 'Windows' ] && 12 <= X_UA[ 'Opera' ] ) || X_UA[ 'ChromeWK' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ), + X_HTMLAudio_need1stTouch = X_UA[ 'iOS' ] || X_UA[ 'ChromeWV' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ), + X_HTMLAudio_durationFix = ( X_UA[ 'Windows' ] && 12 <= X_UA[ 'Opera' ] ) || X_UA[ 'ChromeWV' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ), X_HTMLAudio_shortPlayFix = X_UA[ 'AOSP' ]; // Android 4.1.1 でも遭遇(ただしm4a, mp3は優秀, oggはシークが乱れる) diff --git a/0.6.x/js/07_audio/03_XSilverlightAudio.js b/0.6.x/js/07_audio/03_XSilverlightAudio.js index 7133272..3a3f0b0 100644 --- a/0.6.x/js/07_audio/03_XSilverlightAudio.js +++ b/0.6.x/js/07_audio/03_XSilverlightAudio.js @@ -222,11 +222,10 @@ if( X[ 'Pulgin' ][ 'Silverlight' ] ){ // stop() case 'Stopped': this.playing && X_Timer_once( 16, this, this.actualPlay ); - return; //this.playing = false; - this._ended = true; - this._paused = false; + //this._ended = true; + //this._paused = false; //this.setCurrentTime( this.startTime ); break; }; diff --git a/0.6.x/js/07_audio/10_XAudioSprite.js b/0.6.x/js/07_audio/10_XAudioSprite.js index 99ff9b2..cd11ea6 100644 --- a/0.6.x/js/07_audio/10_XAudioSprite.js +++ b/0.6.x/js/07_audio/10_XAudioSprite.js @@ -4,23 +4,23 @@ * Mobile Opera11 は Audio をサポートするがイベントが取れない * iframe 内で生成して、Audio Sprite の preset で再生できないか? */ -var X_Audio_Sprite_shouldUse = window.HTMLAudioElement && ( X_UA[ 'iOS' ] || X_UA[ 'AndroidBrowser' ] || X_UA[ 'OperaMobile' ] || X_UA[ 'OperaTablet' ] ), // Flash がない - X_Audio_Sprite_useVideoForMulti = //( X_UA[ 'AndroidBrowser3' ] && 3.1 <= X_UA[ 'AndroidBrowser' ] ) || - //( ( 4.2 <= X_UA[ 'AndroidBrowser' ] || ( 4.1 <= X_UA[ 'AndroidBrowser' ] && 2 <= X_UA[ 'AndroidPatch' ] ) ) && X_UA[ 'AndroidWebkit' ] <= 534.3 ), - // ドスパラパッドはビデオのインライン再生が不可, 534.30 で Webkit系は終了, 次は 537.36 で Chrome系 - false, //X_UA[ 'AndroidChromeBrowser' ], - X_Audio_Sprite_needTouchAndroid = X_UA[ 'AndroidChromeBrowser' ] && !X_Audio_WebAudioWrapper, - X_Audio_Sprite_needTouchFirst = X_UA[ 'iOS' ] || X_Audio_Sprite_needTouchAndroid || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ), - X_Audio_Sprite_disableMultiTrack = ( X_UA[ 'iOS' ] && !X_Audio_WebAudio_context ) || ( !X_UA[ 'AndroidChromeBrowser' ] && X_UA[ 'AndroidBrowser4' ] ) || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE' ] < 12 ), - X_Audio_Sprite_enableVolume = window.HTMLAudioElement && ( !X_UA[ 'iOS' ] && !X_UA[ 'AndroidBrowser' ] && !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] ), // TODO fennec は 25以上 +var X_AudioSprite_shouldUse = X_HTMLAudio && ( X_UA[ 'iOS' ] || X_UA[ 'AOSP' ] || X_UA[ 'OperaMobile' ] || X_UA[ 'OperaTablet' ] ), // Flash がない + X_AudioSprite_useVideoForMulti = //( 3.1 <= X_UA[ 'AOSP' ] < 4 ) || + //( ( 4.2 <= X_UA[ 'AOSP' ] ), + // ドスパラパッドはビデオのインライン再生が不可 + false, //X_UA[ 'ChromeWV' ], + X_AudioSprite_needTouchAndroid = X_UA[ 'ChromeWV' ] && !X_WebAudio, + X_AudioSprite_needTouchFirst = X_HTMLAudio_need1stTouch, + X_AudioSprite_disableMultiTrack = ( X_UA[ 'iOS' ] && !X_WebAudio_context ) || ( X_UA[ 'AOSP4' ] ) || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE' ] < 12 ), + X_AudioSprite_enableVolume = X_HTMLAudio && ( !X_UA[ 'iOS' ] && !X_UA[ 'AOSP' ] && !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] ), // TODO fennec は 25以上 // http://tukumemo.com/html5-audio-sp/ // iOS6、Android4.1から同時再生が可能になりました。 - X_Audio_Sprite_maxTracks = X_Audio_Sprite_useVideoForMulti ? 2 : X_Audio_Sprite_disableMultiTrack ? 1 : 9, - X_Audio_Sprite_lengthSilence = 10000, // 一番最初の無音部分の長さ - X_Audio_Sprite_lengthDistance = 5000, // 音間の無音の長さ - X_Audio_Sprite_uid = 0, - X_Audio_Sprite_members = {}, - X_Audio_Sprite_TEMP = { + X_AudioSprite_maxTracks = X_AudioSprite_useVideoForMulti ? 2 : X_AudioSprite_disableMultiTrack ? 1 : 9, + X_AudioSprite_lengthSilence = 10000, // 一番最初の無音部分の長さ + X_AudioSprite_lengthDistance = 5000, // 音間の無音の長さ + X_AudioSprite_uid = 0, + X_AudioSprite_members = {}, + X_AudioSprite_TEMP = { presets : {}, BGMs : {}, tracks : [], @@ -32,14 +32,34 @@ var X_Audio_Sprite_shouldUse = window.HTMLAudioElement && ( X_UA[ 'iOS' ] bgmLooped : false, bgmPlaying : false }, - X_Audio_Sprite_instance, - X_Audio_Sprite_numTracks, - X_Audio_Sprite_useVideo; + X_AudioSprite_instance, + X_AudioSprite_numTracks, + X_AudioSprite_useVideo; +/** + * { + * urls : [ 'xx.ogg', 'xx.mp3' ], + * numTracks : 3, + * useVideo : false, + * volume : 1, + * BGM_01 : [ '15.00', '45.500', true, '17.666', '50.999' ], + * BGM_02 : [ '56.00', '1:15.230', true ] + * } + * + * X_EVENT_BACKEND_READY + * X_EVENT_BACKEND_NONE + * + * X_EVENT_READY + * X_EVENT_MEDIA_LOOPED + * X_EVENT_MEDIA_ENDED + * + * @namespace X.AudioSprite + * @alias X.AudioSprite + */ X[ 'AudioSprite' ] = function( setting ){ - var tracks = X_Audio_Sprite_TEMP.tracks, - bgms = X_Audio_Sprite_TEMP.BGMs, - presets = X_Audio_Sprite_TEMP.presets, + var tracks = X_AudioSprite_TEMP.tracks, + bgms = X_AudioSprite_TEMP.BGMs, + presets = X_AudioSprite_TEMP.presets, urls = setting[ 'urls' ], video = setting[ 'useVideo' ], n = video ? 1 : setting[ 'numTracks' ] || 1, @@ -47,21 +67,21 @@ X[ 'AudioSprite' ] = function( setting ){ volume : setting[ 'volume' ] || 0.5, autoplay : false, startTime : 0, - endTime : X_Audio_Sprite_lengthSilence, + endTime : X_AudioSprite_lengthSilence, loop : true }, k, i, v, track; - if( !X_Audio_Sprite_instance ){ - X_Audio_Sprite_instance = X_Class_override( X_EventDispatcher(), X_Audio_Sprite_members ); - X_ViewPort[ 'listen' ]( [ X_EVENT_VIEW_ACTIVATE, X_EVENT_VIEW_DEACTIVATE ], X_Audio_Sprite_instance, X_Audio_Sprite_handleEvent ); + if( !X_AudioSprite_instance ){ + X_AudioSprite_instance = X_Class_override( X_EventDispatcher(), X_AudioSprite_members ); + X_ViewPort[ 'listen' ]( [ X_EVENT_VIEW_ACTIVATE, X_EVENT_VIEW_DEACTIVATE ], X_AudioSprite_instance, X_AudioSprite_handleEvent ); }; - n = n <= X_Audio_Sprite_maxTracks ? n : X_Audio_Sprite_maxTracks; + n = n <= X_AudioSprite_maxTracks ? n : X_AudioSprite_maxTracks; // TODO // Android4.x標準ブラウザ(Chrome系)でブラウザが隠れた場合に音が鳴り続ける問題、ビデオで解決できる? - //if( X_Audio_Sprite_needTouchAndroid && n === 1 ){ + //if( X_AudioSprite_needTouchAndroid && n === 1 ){ // video = true; //}; @@ -71,32 +91,32 @@ X[ 'AudioSprite' ] = function( setting ){ v = X_Array_copy( v ); for( i = v.length; i; ){ --i; - if( i !== 2 ) v[ i ] = X_AudioWrapper_timeStringToNumber( v[ i ] ); + if( i !== 2 ) v[ i ] = X_Audio_timeStringToNumber( v[ i ] ); }; if( v[ 2 ] ) bgms[ k ] = v; presets[ k ] = v; }; }; - X_Audio_startDetectionBackend( X_Audio_BACKENDS[ 0 ], X_Audio_Sprite_instance, X_Array_copy( urls ), option ); + X_Audio_startDetectionBackend( X_Audio_BACKENDS[ 0 ], X_AudioSprite_instance, X_Array_copy( urls ), option ); - X_Audio_Sprite_instance[ 'listenOnce' ]( [ X_EVENT_BACKEND_READY, X_EVENT_BACKEND_NONE ], X_AudioSprite_backendHandler ); - X_Audio_Sprite_instance[ 'listenOnce' ]( X_EVENT_KILL_INSTANCE, X_Audio_Sprite_handleEvent ); + X_AudioSprite_instance[ 'listenOnce' ]( [ X_EVENT_BACKEND_READY, X_EVENT_BACKEND_NONE ], X_AudioSprite_backendHandler ); + X_AudioSprite_instance[ 'listenOnce' ]( X_EVENT_KILL_INSTANCE, X_AudioSprite_handleEvent ); - X_Audio_Sprite_useVideo = video; - X_Audio_Sprite_numTracks = X_Audio_Sprite_instance[ 'numTracks' ] = n; + X_AudioSprite_useVideo = video; + X_AudioSprite_numTracks = X_AudioSprite_instance[ 'numTracks' ] = n; - return X_Audio_Sprite_instance; + return X_AudioSprite_instance; }; -X[ 'AudioSprite' ][ 'shouldUse' ] = X_Audio_Sprite_shouldUse; -X[ 'AudioSprite' ][ 'needTouchFirst' ] = X_Audio_Sprite_needTouchFirst; -X[ 'AudioSprite' ][ 'enableMultiTrack' ] = !X_Audio_Sprite_disableMultiTrack; +X[ 'AudioSprite' ][ 'shouldUse' ] = X_AudioSprite_shouldUse; +X[ 'AudioSprite' ][ 'needTouchFirst' ] = X_AudioSprite_needTouchFirst; +X[ 'AudioSprite' ][ 'enableMultiTrack' ] = !X_AudioSprite_disableMultiTrack; // 再生が終わっているもの、終わりかけのものを探す // TODO 終わりかけのもの、と一番古いもの、どちらを再利用するか?これ以上に細かい実装を望む場合は X.Audio.Sprite は使わず自力で実装 -function X_Audio_Sprite_getTrackEnded(){ - var tracks = X_Audio_Sprite_TEMP.tracks, +function X_AudioSprite_getTrackEnded(){ + var tracks = X_AudioSprite_TEMP.tracks, l = tracks.length, i = 0, track, state, last = 1 / 0, _last, index; @@ -104,8 +124,8 @@ function X_Audio_Sprite_getTrackEnded(){ track = tracks[ i ]; state = track.getState(); if( !state.playing ) return track; - if( track === X_Audio_Sprite_TEMP.bgmTrack ) continue; - if( state.currentTime <= X_Audio_Sprite_lengthSilence + X_Audio_Sprite_lengthDistance ) return track; + if( track === X_AudioSprite_TEMP.bgmTrack ) continue; + if( state.currentTime <= X_AudioSprite_lengthSilence + X_AudioSprite_lengthDistance ) return track; _last = state.endTime - state.currentTime; if( _last < last ){ last = _last; @@ -115,42 +135,30 @@ function X_Audio_Sprite_getTrackEnded(){ return tracks[ index ]; }; -/* - * { - * urls : [ 'xx.ogg', 'xx.mp3' ], - * numTracks : 3, - * useVideo : false, - * volume : 1, - * BGM_01 : [ '15.00', '45.500', true, '17.666', '50.999' ], - * BGM_02 : [ '56.00', '1:15.230', true ] - * } - * - * X_EVENT_BACKEND_READY - * X_EVENT_BACKEND_NONE - * - * X_EVENT_READY - * X_EVENT_MEDIA_LOOPED - * X_EVENT_MEDIA_ENDED - * - */ - -X_Audio_Sprite_members = { - +X_AudioSprite_members = +/** @lends X.AudioSprite.prototype */ +{ + /** + * @type {number} + */ 'numTracks' : 0, + /** + * モバイル用タッチイベント中に呼び出す + */ 'load' : function(){ - var tracks = X_Audio_Sprite_TEMP.tracks, + var tracks = X_AudioSprite_TEMP.tracks, i = 0, l = tracks.length; for( ; i < l; ++i ){ - if( X_Audio_Sprite_needTouchAndroid ){ + if( X_AudioSprite_needTouchAndroid ){ console.log( '[duration fix]開始 - ' + tracks[ i ][ '_rawObject' ].duration ); - tracks[ i ]._playForDuration = 1; + tracks[ i ]._durationFixPhase = 1; tracks[ i ][ '_rawObject' ].play(); } else if( X_UA[ 'WinPhone' ] ){ console.log( 'WinPhone : touch -> play()' ); - //tracks[ i ].play( 0, X_Audio_Sprite_lengthSilence, true, 0, X_Audio_Sprite_lengthSilence ).seek( 0 ); + //tracks[ i ].play( 0, X_AudioSprite_lengthSilence, true, 0, X_AudioSprite_lengthSilence ).seek( 0 ); this[ 'pause' ]( i ); } else { tracks[ i ][ '_rawObject' ].load(); @@ -158,70 +166,72 @@ X_Audio_Sprite_members = { }; }, - /* + /** + * 再生 + * @param {string} name トラック名 * @return {number} uid */ 'play' : function( name ){ - var bgm = X_Audio_Sprite_TEMP.bgmTrack, - tracks = X_Audio_Sprite_TEMP.tracks, - bgms = X_Audio_Sprite_TEMP.BGMs, - presets = X_Audio_Sprite_TEMP.presets, + var bgm = X_AudioSprite_TEMP.bgmTrack, + tracks = X_AudioSprite_TEMP.tracks, + bgms = X_AudioSprite_TEMP.BGMs, + presets = X_AudioSprite_TEMP.presets, preset = presets[ name ], track, i, k; if( preset ){ if( bgms[ name ] ){ - if( name !== X_Audio_Sprite_TEMP.bgmName ){ + if( name !== X_AudioSprite_TEMP.bgmName ){ // bgm変更 - X_Audio_Sprite_TEMP.bgmName = name; - X_Audio_Sprite_TEMP.bgmPosition = preset[ 0 ]; - X_Audio_Sprite_TEMP.bgmLooped = false; + X_AudioSprite_TEMP.bgmName = name; + X_AudioSprite_TEMP.bgmPosition = preset[ 0 ]; + X_AudioSprite_TEMP.bgmLooped = false; }; - X_Audio_Sprite_TEMP.bgmPlaying = true; + X_AudioSprite_TEMP.bgmPlaying = true; if( bgm ){ track = bgm; } else if( 1 < tracks.length ){ - track = X_Audio_Sprite_TEMP.bgmTrack = X_Audio_Sprite_getTrackEnded(); + track = X_AudioSprite_TEMP.bgmTrack = X_AudioSprite_getTrackEnded(); } else { - track = X_Audio_Sprite_TEMP.bgmTrack = tracks[ 0 ]; + track = X_AudioSprite_TEMP.bgmTrack = tracks[ 0 ]; }; - if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_BEFORE_LOOP ], this, X_Audio_Sprite_handleEvent ).playing ){ + if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_BEFORE_LOOP ], this, X_AudioSprite_handleEvent ).playing ){ track.setState({ 'loop' : true, - 'looped' : X_Audio_Sprite_TEMP.bgmLooped, - 'currentTime' : X_Audio_Sprite_TEMP.bgmPosition, + 'looped' : X_AudioSprite_TEMP.bgmLooped, + 'currentTime' : X_AudioSprite_TEMP.bgmPosition, 'startTime' : preset[ 0 ], 'endTime' : preset[ 1 ], 'loopStartTime' : preset[ 3 ], 'loopEndTime' : preset[ 4 ] }); } else { - track.setState( { 'looped' : X_Audio_Sprite_TEMP.bgmLooped } ); + track.setState( { 'looped' : X_AudioSprite_TEMP.bgmLooped } ); track.play( preset[ 0 ], preset[ 1 ], true, preset[ 3 ], preset[ 4 ] ); - track.seek( X_Audio_Sprite_TEMP.bgmPosition ); + track.seek( X_AudioSprite_TEMP.bgmPosition ); }; } else { if( 1 < tracks.length ){ - track = X_Audio_Sprite_getTrackEnded( X_Audio_Sprite_TEMP.bgmPlaying ); + track = X_AudioSprite_getTrackEnded( X_AudioSprite_TEMP.bgmPlaying ); track - [ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_BEFORE_LOOP ], this, X_Audio_Sprite_handleEvent ) + [ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_BEFORE_LOOP ], this, X_AudioSprite_handleEvent ) .setState( { 'looped' : false } ); - track.play( preset[ 0 ], preset[ 1 ], true, 0, X_Audio_Sprite_lengthSilence ); + track.play( preset[ 0 ], preset[ 1 ], true, 0, X_AudioSprite_lengthSilence ); } else { // single track, iOS if( bgm ){ - X_Audio_Sprite_TEMP.bgmPosition = bgm.currentTime(); - //console.log( 'bgm position : ' + X_Audio_Sprite_TEMP.bgmPosition + ' isPlay:' + bgm.playing ); - X_Audio_Sprite_TEMP.bgmTrack = null; + X_AudioSprite_TEMP.bgmPosition = bgm.currentTime(); + //console.log( 'bgm position : ' + X_AudioSprite_TEMP.bgmPosition + ' isPlay:' + bgm.playing ); + X_AudioSprite_TEMP.bgmTrack = null; }; track = tracks[ 0 ]; - if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_BEFORE_LOOP ], this, X_Audio_Sprite_handleEvent ).playing ){ + if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_BEFORE_LOOP ], this, X_AudioSprite_handleEvent ).playing ){ track.setState({ 'loop' : true, 'looped' : false, @@ -229,11 +239,11 @@ X_Audio_Sprite_members = { 'startTime' : preset[ 0 ], 'endTime' : preset[ 1 ], 'loopStartTime' : 0, - 'loopEndTime' : X_Audio_Sprite_lengthSilence + 'loopEndTime' : X_AudioSprite_lengthSilence }); } else { - track.play( preset[ 0 ], preset[ 1 ], true, 0, X_Audio_Sprite_lengthSilence ); + track.play( preset[ 0 ], preset[ 1 ], true, 0, X_AudioSprite_lengthSilence ); }; }; }; @@ -242,44 +252,61 @@ X_Audio_Sprite_members = { return -1; }, + /** + * ポーズ + * @param {number} uid トラックID + * @return {number} uid + */ 'pause' : function( uid ){ - var track = X_Audio_Sprite_TEMP.tracks[ uid ]; - if( X_Audio_Sprite_TEMP.bgmTrack === track ){ - X_Audio_Sprite_TEMP.bgmPosition = track.currentTime(); - X_Audio_Sprite_TEMP.bgmPlaying = false; - X_Audio_Sprite_TEMP.bgmTrack = null; + var track = X_AudioSprite_TEMP.tracks[ uid ]; + if( X_AudioSprite_TEMP.bgmTrack === track ){ + X_AudioSprite_TEMP.bgmPosition = track.currentTime(); + X_AudioSprite_TEMP.bgmPlaying = false; + X_AudioSprite_TEMP.bgmTrack = null; }; - track && track.play( 0, X_Audio_Sprite_lengthSilence, true, 0, X_Audio_Sprite_lengthSilence ); + track && track.play( 0, X_AudioSprite_lengthSilence, true, 0, X_AudioSprite_lengthSilence ); track && track.seek( 0 ); this[ 'asyncDispatch' ]( X_EVENT_MEDIA_PAUSED ); return this; }, + /** + * シーク + * @param {number} uid トラックID + * @param {number} position ms + * @return {AudioSprite} + */ 'seek' : function( uid, position ){ - var track = X_Audio_Sprite_TEMP.tracks[ uid ], + var track = X_AudioSprite_TEMP.tracks[ uid ], end, strat; if( track ){ delete track.seekTime; - end = X_AudioWrapper_getEndTime( track ); - start = X_AudioWrapper_getStartTime( track, end ); + end = X_Audio_getEndTime( track ); + start = X_Audio_getStartTime( track, end ); 0 <= position && position <= ( end - start ) && track.seek( start + position ); }; return this; }, + /** + * ボリューム + * @param {number} uid トラックID + * @param {number} opt_volume= ボリューム + * @return {AudioSprite|number} + */ 'volume' : function( uid, opt_volume ){ var track, i; // TODO uid = 0 if( uid === 0 ){ if( opt_volume === undefined ){ - return X_Audio_Sprite_TEMP.volume; + return X_AudioSprite_TEMP.volume; }; - for( i = X_Audio_Sprite_TEMP.tracks.length; i; ){ - X_Audio_Sprite_TEMP.tracks[ --i ].volume( opt_volume ); + for( i = X_AudioSprite_TEMP.tracks.length; i; ){ + X_AudioSprite_TEMP.tracks[ --i ].volume( opt_volume ); }; return this; }; - track = X_Audio_Sprite_TEMP.tracks[ uid ]; + track = X_AudioSprite_TEMP.tracks[ uid ]; if( opt_volume === undefined ){ return track ? track.gain : -1; }; @@ -287,8 +314,14 @@ X_Audio_Sprite_members = { return this; }, + /** + * 状態の取得・更新 + * @param {number} uid トラックID + * @param {object} opt_obj= 上書きする状態を書き込んだオブジェクト + * @return {AudioSprite|object} + */ 'state' : function( uid, opt_obj ){ - var track = X_Audio_Sprite_TEMP.tracks[ uid ], + var track = X_AudioSprite_TEMP.tracks[ uid ], state, start, end; // TODO uid = 0 if( opt_obj === undefined ){ @@ -300,10 +333,10 @@ X_Audio_Sprite_members = { 'currentTime' : state.currentTime - start, 'playing' : start <= state.currentTime && state.currentTime <= state.endTime, 'duration' : state.endTime - start, - 'volume' : X_Audio_Sprite_TEMP.volume + 'volume' : X_AudioSprite_TEMP.volume }; }; - return { 'volume' : X_Audio_Sprite_TEMP.volume, 'playing' : false }; + return { 'volume' : X_AudioSprite_TEMP.volume, 'playing' : false }; }; track && track.setState( opt_obj ); return this; @@ -323,15 +356,15 @@ function X_AudioSprite_backendHandler( e ){ this[ 'source' ] = src = e[ 'source' ]; this[ 'backendName' ] = name = backend.backendName; - //console.log( i + ' / ' + X_Audio_Sprite_numTracks ); + //console.log( i + ' / ' + X_AudioSprite_numTracks ); - for( i = 0; i < X_Audio_Sprite_numTracks; ++i ){ - if( X_Audio_Sprite_useVideo || ( i === 1 && X_Audio_Sprite_useVideoForMulti ) ){ + for( i = 0; i < X_AudioSprite_numTracks; ++i ){ + if( X_AudioSprite_useVideo || ( i === 1 && X_AudioSprite_useVideoForMulti ) ){ option[ 'useVideo' ] = true; console.log( 'use video' ); }; // Audiobackend の owner として null を渡すとAudioBackend 自身へ dispatch する - X_Audio_Sprite_TEMP.tracks.push( last = backend.klass( null, e[ 'source' ], option ) ); + X_AudioSprite_TEMP.tracks.push( last = backend.klass( null, e[ 'source' ], option ) ); //console.dir( backend ); @@ -344,7 +377,7 @@ function X_AudioSprite_backendHandler( e ){ 'backendName' : name }; - if( X_Audio_Sprite_needTouchFirst ){ + if( X_AudioSprite_needTouchFirst ){ if( name === 'Web Audio' ){ _e[ 'needTouchForPlay' ] = true; } else { @@ -358,8 +391,8 @@ function X_AudioSprite_backendHandler( e ){ last[ 'listenOnce' ]( X_EVENT_READY, this, X_AudioSprite_backendHandler ); // READY, needTouchForPlay, needTouchForLoad - if( X_HTMLAudio_durationFix && !X_Audio_Sprite_needTouchFirst ){ - for( i = 0; i < X_Audio_Sprite_TEMP.tracks.length; ++i ){ + if( X_HTMLAudio_durationFix && !X_AudioSprite_needTouchFirst ){ + for( i = 0; i < X_AudioSprite_TEMP.tracks.length; ++i ){ this[ 'pause' ]( i ); }; }; @@ -372,8 +405,8 @@ function X_AudioSprite_backendHandler( e ){ return X_CALLBACK_STOP_NOW; case X_EVENT_READY : - if( X_Audio_Sprite_needTouchAndroid ){ - for( i = 0; i < X_Audio_Sprite_TEMP.tracks.length; ++i ){ + if( X_AudioSprite_needTouchAndroid ){ + for( i = 0; i < X_AudioSprite_TEMP.tracks.length; ++i ){ this[ 'pause' ]( i ); }; e.target[ 'listenOnce' ]( X_EVENT_MEDIA_PLAYING, this, this[ 'asyncDispatch' ], [ X_EVENT_READY ] ); @@ -387,17 +420,17 @@ function X_AudioSprite_backendHandler( e ){ }; -function X_Audio_Sprite_handleEvent( e ){ +function X_AudioSprite_handleEvent( e ){ var i, tracks, track, _e, k; switch( e.type ){ case X_EVENT_MEDIA_PLAYING : - ( e.target === X_Audio_Sprite_TEMP.bgmTrack || !e.target.looped ) && this[ 'asyncDispatch' ]( X_EVENT_MEDIA_PLAYING ); + ( e.target === X_AudioSprite_TEMP.bgmTrack || !e.target.looped ) && this[ 'asyncDispatch' ]( X_EVENT_MEDIA_PLAYING ); break; case X_EVENT_MEDIA_BEFORE_LOOP : - if( e.target === X_Audio_Sprite_TEMP.bgmTrack ){ - X_Audio_Sprite_TEMP.bgmLooped = true; + if( e.target === X_AudioSprite_TEMP.bgmTrack ){ + X_AudioSprite_TEMP.bgmLooped = true; this[ 'asyncDispatch' ]( X_EVENT_MEDIA_LOOPED ); // TODO uid } else { if( e.target.looped ){ @@ -406,12 +439,12 @@ function X_Audio_Sprite_handleEvent( e ){ this[ 'asyncDispatch' ]( X_EVENT_MEDIA_ENDED ); // TODO uid }; - //console.log( '[AudioSprite] bgmPlaying:' + X_Audio_Sprite_TEMP.bgmPlaying + ' ' + !X_Audio_Sprite_TEMP.bgmTrack ); + //console.log( '[AudioSprite] bgmPlaying:' + X_AudioSprite_TEMP.bgmPlaying + ' ' + !X_AudioSprite_TEMP.bgmTrack ); // single track | iOS - if( X_Audio_Sprite_TEMP.bgmPlaying && !X_Audio_Sprite_TEMP.bgmTrack ){ - X_Audio_Sprite_TEMP.bgmTrack = e.target; - this.play( X_Audio_Sprite_TEMP.bgmName ); + if( X_AudioSprite_TEMP.bgmPlaying && !X_AudioSprite_TEMP.bgmTrack ){ + X_AudioSprite_TEMP.bgmTrack = e.target; + this.play( X_AudioSprite_TEMP.bgmName ); return X_CALLBACK_PREVENT_DEFAULT; }; }; @@ -421,41 +454,41 @@ function X_Audio_Sprite_handleEvent( e ){ case X_EVENT_VIEW_ACTIVATE : console.log( '■ アクティブ' ); // track.play(); or iOS need touch?? - tracks = X_Audio_Sprite_TEMP.pauseTracks; + tracks = X_AudioSprite_TEMP.pauseTracks; while( tracks.length ) tracks.pop().actualPlay(); break; case X_EVENT_VIEW_DEACTIVATE : console.log( '■ デアクティブ' ); // track.pause(); - tracks = X_Audio_Sprite_TEMP.tracks; + tracks = X_AudioSprite_TEMP.tracks; i = tracks.length; for( ; i; ){ track = tracks[ --i ]; - track.playing && X_Audio_Sprite_TEMP.pauseTracks.push( track ) && track.pause(); + track.playing && X_AudioSprite_TEMP.pauseTracks.push( track ) && track.pause(); }; break; case X_EVENT_KILL_INSTANCE : - while( X_Audio_Sprite_TEMP.tracks.length ){ - X_Audio_Sprite_TEMP.tracks.pop()[ 'kill' ](); + while( X_AudioSprite_TEMP.tracks.length ){ + X_AudioSprite_TEMP.tracks.pop()[ 'kill' ](); }; - for( k in X_Audio_Sprite_TEMP.bgms ){ - delete X_Audio_Sprite_TEMP.bgms[ k ]; + for( k in X_AudioSprite_TEMP.bgms ){ + delete X_AudioSprite_TEMP.bgms[ k ]; }; - for( k in X_Audio_Sprite_TEMP.presets ){ - delete X_Audio_Sprite_TEMP.presets[ k ]; + for( k in X_AudioSprite_TEMP.presets ){ + delete X_AudioSprite_TEMP.presets[ k ]; }; - X_Audio_Sprite_TEMP.bgmTrack = null; - X_Audio_Sprite_TEMP.bgmPosition = 0; - X_Audio_Sprite_TEMP.bgmName = ''; - X_Audio_Sprite_TEMP.bgmLooped = false; - X_Audio_Sprite_TEMP.bgmPlaying = false; + X_AudioSprite_TEMP.bgmTrack = null; + X_AudioSprite_TEMP.bgmPosition = 0; + X_AudioSprite_TEMP.bgmName = ''; + X_AudioSprite_TEMP.bgmLooped = false; + X_AudioSprite_TEMP.bgmPlaying = false; - X_ViewPort[ 'unlisten' ]( [ X_EVENT_VIEW_ACTIVATE, X_EVENT_VIEW_DEACTIVATE ], this, X_Audio_Sprite_handleEvent ); + X_ViewPort[ 'unlisten' ]( [ X_EVENT_VIEW_ACTIVATE, X_EVENT_VIEW_DEACTIVATE ], this, X_AudioSprite_handleEvent ); break; }; }; -- 2.11.0