* この意識は常にありましたが、このたび pettanR フレームワークの API ドキュメントを作成するにあたり、それに付記していく形で取り組んでみようと思います。\r
* \r
* <h4>フレームワークのレイヤー構造について</h4>\r
+ * <h5>\core 以下:javascript の整地を行い大規模開発の基礎を整える</h5>\r
+ * <p>ブラウザの種類とバージョンを調べ、続いて javascript 自体の差異を埋め、足りない関数を補います。\r
+ * <p>続いて、ファーストオブジェクトとも呼ばれる function について、その能力を引き出しつつ安心して使えるように、再利用可能クロージャの生成・破棄ができるようにします。\r
+ * ガベージコレクション周りが怪しいブラウザがあるため、クロージャを再利用可能にしておくことは重要です。\r
+ * <p>javascript が大規模開発に使えるように、クラス定義関数を用意します。prototype 周りの差異やバグを吸収するためにも、クラス定義の共通化は有効です。\r
+ * <p>このクラス定義関数を用いて EventDispatcher クラスを定義します。ブラウザの提供するイベントターゲットオブジェクトをラップしたり、単にアプリケーション独自のイベントを配信するためにも使えます。\r
+ * フレームワークの各所でサブクラスや単にインスタンスを拡張して使われています。フレームワークの API 設計の性格を決めている、とても重要なクラスです。\r
+ * 再利用可能クロージャや、タイマー(setTimeout のラッパー) とも密に結合しています。\r
* \r
+ * <h5>\dom 以下:DHTML の差異を吸収し、非同期化された仮想 Node を提供する</h5>\r
+ * <p>jQuery ライクな構文で DOM ツリーの操作を行います。チェーンメソッドは速い、と聞きかじったのでこのデザインにしました。\r
+ * <p>Real DOM の操作は非同期に行われるため高速です。Virtual DOM 時代のライバル達にひけをとることはありません。\r
+ * <p>10 年後の変化に対応するため、確かな抽象化実装を行う。それを証明するために 10 年前の環境でも動作させます。\r
* \r
- * ライブラリは X という名前空間を使用します。\r
- * @example //ショートハンド\r
+ * <h5>\ui 以下:UI フレームワーク</h5>\r
+ * <p>\dom までで吸収できなかった Web ブラウザの差異を最終的に吸収し、HTML 要素を UI 部品として利用するためのレイヤーです。\r
+ * <p>この層で吸収できなかった差異に関する情報を提供して、アプリケーションに UI をグレースフルグラデーションするための情報を提供します。\r
+ * <p>任意の UI を実現するための最適な HTML タグ構造がブラウザ毎に異なる場合に、その差異をカプセル化します。\r
+ * <p>Web ブラウザ自体のレンダリングコストを最小にし、高速な UI 部品を提供するために、独自のレイアウトルールを持ちます。\r
+ * <p>フォントサイズをベースとしたレイアウト指定のため、レスポンシブな画面作りを後押しします。\r
+ * \r
+ * @example // ライブラリは X という名前空間を使用します。\r
+ * //ショートハンド\r
* X( func ) == X.ViewPort.listenOnce(X.Event.XDOM_READY, func);\r
* X('#mydiv') == X.Doc.find('#mydiv');\r
* @namespace X\r
*/ \r
function X( v ){\r
- if( X.Type.isFunction( v ) ){\r
- X.ViewPort.listenOnce( X.Event.XDOM_READY, v );\r
+ if( X_Type_isFunction( v ) ){\r
+ X.ViewPort.listenOnce( X_Event[ 'XDOM_READY' ], v );\r
} else\r
if( X_shortcutFunction ){\r
return X_shortcutFunction.apply( X_shortcutContext || X, arguments );\r
} };\r
//+DEV}\r
\r
+//{-AUDIO\r
+//-AUDIO}\r
+\r
var undefined,\r
X_EMPTY_OBJECT = {},\r
X_TEMP = { onSystemReady : [] },\r
// ------------------------------------------------------------------------- //\r
// ------------ local variables -------------------------------------------- //\r
// ------------------------------------------------------------------------- //\r
-var X_UA = (function( n, undefined ){\r
- var\r
- /** @alias X.UA */\r
- acme = {},\r
- dua = n.userAgent,\r
+\r
+/**\r
+ * UserAgent の関する定数を保持する。\r
+ * @namespace X.UA\r
+ * @alias X.UA\r
+ * @type {object}\r
+ */\r
+var X_UA = X[ 'UA' ] = {};\r
+\r
+(function( n ){\r
+ var dua = n.userAgent,\r
dav = n.appVersion,\r
tv = parseFloat(dav),\r
sys = n.platform,\r
\r
v = dua.split( 'OS ' )[ 1 ].split( '_' );\r
i = window.devicePixelRatio === 1;\r
- /** @memberof X.UA */\r
- acme.iOSMajor = parseFloat( v[ 0 ] ) || 0;\r
- /** @memberof X.UA */\r
- acme.iOSMinor = parseFloat( v[ 1 ] ) || 0;\r
- /** @memberof X.UA */\r
- acme.iOSPatch = parseFloat( v[ 2 ] ) || 0;\r
- /** @memberof X.UA */\r
- acme.iOS = acme.iOSMajor + acme.iOSMinor / 10;\r
+ /**\r
+ * @alias X.UA.iOSMajor\r
+ * @type {number}\r
+ */\r
+ X_UA[ 'iOSMajor' ] = parseFloat( v[ 0 ] ) || 0;\r
+ /**\r
+ * @alias X.UA.iOSMinor\r
+ * @type {number}\r
+ */\r
+ X_UA[ 'iOSMinor' ] = parseFloat( v[ 1 ] ) || 0;\r
+ /**\r
+ * @alias X.UA.iOSPatch\r
+ * @type {number}\r
+ */\r
+ X_UA[ 'iOSPatch' ] = parseFloat( v[ 2 ] ) || 0;\r
+ /**\r
+ * @alias X.UA.iOS\r
+ * @type {number}\r
+ */\r
+ X_UA[ 'iOS' ] = X_UA[ 'iOSMajor' ] + X_UA[ 'iOSMinor' ] / 10;\r
\r
if( screen.width === screen.height * 1.5 || screen.width * 1.5 === screen.height ){\r
v = true; // 4:3 model\r
};\r
\r
if( sys === 'iPhone' ){\r
- /** @memberof X.UA */\r
- acme.iPhone = true;\r
+ /**\r
+ * @alias X.UA.iPhone\r
+ * @type {boolean}\r
+ */\r
+ X_UA[ 'iPhone' ] = true;\r
if( v ){\r
/** iPhone4s以下\r
* @memberof X.UA */\r
- acme.iPhone_4s = true;\r
+ X_UA[ 'iPhone_4s' ] = true;\r
};\r
if( v && i ){\r
- /** iPhone3GS以下\r
- * @memberof X.UA */\r
- acme.iPhone_3GS = true;\r
+ /**\r
+ * iPhone3GS以下\r
+ * @alias X.UA.iPhone_3GS\r
+ * @type {boolean}\r
+ */\r
+ X_UA[ 'iPhone_3GS' ] = true;\r
};\r
- //alert( 'iPhone ' + ( acme.iPhone_3GS ? '3GS以下' : acme.iPhone_4s ? '4s以下' : '5以上' ) );\r
+ //alert( 'iPhone ' + ( X_UA[ 'iPhone_3GS' ] ? '3GS以下' : X_UA[ 'iPhone_4s' ] ? '4s以下' : '5以上' ) );\r
};\r
if( sys === 'iPad' ){\r
/** @memberof X.UA */\r
- acme.iPad = true;\r
+ X_UA[ 'iPad' ] = true;\r
if( i ){\r
/**\r
* iPad2以下または初代iPad mini 以下\r
* @memberof X.UA */\r
- acme.iPad_2Mini1 = true;\r
+ X_UA[ 'iPad_2Mini1' ] = true;\r
};\r
};\r
if( sys === 'iPod' ){\r
/** @memberof X.UA */\r
- acme.iPod = true;\r
+ X_UA[ 'iPod' ] = true;\r
if( v && i ){\r
/**\r
* iPod3以下\r
* @memberof X.UA */\r
- acme.iPod_3 = true;\r
+ X_UA[ 'iPod_3' ] = true;\r
};\r
if( v ){\r
/**\r
* iPod4以下\r
* @memberof X.UA */\r
- acme.iPod_4 = true;\r
+ X_UA[ 'iPod_4' ] = true;\r
};\r
- //alert( 'iPod touch ' + ( acme.iPod_3 ? '3以下' : acme.iPod_4 ? '4以下' : '5以上' ) );\r
+ //alert( 'iPod touch ' + ( X_UA[ 'iPod_3' ] ? '3以下' : X_UA[ 'iPod_4' ] ? '4以下' : '5以上' ) );\r
};\r
\r
- console.log( '>> iOS : ' + acme.iOS );\r
+ console.log( '>> iOS : ' + X_UA[ 'iOS' ] );\r
} else\r
if( dua.indexOf( 'hp-tablet' ) !== -1 || dua.indexOf( 'webOS' ) !== -1 ){\r
// http://user-agent-string.info/list-of-ua/os-detail?os=webOS\r
/** @memberof X.UA */\r
- acme.webOS = true; // webOS\r
+ X_UA[ 'webOS' ] = true; // webOS\r
} else\r
if( sys.indexOf( 'Win' ) + 1 ){\r
console.log( 'Win' );\r
/** @memberof X.UA */\r
- acme.Windows = true;\r
+ X_UA[ 'Windows' ] = true;\r
switch( sys ){\r
case 'Win16' :\r
case 'Win32' :\r
case 'Win64' :\r
case 'WinCE' :\r
- acme[ sys ] = true;\r
+ X_UA[ sys ] = true;\r
};\r
// winRT\r
} else\r
if( sys.indexOf( 'Mac' ) + 1 ){\r
console.log( 'Mac' );\r
/** @memberof X.UA */\r
- acme.Mac = true;\r
+ X_UA[ 'Mac' ] = true;\r
switch( sys ){\r
case 'MacPowerPC' :\r
/** @memberof X.UA */\r
- acme.MacPPC = true;\r
+ X_UA[ 'MacPPC' ] = true;\r
break;\r
case 'MacPPC' :\r
case 'Mac68K' :\r
case 'MacIntel' :\r
- acme[ sys] = true;\r
+ X_UA[ sys ] = true;\r
};\r
} else\r
if( ( sys.indexOf( 'Linux' ) + 1 ) || ( sys.indexOf( 'Android' ) + 1 ) ){\r
console.log( 'Linux' );\r
/** @memberof X.UA */\r
- acme.Linux = true;\r
+ X_UA[ 'Linux' ] = true;\r
\r
if( ( i = dua.indexOf( 'Android' ) ) !== -1 ){\r
/** @memberof X.UA */\r
- acme.Android = parseFloat( dua.substr( i + 8 ) ) || 0.1; // Firefox で Version が取れない!\r
- console.log( '>> Android : ' + acme.Android );\r
+ X_UA[ 'Android' ] = parseFloat( dua.substr( i + 8 ) ) || 0.1; // Firefox で Version が取れない!\r
+ console.log( '>> Android : ' + X_UA[ 'Android' ] );\r
};\r
};\r
\r
i = dua.indexOf( 'Opera' ); // Opera/\r
j = dua.indexOf( 'Version/' );\r
/** @memberof X.UA */\r
- acme.Opera = Math.max(\r
+ X_UA[ 'Opera' ] = v = Math.max(\r
i !== -1 ? parseFloat( dua.substr( i + 6 ) ) : 0,\r
j !== -1 ? parseFloat( dua.substr( j + 8 ) ) : 0,\r
tv );\r
// closure compiler で minify するとOpera7で動かない \r
// --compilation_level WHITESPACE_ONLY --formatting pretty_print <- 動く\r
/** @memberof X.UA */\r
- acme.Opera7 = acme.Opera < 8;\r
+ X_UA[ 'Opera7' ] = v < 8;\r
/** @memberof X.UA */\r
- acme.Opera78 = acme.Opera < 9;\r
+ X_UA[ 'Opera78' ] = v < 9;\r
/** @memberof X.UA */\r
- acme.OperaMini = 0 < dua.indexOf('Opera Mini');\r
+ X_UA[ 'OperaMini' ] = 0 < dua.indexOf('Opera Mini');\r
/** @memberof X.UA */\r
- acme.OperaMobile = 0 < dua.indexOf('Opera Mobi');\r
+ X_UA[ 'OperaMobile' ] = 0 < dua.indexOf('Opera Mobi');\r
/** @memberof X.UA */\r
- acme.OperaTablet = 0 < dua.indexOf('Opera Tablet');\r
+ X_UA[ 'OperaTablet' ] = 0 < dua.indexOf('Opera Tablet');\r
/** @memberof X.UA */\r
- acme.Wii = dua.indexOf( 'Nintendo Wii' ) !== -1;\r
+ X_UA[ 'Wii' ] = dua.indexOf( 'Nintendo Wii' ) !== -1;\r
/** @memberof X.UA */\r
- acme.NDS = dua.indexOf( 'Nitro' ) !== -1;\r
- console.log( '>> Opera : ' + acme.Opera );\r
- return acme;\r
+ X_UA[ 'NDS' ] = dua.indexOf( 'Nitro' ) !== -1;\r
+ console.log( '>> Opera : ' + v );\r
+ return;\r
};\r
\r
// Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\r
if( document.all || dav.indexOf( 'Trident/' ) !== -1 ){\r
/** @memberof X.UA */\r
- acme.ActiveX = !!window[ 'ActiveXObject' ];\r
+ X_UA[ 'ActiveX' ] = !!window[ 'ActiveXObject' ];\r
/**\r
* documentモードを考慮しないIEのバージョン\r
* @memberof X.UA\r
* @type {number}*/\r
- acme._IE = parseFloat(dua.split('MSIE ')[1]) || parseFloat(dua.split('rv:')[1]) || parseFloat(dav.split('MSIE ')[1]) || 0;\r
- // IE11 の互換モードの dav にも Trident/7.0 が書かれているため互換モードか?判定ができる\r
+ X_UA[ '_IE' ] = parseFloat(dua.split('MSIE ')[1]) || parseFloat(dua.split('rv:')[1]) || parseFloat(dav.split('MSIE ')[1]) || 0;\r
+ // IE11 の互換モードの dav にも Trident/7.0 が書かれているため互換モードか?判定ができる\r
// 互換モードでは Silverlight でエラーが出る?\r
/** @memberof X.UA */\r
- acme.Trident = parseFloat(dav.split('Trident/')[1]) || 0;\r
+ X_UA[ 'Trident' ] = parseFloat(dav.split('Trident/')[1]) || 0;\r
/**\r
* documentモードを考慮したIEのバージョン\r
* @memberof X.UA */\r
- acme.IE = document.documentMode || acme._IE;\r
- tridentToVer = acme.Trident ? ( acme.Trident + 4 | 0 ) : acme._IE;\r
+ X_UA[ 'IE' ] = v = document.documentMode || X_UA[ '_IE' ];\r
+ tridentToVer = X_UA[ 'Trident' ] ? ( X_UA[ 'Trident' ] + 4 | 0 ) : X_UA[ '_IE' ];\r
/**\r
* IE11 の互換モードを使用しているか?\r
* @memberof X.UA */\r
- acme.IECompat = /* acme.IE !== acme._IE || */ tridentToVer !== acme._IE && tridentToVer;\r
+ X_UA[ 'IECompat' ] = /* v !== X_UA[ '_IE' ] || */ tridentToVer !== X_UA[ '_IE' ] && tridentToVer;\r
/** @memberof X.UA */\r
- acme.IE4 = acme.IE && acme.IE < 5;\r
+ X_UA[ 'IE4' ] = v && v < 5;\r
/** @memberof X.UA */\r
- acme.IE5678 = 5 <= acme.IE && acme.IE < 9;\r
+ X_UA[ 'IE5678' ] = 5 <= v && v < 9;\r
/** @memberof X.UA */\r
- acme.IE5 = 5 <= acme.IE && acme.IE < 5.5;\r
+ X_UA[ 'IE5' ] = 5 <= v && v < 5.5;\r
/** @memberof X.UA */\r
- acme.IE55 = 5.5 <= acme.IE && acme.IE < 6;\r
+ X_UA[ 'IE55' ] = 5.5 <= v && v < 6;\r
/** @memberof X.UA */\r
- acme.IE5x = acme.IE5 || acme.IE55;\r
+ X_UA[ 'IE5x' ] = X_UA[ 'IE5' ] || X_UA[ 'IE55' ];\r
/** @memberof X.UA */\r
- acme.IE6 = 6 <= acme.IE && acme.IE < 7;\r
+ X_UA[ 'IE6' ] = 6 <= v && v < 7;\r
/** @memberof X.UA */\r
- acme.IE7 = 7 <= acme.IE && acme.IE < 8;\r
+ X_UA[ 'IE7' ] = 7 <= v && v < 8;\r
/** @memberof X.UA */\r
- acme.IE8 = 8 <= acme.IE && acme.IE < 9;\r
+ X_UA[ 'IE8' ] = 8 <= v && v < 9;\r
/** @memberof X.UA */\r
- acme.IE9 = 9 <= acme.IE && acme.IE < 10;\r
+ X_UA[ 'IE9' ] = 9 <= v && v < 10;\r
/** @memberof X.UA */\r
- acme.MacIE = acme.Mac;\r
+ X_UA[ 'MacIE' ] = X_UA[ 'Mac' ];\r
/** @memberof X.UA */\r
- acme.IEMobile = dua.toLowerCase().indexOf( 'iemobile' ) !== -1 || acme.WinCE;\r
+ X_UA[ 'IEMobile' ] = dua.toLowerCase().indexOf( 'iemobile' ) !== -1 || X_UA[ 'WinCE' ];\r
/** @memberof X.UA */\r
- acme.WinPhone = dua.toLowerCase().indexOf( 'windows phone' ) !== -1 || 0 < dav.indexOf( 'ZuneWP' ); // ZuneWP は IEM のデスクトップモードで使用\r
- console.log( '>> IE : ' + acme.IE + ' ActiveX : ' + acme.ActiveX );\r
+ X_UA[ 'WinPhone' ] = dua.toLowerCase().indexOf( 'windows phone' ) !== -1 || 0 < dav.indexOf( 'ZuneWP' ); // ZuneWP は IEM のデスクトップモードで使用\r
+ console.log( '>> IE : ' + v + ' ActiveX : ' + X_UA[ 'ActiveX' ] );\r
// TODO XBox360, XBox1, Modern or Desktop, Standalone\r
- return acme;\r
+ return;\r
};\r
\r
// http://qa.support.sony.jp/solution/S0812181056444/common/nfb34_dom_200jp/dom_dom0_JP.html\r
if( ( i = dua.indexOf( 'NetFront\/' ) !== -1 ) ){\r
/** @memberof X.UA */\r
- acme.NetFront = parseFloat( dua.substr( i + 9 ) ) || 0.1;\r
- console.log( '>> NetFront : ' + acme.NetFront );\r
- return acme;\r
+ X_UA[ 'NetFront' ] = parseFloat( dua.substr( i + 9 ) ) || 0.1;\r
+ console.log( '>> NetFront : ' + X_UA[ 'NetFront' ] );\r
+ return;\r
};\r
\r
- if( acme.Linux && tv === 2 && dua.indexOf( 'Sony\/COM2\/' ) !== -1 ){\r
- acme.NetFront = 3.4;\r
- console.log( '>> NetFront : ' + acme.NetFront );\r
- return acme;\r
+ if( X_UA[ 'Linux' ] && tv === 2 && dua.indexOf( 'Sony\/COM2\/' ) !== -1 ){\r
+ X_UA[ 'NetFront' ] = 3.4;\r
+ console.log( '>> NetFront : ' + X_UA[ 'NetFront' ] );\r
+ return;\r
};\r
\r
// http://www.useragentstring.com/pages/Playstation%203/\r
/**\r
* PlayStation 3 システムバージョン 4.10 未満の SONY 独自ブラウザ\r
* @memberof X.UA */\r
- acme.PS3 = parseFloat( dua.substr( i + 15 ) ) || 0.1;\r
- console.log( '>> PS3 : ' + acme.PS3 );\r
- return acme;\r
+ X_UA[ 'PS3' ] = parseFloat( dua.substr( i + 15 ) ) || 0.1;\r
+ console.log( '>> PS3 : ' + X_UA[ 'PS3' ] );\r
+ return;\r
};\r
\r
// http://www.useragentstring.com/pages/iCab/\r
// Mozilla/5.0 (Macintosh; U; PPC Mac OS; en) iCab 3\r
if( ( i = dua.indexOf( 'iCab' ) !== -1 ) ){\r
/** @memberof X.UA */\r
- acme.iCab = parseFloat( dua.substr( i + 5 ) ) || 0.1;\r
- console.log( '>> iCab : ' + acme.iCab );\r
- return acme;\r
+ X_UA[ 'iCab' ] = parseFloat( dua.substr( i + 5 ) ) || 0.1;\r
+ console.log( '>> iCab : ' + X_UA[ 'iCab' ] );\r
+ return;\r
};\r
\r
if( 0 < dua.indexOf( 'Gecko\/' ) && ( i = dua.indexOf( 'rv:' ) ) ){\r
v = dua.substr( i + 3 ).split( '.' );\r
/** @memberof X.UA */\r
- acme.Gecko = parseFloat( v[ 0 ] ) || 0 +\r
+ X_UA[ 'Gecko' ] = parseFloat( v[ 0 ] ) || 0 +\r
( parseFloat( v[ 1 ] ) || 0 ) / 10 +\r
( parseFloat( v[ 2 ] ) || 0 ) / 100;\r
/** @memberof X.UA */\r
- acme.GeckoMajor = parseFloat( v[ 0 ] ) || 0;\r
+ X_UA[ 'GeckoMajor' ] = parseFloat( v[ 0 ] ) || 0;\r
/** @memberof X.UA */\r
- acme.GeckoMinor = parseFloat( v[ 1 ] ) || 0;\r
+ X_UA[ 'GeckoMinor' ] = parseFloat( v[ 1 ] ) || 0;\r
/** @memberof X.UA */\r
- acme.GeckoPatch = parseFloat( v[ 2 ] ) || 0;\r
+ X_UA[ 'GeckoPatch' ] = parseFloat( v[ 2 ] ) || 0;\r
\r
//Fennec\r
// Mozilla/5.0 (Android; Linux armv7l; rv:9.0) Gecko/20111216 Firefox/9.0 Fennec/9.0\r
if( ( i = dua.indexOf( 'Fennec/' ) ) !== -1 ){\r
/** @memberof X.UA */\r
- acme.Fennec = parseFloat( dua.substr( i + 7 ) );\r
- console.log( '>> Fennec : ' + acme.Fennec + ', Gecko : ' + acme.Gecko );\r
- return acme;\r
+ X_UA[ 'Fennec' ] = parseFloat( dua.substr( i + 7 ) );\r
+ console.log( '>> Fennec : ' + X_UA[ 'Fennec' ] + ', Gecko : ' + X_UA[ 'Gecko' ] );\r
+ return;\r
};\r
//Firefox\r
\r
//Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:0.9.4.1) Gecko/20020508 Netscape6/6.2.3\r
if( ( i = dua.indexOf( 'Netscape6/' ) ) !== -1 ){\r
/** @memberof X.UA */\r
- acme.NN = parseFloat( dua.substr( i + 10 ) ) || 6;\r
+ X_UA[ 'NN' ] = parseFloat( dua.substr( i + 10 ) ) || 6;\r
/** @memberof X.UA */\r
- acme.NN6 = true;\r
- console.log( '>> NN : ' + acme.NN + ', Gecko : ' + acme.Gecko );\r
- return acme;\r
+ X_UA[ 'NN6' ] = true;\r
+ console.log( '>> NN : ' + X_UA[ 'NN' ] + ', Gecko : ' + X_UA[ 'Gecko' ] );\r
+ return;\r
} else\r
//Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax)\r
//Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20070321 Netscape/8.1.3\r
if( ( i = dua.indexOf( 'Netscape/' ) ) !== -1 ){\r
- acme.NN = parseFloat( dua.substr( i + 9 ) ) || 7;\r
- console.log( '>> NN : ' + acme.NN + ', Gecko : ' + acme.Gecko );\r
- return acme;\r
+ X_UA[ 'NN' ] = parseFloat( dua.substr( i + 9 ) ) || 7;\r
+ console.log( '>> NN : ' + X_UA[ 'NN' ] + ', Gecko : ' + X_UA[ 'Gecko' ] );\r
+ return;\r
} else\r
//Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080219 Firefox/2.0.0.12 Navigator/9.0.0.6\r
if( ( i = dua.indexOf( 'Navigator/' ) ) !== -1 ){\r
- acme.NN = parseFloat( dua.substr( i + 10 ) ) || 9;\r
- console.log( '>> NN : ' + acme.NN + ', Gecko : ' + acme.Gecko );\r
- return acme;\r
+ X_UA[ 'NN' ] = parseFloat( dua.substr( i + 10 ) ) || 9;\r
+ console.log( '>> NN : ' + X_UA[ 'NN' ] + ', Gecko : ' + X_UA[ 'Gecko' ] );\r
+ return;\r
};\r
\r
- console.log( '>> Gecko : ' + acme.Gecko );\r
+ console.log( '>> Gecko : ' + X_UA[ 'Gecko' ] );\r
};\r
\r
// TODO Blink\r
if( window.chrome ){\r
/** @memberof X.UA */\r
- acme.Blink = tv;\r
- console.log( '>>Blink : ' + acme.Blink );\r
+ X_UA[ 'Blink' ] = tv;\r
+ console.log( '>>Blink : ' + X_UA[ 'Blink' ] );\r
\r
} else\r
if( dav.indexOf( 'Konqueror' ) !== -1 ){\r
/** @memberof X.UA */\r
- acme.Khtml = tv;\r
- console.log( '>>Khtml : ' + acme.Khtml );\r
+ X_UA[ 'Khtml' ] = tv;\r
+ console.log( '>>Khtml : ' + X_UA[ 'Khtml' ] );\r
\r
} else\r
if( ( i = dua.indexOf( 'Android ' ) ) !== -1 ){\r
/** @memberof X.UA */\r
- acme.AndroidBrowser = i = parseFloat( dua.substr( i + 8 ) ) || 0.1;\r
+ X_UA[ 'AndroidBrowser' ] = i = parseFloat( dua.substr( i + 8 ) ) || 0.1;\r
/** @memberof X.UA */\r
- acme.AndroidBrowser1 = 1 <= i && i < 2;\r
+ X_UA[ 'AndroidBrowser1' ] = 1 <= i && i < 2;\r
/** @memberof X.UA */\r
- acme.AndroidBrowser2 = 2 <= i && i < 3;\r
+ X_UA[ 'AndroidBrowser2' ] = 2 <= i && i < 3;\r
/** @memberof X.UA */\r
- acme.AndroidBrowser3 = 3 <= i && i < 4;\r
+ X_UA[ 'AndroidBrowser3' ] = 3 <= i && i < 4;\r
/** @memberof X.UA */\r
- acme.AndroidBrowser4 = 4 <= i && i < 5;\r
+ X_UA[ 'AndroidBrowser4' ] = 4 <= i && i < 5;\r
/** @memberof X.UA */\r
- acme.AndroidBrowser5 = 5 <= i && i < 6;\r
- console.log( '>> AndroidBrowser : ' + acme.Android );\r
+ X_UA[ 'AndroidBrowser5' ] = 5 <= i && i < 6;\r
+ console.log( '>> AndroidBrowser : ' + X_UA[ 'Android' ] );\r
\r
i = parseFloat(dua.split('WebKit\/')[1]);\r
/** @memberof X.UA */\r
- acme.AndroidBrowserWebkit = i;\r
+ X_UA[ 'AndroidBrowserWebkit' ] = i;\r
alert( 'AudioSprite調査:Android標準ブラウザ Webkit Version ' + i );\r
\r
} else\r
if( i = parseFloat(dua.split('WebKit\/')[1]) ){\r
/** @memberof X.UA */\r
- acme.WebKit = i;\r
- /** @memberof X.UA */\r
- acme.Chrome = parseFloat(dua.split('Chrome\/')[1]) || undefined;\r
+ X_UA[ 'WebKit' ] = i;\r
+ \r
+ if( v = parseFloat(dua.split('Chrome\/')[1]) ){\r
+ /** @memberof X.UA */\r
+ X_UA[ 'Chrome' ] = v;\r
+ };\r
\r
// TODO webkit Opera\r
\r
- console.log( '>>Webkit : ' + acme.WebKit );\r
+ console.log( '>>Webkit : ' + X_UA[ 'WebKit' ] );\r
\r
- if( i && !acme.Chrome && dua.indexOf( 'Safari' ) !== -1 ){\r
+ if( i && !X_UA[ 'Chrome' ] && dua.indexOf( 'Safari' ) !== -1 ){\r
if( dav.indexOf( 'Version/' ) !== -1 ){\r
/** @memberof X.UA */\r
- acme.Safari = parseFloat( dav.split('Version/')[1] );\r
+ X_UA[ 'Safari' ] = parseFloat( dav.split('Version/')[1] );\r
} else {\r
- if( i < 73 ){\r
- acme.Safari = 0.8;\r
- } else\r
- if( i < 85 ){\r
- acme.Safari = 0.9;\r
- } else\r
- if( i < 100 ){\r
- acme.Safari = 1;\r
- } else\r
- if( i < 125 ){\r
- acme.Safari = 1.1;\r
- } else\r
- if( i < 312 ){\r
- acme.Safari = 1.2;\r
- } else\r
- if( i < 412 ){\r
- acme.Safari = 1.3;\r
- } else\r
- if( i <= 419.3 ){\r
- acme.Safari = 2;\r
- } else\r
- if( i <= 525.13 ){\r
- acme.Safari = 3;\r
- } else\r
- if( i <= 525.25 ){\r
- acme.Safari = 3.1;\r
- } else\r
if( i <= 528.16 ){\r
- acme.Safari = 3.2;\r
+ X_UA[ 'Safari' ] = i < 73 ? 0.8 :\r
+ i < 85 ? 0.9 :\r
+ i < 100 ? 1 :\r
+ i < 125 ? 1.1 :\r
+ i < 312 ? 1.2 :\r
+ i < 412 ? 1.3 :\r
+ i <= 419.3 ? 2 :\r
+ i <= 525.13 ? 3 :\r
+ i <= 525.25 ? 3.1 : 3.2;\r
};\r
};\r
}; \r
\r
- console.log( '>> Webkit : ' + acme.WebKit + ' Safari : ' + acme.Safari );\r
+ console.log( '>> Webkit : ' + X_UA[ 'WebKit' ] + ' Safari : ' + X_UA[ 'Safari' ] );\r
};\r
\r
//http://www.useragentstring.com/pages/Iris/\r
- if( dua.toLowerCase().indexOf( 'iris' ) !== -1 ) acme.Iris = true;\r
+ if( dua.toLowerCase().indexOf( 'iris' ) !== -1 ) X_UA[ 'Iris' ] = true;\r
\r
if( // Kobo Mozilla/5.0 (Linux; U; Android 2.0; en-us;) AppleWebKit/533.1 (KHTML, like Gecko) Verson/4.0 Mobile Safari/533.1 (Kobo Touch)\r
dua.indexOf( 'Kobo' ) !== -1 ||\r
dua.indexOf( 'EBRD' ) !== -1\r
){\r
/** @memberof X.UA */\r
- acme.EInk = true;\r
+ X_UA[ 'EInk' ] = true;\r
};\r
- return acme;\r
-})( navigator ),\r
+})( navigator );\r
\r
-X_UA_DOM = {},\r
-X_UA_EVENT = {},\r
-X_UA_HID = {};\r
-//X_UA.IECompat && alert( X_UA.IE + ' ' + X_UA._IE + ' Tri:' + X_UA.Trident );\r
+var X_UA_DOM = {},\r
+ X_UA_EVENT = {},\r
+ X_UA_HID = {};\r
+//X_UA[ 'IECompat' ] && alert( X_UA[ 'IE' ] + ' ' + X_UA[ '_IE' ] + ' Tri:' + X_UA[ 'Trident' ] );\r
\r
/*\r
* http://d.hatena.ne.jp/t-uchima/20051003/p1\r
* MacIEにはattachEventが一応あるけどwindow.attachEventとdocument.attachEventしかなく他の要素にはattachEventはない。\r
*/\r
-if( X_UA.IE4 && X_UA.IE < 5 ){ // ie4 & iemobi4 & macie4.x\r
+if( X_UA[ 'IE4' ] && X_UA[ 'IE' ] < 5 ){ // ie4 & iemobi4 & macie4.x\r
X_UA_DOM.IE4 = true;\r
X_UA_EVENT.IE4 = true;\r
} else\r
-if( X_UA.MacIE ){\r
+if( X_UA[ 'MacIE' ] ){\r
X_UA_DOM.W3C = true;\r
X_UA_EVENT.IE = true;\r
} else\r
if( navigator.msPointerEnabled || navigator.pointerEnabled ) X_UA_HID.POINTER = true;\r
if( !X_UA_HID.POINTER && window.ontouchstart !== undefined ) X_UA_HID.TOUCH = true;\r
\r
-//alert(X_UA.Safari + ' ' + X_UA.WebKit + '\n\n' + navigator.userAgent + '\n\n' + navigator.appVersion + '\n\n' + navigator.platform );\r
+//alert(X_UA[ 'Safari' ] + ' ' + X_UA[ 'WebKit' ] + '\n\n' + navigator.userAgent + '\n\n' + navigator.appVersion + '\n\n' + navigator.platform );\r
\r
// Safari 3.1 未満は開発コンソールがない!\r
// http://shimax.cocolog-nifty.com/search/2006/09/safarijavascrip_c54d.html\r
/*\r
-if( X_UA.Safari && X_UA.WebKit < 525.13 ){ \r
+if( X_UA[ 'Safari' ] && X_UA[ 'WebKit' ] < 525.13 ){ \r
window.onerror = function( x, y, z ){\r
var n = String.fromCharCode( 10 );\r
alert('window.onerrorによるエラーの捕捉:' + n + x + n + y + 'の' + z + '行目付近です。');\r
};\r
};*/\r
\r
-// ------------------------------------------------------------------------- //\r
-// --- interface ----------------------------------------------------------- //\r
-// ------------------------------------------------------------------------- //\r
-\r
-/**\r
- * UserAgent の関する定数を保持する。\r
- * @namespace X.UA\r
- * @alias X.UA\r
- * @type {object}\r
- */\r
-X.UA = X_UA;\r
-\r
// TODO 構文のサポート instanceof, in, try catch\r
\r
-if( X_UA.IE < 7 ){ // error @ NN7.2\r
- // bonus: hotfix for IE6 SP1 (bug KB823727)\r
- // multipleIEs IE6 standalone 版では不可, IE5.5 は可,,,\r
- X_UA.IE4 || X_UA.MacIE ?\r
+if( X_UA[ 'IE' ] < 7 ){ // error @ NN7.2\r
+ X_UA[ 'IE4' ] || X_UA[ 'MacIE' ] ?\r
document.execCommand && document.execCommand( 'BackgroundImageCache', false, true ) :\r
(function(){\r
- X_UA.IE_EXECOM_ERROR = eval( 'var a=1;try{document.execCommand&&document.execCommand("BackgroundImageCache",!1,!0)}catch(e){a=0}!a' );\r
+ /**\r
+ * ie7 以下で実行する document.execCommand( 'BackgroundImageCache', false, true ) の失敗。\r
+ * bonus: hotfix for IE6 SP1 (bug KB823727)\r
+ * multipleIEs IE6 standalone 版では不可, IE5.5 は可,,,\r
+ * @memberof X.UA */\r
+ X_UA[ 'ieExeComError' ] = eval( 'var a=1;try{document.execCommand&&document.execCommand("BackgroundImageCache",!1,!0)}catch(e){a=0}!a' );\r
})();\r
\r
- X_UA.IE_EXECOM_ERROR && alert( 'document.execCommand error!' );\r
+ X_UA[ 'ieExeComError' ] && alert( 'document.execCommand error!' );\r
};\r
\r
/*\r
- * HTML5 に対応しない IE8 以下でも <a> の下に <div> を作ることができる\r
+ * HTML5 に対応しない IE8 以下でも <a> の下に <div> を作ることができる\r
* その際に <div> の直前に改行文字が出現するが childNodes は長さ 1 で <div> だけの模様、、、\r
X_UA_ATagWrapDiv = (function( e, h ){\r
e = document.createElement( 'div' );\r
+var\r
+ /**\r
+ * Array か?判定する。argumnets 等のフェイク Array は false なので注意。\r
+ * @funciton\r
+ * @alias X.Type._isArray\r
+ */\r
+ X_Type_isArray =\r
+ new Function( 'v',\r
+ X_UA[ 'IE' ] < 5.5 || X_UA[ 'NetFront' ] < 4 ? // netfront3.4 は html に instanceof をすると error になる\r
+ 'return v&&v.push===Array.prototype.push' : // win ie5-, MacIE5.2\r
+ X_UA[ 'IE' ] ?\r
+ 'return v&&Object.prototype.toString.call(v)==="[object Array]"' :\r
+ 'return v instanceof Array'\r
+ ),\r
+\r
+ /**\r
+ * HTMLElement か?判定する。ちなみに return v instanceof Element は ie8 でエラー。\r
+ * @funciton\r
+ * @alias X.Type.isHTMLElement\r
+ */\r
+ X_Type_isHTMLElement =\r
+ new Function( 'v',\r
+ ( X_UA[ 'IE4' ] || X_UA[ 'MacIE' ] ) ?\r
+ 'return v&&v.tagName&&v.insertAdjacentHTML&&true' : // ie4 or MacIE5.23, v.all <- error\r
+ X_UA[ 'NetFront' ] < 4 ?\r
+ 'return v&&v.nodeType===1' : // instanceof not a function. netfront3.4 は html に instanceof をすると error になる\r
+ window[ 'HTMLElement' ] ?\r
+ 'return v instanceof HTMLElement' :\r
+ 'return v&&v.appendChild&&v.nodeType===1'\r
+ );\r
+\r
+\r
+\r
/**\r
* http://pettanr.sourceforge.jp/test/type.html\r
* ビルトイン方の判定に使用する関数を集めたもの。ブラウザのネイティブな判定関数には不可解な挙動があるので、X.Type を使用するほうがよい。\r
* @namespace X.Type\r
* @alias X.Type\r
*/\r
-X.Type = {\r
+X[ 'Type' ] = {\r
+ 'isObject' : X_Type_isObject,\r
+ 'isFunction' : X_Type_isFunction,\r
+ 'isUnknown' : X_Type_isUnknown,\r
+ 'isArray' : X_Type_isArray,\r
+ 'isBoolean' : X_Type_isBoolean,\r
+ 'isString' : X_Type_isString,\r
+ 'isNumber' : X_Type_isNumber,\r
+ 'isFinite' : X_Type_isFinite,\r
+ 'isNaN' : X_Type_isNaN,\r
+ 'isHTMLElement' : X_Type_isHTMLElement,\r
+ 'isImage' : X_Type_isImage,\r
+ 'isNull' : X_Type_isNull,\r
+ 'isUndefined' : X_Type_isUndefined\r
+};\r
+\r
/**\r
* Object か?判定する。typeof null === 'object' に対策済なので null は Object ではない。\r
+ * @alias X.Type.isObject\r
*/\r
- isObject : function( v ){\r
+ function X_Type_isObject( v ){\r
return v && typeof v === 'object'; // typeof null === 'object' に対策\r
- },\r
+ };\r
/**\r
* Function か?判定する。\r
+ * @alias X.Type.isFunction\r
*/\r
- isFunction : function( v ){\r
+ function X_Type_isFunction( v ){\r
return typeof v === 'function';\r
- },\r
+ };\r
/**\r
* ie の XHR.open 等ビルトインオブジェクトか?判定する。\r
+ * @alias X.Type.isUnknown\r
*/\r
- isUnknown : function( v ){\r
+ function X_Type_isUnknown( v ){\r
return typeof v === 'unknown';\r
- },\r
- /**\r
- * Array か?判定する。argumnets 等のファイク Array は false なので注意。\r
- * @funciton\r
- */\r
- isArray :\r
- new Function( 'v',\r
- X_UA.IE < 5.5 || X_UA.NetFront < 4 ? // netfront3.4 は html に instanceof をすると error になる\r
- 'return v&&v.push===Array.prototype.push' : // win ie5-, MacIE5.2\r
- X_UA.IE ?\r
- 'return v&&Object.prototype.toString.call(v)==="[object Array]"' :\r
- 'return v instanceof Array'\r
- ),\r
+ };\r
+\r
/**\r
* 真偽値か?判定する。\r
+ * @alias X.Type.isBoolean\r
*/\r
- isBoolean : function( v ){\r
+ function X_Type_isBoolean( v ){\r
return v === true || v === false;\r
- },\r
+ };\r
/**\r
* 文字列か?判定する。\r
+ * @alias X.Type.isString\r
*/\r
- isString : function( v ){\r
+ function X_Type_isString( v ){\r
return typeof v === 'string'; // v === v + ''; // 文字列の加算は IE で遅いかも。\r
- },\r
+ };\r
/**\r
* 数値値か?判定する。\r
+ * @alias X.Type.isNumber\r
*/\r
- isNumber : function( v ){\r
+ function X_Type_isNumber( v ){\r
return typeof v === 'number'; // v !== v || v + 0 === v;\r
- },\r
+ };\r
/**\r
* finite か?判定する。isFinite( '123' ) === true に対策済。\r
+ * @alias X.Type.isFinite\r
*/\r
- isFinite : function( v ){\r
+ function X_Type_isFinite( v ){\r
return typeof v === 'number' && isFinite( v );\r
- },\r
+ };\r
/**\r
- * NaN か?判定する。isNaN( 'NaN' ) === true に対策済。\r
+ * NaN か?判定する。isNaN( 'NaN' ) === true に対策済。\r
+ * @alias X.Type.isNaN\r
*/\r
- isNaN : function( v ){\r
+ function X_Type_isNaN( v ){\r
return v !== v;\r
- },\r
- /**\r
- * HTMLElement か?判定する。\r
- * @funciton\r
- */\r
- isHTMLElement :\r
- new Function( 'v',\r
- ( X_UA.IE4 || X_UA.MacIE ) ?\r
- 'return v&&v.tagName&&v.insertAdjacentHTML&&true' : // ie4 or MacIE5.23, v.all <- error\r
- X_UA.NetFront < 4 ?\r
- 'return v&&v.nodeType===1' : // instanceof not a function. netfront3.4 は html に instanceof をすると error になる\r
- window[ 'HTMLElement' ] ?\r
- 'return v instanceof HTMLElement' :\r
- //window[ 'Element' ] ?\r
- // 'return v instanceof Element' : // error @ie8\r
- 'return v&&v.appendChild&&v.nodeType===1'\r
- ),\r
+ };\r
+\r
\r
/*\r
* new Image した場合に HTMLImageElement が作られるブラウザと,そうでないブラウザ(IE8-)がある\r
+ * @alias X.Type.isImage\r
*/ \r
- isImage :\r
- function( v ){\r
- if( v && v.constructor === window.Image ) return true;\r
- if( v && window.HTMLImageElement && v.constructor === window.HTMLImageElement ) return true; // ie6- は constructor が undef、HTMLImageElement が undef なので、HTMLElement の存在確認が必要\r
- if( X_UA.WebKit < 525.13 ){ // Safari3-\r
- if( v && v.src !== undefined && v.onload !== undefined && X.Type.isNumber( v.height ) && X.Type.isNumber( v.width ) && X.Type.isBoolean( v.complete ) ){\r
- return true;\r
- };\r
+ function X_Type_isImage( v ){\r
+ if( v && v.constructor === window.Image ) return true;\r
+ if( v && window.HTMLImageElement && v.constructor === window.HTMLImageElement ) return true; // ie6- は constructor が undef、HTMLImageElement が undef なので、HTMLElement の存在確認が必要\r
+ if( X_UA[ 'WebKit' ] < 525.13 ){ // Safari3-\r
+ if( v && v.src !== undefined && v.onload !== undefined && X_Type_isNumber( v.height ) && X_Type_isNumber( v.width ) && X_Type_isBoolean( v.complete ) ){\r
+ return true;\r
};\r
- return false;\r
- },\r
+ };\r
+ return false;\r
+ };\r
/*\r
isElementCollection : function(v) {\r
return (Object.prototype.toString.call(v) === "[object HTMLCollection]");\r
*/\r
/**\r
* Null か?判定する。\r
+ * @alias X.Type.isNull\r
*/\r
- isNull : function( v ){\r
+ function X_Type_isNull( v ){\r
return v === null;\r
- },\r
+ };\r
/**\r
* undefined か?判定する。\r
+ * @alias X.Type.isUndefined\r
*/\r
- isUndefined : function( v ){\r
+ function X_Type_isUndefined( v ){\r
return v === void 0;\r
- }\r
-};\r
+ };\r
\r
console.log( 'X.Core.Type' );\r
* @param {object} obj \r
* @return {boolean} name が定義されている(値が undefined や null でも) -> true\r
*/\r
-var X_Object_inObject = X_UA.IE < 5.5 ? // TODO JScript で判定\r
+var X_Object_inObject = X_UA[ 'IE' ] < 5.5 ? // TODO JScript で判定\r
(function( name, obj ){\r
var p;\r
if( obj[ name ] ) return true; // quick\r
*/\r
function X_Object_override( target, src ){\r
var k;\r
- if( !X.Type.isObject( src ) ) return target;\r
+ if( !X_Type_isObject( src ) ) return target;\r
for( k in src ){\r
//if( X_EMPTY_OBJECT[ k ] ) continue;\r
target[ k ] = src[ k ];\r
if( !src ){ // 0, "", null, undefined, NaN, false\r
return src;\r
} else\r
- if( X.Type.isArray( src ) ){\r
+ if( X_Type_isArray( src ) ){\r
i = objSrc.indexOf( src );\r
if( i !== -1 ) return objCopy[ i ];\r
objSrc[ ++n ] = src;\r
objCopy[ n ] = ret = [];\r
} else\r
- if( X.Type.isObject( src ) ){\r
+ if( X_Type_isObject( src ) ){\r
i = objSrc.indexOf( src );\r
if( i !== -1 ) return objCopy[ i ];\r
objSrc[ ++n ] = src;\r
// ------------------------------------------------------------------------- //\r
function X_String_parse( v ){\r
var _v, n;\r
- if( X.Type.isString( v ) ){\r
+ if( X_Type_isString( v ) ){\r
switch( v ){\r
case '' : return v;\r
//case '{}' : return {};\r
function X_Callback_classifyCallbackArgs( arg1, arg2, arg3, alt_context ){\r
var obj;\r
\r
- if( arg1 && X.Type.isFunction( arg2 ) ){\r
+ if( arg1 && X_Type_isFunction( arg2 ) ){\r
obj = { x : arg1, f : arg2, k : X_Callback_THIS_FUNC };\r
} else\r
- if( arg1 && X.Type.isFunction( arg1[ 'handleEvent' ] ) ){\r
+ if( arg1 && X_Type_isFunction( arg1[ 'handleEvent' ] ) ){\r
obj = { x : arg1, k : X_Callback_HANDLEEVENT };\r
arg3 = arg2;\r
} else\r
- if( X.Type.isFunction( arg1 ) ){\r
+ if( X_Type_isFunction( arg1 ) ){\r
arg3 = arg2;\r
if( alt_context ){\r
obj = { x : alt_context, f : arg1, k : X_Callback_THIS_FUNC };\r
obj = { f : arg1, k : X_Callback_FUNC_ONLY };\r
};\r
} else\r
- if( X.Type.isFunction( arg2 ) ){\r
+ if( X_Type_isFunction( arg2 ) ){\r
//console.log( 'X_Callback_classifyCallbackArgs : arg1 が ' + arg1 + 'です' ); ie4 で error\r
if( alt_context ){\r
obj = { x : alt_context, f : arg2, k : X_Callback_THIS_FUNC };\r
return;\r
};\r
\r
- if( X.Type.isArray( arg3 )){\r
+ if( X_Type_isArray( arg3 )){\r
obj.s = arg3;\r
};\r
return ( obj.x || obj.s ) ? obj : arg1;\r
\r
case X_Callback_HANDLEEVENT :\r
temp = thisObj[ 'handleEvent' ];\r
- if( X.Type.isFunction( temp ) ){\r
+ if( X_Type_isFunction( temp ) ){\r
return args.length === 0 ? thisObj[ 'handleEvent' ]() :\r
args.length === 1 ? thisObj[ 'handleEvent' ]( args[ 0 ] ) : temp.apply( thisObj, args );\r
};\r
break;\r
/*\r
- if( temp !== func && X.Type.isFunction( temp ) ){\r
+ if( temp !== func && X_Type_isFunction( temp ) ){\r
return args.length === 0 ? thisObj[ 'handleEvent' ]() : temp.apply( thisObj, args );\r
} else\r
- if( X.Type.isFunction( thisObj ) ){\r
+ if( X_Type_isFunction( thisObj ) ){\r
return args.length === 0 ? thisObj.call( thisObj ) : thisObj.apply( thisObj, args );\r
};\r
return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args );*/\r
X_Class_killPrivateFlag = false,\r
X_Class_traits = null,\r
X_Class_useObjectCreate = false, // !!Object.create, http://jsperf.com/prototype-vs-object-create-perf\r
- X_Class_use_proto_ = !X_UA.OperaMobile && !X_UA.OperaTablet && !!X.emptyFunction.prototype.__proto__,\r
+ X_Class_use_proto_ = !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] && !!X.emptyFunction.prototype.__proto__,\r
// Opera Mobile 12.10 Android11 IS01 でクラスのメンバが欠落する問題に遭遇。__proto__ を使わないと動作,,,\r
\r
X_Class_CommonMethods =\r
klass = X_Class_getClass( instance ),\r
def = X_Class_getClassDef( klass ),\r
data, p, i;\r
- if( def.isPrivate && !X_Class_killPrivateFlag ){\r
+ if( def.isPrivate && !X_Class_killPrivateFlag && ( !this[ '_listeners' ] || !this[ '_listeners' ][ X_Listeners_.KILL_RESERVED ] ) ){\r
X.Logger.critical( 'PrivateInstance.kill() work in PrivateUser.kill().' );\r
return;\r
};\r
\r
if( this.instanceOf( X.EventDispatcher ) ){\r
if( !def.isPrivate ){\r
- if( this.dispatch( X.Event.BEFORE_KILL_INSTANCE ) & X.Callback.PREVENT_DEFAULT ){\r
- this.dispatch( X.Event.KILL_INSTANCE_CANCELED );\r
+ if( this.dispatch( X_Event.BEFORE_KILL_INSTANCE ) & X.Callback.PREVENT_DEFAULT ){\r
+ this.dispatch( X_Event.KILL_INSTANCE_CANCELED );\r
return;\r
};\r
if( this[ '_listeners' ] && this[ '_listeners' ][ X_Listeners_.DISPATCHING ] ){\r
return;\r
};\r
} else {\r
- this.dispatch( X.Event.BEFORE_KILL_INSTANCE ); \r
+ this.dispatch( X_Event.BEFORE_KILL_INSTANCE ); \r
};\r
\r
// asyncDispatch の削除\r
};\r
};\r
\r
- this.dispatch( X.Event.KILL_INSTANCE );\r
+ this.dispatch( X_Event.KILL_INSTANCE );\r
this._listeners && X_EventDispatcher_systemUnlisten( this );\r
};\r
\r
i = def.userList.indexOf( instance );\r
if( i !== -1 ){\r
data = X_Class_getPrivate( instance );\r
- X_Class_killPrivateFlag = true;\r
if( data[ '_listeners' ] && data[ '_listeners' ][ X_Listeners_.DISPATCHING ] && data.instanceOf( X.EventDispatcher ) ){\r
data[ '_listeners' ][ X_Listeners_.KILL_RESERVED ] = true;\r
} else {\r
+ X_Class_killPrivateFlag = true;\r
data.kill();\r
};\r
def.dataList.splice( i, 1 );\r
var sClass = this,\r
args = arguments,\r
name, p, sFunc, hit = false;\r
- if( X.Type.isFunction( funcNameOrFunc ) ){\r
+ if( X_Type_isFunction( funcNameOrFunc ) ){\r
for( p in this.constructor.prototype ){\r
if( this.constructor.prototype[ p ] === funcNameOrFunc ){\r
name = p;\r
hit = true; // 現在の関数にヒット\r
} else\r
if( hit && X_Object_inObject( name, this ) ){\r
- if( X.Type.isFunction( sFunc ) ){\r
+ if( X_Type_isFunction( sFunc ) ){\r
switch( args.length ){\r
case 1 :\r
return sFunc.call( this );\r
// ------------------------------------------------------------------------- //\r
\r
/**\r
- * Class を定義し システムの管理下に置く.<br>\r
- * 全てのクラスと pool が有効の場合インスタンスへの参照が保持される.\r
+ * <p>Class を定義し システムの管理下に置く。\r
+ * <p>prototype 継承のブラウザ毎の差異も吸収し、 以下から最適な方法をしてくれる。\r
+ * \r
+ * <ol>\r
+ * <li>Object.create はパフォーマンスが悪そうなので現在は使っていない。\r
+ * <li>SubClass.prototype.__proto__ = SuperClass.prototype;\r
+ * <li>SubClass.prototype = new SuperClass;\r
+ * </ol>\r
+ * \r
* <ol>\r
* <li>X.Class.create( opt_settings, opt_name, opt_privateClass, opt_props ) でクラスを登録.\r
* <li>コンストラクタ となるメソッドは、opt_props 内の Constructor : function( arg ){ ... }, に書く.\r
* <li>通常通り new で インスタンス生成\r
* <li>kill() でオブジェクトをクリーンして削除、pool が有効の場合は pool される.\r
* <li>pool が有効の場合、new で pool されたインスタンスが返される.\r
+ * </ol>\r
* @namespace X.Class\r
* @alias X.Class\r
*/ \r
props,\r
klass,\r
classDef = {}, hash;\r
- if( X.Type.isString( displayName ) === true ){\r
+ if( X_Type_isString( displayName ) === true ){\r
classDef.displayName = displayName;\r
args.shift();\r
};\r
\r
// クラス設定\r
classDef.setting = classSetting = args[ 0 ];\r
- if( X.Type.isNumber( classSetting ) ){\r
+ if( X_Type_isNumber( classSetting ) ){\r
opt_pool = !!( classSetting & X.Class.POOL_OBJECT );\r
opt_abstract = !!( classSetting & X.Class.ABSTRACT );\r
opt_final = !!( classSetting & X.Class.FINAL );\r
\r
// インスタンスのメンバー\r
props = args[ 0 ];\r
- if( !X.Type.isObject( props ) ){\r
- // サブクラスの場合、クラス定義の上書きがなくても作成可能\r
- // サブクラスでなくても、クラスメンバ用オブジェクトが無しでも作成可能\r
- //if( !X_Class_traits ){\r
- // X.Logger.critical( 'No Class Def!' );\r
- // return;\r
- //};\r
+ if( !X_Type_isObject( props ) ){\r
+ // クラスメンバ用オブジェクトが無しでもクラスは作成可能\r
props = {};\r
} else\r
- if( props.Constructor && X.Type.isFunction( props.Constructor ) ){\r
+ if( props.Constructor && X_Type_isFunction( props.Constructor ) ){\r
classDef.Constructor = props.Constructor;\r
};\r
\r
if( superDef.Final ) X.Logger.critical( 'X.Class inherits, Class is final!' );\r
\r
// サブクラス名\r
- if( X.Type.isString( displayName ) ){\r
+ if( X_Type_isString( displayName ) ){\r
args.shift();\r
} else {\r
displayName = 'SubClass of ' + superDef.displayName;\r
\r
// サブクラス設定\r
classSetting = args[ 0 ];\r
- if( X.Type.isNumber( classSetting ) ){\r
+ if( X_Type_isNumber( classSetting ) ){\r
args.shift();\r
} else {\r
// クラス設定がない場合、親からコピーして、Abstract flag は落とす??\r
\r
def = X_Class_getClassDef( klass );\r
// 継承用プロパティを控える\r
- //if( opt_super === true ){\r
- //def.superAccess = true;\r
- def.SuperClass = Super;\r
- def.SuperProto = Super.prototype;\r
- def.SuperConstructor = superDef.Constructor || superDef.SuperConstructor;\r
- // else {\r
- // def.SuperClass = Super; // instanceOf() で親クラスを調べる!\r
- //};\r
+ def.SuperClass = Super;\r
+ def.SuperProto = Super.prototype;\r
+ def.SuperConstructor = superDef.Constructor || superDef.SuperConstructor;\r
\r
return klass;\r
};\r
def.Constructor.apply( instance, args ) :\r
def.SuperConstructor &&\r
def.SuperConstructor.apply( instance, args );\r
- if( ( X.Type.isObject( obj ) && obj !== instance ) || X.Type.isFunction( obj ) ){ // Class\r
+ if( ( X_Type_isObject( obj ) && obj !== instance ) || X_Type_isFunction( obj ) ){ // Class\r
instance.kill();\r
return obj;\r
};\r
\r
X_Event_proxy = {\r
\r
- load : X_UA.IE < 9 && {\r
+ load : X_UA[ 'IE' ] < 9 && {\r
check : function( eventDispatcher ){\r
return eventDispatcher._tag === 'IFRAME' || eventDispatcher._tag === 'SCRIPT';\r
},\r
}\r
},\r
\r
- contextmenu : X_UA.Opera && {\r
+ contextmenu : X_UA[ 'Opera' ] && {\r
\r
rename : 'mousedown',\r
\r
* フレームワーク内で定義されたイベント。\r
* @namespace X.Event\r
* @alias X.Event\r
+ * @enum {number}\r
*/\r
-X.Event = {\r
- XDOM_READY : 8,\r
+var X_Event = X[ 'Event' ] = {\r
+ /**\r
+ * X.ViewPort で発生する。DomContentLoaded に相当。document.body.innerHTML の内容から X.Node ツリーの作成が完了した。\r
+ * このイベント以降、X.Doc.create(), X.Doc.find() 等が可能になる。\r
+ * @const\r
+ */\r
+ 'XDOM_READY' : 8,\r
\r
- COMPLETE : 9,\r
- READY : 10,\r
- SUCCESS : 11,\r
- ERROR : 12,\r
- PROGRESS : 13,\r
- BEFORE_CANCEL : 14,\r
- CANCELED : 15,\r
- TIMEOUT : 16,\r
- \r
- BEFORE_KILL_INSTANCE : 17,\r
- KILL_INSTANCE_CANCELED : 18,\r
- KILL_INSTANCE : 19,\r
+ 'COMPLETE' : 9,\r
+ 'READY' : 10,\r
+ 'SUCCESS' : 11,\r
+ 'ERROR' : 12,\r
+ 'PROGRESS' : 13,\r
+ 'BEFORE_CANCEL' : 14,\r
+ 'CANCELED' : 15,\r
+ 'TIMEOUT' : 16,\r
+\r
+ /**\r
+ * X.EventDispatcher インスタンスを kill() すると発生。キャンセル可能。\r
+ */ \r
+ 'BEFORE_KILL_INSTANCE' : 17,\r
+ /**\r
+ * X.EventDispatcher インスタンスの kill() がキャンセルされた場合に発生。\r
+ */ \r
+ 'KILL_INSTANCE_CANCELED' : 18,\r
+ /**\r
+ * X.EventDispatcher インスタンスの kill が確定し、kill プロセスの前に発生。\r
+ */\r
+ 'KILL_INSTANCE' : 19,\r
+\r
+ /**\r
+ * X.ViewPort で発生する。'visibilitychange', 'pageshow', window.onfocus を検出している。\r
+ */\r
+ 'VIEW_ACTIVATE' : 20,\r
+ /**\r
+ * X.ViewPort で発生する。'visibilitychange', 'pagehide', window.onblur を検出している。\r
+ */\r
+ 'VIEW_DEACTIVATE' : 21,\r
+ /**\r
+ * X.ViewPort で発生する。\r
+ */\r
+ 'VIEW_RESIZED' : 22,\r
+ /**\r
+ * X.ViewPort で発生する。\r
+ */\r
+ 'VIEW_TURNED' : 23,\r
+ /**\r
+ * X.ViewPort で発生する。ベースフォントサイズが変化すると発生する。body 直下の隠し要素のテキストサイズの変化で検出している。\r
+ */\r
+ 'BASE_FONT_RESIZED' : 24,\r
\r
- VIEW_ACTIVATE : 20,\r
- VIEW_DEACTIVATE : 21,\r
- VIEW_RESIZED : 22,\r
- VIEW_TURNED : 23,\r
- BASE_FONT_RESIZED : 24,\r
// in_page_jump\r
// on_screen_keyboard_show\r
// on_screen_keyboard_hide\r
- BEFORE_UPDATE : 25,// X_System このイベントで要素のサイズを取得すると無限ループに!\r
- UPDATED : 26,// X_System\r
- AFTER_UPDATE : 27,\r
\r
- HASH_CHANGED : 28,\r
+ 'BEFORE_UPDATE' : 25,// X_System このイベントで要素のサイズを取得すると無限ループに!\r
+ 'UPDATED' : 26,// X_System\r
+ 'AFTER_UPDATE' : 27,\r
+\r
+ 'HASH_CHANGED' : 28,\r
\r
- BEFORE_UNLOAD : 29,\r
- UNLOAD : 30,\r
+ /**\r
+ * X.ViewPort で発生する。\r
+ */\r
+ 'BEFORE_UNLOAD' : 29,\r
+ /**\r
+ * X.ViewPort で発生する。\r
+ */\r
+ 'UNLOAD' : 30,\r
\r
- BACKEND_READY : 31,\r
- BACKEND_NONE : 32,\r
- BACKEND_RESEARCH : 33,\r
- BACKEND_CHANGED : 34,\r
+ 'BACKEND_READY' : 31,\r
+ 'BACKEND_NONE' : 32,\r
+ 'BACKEND_RESEARCH' : 33,\r
+ 'BACKEND_CHANGED' : 34,\r
\r
- ANIME_BEFORE_START : 35,\r
- ANIME_START : 36,\r
- ANIME : 37,\r
- ANIME_END : 38,\r
- ANIME_BEFORE_STOP : 39, // xnode.stop() のみ、指定時間による停止では呼ばれない\r
- ANIME_STOP : 40,\r
+ 'ANIME_BEFORE_START' : 35,\r
+ 'ANIME_START' : 36,\r
+ 'ANIME' : 37,\r
+ 'ANIME_END' : 38,\r
+ 'ANIME_BEFORE_STOP' : 39, // xnode.stop() のみ、指定時間による停止では呼ばれない\r
+ 'ANIME_STOP' : 40,\r
\r
- GPU_RELEASED : 41,\r
+ 'GPU_RELEASED' : 41,\r
\r
- MEDIA_PLAYING : 42,\r
- MEDIA_BEFORE_LOOP : 43, // cancelable\r
- MEDIA_LOOPED : 44,\r
- MEDIA_PAUSED : 45,\r
- MEDIA_ENDED : 46,\r
- MEDIA_WAITING : 47,\r
- MEDIA_SEEKING : 48\r
+ 'MEDIA_PLAYING' : 42,\r
+ 'MEDIA_BEFORE_LOOP' : 43, // cancelable\r
+ 'MEDIA_LOOPED' : 44,\r
+ 'MEDIA_PAUSED' : 45,\r
+ 'MEDIA_ENDED' : 46,\r
+ 'MEDIA_WAITING' : 47,\r
+ 'MEDIA_SEEKING' : 48\r
};\r
\r
X_Event_last = 48;\r
for( k in X_Event_Rename ){\r
//if( X_EMPTY_OBJECT[ k ] ) continue;\r
name = X_Event_Rename[ k ];\r
- if( X.Type.isArray( name ) ){\r
+ if( X_Type_isArray( name ) ){\r
for( i = name.length; i; ){\r
X_Event_RenameTo[ name[ --i ] ] = k;\r
};\r
-/*\r
- * <p>EventDispatcher インスタンスのメンバ(_listeners)でイベントリスナをイベント名(string)やイベントID(5~以上の number, フレームワーク内で定義、5 以上になる理由は後述)をキーとする Array で記憶します。\r
- * Arrayには、__CallbackHash__ というハッシュ、または関数が蓄えられています。\r
+/**\r
+ * <p>EventDispatcher インスタンスのメンバ(_listeners)でイベントリスナをイベント名(string)や\r
+ * イベントID(5~以上の number, フレームワーク内で定義、5 以上になる理由は後述)をキーとする Array で記憶します。\r
+ * \r
+ * <p>Arrayには、__CallbackHash__ というハッシュ、または関数が蓄えられています。\r
+ * \r
+ * <p>また、イベントターゲット(EventDispatcher._rawObject)に渡された再利用可能クロージャの控えを _listeners[0] に記憶します。(ACTUAL_HANDLER)\r
* \r
- * また、dispatch 中の状態と操作を記録し不整合が起きないようにするためのプロパティを持ち、0 から 4 の番号が与えられています。\r
+ * <p>dispatch 中の状態と操作を記録し不整合が起きないようにするためのプロパティ(_listeners[1]~_listeners[4])を持ちます。イベントID が 5 から始まるのはこのためです。\r
* \r
* <dl>\r
* <dt>0:ACTUAL_HANDLER\r
* <dd>イベントターゲットの addEventListener 等に渡される実際の関数(再利用可能クロージャ)を控えています。\r
* <dt>1:DISPATCHING number\r
- * <dd>イベントディスパッチ中か?またディスパッチがネストした場合、その深さを記憶します。\r
+ * <dd>dispatch 中か?さらにインスタンス自身の dispatch がネストした場合、その深さを記憶します。\r
* <dt>2:RESERVES Array\r
- * <dd>ã\82¤ã\83\99ã\83³ã\83\88ç\99ºç\81«ä¸ã\81« listen() ã\81\8cå\91¼ã\81°ã\82\8cã\81\9få ´å\90\88ã\81«å¼\95æ\95°ã\82\92è\93\84ã\81\88ã\80\81å\85¨ã\81¦ã\81®ã\83\87ã\82£ã\82¹ã\83\91ã\83\83ã\83\81ã\81®å®\8cäº\86æ\99\82(_dispatching===0)に再度 listen() するための一時ストアです。\r
+ * <dd>ã\82¤ã\83\99ã\83³ã\83\88ç\99ºç\81«ä¸ã\81« listen() ã\81\8cå\91¼ã\81°ã\82\8cã\81\9få ´å\90\88ã\81«å¼\95æ\95°ã\82\92è\93\84ã\81\88ã\80\81å®\8cäº\86æ\99\82(DISPATCHING===0)に再度 listen() するための一時ストアです。\r
* <dt>3:UNLISTENS Array\r
- * <dd>ã\82¤ã\83\99ã\83³ã\83\88ç\99ºç\81«ä¸ã\81« unlisten() ã\81\8cå\91¼ã\81°ã\82\8cã\81\9få ´å\90\88ã\81«å¯¾è±¡ã\83ªã\82¹ã\83\8aã\82\92è¨\98æ\86¶ã\81\97ã\80\81ã\83ªã\82¹ã\83\8aã\81\8cå\91¼ã\81°ã\82\8cã\81ªã\81\84ã\82\88ã\81\86ã\81«ã\81\97ã\81¾ã\81\99ã\80\82å\85¨ã\81¦ã\81®ã\83\87ã\82£ã\82¹ã\83\91ã\83\83ã\83\81ã\81®å®\8cäº\86æ\99\82(_dispatching===0)に再度 unlisten() します。\r
+ * <dd>ã\82¤ã\83\99ã\83³ã\83\88ç\99ºç\81«ä¸ã\81« unlisten() ã\81\8cå\91¼ã\81°ã\82\8cã\81\9få ´å\90\88ã\81«å¯¾è±¡ã\83ªã\82¹ã\83\8aã\82\92è¨\98æ\86¶ã\81\97ã\80\81ã\83ªã\82¹ã\83\8aã\81\8cå\91¼ã\81°ã\82\8cã\81ªã\81\84ã\82\88ã\81\86ã\81«ã\81\97ã\81¾ã\81\99ã\80\82å®\8cäº\86æ\99\82(DISPATCHING===0)に再度 unlisten() します。\r
* <dt>4:KILL_RESERVED boolean\r
- * <dd>イベント発火中に kill() が呼ばれた場合に、全てのディスパッチの完了時(_dispatching===0)に再度 kill() するためのフラグです。\r
+ * <dd>dispatch 中に kill() が呼ばれた場合に一旦 kill をキャンセルし、完了時(DISPATCHING===0)に再度 kill() するためのフラグです。\r
* </dl>\r
+ * \r
+ * @class __X_EventDispatcher_Listeners__\r
+ * @private\r
+ * @abstract\r
*/\r
-var X_Listeners,\r
-\r
+var\r
/** @enum {number} */\r
- X_Listeners_ = {\r
+ X_Listeners_ =\r
+ /** @lends __X_EventDispatcher_Listeners__ */\r
+ {\r
ACTUAL_HANDLER : 0,\r
DISPATCHING : 1,\r
RESERVES : 2,\r
* Arrayには、{k:種類,x:コンテキスト(thisObject),f:関数,s:サプリメントする引数の配列} というハッシュ、または関数が蓄えられています。\r
* \r
* @private\r
- * @type {X_Listeners}\r
+ * @type {__X_EventDispatcher_Listeners__}\r
*/\r
'_listeners' : null,\r
\r
},\r
\r
/**\r
- * delay(ミリ秒)後にイベントを dispatch する。戻り値は uid = X.Timer.add() のタイマーID(数値)。X.Timer.remove(uid) でタイマーを解除して dispatch を中止できる。\r
- * kill() 時には内部でまだ呼ばれていないタイマーの X.Timer.remove() が行われる。\r
+ * delay(ミリ秒)後にイベントを dispatch する。戻り値は uid = X.Timer.once() のタイマーID(数値)。X.Timer.remove(uid) でタイマーを解除して dispatch を中止できる。\r
+ * kill() 時には内部でまだ呼ばれていないタイマーの X.Timer.remove() が行われる。インスタンスが破棄された後にタイマーが呼ばれることがないので神経質にならなくても安全に使える。\r
* @example this.asyncDispatch( 'myevent' );\r
* // どちらのコードも同じ動作をする。\r
* this.asyncDispatch( 0, 'myevent' );\r
if( r & X.Callback.STOP_NOW ){\r
sysOnly = true;\r
};\r
- ret |= X.Type.isFinite( r ) ? r : 0;\r
+ ret |= X_Type_isFinite( r ) ? r : 0;\r
};\r
\r
if( ( --listeners[ X_Listeners_.DISPATCHING ] ) === 0 ){\r
return this;\r
};\r
\r
- if( X.Type.isArray( type ) ){\r
+ if( X_Type_isArray( type ) ){\r
for( i = type.length; i; ){\r
this.listen( type[ --i ], opt_arg1, opt_arg2, opt_arg3 );\r
};\r
};\r
\r
raw = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this );\r
- add = raw && ( !listeners || !listeners[ type ] ) && X.Type.isString( type );\r
+ add = raw && ( !listeners || !listeners[ type ] ) && X_Type_isString( type );\r
\r
if( this.listening( type, opt_arg1 || this, opt_arg2, opt_arg3 ) ) return this;\r
\r
list, reserves, unlistens, i, f, raw, k, empty;\r
if( !listeners ) return this;\r
\r
- if( X.Type.isArray( opt_type ) ){\r
+ if( X_Type_isArray( opt_type ) ){\r
for( i = opt_type.length; i; ){\r
this.unlisten( opt_type[ --i ], opt_arg1, opt_arg2, opt_arg3 );\r
if( !opt_type[ i ] ){\r
var i;\r
X_EventDispatcher_lock || ( type = X_Event_Rename[ type ] || type );\r
\r
- if( X.Type.isArray( type ) ){\r
+ if( X_Type_isArray( type ) ){\r
for( i = type.length; i; ){\r
X_EventDispatcher_systemListen( that, type[ --i ], X.emptyFunction );\r
console.log( 'events fix > ' + type[ i ] );\r
break;\r
\r
case X_EventDispatcher_EVENT_TARGET_TYPE.XHR :\r
- if( X_UA.Opera < 12 ){\r
+ if( X_UA[ 'Opera' ] < 12 ){\r
// Opera11- の XHR は event オブジェクトが返らないため, eventType 毎に callback を指定する addEventListener もない\r
raw[ 'on' + type ] = X_Callback_create( that, X_EventDispatcher_dispatch, [ type ] );\r
break;\r
default :\r
// iOS と MacOSX Iron36 で発生。連続してアニメーションが起こると、クロージャの束縛された obj へのアクセスに失敗する。Win では起きない?\r
// むしろ、MacOSX のブラウザ全般で起こる??\r
- if( ( X_UA.WebKit || X_UA.Blink ) &&\r
+ if( ( X_UA[ 'WebKit' ] || X_UA[ 'Blink' ] ) &&\r
( type === 'webkitTransitionEnd' || type === 'transitionend' ||\r
type === 'animationend' || type === 'webkitAnimationEnd' ||\r
type === 'animationstart' || type === 'webkitAnimationStart' ||\r
var i;\r
X_EventDispatcher_unlock || ( type = X_Event_Rename[ type ] || type );\r
\r
- if( X.Type.isArray( type ) ){\r
+ if( X_Type_isArray( type ) ){\r
for( i = type.length; i; ){\r
X_EventDispatcher_systemUnlisten( that, type[ --i ], X.emptyFunction );\r
};\r
break;\r
\r
case X_EventDispatcher_EVENT_TARGET_TYPE.XHR :\r
- if( X_UA.Opera < 12 ){\r
+ if( X_UA[ 'Opera' ] < 12 ){\r
// Opera11- の XHR は event オブジェクトが返らないため, eventType 毎に callback を指定する addEventListener もない\r
X_Callback_correct( raw[ 'on' + type ] );\r
raw[ 'on' + type ] = '';\r
};\r
\r
default :\r
- if( ( X_UA.WebKit || X_UA.Blink ) &&\r
+ if( ( X_UA[ 'WebKit' ] || X_UA[ 'Blink' ] ) &&\r
( type === 'webkitTransitionEnd' || type === 'transitionend' ||\r
type === 'animationend' || type === 'webkitAnimationEnd' ||\r
type === 'animationstart' || type === 'webkitAnimationStart' ||\r
i, l;\r
//console.log( '>>>>>>>>>> ' + e.type );\r
// touch event -> pointer\r
- if( X.Type.isArray( ev ) ){\r
+ if( X_Type_isArray( ev ) ){\r
if( ev.length === 0 ){\r
// TouchEvent の後に発生した MouseEvent のキャンセル\r
ret = X.Callback.STOP_PROPAGATION | X.Callback.PREVENT_DEFAULT;\r
if( ret & X.Callback.PREVENT_DEFAULT ){\r
this._tag === 'A' && this._rawObject.blur();\r
e.preventDefault();\r
- if( X_UA.WebKit < 525.13 ){ // Safari3-\r
+ if( X_UA[ 'WebKit' ] < 525.13 ){ // Safari3-\r
if( e.type === 'click' || e.type === 'dbclick' ){\r
X_EventDispatcher_safariPreventDefault = true;\r
};\r
};\r
});\r
\r
-if( X_UA.WebKit < 525.13 ){ // Safari3-\r
+if( X_UA[ 'WebKit' ] < 525.13 ){ // Safari3-\r
document.documentElement.onclick =\r
document.documentElement.ondbclick = function( e ){\r
if( X_EventDispatcher_safariPreventDefault ){\r
-/**\r
+/*\r
* use X.Callback\r
*/\r
\r
// ------------ local variables -------------------------------------------- //\r
// ------------------------------------------------------------------------- //\r
\r
-var X_Timer_now = Date.now || function(){ return +new Date; },\r
+var\r
+\r
+ /**\r
+ * 現在時の ms を返します。 new Date().getTime() の値です。\r
+ * @alias X.Timer.now\r
+ * @function\r
+ * @return {number} ミリ秒\r
+ */\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
// --- interface ----------------------------------------------------------- //\r
// ------------------------------------------------------------------------- //\r
+\r
+/**\r
+ * <p>setTimeout をラップします。複数のタイマーを登録しても Web ブラウザにはひとつのタイマーを登録します。\r
+ * <p>参考:<a href="http://d.hatena.ne.jp/amachang/20060924/1159084608" target="_blank">複雑で重くなった JavaScript を超高速化する方法3</a>,\r
+ * <a href="http://d.hatena.ne.jp/sawat/20070329" target="_blank">[JavaScript]setIntervalを実験する</a>\r
+ * <p>指定時間の経過したタイマーは、より過去のものから順番にコールバックされます。\r
+ * <p>setTimeout のコールバックに文字列しか指定できないブラウザがあり対策しています。\r
+ * <p>requestAnimationFrame をラップします。ベンダープレフィックス付の requestAnimationFrame もない場合、setTimeout にフォールバックします。\r
+ * \r
+ * @example X.Timer.add( 1000, 5, thisContext, onTimer );\r
+ * \r
+ * @namespace X.Timer\r
+ * @alias X.Timer\r
+ */ \r
X.Timer = {\r
- \r
+\r
now : X_Timer_now,\r
\r
+ /**\r
+ * タイマーをセットします。\r
+ * @param {number} time ミリ秒\r
+ * @param {number} opt_count 回数。省略可能。指定回数で自動でタイマーを破棄します。0 を指定した場合無限にタイマーが呼ばれます。省略した場合 0 と同じです。\r
+ * @param {*} args1 コールバックのための最大で 3 つの引数を指定します。参考:__CallbackHash__\r
+ * @param {*} args2\r
+ * @param {*} args3\r
+ * @return {number} タイマーID。1 以上の数値。タイマーの解除に使用。\r
+ */\r
add : function( time, opt_count, args1, args2, args3 ){\r
var list = X_Timer_TICKET_LIST,\r
hash, obj;\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
+ if( !X_Type_isNumber( opt_count ) ){\r
args3 = args2;\r
args2 = args1;\r
args1 = opt_count;\r
return X_Timer_uid;\r
},\r
\r
+ /**\r
+ * 1 回呼ばれたら解除されるタイマーをセットします。\r
+ * @param {number} time ミリ秒\r
+ * @param {*} args1 コールバックのための最大で 3 つの引数を指定します。参考:__CallbackHash__\r
+ * @param {*} args2\r
+ * @param {*} args3\r
+ * @return {number} タイマーID。1 以上の数値。タイマーの解除に使用。\r
+ */\r
once : function( time, args1, args2, args3 ){\r
return X.Timer.add( time, 1, args1, args2, args3 );\r
},\r
\r
+ /**\r
+ * タイマーを解除します。登録時に受け取ったタイマーIDを使用します。\r
+ * @param {number} タイマーID\r
+ */\r
remove : function( uid ){\r
var list = X_Timer_TICKET_LIST,\r
i = list.length,\r
* lazyDispatch 中の EventDispatcher の有無を調べる\r
*/\r
if( X_EventDispatcher_LAZY_TIMERS[ uid ] ){\r
- eventDispatcher = X_EventDispatcher_LAZY_TIMERS[ uid ];\r
+ // eventDispatcher = X_EventDispatcher_LAZY_TIMERS[ uid ];\r
delete X_EventDispatcher_LAZY_TIMERS[ uid ];\r
/*\r
listeners = eventDispatcher[ '_listeners' ];\r
};\r
},\r
\r
+ /**\r
+ * requestAnimationFrame をセットします。\r
+ * @function\r
+ * @param {*} args1 コールバックのための最大で 3 つの引数を指定します。参考:__CallbackHash__\r
+ * @param {*} args2\r
+ * @param {*} args3\r
+ * @return {number} タイマーID。1 以上の数値。タイマーの解除に使用。\r
+ */\r
requestFrame : X_Timer_REQ_ANIME_FRAME ?\r
(function( args1, args2, args3 ){\r
var i = X_Timer_REQ_FRAME_LIST.length,\r
f = X_Timer_REQ_FRAME_LIST[ i ] = X_Callback_classifyCallbackArgs( args1, args2, args3 );\r
return f.uid = ++X_Timer_uid;\r
}),\r
- \r
+\r
+ /**\r
+ * requestAnimationFrame を解除します。登録時に受け取ったタイマーIDを使用します。\r
+ * @function\r
+ * @param {number} タイマーID\r
+ */\r
cancelFrame : X_Timer_CANCEL_ANIME_FRAME ?\r
(function( uid ){\r
var list = X_Timer_REQ_FRAME_LIST,\r
// --- implements ---------------------------------------------------------- //\r
// ------------------------------------------------------------------------- //\r
\r
-if( X_UA.IE4 || X_UA.MacIE ){\r
+if( X_UA[ 'IE4' ] || X_UA[ 'MacIE' ] ){\r
X.Timer[ '_' ] = X_Timer_onTimeout;\r
X_Timer_onTimeout = 'X.Timer._()';\r
};\r
\r
// http://havelog.ayumusato.com/develop/javascript/e528-ios6_scrolling_timer_notcall.html\r
// iOS6 スクロール中のタイマー発火絡みのバグ備忘\r
-if( X_UA.iOS ){\r
+if( X_UA[ 'iOS' ] ){\r
window.addEventListener( 'scroll', function(){\r
var last, now;\r
if( X_Timer_timerId ){\r
X_ViewPort_vScrollbarSize,
X_ViewPort_hScrollbarSize,
- X_Dom_detectFontSize = !( X_UA.IE < 9 || X_UA.iOS ) && function(){
+ X_Dom_detectFontSize = !( X_UA[ 'IE' ] < 9 || X_UA[ 'iOS' ] ) && function(){
var size = X_Node_fontSizeNode._rawObject.offsetHeight;
if( X_ViewPort_baseFontSize !== size ){
- X_ViewPort_baseFontSize && X_ViewPort.asyncDispatch( X.Event.BASE_FONT_RESIZED );
+ X_ViewPort_baseFontSize && X_ViewPort.asyncDispatch( X_Event.BASE_FONT_RESIZED );
X_ViewPort_baseFontSize = size;
};
},
X_ViewPort_orientationFlag,
X_Dom_orientationchange = window[ 'orientation' ] !== undefined && function( e ){
X_ViewPort_orientationFlag = true;
- !X_UA.Android && X_ViewPort_resize();
+ !X_UA[ 'Android' ] && X_ViewPort_resize();
//console.log( '-- orientationchange : ' + X.ViewPort.getSize[ 0 ] + ' ' + X.ViewPort.getSize[ 1 ] );
},
href = e.target && e.target.attr && e.target.attr( 'href' );
if( href && href.indexOf && href.indexOf( 'javascript:' ) === 0 ) return X.Callback.PREVENT_DEFAULT | X.Callback.STOP_PROPAGATION;
- return X_ViewPort.dispatch( X.Event.BEFORE_UNLOAD );
+ return X_ViewPort.dispatch( X_Event.BEFORE_UNLOAD );
case 'unload' :
- X_ViewPort.dispatch( X.Event.UNLOAD );
+ X_ViewPort.dispatch( X_Event.UNLOAD );
//alert('unload');
X_ViewPort_document.kill();
this.kill();
- //X_System.dispatch( X.Event.SHUT_DOWN );
+ //X_System.dispatch( X_Event.SHUT_DOWN );
break;
case 'visibilitychange' :
- X_ViewPort.dispatch( ( X_ViewPort_active = document[ 'hidden' ] ) ? X.Event.VIEW_DEACTIVATE : X.Event.VIEW_ACTIVATE );
+ X_ViewPort.dispatch( ( X_ViewPort_active = document[ 'hidden' ] ) ? X_Event.VIEW_DEACTIVATE : X_Event.VIEW_ACTIVATE );
break;
case 'mozvisibilitychange' :
- X_ViewPort.dispatch( ( X_ViewPort_active = document[ 'mozHidden' ] ) ? X.Event.VIEW_DEACTIVATE : X.Event.VIEW_ACTIVATE );
+ X_ViewPort.dispatch( ( X_ViewPort_active = document[ 'mozHidden' ] ) ? X_Event.VIEW_DEACTIVATE : X_Event.VIEW_ACTIVATE );
break;
case 'webkitvisibilitychange' :
- X_ViewPort.dispatch( ( X_ViewPort_active = document[ 'webkitHidden' ] ) ? X.Event.VIEW_DEACTIVATE : X.Event.VIEW_ACTIVATE );
+ X_ViewPort.dispatch( ( X_ViewPort_active = document[ 'webkitHidden' ] ) ? X_Event.VIEW_DEACTIVATE : X_Event.VIEW_ACTIVATE );
break;
case 'pageshow' :
case 'focus' :
if( !X_ViewPort_active ){
X_ViewPort_active = true;
- X_ViewPort.dispatch( X.Event.VIEW_ACTIVATE );
+ X_ViewPort.dispatch( X_Event.VIEW_ACTIVATE );
};
break;
case 'blur' :
if( X_ViewPort_active ){
X_ViewPort_active = false;
- X_ViewPort.dispatch( X.Event.VIEW_DEACTIVATE );
+ X_ViewPort.dispatch( X_Event.VIEW_DEACTIVATE );
};
break;
};
);
+/**
+ * window に相当する ViewPort 情報を提供するオブジェクト。
+ * @namespace X.ViewPort
+ * @alias X.ViewPort
+ */
X.ViewPort = {
listen : function( type, arg1, arg2, arg3 ){
if( type <= X_ViewPort_readyState ){
/*
- * X.Event.XDOM_READY 以後に listen した場合の対策
+ * X_Event.XDOM_READY 以後に listen した場合の対策
*/
X_ViewPort.asyncDispatch( type );
};
},
- /* 要素が視界に入った http://remysharp.com/2009/01/26/element-in-view-event-plugin/ */
+ /* 要素が視界に入った http://remysharp.com/2009/01/26/element-in-view-event-plugin/
+ * TODO -> Node.call('inView')
+ */
inView : function( elm ){
},
// Safari2.0.4では標準・互換どちらも document.body
X_Node_updateTimerID && X_Node_startUpdate();
- /*X_UA.Opera ?
+ /*X_UA[ 'Opera' ] ?
( document.documentElement && document.documentElement.clientWidth ?
new Function( 'return[document.documentElement.clientWidth,document.documentElement.clientHeight]' ) :
new Function( 'return[document.body.clientWidth,document.body.clientHeight]' )
*/
var X_ViewPort_resize =
// iOS もループで回す,,,iOS3.1.3, iOS6 で確認
- X_UA.IE < 9 || X_UA.iOS ?
+ X_UA[ 'IE' ] < 9 || X_UA[ 'iOS' ] ?
(function(){
var size;
if( !X_ViewPort_lock ){
size = X_Node_fontSizeNode._rawObject.offsetHeight;
if( X_ViewPort_baseFontSize !== size ){
- X_ViewPort_baseFontSize && X_ViewPort.asyncDispatch( X.Event.BASE_FONT_RESIZED );
+ X_ViewPort_baseFontSize && X_ViewPort.asyncDispatch( X_Event.BASE_FONT_RESIZED );
X_ViewPort_baseFontSize = size;
};
} else {
console.log( '-- detectFinishResizing : ' + X_Timer_now() );
- X_ViewPort.asyncDispatch( X.Event.VIEW_RESIZED );
+ X_ViewPort.asyncDispatch( X_Event.VIEW_RESIZED );
X_ViewPort_lock = false;
if( X_ViewPort_orientationFlag ){
X_ViewPort_orientationFlag = false;
- X_ViewPort.asyncDispatch( 100, { type : X.Event.VIEW_TURNED, orientation : window.orientation } );
+ X_ViewPort.asyncDispatch( 100, { type : X_Event.VIEW_TURNED, orientation : window.orientation } );
};
};
};
X_ViewPort.listenOnce( X_TEMP.SYSTEM_EVENT_XTREE, function(){
X_ViewPort_readyState = X_TEMP.SYSTEM_EVENT_INIT;
- //X_UA.Opera7 && alert( 'bc' );
+ //X_UA[ 'Opera7' ] && alert( 'bc' );
X_Node_body.appendAt( 0,
X_Node_systemNode = X_Doc_create( 'div', { 'class' : 'hidden-system-node' } ),
X_Node_fontSizeNode = X_Doc_create( 'div', { 'class' : 'hidden-system-node' } ).cssText( 'line-height:1;height:1em;' ).text( 'X' )
X_ViewPort_baseFontSize = X_Node_fontSizeNode._rawObject.offsetHeight;
- X_ViewPort_readyState = X.Event.XDOM_READY;
- X_ViewPort.asyncDispatch( { type : X.Event.XDOM_READY, w : X_ViewPort_width = size[ 0 ], h : X_ViewPort_height = size[ 1 ] } );
+ X_ViewPort_readyState = X_Event.XDOM_READY;
+ X_ViewPort.asyncDispatch( { type : X_Event.XDOM_READY, w : X_ViewPort_width = size[ 0 ], h : X_ViewPort_height = size[ 1 ] } );
} );
X_ViewPort.asyncDispatch( X_TEMP.SYSTEM_EVENT_PRE_INIT );
if( document[ 'webkitHidden' ] !== undefined ){
X_EventDispatcher_systemListen( X_ViewPort_document, 'webkitvisibilitychange', X_ViewPort );
} else
- if( X_UA.iOS && window[ 'onpageshow' ] !== undefined ){
+ if( X_UA[ 'iOS' ] && window[ 'onpageshow' ] !== undefined ){
X_EventDispatcher_systemListen( X_ViewPort, [ 'pageshow', 'pagehide' ] );
} else {
X_EventDispatcher_systemListen( X_ViewPort, [ 'focus', 'blur' ] );
};
function X_ViewPort_getWindowSize(){
- return X_UA.IE ?
+ return X_UA[ 'IE' ] ?
[ X_ViewPort_rootElement.clientWidth, X_ViewPort_rootElement.clientHeight ] :
[ window.innerWidth, window.innerHeight ];
};
if( X_UA_EVENT.W3C ){
X_ViewPort_document.listenOnce( 'DOMContentLoaded', X_TEMP.onDomContentLoaded );
} else
-if( 6 <= X_UA.IE && X.inHead ){
+if( 6 <= X_UA[ 'IE' ] && X.inHead ){
// if this script in Head
document.write( "<script id=__ie_onload defer src=javascript:void(0)><\/script>" );
X_TEMP._script = document.getElementById( "__ie_onload" );
};
// Re: onLoad doesn't work with Safari?
// http://lists.apple.com/archives/web-dev/2003/Oct/msg00036.html
-if( X_UA.WebKit || X_UA.Safari < 3 ){ // sniff
+if( X_UA[ 'WebKit' ] || X_UA[ 'Safari' ] < 3 ){ // sniff
X.Timer.add( 16, function(){
if( !X_TEMP.onDomContentLoaded ) return X_Callback_UN_LISTEN;
if( document.readyState === 'loaded' || document.readyState === 'complete' ) return X_TEMP.onDomContentLoaded();
+/**\r
+ * @namespace X.Logger\r
+ * @alias X.Logger\r
+ */\r
X.Logger = {\r
_$LogArea : null,\r
debug : function( msg ){\r
},\r
_output : function( msg, level ){\r
var body, $Area;\r
- if( X.Event.XDOM_READY <= X_ViewPort_readyState ){\r
+ if( X_Event.XDOM_READY <= X_ViewPort_readyState ){\r
if( $Area = X.Logger._$LogArea ){\r
$Area.remove();\r
delete X.Logger._$LogArea;\r
\r
\r
} else\r
- if( X.Event.XDOM_READY <= X_ViewPort_readyState ){\r
+ if( X_Event.XDOM_READY <= X_ViewPort_readyState ){\r
if( !( $Area = X.Logger._$LogArea ) ){\r
$Area = X.Logger._$LogArea = X.Node( 'div' ).addToRoot( 0 );\r
};\r
-
-
+/**
+ * document をラップする
+ * @namespace X.Doc
+ * @alias X.Doc
+ */
X.Doc = {
listen : function( type, arg1, arg2, arg3 ){
if( type <= X_ViewPort_readyState && type === 'DOMContentLoaded' ){
// find
};
+/**
+ * X.Node 要素を作成する。この時点でツリーには追加されない。
+ * @alias X.Doc.create
+ * @param {string} tag タグ名
+ * @param {object} opt_attrs 属性
+ * @param {object} opt_css スタイル
+ * @return {Node}
+ */
function X_Doc_create( tag, opt_attrs, opt_css ){
var list, i;
switch( X_Node_getType( tag ) ){
};
};
+/**
+ * X.Node テキストを作成する。この時点でツリーには追加されない。
+ * @alias X.Doc.createText
+ * @param {string} textContent
+ * @return {Node}
+ */
function X_Doc_createText( text ){
X_Node_newByText = true;
return new Node( text );
* TODO html5 要素, audio, video は?\r
*/ \r
X_Dom_DTD_TAG_FIX =\r
- X_UA.IE4 ?\r
+ X_UA[ 'IE4' ] ?\r
{ ABBR : 'ACRONYM', BDO : '', RUBY : '' } :\r
- X_UA.IE5 || X_UA.IE55 || X_UA.IE6 ?\r
+ X_UA[ 'IE5x' ] || X_UA[ 'IE6' ] ?\r
{ ABBR : 'ACRONYM' } :\r
{},\r
\r
DIRTY_CLASSNAME : 2 << 13, // X_Node_CSS_getCharSize, width, height, x, y\r
DIRTY_ATTR : 2 << 14, // X_Node_CSS_getCharSize, width, height, x, y\r
DIRTY_CSS : 2 << 15, // X_Node_CSS_getCharSize, width, height, x, y\r
- DIRTY_IE_FILTER : X_UA.IE < 10 && X_UA.ActiveX ? 2 << 16 : 0, // \r
+ DIRTY_IE_FILTER : X_UA[ 'IE' ] < 10 && X_UA[ 'ActiveX' ] ? 2 << 16 : 0, // \r
\r
ACTUAL_LISTENING : 2 << 17,\r
OLD_ATTRTEXT : 2 << 18,\r
GPU_RELEASE_RESERVED : 2 << 23, // 4:GPU解除予約\r
GPU_CHILD : 2 << 24, \r
\r
- IE4_HAS_TEXTNODE : X_UA.IE4 ? 2 << 21 : 0,\r
- IE4_HAS_ELEMENT : X_UA.IE4 ? 2 << 22 : 0,\r
- IE4_DIRTY_CHILDREN : X_UA.IE4 ? 2 << 23 : 0,\r
- IE4_FIXED : X_UA.IE4 ? 2 << 24 : 0,\r
+ IE4_HAS_TEXTNODE : X_UA[ 'IE4' ] ? 2 << 21 : 0,\r
+ IE4_HAS_ELEMENT : X_UA[ 'IE4' ] ? 2 << 22 : 0,\r
+ IE4_DIRTY_CHILDREN : X_UA[ 'IE4' ] ? 2 << 23 : 0,\r
+ IE4_FIXED : X_UA[ 'IE4' ] ? 2 << 24 : 0,\r
\r
- IE5_DISPLAY_NONE_FIX : X_UA.IE5 && X_UA.ActiveX ? 2 << 24 : 0\r
+ IE5_DISPLAY_NONE_FIX : X_UA[ 'IE5' ] && X_UA[ 'ActiveX' ] ? 2 << 24 : 0\r
},\r
\r
X_Node_BITMASK_RESET_STYLE = ( ( 2 << 29 ) - 1 + ( 2 << 29 ) ) ^ (\r
IMAGE : 10\r
},\r
\r
- X_Node_strictElmCreation = !X_UA.MacIE && X_UA.IE5678,// && !X_UA.MacIE;\r
+ X_Node_strictElmCreation = !X_UA[ 'MacIE' ] && X_UA[ 'IE' ] <= 8,\r
\r
- X_Node_documentFragment = document.createDocumentFragment && ( !X_UA.IE || 5.5 <= X_UA.IE ) && document.createDocumentFragment(),\r
+ X_Node_documentFragment = document.createDocumentFragment && ( !X_UA[ 'IE' ] || 5.5 <= X_UA[ 'IE' ] ) && document.createDocumentFragment(),\r
\r
// 子の生成後に リアル文書 tree に追加する\r
- X_Node_addTreeAfterChildren = !( X.UA.IE < 9 ),\r
+ X_Node_addTreeAfterChildren = !( X_UA[ 'IE' ] < 9 ),\r
\r
X_Node_displayNoneFixForIE5 = !!X_Node_State.IE5_DISPLAY_NONE_FIX,\r
\r
\r
X_Node_outerXNode = null,\r
\r
- X_Node_updateTimerID = 0,\r
-/*\r
+ X_Node_updateTimerID = 0;\r
+\r
+/**\r
* Node( rawElement | rawTextnode | htmlString | textString )\r
- */ \r
- Node = X.Node = X.EventDispatcher.inherits(\r
- 'XDomNode',\r
+ * \r
+ * @alias X.Node\r
+ * @class Node HTMLElement、TextNode をラップし jQuery 風な API で操作できます。\r
+ * @constructor \r
+ * @constructs Node\r
+ * @extends {EventDispatcher}\r
+ */\r
+var Node = X.Node = X.EventDispatcher.inherits(\r
+ 'X.Node',\r
X.Class.POOL_OBJECT, // X.Class.FINAL\r
{\r
_uid : 0,\r
length : 1,\r
parent : null, // remove された枝も親子構造は維持している。\r
_xnodes : null, // Array.<Node>\r
- _gpuParent : null,\r
+ _gpuParent : null, // TODO\r
\r
_tag : '',\r
_text : '',\r
this._tag = v.toUpperCase();\r
arguments[ 1 ] && this.attr( arguments[ 1 ] );\r
css = arguments[ 2 ];\r
- css && this[ X.Type.isString( css ) ? 'cssText' : 'css' ]( css );\r
+ css && this[ X_Type_isString( css ) ? 'cssText' : 'css' ]( css );\r
} else\r
if( X_Node_newByText ){\r
X_Node_newByText = false;\r
this._text = v;\r
} else {\r
if( 1 < arguments.length ) return new X_NodeList( arguments );\r
- if( X.Type.isArray( v ) && v.length ) return new X_NodeList( v );\r
+ if( X_Type_isArray( v ) && v.length ) return new X_NodeList( v );\r
\r
switch( X_Node_getType( v ) ){\r
case X_Node_TYPE.XNODE :\r
if( v === document ) return X_Node_TYPE.DOCUMENT;\r
if( v.constructor === Node ) return X_Node_TYPE.XNODE;\r
if( v.constructor === X_NodeList ) return X_Node_TYPE.XNODE_LIST;\r
- if( X.Type.isHTMLElement( v ) ) return X_Node_TYPE.RAW_HTML;\r
+ if( X_Type_isHTMLElement( v ) ) return X_Node_TYPE.RAW_HTML;\r
if( v.nodeType === 3 ) return X_Node_TYPE.RAW_TEXT;\r
- if( X.Type.isString( v ) ){\r
+ if( X_Type_isString( v ) ){\r
return '<' === v.charAt( 0 ) && v.charAt( v.length - 1 ) === '>' ? X_Node_TYPE.HTML_STRING : X_Node_TYPE.STRING;\r
};\r
return 0;\r
X_UA_DOM.IE4 ?\r
X.emptyFunction :\r
(function( root ){\r
- if( X.Type.isBoolean( root.isXML ) ) return root.isXML;\r
+ if( X_Type_isBoolean( root.isXML ) ) return root.isXML;\r
return root.isXML = root._rawObject.createElement( 'p' ).tagName !== root._rawObject.createElement( 'P' ).tagName;\r
}),\r
X_Node_CHASHE = [],\r
// 親の xnodes から v を消す\r
v.parent && v.remove();\r
// IE4 でテキストノードの追加、FIXED 済でない場合、親に要素の追加を通知\r
- if( X_UA.IE4 && !v._tag && ( this._flags & X_Node_State.IE4_FIXED ) === 0 ) this._flags |= X_Node_State.IE4_DIRTY_CHILDREN;\r
+ if( X_UA[ 'IE4' ] && !v._tag && ( this._flags & X_Node_State.IE4_FIXED ) === 0 ) this._flags |= X_Node_State.IE4_DIRTY_CHILDREN;\r
break;\r
default :\r
return this;\r
// 親の xnodes から v を消す\r
v.parent && v.remove();\r
// IE4 でテキストノードの追加、FIXED 済でない場合、親に要素の追加を通知\r
- if( X_UA.IE4 && !v._tag && ( this._flags & X_Node_State.IE4_FIXED ) === 0 ) this._flags |= X_Node_State.IE4_DIRTY_CHILDREN;\r
+ if( X_UA[ 'IE4' ] && !v._tag && ( this._flags & X_Node_State.IE4_FIXED ) === 0 ) this._flags |= X_Node_State.IE4_DIRTY_CHILDREN;\r
break;\r
default :\r
return this;\r
\r
// setter\r
if( this._className === v ) return this;\r
- if( !v || !X.Type.isString( v ) ){\r
+ if( !v || !X_Type_isString( v ) ){\r
delete this._className;\r
} else {\r
// cleanup\r
};\r
\r
func = raw[ name ];\r
- if( X.Type.isFunction( func ) ){\r
+ if( X_Type_isFunction( func ) ){\r
if( l ){\r
args = X_Object_cloneArray( arguments );\r
args.shift();\r
};\r
return raw[ name ](); \r
} else\r
- if( X.Type.isUnknown( func ) ){\r
+ if( X_Type_isUnknown( func ) ){\r
// typeof func === unknown に対策\r
// http://la.ma.la/blog/diary_200509031529.htm \r
if( l ){\r
\r
if( time ){\r
// X.Timer 経由でないと発火しない このイベントでサイズを取ると無限ループに\r
- X_System._listeners && X_System._listeners[ X.Event.BEFORE_UPDATE ] && X_System.dispatch( X.Event.BEFORE_UPDATE );\r
+ X_System._listeners && X_System._listeners[ X_Event.BEFORE_UPDATE ] && X_System.dispatch( X_Event.BEFORE_UPDATE );\r
};\r
\r
removal = X_Node_reserveRemoval;\r
\r
if( time ){\r
// X.Timer 経由でないと発火しない このイベントでサイズを取ると無限ループに\r
- X_System._listeners && X_System._listeners[ X.Event.UPDATED ] && X_System.dispatch( X.Event.UPDATED ); \r
+ X_System._listeners && X_System._listeners[ X_Event.UPDATED ] && X_System.dispatch( X_Event.UPDATED ); \r
};\r
\r
- X_ViewPort._listeners && X_ViewPort._listeners[ X.Event.AFTER_UPDATE ] && X_ViewPort.asyncDispatch( X.Event.AFTER_UPDATE );\r
+ X_ViewPort._listeners && X_ViewPort._listeners[ X_Event.AFTER_UPDATE ] && X_ViewPort.asyncDispatch( X_Event.AFTER_UPDATE );\r
};\r
\r
/*\r
if( !that._tag ){\r
that._flags &= X_Node_BitMask_RESET_DIRTY;\r
that._rawObject = elm = document.createTextNode( X_String_chrReferanceTo( that._text ) );\r
- if( !X.UA.IE ){\r
+ if( !X_UA[ 'IE' ] ){\r
elm.UID = that._uid;\r
};\r
} else\r
\r
// http://outcloud.blogspot.jp/2010/09/iframe.html\r
// この問題は firefox3.6 で確認\r
- if( X_UA.Gecko ){\r
+ if( X_UA[ 'Gecko' ] ){\r
if( that._tag === 'IFRAME' && ( !that._attrs || !that._attrs[ 'src' ] ) ){\r
//elm.contentWindow.location.replace = elm.src = 'about:blank';\r
that.attr( 'src', 'about:blank' );\r
parentElement.insertBefore( elm, nextElement ) :\r
parentElement.appendChild( elm );\r
\r
- if( X_UA.Gecko && that._tag === 'IFRAME' && elm.contentWindow ){\r
+ if( X_UA[ 'Gecko' ] && that._tag === 'IFRAME' && elm.contentWindow ){\r
// tree に追加されるまで contentWindow は存在しない。\r
elm.contentWindow.location.replace = elm.src;\r
};\r
};\r
// className\r
if( that._flags & X_Node_State.DIRTY_CLASSNAME ){\r
- that._className ? ( elm.className = that._className ) : ( elm.className && elm.removeAttribute( X_UA.IE < 8 ? 'className' : 'class' ) ); // className は ie7- \r
+ that._className ? ( elm.className = that._className ) : ( elm.className && elm.removeAttribute( X_UA[ 'IE' ] < 8 ? 'className' : 'class' ) ); // className は ie7- \r
};\r
\r
// attr\r
switch( that._tag + k ){\r
case 'TEXTAREAvalue' :\r
// IETester 5.5 ではエラーが出なかった.MultipulIE5.5 ではエラーが出たので\r
- if( !X_UA.MacIE && X_UA.IE5x ){\r
+ if( !X_UA[ 'MacIE' ] && X_UA[ 'IE5x' ] ){\r
elm.firstChild ?\r
( elm.firstChild.data = v || '' ) :\r
elm.appendChild( document.createTextNode( v || '' ) );\r
case 'IFRAMEsrc' :\r
// http://outcloud.blogspot.jp/2010/09/iframe.html\r
// この問題は firefox3.6 で確認\r
- if( X_UA.Gecko && elm.contentWindow ){\r
+ if( X_UA[ 'Gecko' ] && elm.contentWindow ){\r
elm.contentWindow.location.replace = elm.src = v || '';\r
continue;\r
};\r
// http://d.hatena.ne.jp/NeoCat/20080921/1221940658\r
// こちらに名前をsetしないとtargetが動作しない\r
// これってあとから name を変更できないバグでは? itozyun\r
- // if( X_UA.IE ) elm.name = elm.contentWindow.name = v || '';\r
+ // if( X_UA[ 'IE' ] ) elm.name = elm.contentWindow.name = v || '';\r
};\r
\r
//if( X_EMPTY_OBJECT[ k ] ) continue;\r
// style\r
if( that._flags & X_Node_State.DIRTY_CSS ){\r
if( that._flags & X_Node_State.OLD_CSSTEXT ? X_Node_CSS_objToCssText( that ) : that._cssText ){\r
- X_UA.Opera78 || X_UA.NN6 ?\r
+ X_UA[ 'Opera78' ] || X_UA[ 'NN6' ] ?\r
elm.setAttribute( 'style', that._cssText ) : // opera8用\r
( elm.style.cssText = that._cssText );\r
} else {\r
};\r
};\r
\r
- if( !X_UA.MacIE ){\r
+ if( !X_UA[ 'MacIE' ] ){\r
// elm.parentNode.tagName for ie7\r
!isChild && elm.parentNode && elm.parentNode.tagName && elm.parentNode.removeChild( elm );\r
} else {\r
}) :\r
(function(){});\r
\r
-X_ViewPort.listenOnce( X.Event.UNLOAD, X_Node__actualRemove, [ X_Node_html, true ] );\r
+X_ViewPort.listenOnce( X_Event.UNLOAD, X_Node__actualRemove, [ X_Node_html, true ] );\r
\r
'4' : 'mouse'\r
}; */\r
\r
-if( !X_UA.IE || 9 <= X_UA.IE ){\r
+if( !X_UA[ 'IE' ] || 9 <= X_UA[ 'IE' ] ){\r
X.Dom.Event = function( e, xnode ){\r
var originalType = e.type,\r
type, pointerEventType,\r
\r
// http://www.programming-magic.com/20090127231544/\r
// Opera で button==2の場合、コンテキストメニューイベントを発火 「ツール」->「設定」->「詳細設定」->「コンテンツ」->「Javascriptオプション」で「右クリックを制御するスクリプトを許可する」\r
- if( originalType === 'mousedown' && this.button === 2 && X_UA.Opera ){\r
+ if( originalType === 'mousedown' && this.button === 2 && X_UA[ 'Opera' ] ){\r
events = [ X.Object.clone( this ), X.Object.clone( this ) ];\r
events[ 1 ].type = 'contextmenu';\r
return events;\r
//event.pageY = DOMAssistant.def(e.pageY)? e.pageY : (event.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0)); \r
//};\r
\r
- if( 5 <= X_UA.IE ){\r
+ if( 5 <= X_UA[ 'IE' ] ){\r
this.offsetX = e.offsetX; // イベントターゲット左上からの座標\r
this.offsetY = e.offsetY; \r
}// else\r
//\r
if( document.onwheel === undefined ){\r
// DOMMoseScroll\r
- if( X_UA.Gecko && window.MouseScrollEvent ){\r
- if( 2 <= X_UA.Gecko || ( 1.9 <= X_UA.Gecko && 1 <= X_UA.GeckoPatch ) ){ // Gecko 1.9.1+ (firefox3.5+)\r
+ if( X_UA[ 'Gecko' ] && window.MouseScrollEvent ){\r
+ if( 2 <= X_UA[ 'Gecko' ] || ( 1.9 <= X_UA[ 'Gecko' ] && 1 <= X_UA[ 'GeckoPatch' ] ) ){ // Gecko 1.9.1+ (firefox3.5+)\r
console.log( 'wheel <= MozMousePixelScroll' );\r
X_Event_Rename[ 'wheel' ] = 'MozMousePixelScroll';\r
} else\r
- if( 1 <= X_UA.Gecko || ( 0.9 <= X_UA.Gecko && 7 <= X_UA.GeckoPatch ) ){ // Gecko 0.9.7+ (NN6.2+?)\r
+ if( 1 <= X_UA[ 'Gecko' ] || ( 0.9 <= X_UA[ 'Gecko' ] && 7 <= X_UA[ 'GeckoPatch' ] ) ){ // Gecko 0.9.7+ (NN6.2+?)\r
console.log( 'wheel <= DOMMouseScroll' );\r
X_Event_Rename[ 'wheel' ] = 'DOMMouseScroll';\r
};\r
X_Event_Rename[ 'transitionend' ] = 'webkitTransitionEnd';\r
} else\r
if( window.onotransitionend !== undefined && window.ontransitionend === undefined ){\r
- if( X_UA.Opera < 12 ){\r
- console.log( 'transitionend <= oTransitionEnd|ver.' + X_UA.Opera );\r
+ if( X_UA[ 'Opera' ] < 12 ){\r
+ console.log( 'transitionend <= oTransitionEnd|ver.' + X_UA[ 'Opera' ] );\r
X_Event_Rename[ 'transitionend' ] = 'oTransitionEnd';\r
} else {\r
- console.log( 'transitionend <= otransitionEnd|ver.' + X_UA.Opera );\r
+ console.log( 'transitionend <= otransitionEnd|ver.' + X_UA[ 'Opera' ] );\r
X_Event_Rename[ 'transitionend' ] = 'otransitionEnd';\r
};\r
} else\r
X_Event_Rename[ 'pointercancel' ] = 'mouseleave';//??\r
\r
// Opera は ブラウザ設定から右クリックの通知を許可すると mousedown で e.button==2 が返る,キャンセルは可能??\r
- X_UA.Opera && (\r
+ X_UA[ 'Opera' ] && (\r
X_Event_Rename[ 'contextmenu' ] = 'mousedown' );\r
\r
/*\r
return { x:(pos.left + (body.scrollLeft||html.scrollLeft) - html.clientLeft)\r
, y:(pos.top + (body.scrollTop||html.scrollTop) - html.clientTop) };\r
} :\r
- X.UA.Opera < 10 ?\r
+ X_UA[ 'Opera' ] < 10 ?\r
function( el ){\r
var ex = 0;\r
var ey = 0;\r
\r
if( !this._tag ) return this;\r
\r
- if( nameOrObj && X.Type.isObject( nameOrObj ) ){\r
+ if( nameOrObj && X_Type_isObject( nameOrObj ) ){\r
attrs || ( attrs = this._attrs = {} );\r
newAttrs = this._newAttrs || ( this._newAttrs = {} );\r
\r
// kquery.js : safariのバグ対策\r
// if ($.browser.safari && key === "selected" && tmp) tmp.selectedIndex;\r
// 親ノードの selectedIndex の getter を呼んでおくと値が正しくなる、ということ?( by itozyun )\r
- if( X_UA.WebKit ) this._rawObject.parentNode && this._rawObject.parentNode.selectedIndex;\r
+ if( X_UA[ 'WebKit' ] ) this._rawObject.parentNode && this._rawObject.parentNode.selectedIndex;\r
case 'value' :\r
if( this._tag === 'INPUT' && X_Node_Attr_STATIC_VALUE_TYPES[ attrs[ 'type' ] ] ) break;\r
case 'checked' :\r
*/
X_Node_CSS_VENDER_PREFIX = {},
-X_Node_CSS__CLIP_SEPARATOR = X_UA.IE < 8 ? ' ' : ',',
+X_Node_CSS__CLIP_SEPARATOR = X_UA[ 'IE' ] < 8 ? ' ' : ',',
X_Node_CSS__UNIT_RATIO = {},
X_Node_CSS__FONT_SIZE_RATIO = {},
function X_Node_CSS_parseColor( x ){
var rgb, r, g, b;
- if( X.Type.isNumber( x ) ){
+ if( X_Type_isNumber( x ) ){
return ( 0x0 <= x && x <= 0xFFFFFF ) ? x : undefined;
} else
- if( !X.Type.isString( x ) ) return;
+ if( !X_Type_isString( x ) ) return;
- if( X.Type.isNumber( rgb = X_Node_CSS_COLOR[ x.toUpperCase() ] ) && 0x0 <= rgb && rgb <= 0xFFFFFF ){
+ if( X_Type_isNumber( rgb = X_Node_CSS_COLOR[ x.toUpperCase() ] ) && 0x0 <= rgb && rgb <= 0xFFFFFF ){
return rgb;
} else
if( x.charAt( 0 ) === '#' ){
var
X_Node_CSS_FILTER_FIX_PROPS =
- X_UA.ActiveX && X_UA.IE < 9 && !X_UA.MacIE ?
+ X_UA[ 'ActiveX' ] && X_UA[ 'IE' ] < 9 && !X_UA[ 'MacIE' ] ?
{
opacity : 2,
boxShadow : 3,
textShadow : 4,
transform : 5
} :
- X_UA.ActiveX && X_UA.IE9 ? // == 9
+ X_UA[ 'ActiveX' ] && X_UA[ 'IE9' ] ? // == 9
{
textShadow : 4
} :
*/
function X_Node_CSS__splitValueAndUnit( v ){
var num, _num, u;
- if( X.Type.isNumber( v ) ) return [ v || 0, '' ];
+ if( X_Type_isNumber( v ) ) return [ v || 0, '' ];
num = parseFloat( v );
if( num !== num ) return [ 0, '' ];
_num = '' + num;
p, name, v, plain, camelize, flags;
if( !this._tag || X_Dom_DTD_MOVE_TO_HEAD[ this._tag ] || this._tag === 'SCRIPT' ) return this;
// setter:object
- if( X.Type.isObject( nameOrObj ) ){
+ if( X_Type_isObject( nameOrObj ) ){
if( !css ) css = this._css = {};
plain = X_EMPTY_OBJECT;
camelize = X_Node_CSS_camelize;
this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();
return this;
} else
- if( X.Type.isString( v ) ){
+ if( X_Type_isString( v ) ){
delete this._css;
obj = {};
v = v.split( ';' ); // TODO content ";" などにも対応 <- 不要 :before :after 疑似要素には触らない
return that._fontSize = parseFloat( X_node_CSS_getComputedStyle( that._rawObject, null ).fontSize );
}) :
- 5 <= X_UA.IE ?
+ 5 <= X_UA[ 'IE' ] ?
(function( that ){
var font, vu, v, u, _v;
X_Node_updateTimerID && X_Node_startUpdate();
X_Node_CSS_SPECIAL_FIX_PROP = {
- transitionDuration : X_UA.Android && !X_UA.Chrome && function( v ){ // bad Android
+ transitionDuration : X_UA[ 'Android' ] && !X_UA[ 'Chrome' ] && function( v ){ // bad Android
return parseFloat( v ) === 0 ? '0.001s' : v;
}
*/
(function(){
- var testStyle = X_UA.IE4 ? {} : ( /*document.documentElement ||*/ document.createElement( 'div' ) ).style,
+ var testStyle = X_UA[ 'IE4' ] ? {} : ( /*document.documentElement ||*/ document.createElement( 'div' ) ).style,
temp = testStyle.cssText,
vendors = 'webkit,Webkit,Moz,moz,Ms,ms,O,o,khtml,Khtml'.split( ',' ),
searches = (
for( p in src ){\r
//if( X_EMPTY_OBJECT[ p ] ) continue;\r
v = src[ p ];\r
- if( X.Type.isFunction( v ) && !target[ p ] ){\r
+ if( X_Type_isFunction( v ) && !target[ p ] ){\r
target[ p ] = multi = new Function( [\r
'var a=arguments,f=X.Node.prototype.', p, ',t=this,i,l=t.length;',\r
'if(l)',\r
links, className, attr, flag;\r
\r
/*@+debug[*/\r
- if( X_ViewPort_readyState < X.Event.XDOM_READY ){\r
- alert( 'not ready! use X.ViewPort.listenOnce( X.Event.XDOM_READY, callback )' );\r
+ if( X_ViewPort_readyState < X_Event.XDOM_READY ){\r
+ alert( 'not ready! use X.ViewPort.listenOnce( X_Event.XDOM_READY, callback )' );\r
return;\r
};\r
/*]@+debug*/\r
// 諦めて、funcAttrを呼ぶ\r
// flag_call = ($.browser.safari && key === 'selected');\r
// getAttributeを使わない\r
- useName = X_UA.IE && key !== 'href' && key !== 'src';\r
+ useName = X_UA[ 'IE' ] && key !== 'href' && key !== 'src';\r
toLower = !!val && !isXML && noLower.indexOf( key ) === -1; //!noLower.test(key);\r
if( toLower ) val = val.toLowerCase();\r
if( op === 3 ) val = _ + val + _;\r
_attrs = {};\r
for( ; i; ){\r
if( attr = attrs[ --i ] ){\r
- if( X.Type.isString( attr ) ){\r
+ if( X_Type_isString( attr ) ){\r
name = attr;\r
_attrs[ name ] = true;\r
} else {\r
var X_HTMLParser_asyncHtmlStringToXNode = {\r
err : function( html ){\r
X_HTMLParser_htmlStringToXNode.err( html );\r
- this.asyncDispatch( X.Event.ERROR );\r
+ this.asyncDispatch( X_Event.ERROR );\r
},\r
start : X_HTMLParser_htmlStringToXNode.start,\r
end : X_HTMLParser_htmlStringToXNode.end,\r
comment : X.emptyFunction,\r
\r
progress : function( pct ){\r
- this.asyncDispatch( { type : X.Event.PROGRESS, percent : pct } );\r
+ this.asyncDispatch( { type : X_Event.PROGRESS, percent : pct } );\r
},\r
complete : function(){\r
var ret = X_HTMLParser_htmlStringToXNode.flat;\r
delete X_HTMLParser_htmlStringToXNode.flat;\r
- this.asyncDispatch( { type : X.Event.SUCCESS, xnodes : ret } );\r
+ this.asyncDispatch( { type : X_Event.SUCCESS, xnodes : ret } );\r
}\r
};\r
\r
function X_HTMLParser_asyncParse( html, ignoreError ){\r
var dispatcher = X_Class_override( new X.EventDispatcher(), X_HTMLParser_asyncHtmlStringToXNode ),\r
worker = X_HTMLParser_htmlStringToXNode;\r
- dispatcher.listenOnce( X.Event.SUCCESS, dispatcher, dispatcher.kill );\r
+ dispatcher.listenOnce( X_Event.SUCCESS, dispatcher, dispatcher.kill );\r
worker.flat = [];\r
worker.nest.length = 0;\r
worker.ignoreError = ignoreError;\r
X_Node_Anime_hasTransform = !!X_Node_CSS_VENDER_PREFIX[ 'transform' ],\r
/* Opera mobile で translateZ(0) が有効だと XY が 0 0 になる */\r
/* GPUレイヤーにいる間に要素のコンテンツを変更をすると transitionend が動かなくなるっぽい Mac safari と firefox, 手当てが済むまでここは常に false */\r
- X_Node_Anime_translateZ = X_Node_CSS_VENDER_PREFIX[ 'perspective' ] && !X_UA.OperaMobile && !X_UA.OperaTablet ? ' translateZ(0)' : '',\r
+ X_Node_Anime_translateZ = X_Node_CSS_VENDER_PREFIX[ 'perspective' ] && !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] ? ' translateZ(0)' : '',\r
/* Opera12(XP,8.1) 切った方がスムース, win Safari3 で、たまに動作が止まってしまう、、、 */\r
- X_Node_Anime_hasTransition = !!X_Node_CSS_VENDER_PREFIX[ 'transitionDelay' ] && !X_UA.Opera && !( X_UA.Webkit <= 528.16 ),\r
+ X_Node_Anime_hasTransition = !!X_Node_CSS_VENDER_PREFIX[ 'transitionDelay' ] && !X_UA[ 'Opera' ] && !( X_UA[ 'Webkit' ] <= 528.16 ),\r
X_Node_Anime_transitionProps = X_Node_Anime_hasTransform ? X_Node_CSS_VENDER_PREFIX[ 'transform' ] : 'left,top',\r
// transitionEnd イベント中に要素の更新( X_Node_startUpdate() )ができるか?\r
// iOS3+4 では可能、iOS6.1.5 で不可。TODO iOS5 及び他の環境で調査。ダメな場合、anime.html が正しく描画されない。\r
- X_Node_updateOnTransitionEnd = X_UA.iOS < 6,\r
+ X_Node_updateOnTransitionEnd = X_UA[ 'iOS' ] < 6,\r
X_Node_Anime_onTransition = false;\r
\r
// gpu化だけ transformX , willChange\r
var isNew = !this._anime,\r
obj = this._anime || ( this._anime = {} );\r
\r
- obj.duration = 0 <= duration && X.Type.isFinite( duration ) ? duration : 500;\r
+ obj.duration = 0 <= duration && X_Type_isFinite( duration ) ? duration : 500;\r
obj.easing = ease[ easing ] || ease.circular;\r
// 現在 GPUレイヤーのtop になっているか?将来については phase で判定\r
obj.gpuParent = obj.gpuParent || false;\r
obj.phase = duration === 0 ? 9 : obj.phase === 9 ? 9 : 0; //\r
- obj.wait = X.Type.isFinite( wait ) ? wait : 1000;\r
+ obj.wait = X_Type_isFinite( wait ) ? wait : 1000;\r
\r
obj.startTime = X_Timer_now();\r
obj.startX = ( start.x || start.x === 0 ) ? start.x : obj.x || 0;\r
\r
X_Node_Anime_reserveUpdate( true );\r
} else {\r
- X_System.unlisten( X.Event.UPDATED, X_Node_Anime_updateAnimationsNoTransition );\r
+ X_System.unlisten( X_Event.UPDATED, X_Node_Anime_updateAnimationsNoTransition );\r
X_Node_Anime_updateTimerID || ( X_Node_Anime_updateTimerID = X.Timer.requestFrame( X_Node_Anime_updateAnimationsNoTransition ) );\r
\r
- isNew && this.dispatch( { type : X.Event.ANIME_START, gpu : false } );\r
+ isNew && this.dispatch( { type : X_Event.ANIME_START, gpu : false } );\r
};\r
\r
console.log( 'animate ' + this._id + ' y:' + obj.startX + ' > ' + obj.destX + ' d:' + obj.duration );\r
if( X_Node_updateTimerID ){\r
console.log( before ? '> BEFORE_UPDATE' : '> UPDATED' );\r
before = false;\r
- X_System.listenOnce( before ? X.Event.BEFORE_UPDATE : X.Event.UPDATED, X_Node_Anime_updateAnimations );\r
+ X_System.listenOnce( before ? X_Event.BEFORE_UPDATE : X_Event.UPDATED, X_Node_Anime_updateAnimations );\r
} else {\r
console.log( '> Timer' );\r
// Opera12 requestAnimationFrame では transition が動かない、、、\r
X_Node_Anime_updateTimerID =\r
- X_UA.Opera ?\r
+ X_UA[ 'Opera' ] ?\r
X.Timer.once( 0, X_Node_Anime_updateAnimations ) :\r
X.Timer.requestFrame( X_Node_Anime_updateAnimations ); \r
};\r
break;\r
case 0 : // 開始位置+アニメーションの設定 \r
case 8 :\r
- X_ViewPort.unlisten( X.Event.AFTER_UPDATE, xnode, X_Node_Anime_gpuReleased );\r
+ X_ViewPort.unlisten( X_Event.AFTER_UPDATE, xnode, X_Node_Anime_gpuReleased );\r
\r
xnode.css({\r
//willChange : X_Node_Anime_transitionProps + ',opacity,width,height',\r
console.log( '開始位置 ' + phase );\r
X_Node_Anime_updatePosition( xnode, obj.startX, obj.startY, obj.startA, phase === 8 );\r
\r
- xnode.dispatch( { type : X.Event.ANIME_START, gpu : phase === 8 } );\r
+ xnode.dispatch( { type : X_Event.ANIME_START, gpu : phase === 8 } );\r
++obj.phase;\r
break;\r
case 1 :\r
obj.phase = obj.gpuParent ? 10 : 4;\r
// このタイミングで animation 関連の css を削除したところ(X_Node_Anime_clearTransition)、iOS3、4 で再描画忘れが度々起きるように、、、\r
if( !obj.gpuParent ) X_Node_Anime_clearTransition( xnode );\r
- xnode.dispatch( { type : X.Event.ANIME_END, gpu : obj.gpuParent } );\r
+ xnode.dispatch( { type : X_Event.ANIME_END, gpu : obj.gpuParent } );\r
break;\r
\r
case 4 :\r
X_Node_Anime_clearTransition( xnode );\r
X_Node_Anime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, phase === 14 );\r
obj.phase = phase === 14 ? 10 : 4;\r
- xnode.dispatch( { type : X.Event.ANIME_END, gpu : obj.gpuParent } );\r
+ xnode.dispatch( { type : X_Event.ANIME_END, gpu : obj.gpuParent } );\r
} else {\r
current = X_Node_Anime_getComputedPosition( xnode );\r
obj.startX = current.x;\r
X_Node_Anime_clearTransition( xnode );\r
X_Node_Anime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, false );\r
obj.gpuTimerID && X.Timer.remove( obj.gpuTimerID );\r
- X_ViewPort.listenOnce( X.Event.AFTER_UPDATE, xnode, X_Node_Anime_gpuReleased );\r
+ X_ViewPort.listenOnce( X_Event.AFTER_UPDATE, xnode, X_Node_Anime_gpuReleased );\r
return true;\r
\r
case 100 : // stop() : アニメーションを中断して削除\r
console.log( 'トランジション終了' );\r
\r
X_Node_Anime_onTransition = true;\r
- this.dispatch( { type : X.Event.ANIME_END, gpu : this._anime.gpuParent } );\r
+ this.dispatch( { type : X_Event.ANIME_END, gpu : this._anime.gpuParent } );\r
X_Node_Anime_onTransition = false;\r
\r
X_Node_Anime_needsDetection = true;\r
delete this._anime;\r
console.log( 'GPUレイヤーの破棄を指示' );\r
\r
- X_ViewPort.listenOnce( X.Event.AFTER_UPDATE, this, X_Node_Anime_gpuReleased );\r
+ X_ViewPort.listenOnce( X_Event.AFTER_UPDATE, this, X_Node_Anime_gpuReleased );\r
};\r
\r
function X_Node_Anime_gpuReleased(){\r
console.log( 'GPU レイヤーが解放されました' );\r
- this.dispatch( { type : X.Event.GPU_RELEASED, gpu : true } );\r
+ this.dispatch( { type : X_Event.GPU_RELEASED, gpu : true } );\r
};\r
\r
function X_Node_Anime_clearTransition( xnode ){\r
X_Node_ANIMATIONS.splice( i, 1 );\r
\r
// filter な 親が解除されないと子要素への filter が反映されない\r
- xnode.asyncDispatch( { type : X.Event.ANIME_END, gpu : false } );\r
+ xnode.asyncDispatch( { type : X_Event.ANIME_END, gpu : false } );\r
} else {\r
easing = obj.easing.fn( ( now - obj.startTime ) / obj.duration );\r
newX = ( obj.destX - obj.startX ) * easing + obj.startX;\r
\r
if( c ){\r
if( X_Node_updateTimerID ){\r
- X_System.listen( X.Event.UPDATED, X_Node_Anime_updateAnimationsNoTransition );\r
+ X_System.listen( X_Event.UPDATED, X_Node_Anime_updateAnimationsNoTransition );\r
X_Node_Anime_updateTimerID = 0;\r
} else {\r
X_Node_Anime_updateTimerID = X.Timer.requestFrame( X_Node_Anime_updateAnimationsNoTransition );\r
( X_Dom_DTD_CLEANUP_TAGS[ tag ] || cname.indexOf( ' cleanup-target ' ) !== -1 );\r
};\r
\r
-if( X_UA.MacIE ){\r
+if( X_UA[ 'MacIE' ] ){\r
\r
X_TEMP._fixed_remove = function( node, xnode ){\r
var parent = node.parentNode, l;\r
};\r
\r
} else\r
-if( X_UA.Opera7 ){\r
+if( X_UA[ 'Opera7' ] ){\r
\r
X_TEMP._fixed_remove = function( node ){\r
if( node.nodeType === 1 || node.nodeType === 3 ){\r
\r
// TODO\r
// textarea の内容を控えて、消す。xnode tree 構築後に復帰。でないと、html パースでこける\r
- //X_UA.MacIE && alert( body.innerHTML );\r
+ //X_UA[ 'MacIE' ] && alert( body.innerHTML );\r
// cleanup tree \r
(function/*cleanUpTree*/( elm, skip, head ){\r
var nodes = X_Object_cloneArray( elm.childNodes ),\r
// ブロック要素直下のスペースだけは削除??\r
default :\r
//console.log( 'Remove type: ' + node.nodeType + ' value: ' + node.nodeValue );\r
- if( !X_UA.Opera7 /*&& !X_UA.MacIE */ ){\r
+ if( !X_UA[ 'Opera7' ] /*&& !X_UA[ 'MacIE' ] */ ){\r
elm.removeChild( node );\r
} else {\r
X_TEMP._fixed_remove( node );\r
//++count;\r
};\r
};\r
- })( X_UA.MacIE ? ( copy = body.cloneNode( true ) ) : body );\r
+ })( X_UA[ 'MacIE' ] ? ( copy = body.cloneNode( true ) ) : body );\r
\r
- if( X_UA.MacIE ){\r
+ if( X_UA[ 'MacIE' ] ){\r
document.write( html = copy.innerHTML );\r
} else {\r
// body の属性値の取得\r
- if( X_UA.IE5678 ){\r
+ if( X_UA[ 'IE' ] <= 8 ){\r
html = body.innerHTML.split( X_String_CRLF ).join( '' ); // 不要な改行が入る\r
} else {\r
html = body.innerHTML;\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_HTMLParser_asyncParse( html, true )\r
- .listen( X.Event.PROGRESS,\r
+ .listen( X_Event.PROGRESS,\r
function(e){\r
elmProgress.style.width = ( e.percent * 100 | 0 ) + '%';\r
}\r
)\r
- .listenOnce( X.Event.SUCCESS, function( e ){\r
+ .listenOnce( X_Event.SUCCESS, function( e ){\r
var xnodes = X_Node_body._xnodes = [], t;\r
xnodes.push.apply( xnodes, e.xnodes );\r
elmProgress.style.width = '100%';\r
elmProgress = document.all[ elmProgress ];\r
\r
X_HTMLParser_asyncParse( html, true )\r
- .listen( X.Event.PROGRESS,\r
+ .listen( X_Event.PROGRESS,\r
function( e ){\r
elmProgress.style.width = ( e.percent * 100 | 0 ) + '%';\r
}\r
)\r
- .listenOnce( X.Event.SUCCESS,\r
+ .listenOnce( X_Event.SUCCESS,\r
function( e ){\r
var xnodes = X_Node_body._xnodes = [], t;\r
xnodes.push.apply( xnodes, e.xnodes );\r
elm = elems[ current.j ];\r
tag = elm.tagName && elm.tagName.toUpperCase();\r
if( ( elm.nodeType !== 1 && elm.nodeType !== 3 ) || tag === '!' || ( tag && tag.charAt( 0 ) === '/' ) ){\r
- if( !X_UA.Opera7 && !X_UA.MacIE ){\r
+ if( !X_UA[ 'Opera7' ] && !X_UA[ 'MacIE' ] ){\r
elm.parentNode.removeChild( elm );\r
} else {\r
X_TEMP._fixed_remove( elm );\r
if( elm.nodeType === 3 ){\r
if( !( text = elm.data ) || ( text = X_String_cleanupWhiteSpace( text ) ) === ' ' ){\r
//alert( text.charCodeAt( 0 ) );\r
- if( !X_UA.Opera7 && !X_UA.MacIE ){\r
+ if( !X_UA[ 'Opera7' ] && !X_UA[ 'MacIE' ] ){\r
elm.parentNode.removeChild( elm );\r
} else {\r
X_TEMP._fixed_remove( elm );\r
* flash player 11.1, Win2k, Android 2.x-4.x
*/
var X_Pulgin_FLASH_VERSION =
- !X_UA.IE && navigator.plugins[ 'Shockwave Flash' ] ?
+ !X_UA[ 'IE' ] && navigator.plugins[ 'Shockwave Flash' ] ?
parseFloat( navigator.plugins[ 'Shockwave Flash' ].version ) :
- !X_UA.IE4 && !X_UA.IE5 && X_UA.ActiveX ? (function(){
+ !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' ),
ver = obj && obj.GetVariable( '$version' ).split( ' ' ).join( '.' );
return parseFloat( ver ) || 0;
0,
X_Pulgin_FLASH_ENABLED =
- X_UA.ActiveX ? !!X_Pulgin_FLASH_VERSION :
+ X_UA[ 'ActiveX' ] ? !!X_Pulgin_FLASH_VERSION :
navigator.mimeTypes &&
navigator.mimeTypes[ 'application/x-shockwave-flash' ] &&
navigator.mimeTypes[ 'application/x-shockwave-flash' ].enabledPlugin,
* ie11 の 互換モード(8,7)では、Silverlight が動作しない?
*/
X_Pulgin_SILVER_LIGHT_VERSION =
- !X_UA.IE && navigator.plugins[ 'Silverlight Plug-In' ] ?
+ !X_UA[ 'IE' ] && navigator.plugins[ 'Silverlight Plug-In' ] ?
parseFloat( navigator.plugins[ 'Silverlight Plug-In' ].version ) :
- X_UA.ActiveX && 6 <= X_UA.IE && !X_UA.IECompat ? (function(){
+ X_UA[ 'ActiveX' ] && 6 <= X_UA[ 'IE' ] && !X_UA[ 'IECompat' ] ? (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' );
})() :
0,
X_Pulgin_SILVER_LIGHT_ENABLED =
- X_UA.ActiveX ? !!X_Pulgin_SILVER_LIGHT_VERSION :
+ X_UA[ 'ActiveX' ] ? !!X_Pulgin_SILVER_LIGHT_VERSION :
navigator.mimeTypes &&
navigator.mimeTypes[ 'application/x-silverlight' ] &&
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 && navigator.plugins[ 'Unity Player' ] ?
+ !X_UA[ 'IE' ] && navigator.plugins[ 'Unity Player' ] ?
parseFloat( navigator.plugins[ 'Unity Player' ].version ) :
- !X_UA.IE4 && !X_UA.IE5 && X_UA.ActiveX ? (function(){
+ !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' );
return obj ? parseFloat( obj.GetPluginVersion() ) : 0;
})() :
0,
X_Pulgin_UNITY_ENABLED =
- X_UA.ActiveX ? !!X_Pulgin_UNITY_VERSION :
+ X_UA[ 'ActiveX' ] ? !!X_Pulgin_UNITY_VERSION :
navigator.mimeTypes &&
navigator.mimeTypes[ 'application/vnd.unity' ] &&
navigator.mimeTypes[ 'application/vnd.unity' ].enabledPlugin,
X_Pulgin_GEARS_ENABLED =
window.GearsFactory ||
- ( X_UA.ActiveX && 6 <= X_UA.IE ?
+ ( X_UA[ 'ActiveX' ] && 6 <= X_UA[ 'IE' ] ?
(function(){
return eval( 'var a,e;try{a=new ActiveXObject("Gears.Factory")}catch(e){}!!a' );
})() :
}\r
);\r
\r
- X_ViewPort.listenOnce( X.Event.AFTER_UPDATE, this );\r
+ X_ViewPort.listenOnce( X_Event.AFTER_UPDATE, this );\r
\r
// http://nanto.asablo.jp/blog/2011/12/08/6237308\r
// IE 6/7 で文書間通信を実現するための一案\r
- if( X_UA.IE < 9 ){\r
+ if( X_UA[ 'IE' ] < 9 ){\r
this.xnodeIframe.attr( 'src', 'about:blank' );\r
};\r
// Safari 2.0.* bug: iframe's absolute position and src set.\r
- if( !X_UA.Webkit ){\r
+ if( !X_UA[ 'Webkit' ] ){\r
this.xnodeIframe.css( { position : 'absolute' } );\r
};\r
\r
var raw = this.xnodeIframe._rawObject;\r
\r
switch( e.type ){\r
- case X.Event.AFTER_UPDATE :\r
+ case X_Event.AFTER_UPDATE :\r
this._iwin = raw.contentWindow || ( raw.contentDocument && raw.contentDocument.parentWindow ) || window.frames[ this._name ];\r
// http://d.hatena.ne.jp/NeoCat/20080921/1221940658\r
// こちらに名前をsetしないとtargetが動作しない\r
- if( X_UA.IE ) this._iwin.name = this._name;\r
+ if( X_UA[ 'IE' ] ) this._iwin.name = this._name;\r
\r
- this.xnodeIframe.listen( [ X_UA.IE < 9 ? 'readystatechange' : 'load', 'error' ], this );\r
+ this.xnodeIframe.listen( [ X_UA[ 'IE' ] < 9 ? 'readystatechange' : 'load', 'error' ], this );\r
\r
- if( !( X_UA.IE < 9 ) ){\r
+ if( !( X_UA[ 'IE' ] < 9 ) ){\r
this._contentHTML && X_Util_NinjaIframe_writeToIframe( this );\r
this._ready = true;\r
return;\r
// onload\r
case 'load' :\r
console.log( 'iframe load.' );\r
- this.asyncDispatch( X.Event.SUCCESS );\r
+ this.asyncDispatch( X_Event.SUCCESS );\r
break;\r
case 'error' :\r
- this.asyncDispatch( X.Event.ERROR );\r
+ this.asyncDispatch( X_Event.ERROR );\r
break;\r
};\r
\r
return this;\r
};\r
\r
- if( X_UA.IE5 || X_UA.IE55 ){\r
+ if( X_UA[ 'IE5x' ] ){\r
this._iwin.location.href = 'about:blank'; // reload() では、IE5.5(IETester)で2回目移行の操作でerrorが出る(doc取得やopen,writeで)\r
} else {\r
this._iwin.location.reload();\r
if( !opt_contentHTML ) return this;\r
\r
this._contentHTML = opt_contentHTML;\r
- X_UA.IE < 9 || X_Util_NinjaIframe_writeToIframe( this );\r
+ X_UA[ 'IE' ] < 9 || X_Util_NinjaIframe_writeToIframe( this );\r
\r
return this;\r
},\r
\r
close : function(){\r
- X_ViewPort.unlisten( X.Event.AFTER_UPDATE, this );\r
+ X_ViewPort.unlisten( X_Event.AFTER_UPDATE, this );\r
this.xnodeIframe.call( 'close' );\r
this.xnodeIframe.destroy();\r
}\r
function X_Util_Image_getActualDimension( XnodeOrImageElemOrSrc ){\r
var xnode, img, remove, ret, run, memW, memH, w, h;\r
\r
- if( X.Type.isString( XnodeOrImageElemOrSrc ) ){\r
+ if( X_Type_isString( XnodeOrImageElemOrSrc ) ){\r
if( ret = X_Util_Image_actualSize[ X_URL_toAbsolutePath( XnodeOrImageElemOrSrc ) ] ) return ret;\r
\r
xnode = X_Node_systemNode.create(\r
xnode = XnodeOrImageElemOrSrc;\r
img = X_UA_DOM.IE4 ? X_Node__ie4getRawNode( xnode )._rawObject : xnode._rawObject;\r
} else\r
- if( X.Type.isHTMLElement( XnodeOrImageElemOrSrc ) ){\r
+ if( X_Type_isHTMLElement( XnodeOrImageElemOrSrc ) ){\r
img = XnodeOrImageElemOrSrc;\r
} else\r
- if( XnodeOrImageElemOrSrc.constructor === X.EventDispatcher && X.Type.isImage( XnodeOrImageElemOrSrc._rawObject ) ){\r
+ if( XnodeOrImageElemOrSrc.constructor === X.EventDispatcher && X_Type_isImage( XnodeOrImageElemOrSrc._rawObject ) ){\r
xnode = XnodeOrImageElemOrSrc;\r
img = xnode._rawObject;\r
} else {\r
// for Firefox, Safari, Google Chrome\r
if( img.naturalWidth ) return [ img.naturalWidth, img.naturalHeight ];\r
\r
- if( 5 <= X_UA.IE ){// for IE\r
+ if( 5 <= X_UA[ 'IE' ] ){// for IE\r
run = img.runtimeStyle;\r
memW = run.width;\r
memH = run.height;\r
this.type = type;\r
this.data = data; \r
\r
- //this.listenOnce( X.Event.COMPLETE, X_NET_proxyDispatch );\r
- X_EventDispatcher_systemListen( this, X.Event.COMPLETE, X_NET_proxyDispatch );\r
+ //this.listenOnce( X_Event.COMPLETE, X_NET_proxyDispatch );\r
+ X_EventDispatcher_systemListen( this, X_Event.COMPLETE, X_NET_proxyDispatch );\r
\r
X_NET_QUEUE_LIST[ X_NET_QUEUE_LIST.length ] = this;\r
!X_NET_currentQueue && X_NET_shiftQueue();\r
var i = X_NET_QUEUE_LIST.indexOf( this );\r
if( i !== -1 ){\r
X_NET_QUEUE_LIST.splice( i, 1 );\r
- this.asyncDispatch( X.Event.CANCELED );\r
- this.asyncDispatch( 16, X.Event.COMPLETE );\r
+ this.asyncDispatch( X_Event.CANCELED );\r
+ this.asyncDispatch( 16, X_Event.COMPLETE );\r
} else\r
if( this === X_NET_currentQueue ){\r
X_NET_currentWrapper.cancel();\r
\r
function X_NET_proxyDispatch( e ){\r
switch( e.type ){\r
- case X.Event.BEFORE_KILL_INSTANCE :\r
+ case X_Event.BEFORE_KILL_INSTANCE :\r
break;\r
- case X.Event.KILL_INSTANCE :\r
+ case X_Event.KILL_INSTANCE :\r
break; \r
- case X.Event.KILL_INSTANCE_CANCELED :\r
+ case X_Event.KILL_INSTANCE_CANCELED :\r
break;\r
- case X.Event.PROGRESS :\r
+ case X_Event.PROGRESS :\r
this.dispatch( e );\r
break;\r
- case X.Event.SUCCESS :\r
- case X.Event.ERROR :\r
- case X.Event.TIMEOUT :\r
- case X.Event.CANCELED :\r
+ case X_Event.SUCCESS :\r
+ case X_Event.ERROR :\r
+ case X_Event.TIMEOUT :\r
+ case X_Event.CANCELED :\r
this.dispatch( e );\r
- this.asyncDispatch( X.Event.COMPLETE );\r
+ this.asyncDispatch( X_Event.COMPLETE );\r
break;\r
- case X.Event.COMPLETE :\r
+ case X_Event.COMPLETE :\r
this.kill();\r
X_NET_shiftQueue();\r
break;\r
console.log( 'X_NET_shiftQueue ' + X_NET_currentWrapper._busy );\r
if( X_NET_currentWrapper._busy ) return;\r
X_NET_currentWrapper\r
- .unlisten( [ X.Event.PROGRESS, X.Event.SUCCESS, X.Event.ERROR, X.Event.TIMEOUT, X.Event.CANCELED ], X_NET_currentQueue, X_NET_proxyDispatch )\r
+ .unlisten( [ X_Event.PROGRESS, X_Event.SUCCESS, X_Event.ERROR, X_Event.TIMEOUT, X_Event.CANCELED ], X_NET_currentQueue, X_NET_proxyDispatch )\r
.reset();\r
X_NET_currentQueue = X_NET_currentWrapper = null;\r
};\r
break;\r
};\r
\r
- X_NET_currentWrapper.listen( [ X.Event.PROGRESS, X.Event.SUCCESS, X.Event.ERROR, X.Event.TIMEOUT, X.Event.CANCELED ], X_NET_currentQueue = queue, X_NET_proxyDispatch );\r
+ X_NET_currentWrapper.listen( [ X_Event.PROGRESS, X_Event.SUCCESS, X_Event.ERROR, X_Event.TIMEOUT, X_Event.CANCELED ], X_NET_currentQueue = queue, X_NET_proxyDispatch );\r
\r
X_NET_currentWrapper.load( queue.data );\r
};\r
*/\r
var // Opera7.6+, Safari1.2+, khtml3.?+, Gecko0.9.7+\r
// ie7 ではローカルリソースには ActiveX の XHR を使う\r
- X_Net_XHR_W3C = ( !X_UA.IE7 || !X_URL_IS_LOCAL ) && window[ 'XMLHttpRequest' ] && new XMLHttpRequest(),\r
+ X_Net_XHR_W3C = ( !X_UA[ 'IE7' ] || !X_URL_IS_LOCAL ) && window[ 'XMLHttpRequest' ] && new XMLHttpRequest(),\r
\r
X_Net_XHR_X_DOMAIN = window[ 'XDomainRequest' ] && new XDomainRequest(),\r
X_Net_XHR_VERSION = 0,\r
- X_Net_XHR_ACTIVE_X = !X_UA.IE4 && X_UA.IE < 8 && X_UA.ActiveX && ( new Function( [\r
+ X_Net_XHR_ACTIVE_X = !X_UA[ 'IE4' ] && X_UA[ 'IE' ] < 8 && X_UA[ 'ActiveX' ] && ( new Function( [\r
'var x=".XMLHTTP",',\r
'm="MSXML2"+x,',\r
'n=[m+".6.0",m+".3.0",m+".5.0",m+".4.0",m,"Microsoft"+x],',\r
break;\r
case 'json' :\r
case 'moz-json' :\r
- raw.responseType = X_UA.Gecko ? this._type : ''; // Iron 37 でエラー\r
+ raw.responseType = X_UA[ 'Gecko' ] ? this._type : ''; // Iron 37 でエラー\r
break;\r
case 'document' :\r
case 'xml' :\r
\r
// http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_r_1.html\r
// raw.overrideMimeType()\r
- if( !X_Net_XHR_ACTIVE_X && X.Type.isFunction( raw.setRequestHeader ) ){\r
+ if( !X_Net_XHR_ACTIVE_X && X_Type_isFunction( raw.setRequestHeader ) ){\r
\r
// http://nakigao.sitemix.jp/blog/?p=2040\r
// SafariでHTTP/412のエラー\r
cancel : function(){\r
/* X.Net.XHR.CANCELABLE && */ this._rawObject.abort && this._rawObject.abort();\r
this._canceled = true;\r
- this.asyncDispatch( X.Event.CANCELED );\r
+ this.asyncDispatch( X_Event.CANCELED );\r
},\r
\r
reset : function(){\r
// Opera 10.10、Safari 4.1 では、同一オリジン制限に違反した XMLHttpRequest オブジェクトは再度 open() しても未送信状態に戻りません。\r
\r
// Timeout した Gecko の xhr.response に触るとエラー??\r
- if( X_UA.Opera || X_UA.Webkit || X_UA.Gecko ){\r
+ if( X_UA[ 'Opera' ] || X_UA[ 'Webkit' ] || X_UA[ 'Gecko' ] ){\r
if( this._error ){\r
X_EventDispatcher_toggleAllEvents( this, false );\r
this._rawObject = new XMLHttpRequest();\r
case 1 :\r
return;\r
case 2 : // 0% ajaxstart\r
- live && this.asyncDispatch( { type : X.Event.PROGRESS, percent : 0 } );\r
+ live && this.asyncDispatch( { type : X_Event.PROGRESS, percent : 0 } );\r
return;\r
case 3 :\r
- live && this.asyncDispatch( { type : X.Event.PROGRESS, percent : this._percent < 99.9 ? 99.9 : ( this._percent + 100 ) / 2 } );\r
+ live && this.asyncDispatch( { type : X_Event.PROGRESS, percent : this._percent < 99.9 ? 99.9 : ( this._percent + 100 ) / 2 } );\r
// 99.9%\r
return;\r
case 4 :\r
( 200 <= status && status < 400 ) ||\r
//status === 304 ||\r
status === 1223 ||\r
- ( X_UA.Webkit && status === undefined ) // safari: /webkit/.test(userAgent)\r
+ ( X_UA[ 'Webkit' ] && status === undefined ) // safari: /webkit/.test(userAgent)\r
){\r
/*\r
* opera8, safari2, khtml3 で utf8 日本語文字列の文字化け\r
// eval() を使っているけど JSON の無いブラウザは XDomain な XHR はできないのでよしとする。\r
// XDomain な XHR の際は Flash 等で代替し、その中に Json parser も組み込む。\r
// http://d.hatena.ne.jp/sshi/20060904/p1\r
- if( !X.Type.isObject( data ) ) data = window.JSON ? JSON.parse( data ) : eval( '(' + data + ')' );\r
+ if( !X_Type_isObject( data ) ) data = window.JSON ? JSON.parse( data ) : eval( '(' + data + ')' );\r
break;\r
case 'document' :\r
case 'xml' :\r
break;\r
};\r
\r
- this.asyncDispatch( 32, { type : X.Event.SUCCESS, status : status || 200, data : data } );\r
+ this.asyncDispatch( 32, { type : X_Event.SUCCESS, status : status || 200, data : data } );\r
} else {\r
- live && this.asyncDispatch( 32, { type : X.Event.ERROR, status : raw.status || 0, percent : 100 } );\r
+ live && this.asyncDispatch( 32, { type : X_Event.ERROR, status : raw.status || 0, percent : 100 } );\r
};\r
break;\r
\r
case 'progress' :\r
if( e.lengthComputable ){\r
this._percent = e.loaded / e.total;\r
- live && this.asyncDispatch( { type : X.Event.PROGRESS, percent : this._percent } );\r
+ live && this.asyncDispatch( { type : X_Event.PROGRESS, percent : this._percent } );\r
};\r
break;\r
\r
case 'error' :\r
//console.dir( e );\r
this._busy = false;\r
- this._error = X_UA.Opera || X_UA.Webkit;\r
- live && this.asyncDispatch( 32, { type : X.Event.ERROR, status : raw.status } );\r
+ this._error = X_UA[ 'Opera' ] || X_UA[ 'Webkit' ] ;\r
+ live && this.asyncDispatch( 32, { type : X_Event.ERROR, status : raw.status } );\r
break;\r
\r
case 'timeout' : // Gecko 12.0 https://developer.mozilla.org/ja/docs/XMLHttpRequest/Synchronous_and_Asynchronous_Requests\r
this._busy = false;\r
- this._error = !!X_UA.Gecko;\r
- this.asyncDispatch( X.Event.TIMEOUT );\r
+ this._error = !!X_UA[ 'Gecko' ];\r
+ this.asyncDispatch( X_Event.TIMEOUT );\r
break;\r
};\r
},\r
\r
if( raw.readyState < 3 ){\r
this._busy = false;\r
- live && this.asyncDispatch( X.Event.TIMEOUT );\r
+ live && this.asyncDispatch( X_Event.TIMEOUT );\r
};\r
this._timerID = 0;\r
},\r
);\r
// 同期リクエストでなければならない場合, unload, beforeunload時\r
\r
- if( X_UA.IE8 ){\r
+ if( X_UA[ 'IE8' ] ){\r
X_NET_XHRWrapper.listen( [ 'readystatechange', 'error', 'timeout' ] ); //, 'abort'\r
} else\r
- if( X_UA.IE7 ){\r
+ if( X_UA[ 'IE7' ] ){\r
if( X_URL_IS_LOCAL ){\r
X_NET_XHRWrapper.listen( 'readystatechange' ); // ie7 ActiveX の場合、error は不可\r
} else {\r
X_NET_JSONPWrapper
.asyncDispatch( {
- type : jsonString ? X.Event.SUCCESS : X.Event.ERROR,
+ type : jsonString ? X_Event.SUCCESS : X_Event.ERROR,
data : window.JSON ? JSON.parse( jsonString ) : eval( 'var a=' + jsonString + ';a' )
} );
// http://d.hatena.ne.jp/cnrd/20080518/1211099169
// 最近の仕様変更(引数のtargetOriginとかMessageEventのoriginとか)にはまだ対応してないみたい
- if( X_UA.Opera ){
+ if( X_UA[ 'Opera' ] ){
html = [
( window[ 'JSON' ] ? '' : '<script src="' + json2Path + '"></script>' ),
'<script>',
];
X_Net_JSONP_onloadCount = 2;
} else
- if( X_UA.IE8 ){
+ if( X_UA[ 'IE8' ] ){
html = [
// JavaScriptでunicode文字列をunescapeする
// http://perutago.seesaa.net/article/202801583.html
];
X_Net_JSONP_onloadCount = 2;
} else
- if( X_UA.IE9 ){
+ if( X_UA[ 'IE9' ] ){
html = [
'<script id="jp"></script>',
'<script>',
];
X_Net_JSONP_onloadCount = 1;
} else
- if( X_UA.IE4 || X_UA.MacIE ){
+ if( X_UA[ 'IE4' ] || X_UA[ 'MacIE' ] ){
html = [
'<script id="jn"></script>',
'<script id="jp"></script>',
];
X_Net_JSONP_onloadCount = 3;
} else
- if( X_UA.IE < 8 ){ // ie5-7
+ if( X_UA[ 'IE' ] < 8 ){ // ie5-7
html = [
'<script id="jn"></script>',
'<script id="jp"></script>',
X_NET_JSONP_NinjaIframe
.refresh( html.join( '' ) )
- .listen( [ X.Event.SUCCESS, X.Event.ERROR ], X_NET_JSONPWrapper, X_NET_JSONP_iframeListener );
+ .listen( [ X_Event.SUCCESS, X_Event.ERROR ], X_NET_JSONPWrapper, X_NET_JSONP_iframeListener );
};
function X_NET_JSONP_iframeListener( e ){
switch( e.type ){
- case X.Event.SUCCESS :
+ case X_Event.SUCCESS :
console.log( 'iframe onload, but' );
if( ++X_NET_JSONPWrapper._onloadCount < X_Net_JSONP_onloadCount ) return;
// TODO callback が無ければ error
- X_NET_JSONPWrapper.asyncDispatch( 1000, X.Event.ERROR );
+ X_NET_JSONPWrapper.asyncDispatch( 1000, X_Event.ERROR );
break;
- case X.Event.ERROR :
+ case X_Event.ERROR :
console.log( 'iframe onerror' );
- X_NET_JSONPWrapper.asyncDispatch( X.Event.ERROR );
+ X_NET_JSONPWrapper.asyncDispatch( X_Event.ERROR );
break;
};
X_NET_JSONP_NinjaIframe.unlisten();
var X_Net_Image_hasImage = !!window[ 'Image' ],\r
X_Net_Image_image = X_Net_Image_hasImage && new Image(),\r
// IE では厳密には HTMLImageElement ではなく、appendChild してもサイズが取れず、removeChild に失敗する\r
- X_Net_Image_isElement = !( X_UA.IE < 9 ) && X.Type.isHTMLElement( X_Net_Image_image );\r
+ X_Net_Image_isElement = !( X_UA[ 'IE' ] < 9 ) && X_Type_isHTMLElement( X_Net_Image_image );\r
\r
\r
if( !X_Net_Image_hasImage ){\r
\r
this._rawObject.src = this.abspath;\r
\r
- if( X_UA.Opera7 && this._rawObject.complete ){\r
+ if( X_UA[ 'Opera7' ] && this._rawObject.complete ){\r
this.asyncDispatch( 'load' );\r
} else {\r
this.timerID = X.Timer.add( this.delay, 0, this, this._detect );\r
this._busy = false;\r
this.finish = true;\r
this.timerID && X.Timer.remove( this.timerID );\r
- this.timerID = this.asyncDispatch( /*e.type === 'error' ?*/ X.Event.ERROR /*: X.Event.CANCELED*/ );\r
+ this.timerID = this.asyncDispatch( /*e.type === 'error' ?*/ X_Event.ERROR /*: X_Event.CANCELED*/ );\r
break;\r
case 'load' :\r
// if( finish === true ) return; // これがあると firefox3.6 で駄目、、、\r
this._busy = false;\r
this.finish = true;\r
this.timerID && X.Timer.remove( this.timerID );\r
- if( X_UA.Opera && !this._rawObject.complete ){\r
- this.timerID = this.asyncDispatch( X.Event.ERROR );\r
+ if( X_UA[ 'Opera' ] && !this._rawObject.complete ){\r
+ this.timerID = this.asyncDispatch( X_Event.ERROR );\r
return;\r
};\r
size = X.Util.Image.getActualDimension( !X_Net_Image_isElement ? this.abspath : this );\r
this.timerID = this.asyncDispatch( {\r
- type : X.Event.SUCCESS,\r
+ type : X_Event.SUCCESS,\r
src : this.abspath,\r
w : size[ 0 ],\r
h : size[ 1 ]\r
// time , this._rawObject.fileSize\r
} );\r
break;\r
- case X.Event.KILL_INSTANCE :\r
+ case X_Event.KILL_INSTANCE :\r
this.reset();\r
!X_Net_Image_hasImage && this.destroy(); // if xnode\r
break;\r
this.finish = true;\r
if( this._rawObject.width ) return;\r
X.Timer.remove( this.timerID );\r
- this.timerID = this.asyncDispatch( X.Event.ERROR );\r
+ this.timerID = this.asyncDispatch( X_Event.ERROR );\r
} else\r
if( this.timeout < ( this.tick += this.delay ) ){\r
this._busy = false;\r
this.finish = true;\r
X.Timer.remove( this.timerID );\r
- this.timerID = this.asyncDispatch( X.Event.TIMEOUT );\r
+ this.timerID = this.asyncDispatch( X_Event.TIMEOUT );\r
};\r
},\r
\r
// this._rawObject.src = '';\r
this._busy = false;\r
this.finish = true;\r
- this.asyncDispatch( X.Event.CANCELED );\r
+ this.asyncDispatch( X_Event.CANCELED );\r
},\r
\r
reset : function(){\r
}\r
);\r
\r
-X_NET_ImageWrapper.listen( [ 'load', 'error' /*, 'abort'*/, X.Event.KILL_INSTANCE ] );\r
+X_NET_ImageWrapper.listen( [ 'load', 'error' /*, 'abort'*/, X_Event.KILL_INSTANCE ] );\r
\r
// X_Net_Image_isElement && X_NET_ImageWrapper.appendTo( X.X_Node_systemNode );\r
*/\r
\r
var X_Audio_BACKENDS = [], // Array.<Hash>\r
- X_Audio_WRAPPER_LIST = [], // Array.<AudioWrapper>\r
- X_Audio_CAN_PLAY = 1,\r
- X_Audio_NOT_PLAY = 2;\r
+ X_Audio_WRAPPER_LIST = []; // Array.<AudioWrapper>\r
\r
function X_Audio_getAudioWrapper( proxy ){\r
var i = X_Audio_WRAPPER_LIST.length;\r
};\r
\r
/*\r
- * X.Event.BACKEND_READY\r
- * X.Event.BACKEND_NONE\r
+ * X_Event.BACKEND_READY\r
+ * X_Event.BACKEND_NONE\r
* \r
- * X.Event.READY 再生可能、実際の状態は canplay から loadeddata まで様々、、、\r
- * X.Event.ERROR\r
+ * X_Event.READY 再生可能、実際の状態は canplay から loadeddata まで様々、、、\r
+ * X_Event.ERROR\r
* 1 : ユーザーによってメディアの取得が中断された\r
* 2 : ネットワークエラー\r
* 3 : メディアのデコードエラー\r
* 4 : メディアがサポートされていない\r
* \r
- * X.Event.MEDIA_PLAYING 再生中に1秒以下のタイミングで発生.currentTime が取れる?\r
- * X.Event.MEDIA_LOOP ループ直前に発生、キャンセル可能\r
- * X.Event.MEDIA_LOOPED ループ時に発生\r
- * X.Event.MEDIA_ENDED 再生位置の(音声の)最後についた\r
- * X.Event.MEDIA_PAUSED ポーズした\r
- * X.Event.MEDIA_WAITING 再生中に音声が待機状態に。間もなく X.Event.MEDIA_PLAYING に移行。\r
- * X.Event.MEDIA_SEEKING シーク中に音声が待機状態に。間もなく X.Event.MEDIA_PLAYING に移行。\r
+ * X_Event.MEDIA_PLAYING 再生中に1秒以下のタイミングで発生.currentTime が取れる?\r
+ * X_Event.MEDIA_LOOP ループ直前に発生、キャンセル可能\r
+ * X_Event.MEDIA_LOOPED ループ時に発生\r
+ * X_Event.MEDIA_ENDED 再生位置の(音声の)最後についた\r
+ * X_Event.MEDIA_PAUSED ポーズした\r
+ * X_Event.MEDIA_WAITING 再生中に音声が待機状態に。間もなく X_Event.MEDIA_PLAYING に移行。\r
+ * X_Event.MEDIA_SEEKING シーク中に音声が待機状態に。間もなく X_Event.MEDIA_PLAYING に移行。\r
*/\r
\r
X.Audio = X.EventDispatcher.inherits(\r
Constructor : function( sourceList, opt_option ){\r
X_Audio_startDetectionBackend(\r
X_Audio_BACKENDS[ 0 ], this,\r
- X.Type.isArray( sourceList ) ? X_Object_cloneArray( sourceList ) : [ sourceList ],\r
+ X_Type_isArray( sourceList ) ? X_Object_cloneArray( sourceList ) : [ sourceList ],\r
opt_option || {} );\r
- this.listenOnce( [ X.Event.BACKEND_READY, X.Event.BACKEND_NONE, X.Event.KILL_INSTANCE ], X_Audio_handleEvent );\r
+ this.listenOnce( [ X_Event.BACKEND_READY, X_Event.BACKEND_NONE, X_Event.KILL_INSTANCE ], X_Audio_handleEvent );\r
},\r
\r
play : function( startTime, endTime, loop, loopStartTime, loopEndTime ){\r
\r
function X_Audio_handleEvent( e ){\r
switch( e.type ){\r
- case X.Event.BACKEND_READY :\r
- this.unlisten( X.Event.BACKEND_NONE, X_Audio_handleEvent );\r
+ case X_Event.BACKEND_READY :\r
+ this.unlisten( X_Event.BACKEND_NONE, X_Audio_handleEvent );\r
this.source = e.source;\r
this.backendName = X_Audio_BACKENDS[ this._backend ].backendName;\r
X_Audio_WRAPPER_LIST.push(\r
.klass( this, e.source, e.option ) );\r
break;\r
\r
- case X.Event.BACKEND_NONE :\r
+ case X_Event.BACKEND_NONE :\r
this.kill();\r
break;\r
\r
- case X.Event.KILL_INSTANCE :\r
+ case X_Event.KILL_INSTANCE :\r
this._backend !== -1 && X_Audio_getAudioWrapper( this ).close();\r
break;\r
};\r
sup = [ proxy, sourceList, option, source, ext ];\r
sup[ 5 ] = sup;\r
\r
- proxy.listenOnce( [ X_Audio_CAN_PLAY, X_Audio_NOT_PLAY ], backend, X_Audio_onEndedDetection, sup );\r
+ proxy.listenOnce( X_Event.COMPLETE, backend, X_Audio_onEndedDetection, sup );\r
backend.detect( proxy, source, ext );\r
} else {\r
- proxy.asyncDispatch( X.Event.BACKEND_NONE );\r
+ proxy.asyncDispatch( X_Event.BACKEND_NONE );\r
};\r
};\r
\r
function X_Audio_onEndedDetection( e, proxy, sourceList, option, source, ext, sup ){\r
var i = X_Audio_BACKENDS.indexOf( this ), backend;\r
\r
- proxy.unlisten( [ X_Audio_CAN_PLAY, X_Audio_NOT_PLAY ], this, X_Audio_onEndedDetection, sup );\r
- \r
- switch( e.type ){\r
- case X_Audio_CAN_PLAY :\r
- proxy._backend = i;\r
- proxy.asyncDispatch( {\r
- type : X.Event.BACKEND_READY,\r
- option : option,\r
- source : source,\r
- backendName : this.backendName\r
- } );\r
- break;\r
- case X_Audio_NOT_PLAY :\r
- console.log( 'No ' + source + ' ' + this.backendName );\r
- if( sup[ 3 ] = source = sourceList[ sourceList.indexOf( source ) + 1 ] ){\r
- sup[ 4 ] = ext = X_URL_getEXT( source );\r
- proxy.listenOnce( [ X_Audio_CAN_PLAY, X_Audio_NOT_PLAY ], this, X_Audio_onEndedDetection, sup );\r
- this.detect( proxy, source, ext );\r
- } else\r
- if( backend = X_Audio_BACKENDS[ i + 1 ] ){\r
- X_Audio_startDetectionBackend( backend, proxy, sourceList, option );\r
- } else {\r
- proxy.asyncDispatch( X.Event.BACKEND_NONE );\r
- };\r
- break;\r
+ if( e.canPlay ){\r
+ proxy._backend = i;\r
+ proxy.asyncDispatch( {\r
+ type : X_Event.BACKEND_READY,\r
+ option : option,\r
+ source : source,\r
+ backendName : this.backendName\r
+ } ); \r
+ } else {\r
+ console.log( 'No ' + source + ' ' + this.backendName );\r
+ if( sup[ 3 ] = source = sourceList[ sourceList.indexOf( source ) + 1 ] ){\r
+ sup[ 4 ] = ext = X_URL_getEXT( source );\r
+ proxy.listenOnce( X_Event.COMPLETE, this, X_Audio_onEndedDetection, sup );\r
+ this.detect( proxy, source, ext );\r
+ } else\r
+ if( backend = X_Audio_BACKENDS[ i + 1 ] ){\r
+ X_Audio_startDetectionBackend( backend, proxy, sourceList, option );\r
+ } else {\r
+ proxy.asyncDispatch( X_Event.BACKEND_NONE );\r
+ }; \r
};\r
};\r
\r
switch( k ){\r
case 'currentTime' :\r
v = X_AudioWrapper_timeStringToNumber( v );\r
- if( X.Type.isNumber( v ) ){\r
+ if( X_Type_isNumber( v ) ){\r
if( playing ){\r
if( audioWrapper.state().currentTime !== v ){\r
audioWrapper.seekTime = v;\r
if( playing ) seek = 2;\r
case 'loop' :\r
case 'autoplay' :\r
- if( X.Type.isBoolean( v ) && audioWrapper[ k ] !== v ){\r
+ if( X_Type_isBoolean( v ) && audioWrapper[ k ] !== v ){\r
audioWrapper[ k ] = v;\r
};\r
break;\r
\r
case 'volume' :\r
- if( X.Type.isNumber( v ) ){\r
+ if( X_Type_isNumber( v ) ){\r
v = v < 0 ? 0 : 1 < v ? 1 : v;\r
if( audioWrapper[ k ] !== v ){\r
audioWrapper[ k ] = v;\r
\r
function X_AudioWrapper_timeStringToNumber( time ){\r
var ary, ms, s = 0, m = 0, h = 0;\r
- if( X.Type.isNumber( time ) ) return time;\r
- if( !X.Type.isString( time ) || !time.length ) return;\r
+ if( X_Type_isNumber( time ) ) return time;\r
+ if( !X_Type_isString( time ) || !time.length ) return;\r
\r
ary = time.split( '.' );\r
ms = parseInt( ( ary[ 1 ] + '000' ).substr( 0, 3 ) ) || 0;\r
-var X_Audio_WebAudio_context = !X_UA.iPhone_4s && !X_UA.iPad_2Mini1 && !X_UA.iPod_4 &&
- !( X_UA.Gecko && X_UA.Android ) &&
+var X_Audio_WebAudio_context = !X_UA[ 'iPhone_4s' ] && !X_UA[ 'iPad_2Mini1' ] && !X_UA[ 'iPod_4' ] &&
+ !( X_UA[ 'Gecko' ] && X_UA[ 'Android' ] ) &&
( window.AudioContext || window.webkitAudioContext ),
X_Audio_WebAudioWrapper;
autoplay : false,
volume : 0.5,
+ _startPos : 0,
+ _endPosition : 0,
_startTime : 0,
- _endTime : 0,
- _playTime : 0,
_timerID : 0,
_interval : 0,
buffer : null,
audio.proxy.listenOnce( 'canplaythrough', this, this._onBufferReady );
} else {
this.xhr = X.Net.xhrGet( url, 'arraybuffer' )
- .listen( X.Event.PROGRESS, this )
- .listenOnce( [ X.Event.SUCCESS, X.Event.COMPLETE, X.Event.CANCELED ], this );
+ .listen( X_Event.PROGRESS, this )
+ .listenOnce( [ X_Event.SUCCESS, X_Event.COMPLETE, X_Event.CANCELED ], this );
};
},
handleEvent : function( e ){
switch( e.type ){
- case X.Event.PROGRESS :
+ case X_Event.PROGRESS :
e.percent ?
this.proxy.dispatch( { type : 'progress', percent : e.percent } ) :
this.proxy.dispatch( 'loadstart' );
return;
- case X.Event.SUCCESS :
+ case X_Event.SUCCESS :
console.log( 'WebAudio xhr success! ' + !!X_Audio_WebAudio_context.decodeAudioData + ' t:' + typeof e.data );
// TODO 旧api
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext
// iOS 7.1 で decodeAudioData に処理が入った瞬間にスクリーンを長押しする(スクロールを繰り返す)と
// decoeAudioData の処理がキャンセルされることがある(エラーやコールバックの発火もなく、ただ処理が消滅する)。
// ただし iOS 8.1.2 では エラーになる
- if( X_Audio_WebAudio_context.createBuffer && X_UA.iOS < 8 ){
+ if( X_Audio_WebAudio_context.createBuffer && X_UA[ 'iOS' ] < 8 ){
this._onDecodeSuccess( X_Audio_WebAudio_context.createBuffer( e.data, false ) );
} else
if( X_Audio_WebAudio_context.decodeAudioData ){
};
break;
- case X.Event.CANCELED :
+ case X_Event.CANCELED :
this.error = 1;
this.proxy.dispatch( 'aborted' );
break;
- case X.Event.COMPLETE :
+ case X_Event.COMPLETE :
this.error = 2;
- this.proxy.asyncDispatch( { type : X.Event.ERROR, message : 'xhr error' } );
+ this.proxy.asyncDispatch( { type : X_Event.ERROR, message : 'xhr error' } );
break;
};
- this.xhr.unlisten( [ X.Event.PROGRESS, X.Event.SUCCESS, X.Event.COMPLETE, X.Event.CANCELED ], this );
+ this.xhr.unlisten( [ X_Event.PROGRESS, X_Event.SUCCESS, X_Event.COMPLETE, X_Event.CANCELED ], this );
delete this.xhr;
},
this.onDecodeSuccess && this._onDecodeComplete();
if ( !buffer ) {
- this.proxy.asyncDispatch( { type : X.Event.ERROR, message : 'buffer is ' + buffer } );
+ this.proxy.asyncDispatch( { type : X_Event.ERROR, message : 'buffer is ' + buffer } );
return;
};
this.proxy.asyncDispatch( 'canplay' );
this.proxy.asyncDispatch( 'canplaythrough' );
*/
- this.proxy.asyncDispatch( X.Event.READY );
+ this.proxy.asyncDispatch( X_Event.READY );
this.autoplay && X.Timer.once( 16, this, this.play );
console.log( 'WebAudio decode error!' );
this._onDecodeComplete();
this.error = 3;
- this.proxy.asyncDispatch( { type : X.Event.ERROR, message : 'decode error' } );
+ this.proxy.asyncDispatch( { type : X_Event.ERROR, message : 'decode error' } );
},
_onDecodeComplete : function(){
this.source.noteGrainOn( 0, begin / 1000, end / 1000 );
};
- this.playing = true;
- this._startTime = begin;
- this._endTime = end;
- this._playTime = X_Audio_WebAudio_context.currentTime * 1000;
- this._interval = this._interval || X.Timer.add( 1000, 0, this, this._onInterval );
+ this.playing = true;
+ this._startPos = begin;
+ this._endPosition = end;
+ this._startTime = X_Audio_WebAudio_context.currentTime * 1000;
+ this._interval = this._interval || X.Timer.add( 1000, 0, this, this._onInterval );
},
_onInterval : function(){
delete this._interval;
return X_Callback_UN_LISTEN;
};
- this.proxy.dispatch( X.Event.MEDIA_PLAYING );
+ this.proxy.dispatch( X_Event.MEDIA_PLAYING );
},
_onEnded : function(){
delete this._timerID;
if( this.playing ){
- time = X_Audio_WebAudio_context.currentTime * 1000 - this._playTime - this._endTime + this._startTime | 0;
- //console.log( '> onEnd ' + ( this.playing && ( X_Audio_WebAudio_context.currentTime * 1000 - this._playTime ) ) + ' < ' + ( this._endTime - this._startTime ) );
+ time = X_Audio_WebAudio_context.currentTime * 1000 - this._startTime - this._endPosition + this._startPos | 0;
+ //console.log( '> onEnd ' + ( this.playing && ( X_Audio_WebAudio_context.currentTime * 1000 - this._startTime ) ) + ' < ' + ( this._endPosition - this._startPos ) );
if( this._onended ){
// Firefox 用の対策,,,
if( time < 0 ) return;
} else {
if( time < 0 ){
- console.log( '> onEnd ' + ( -time ) + ' start:' + this._startTime + '-' + this._endTime );
+ console.log( '> onEnd crt:' + ( X_Audio_WebAudio_context.currentTime * 1000 ) + ' startTime:' + this._startTime +
+ ' from:' + this._startPos + ' to:' + this._endPosition );
this._timerID = X.Timer.once( -time, this, this._onEnded );
return;
};
};
if( this.loop ){
- if( !( this.proxy.dispatch( X.Event.MEDIA_BEFORE_LOOP ) & X.Callback.PREVENT_DEFAULT ) ){
+ if( !( this.proxy.dispatch( X_Event.MEDIA_BEFORE_LOOP ) & X.Callback.PREVENT_DEFAULT ) ){
this.looped = true;
- this.proxy.dispatch( X.Event.MEDIA_LOOPED );
+ this.proxy.dispatch( X_Event.MEDIA_LOOPED );
this.play();
};
} else {
this.pause();
- this.proxy.dispatch( X.Event.MEDIA_ENDED );
+ this.proxy.dispatch( X_Event.MEDIA_ENDED );
};
};
},
playing : this.playing,
duration : this.duration,
- currentTime : this.playing ? ( X_Audio_WebAudio_context.currentTime * 1000 - this._playTime + this._startTime | 0 ) : this.seekTime,
+ currentTime : this.playing ? ( X_Audio_WebAudio_context.currentTime * 1000 - this._startTime + this._startPos | 0 ) : this.seekTime,
error : this.error
};
};
//
detect : function( proxy, source, ext ){
- proxy.asyncDispatch( X_Audio_codecs[ ext ] ? X_Audio_CAN_PLAY : X_Audio_NOT_PLAY );
+ proxy.asyncDispatch( { type : X_Event.COMPLETE, canPlay : X_Audio_codecs[ ext ] } );
},
klass : X_Audio_WebAudioWrapper
*/\r
\r
var X_Audio_HTMLAudio_playTrigger =\r
- 6 <= X_UA.iOS ? 'loadeddata' :\r
- X_UA.iOS ? 'suspend' :\r
- X_UA.AndroidBrowser2 ? 'stalled' : // Android 2.3.5(SBM101SH) では stalled は発生しない,,,\r
- X_UA.AndroidBrowser4 ? 'loadeddata' : \r
- X_UA.OperaMobile || X_UA.OperaTablet ? 'loadeddata' : 'canplay',\r
+ 6 <= X_UA[ 'iOS' ] ? 'loadeddata' :\r
+ X_UA[ 'iOS' ] ? 'suspend' :\r
+ X_UA[ 'AndroidBrowser2' ] ? 'stalled' : // Android 2.3.5(SBM101SH) では stalled は発生しない,,,\r
+ X_UA[ 'AndroidBrowser4' ] ? 'loadeddata' : \r
+ X_UA[ 'OperaMobile' ] || X_UA[ 'OperaTablet' ] ? 'loadeddata' : 'canplay',\r
X_Audio_HTMLAudioWrapper,\r
X_Audio_constructor = window.Audio || window.HTMLAudioElement,\r
X_Audio_rawAudio,\r
// Opera Mobile 12 android4.4.4 & 2.3.5 は 2回目以降の currentTime へのセットで currentTime が更新されなくなるため、タイマーを使用する\r
- X_Audio_HTMLAudioWrapper_currentTimeFix = !!X_UA.OperaMobile || !!X_UA.OperaTablet, // || ( X_UA.WinPhone && X_UA.IE9 ),\r
+ X_Audio_HTMLAudioWrapper_currentTimeFix = !!X_UA[ 'OperaMobile' ] || !!X_UA[ 'OperaTablet' ], // || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ),\r
// Android1.6+MobileOpera12では無理っぽい、、、\r
- X_Audio_HTMLAudioWrapper_badOperaAndroid = X_Audio_HTMLAudioWrapper_currentTimeFix && X_UA.Android < 2,\r
+ X_Audio_HTMLAudioWrapper_badOperaAndroid = X_Audio_HTMLAudioWrapper_currentTimeFix && X_UA[ 'Android' ] < 2,\r
\r
// 一方 Desktop の Opera12 は、loadeddata 等では duration が infinity で、再生後の durationchange 時に duration が判明する。\r
// opera12 volume, mute の変更が2度目以降できない\r
// Opera12.17 Win32(XP) portable apps は勝手に再生が始まる、、、その際には timeupdate が発行されない、、、 iframe+image+audio で使わないときは破棄する、とか。\r
// opera11、10.54 WinXP はまとも、、、\r
// X_Audio_Sprite_handleEvent でも使用\r
- X_Audio_HTMLAudioWrapper_ieMobile9Fix = ( X_UA.WinPhone && X_UA.IE9 ),\r
- X_Audio_HTMLAudioWrapper_durationFix = ( !X_Audio_HTMLAudioWrapper_currentTimeFix && 12 <= X_UA.Opera ),\r
+ X_Audio_HTMLAudioWrapper_ieMobile9Fix = ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ),\r
+ X_Audio_HTMLAudioWrapper_durationFix = ( !X_Audio_HTMLAudioWrapper_currentTimeFix && 12 <= X_UA[ 'Opera' ] ),\r
\r
- X_Audio_HTMLAudioWrapper_shortPlayFix = !!X_UA.AndroidBrowser4,\r
+ X_Audio_HTMLAudioWrapper_shortPlayFix = !!X_UA[ 'AndroidBrowser4' ],\r
\r
X_Audio_codecs;\r
\r
} else {\r
// iOS3.2.3\r
X_Audio_codecs = {\r
- mp3 : X_UA.IE || X_UA.Chrome || ( X_UA.Windows && X_UA.Safari ),\r
- ogg : 5 <= X_UA.Gecko || X_UA.Chrome || X_UA.Opera,\r
- wav : X_UA.Gecko || X_UA.Opera || ( X_UA.Windows && X_UA.Safari ),\r
- aac : X_UA.IE || X_UA.WebKit,\r
- m4a : X_UA.IE || X_UA.WebKit,\r
- mp4 : X_UA.IE || X_UA.WebKit,\r
- weba : 2 <= X_UA.Gecko || 10.6 <= X_UA.Opera // firefox4+(Gecko2+)\r
+ mp3 : X_UA[ 'IE' ] || X_UA[ 'Chrome' ] || ( X_UA[ 'Windows' ] && X_UA[ 'Safari' ] ),\r
+ ogg : 5 <= X_UA[ 'Gecko' ] || X_UA[ 'Chrome' ] || X_UA[ 'Opera' ] ,\r
+ wav : X_UA[ 'Gecko' ] || X_UA[ 'Opera' ] || ( X_UA[ 'Windows' ] && X_UA[ 'Safari' ] ),\r
+ aac : X_UA[ 'IE' ] || X_UA[ 'WebKit' ],\r
+ m4a : X_UA[ 'IE' ] || X_UA[ 'WebKit' ],\r
+ mp4 : X_UA[ 'IE' ] || X_UA[ 'WebKit' ],\r
+ weba : 2 <= X_UA[ 'Gecko' ] || 10.6 <= X_UA[ 'Opera' ] // firefox4+(Gecko2+)\r
};\r
};\r
\r
X_Audio_rawAudio = null;\r
};\r
\r
- this.listenOnce( X.Event.KILL_INSTANCE );\r
+ this.listenOnce( X_Event.KILL_INSTANCE );\r
},\r
\r
handleEvent : function( e ){\r
switch( e.type ){\r
\r
- case X.Event.KILL_INSTANCE :\r
+ case X_Event.KILL_INSTANCE :\r
break;\r
};\r
},\r
break;\r
\r
case 'error' : // コンテンツの取得実行中にエラーが発生した場合に発生\r
- type = X.Event.ERROR;\r
+ type = X_Event.ERROR;\r
break;\r
\r
case 'playing' : // 再生が開始された場合に発生\r
if( X_Audio_HTMLAudioWrapper_currentTimeFix ){\r
this._playTime = X_Timer_now();\r
};\r
- type = X.Event.MEDIA_PLAYING;\r
+ type = X_Event.MEDIA_PLAYING;\r
case 'play' : // 再生が開始された。play()メソッドからの復帰後に発生する場合に発生\r
case 'pause' : // 再生が一時停止された。pauseメソッドからの復帰後に発生する場合に発生\r
case 'seeked' : // シークがfalseに変化した場合に発生\r
break;\r
\r
case 'waiting' : // 次のフレームが利用不可のため再生を停止したが、そのフレームがやがて利用可能になると想定している場合に発生\r
- type = X.Event.MEDIA_WAITING;\r
+ type = X_Event.MEDIA_WAITING;\r
case 'seeking' : // シークがtrueに変化し、イベントを発生させるのに十分な時間がシーク操作にかかっている場合に発生\r
- type = type || X.Event.MEDIA_SEEKING;\r
+ type = type || X_Event.MEDIA_SEEKING;\r
if( this._playForDuration === 1 ) return;\r
break;\r
\r
case 'ended' :\r
if( !this._closed && this.loop ){\r
- if( !( this.proxy.dispatch( X.Event.MEDIA_BEFORE_LOOP ) & X.Callback.PREVENT_DEFAULT ) ){\r
+ if( !( this.proxy.dispatch( X_Event.MEDIA_BEFORE_LOOP ) & X.Callback.PREVENT_DEFAULT ) ){\r
this.looped = true;\r
- this.proxy.dispatch( X.Event.MEDIA_LOOPED );\r
+ this.proxy.dispatch( X_Event.MEDIA_LOOPED );\r
this.play();\r
};\r
return;\r
};\r
- type = X.Event.MEDIA_ENDED;\r
+ type = X_Event.MEDIA_ENDED;\r
this.seekTime = 0;\r
delete this.playing;\r
break;\r
if( X_Audio_HTMLAudioWrapper_ieMobile9Fix ){\r
if( this._playForDuration === 1 ){\r
console.log( 'tu ' + this._rawObject.duration );\r
- if( !this.duration && X.Type.isFinite( this._rawObject.duration ) ){\r
+ if( !this.duration && X_Type_isFinite( this._rawObject.duration ) ){\r
this.duration = this.duration || this._rawObject.duration * 1000;\r
this._playForDuration = 2;\r
\r
} else\r
if( this._rawObject.currentTime === this._lastCurrentTime ){\r
//this.proxy.dispatch( 'seeking' );\r
- this.proxy.dispatch( X.Event.MEDIA_WAITING );\r
+ this.proxy.dispatch( X_Event.MEDIA_WAITING );\r
return;\r
};\r
this._lastCurrentTime = this._rawObject.currentTime;\r
now = X_Audio_HTMLAudioWrapper_currentTimeFix ? X_Timer_now() - this._playTime + this._beginTime : this._rawObject.currentTime * 1000 | 0;\r
if( 0 + end <= 0 + now ){ // なぜか iem9 で必要,,,\r
if( this.loop ){\r
- if( !( this.proxy.dispatch( X.Event.MEDIA_BEFORE_LOOP ) & X.Callback.PREVENT_DEFAULT ) ){\r
+ if( !( this.proxy.dispatch( X_Event.MEDIA_BEFORE_LOOP ) & X.Callback.PREVENT_DEFAULT ) ){\r
this.looped = true;\r
- this.proxy.dispatch( X.Event.MEDIA_LOOPED );\r
+ this.proxy.dispatch( X_Event.MEDIA_LOOPED );\r
this.play();\r
};\r
} else {\r
this.pause();\r
- this.proxy.dispatch( X.Event.MEDIA_ENDED );\r
+ this.proxy.dispatch( X_Event.MEDIA_ENDED );\r
};\r
return;\r
};\r
} else {\r
return;\r
};\r
- type = X.Event.MEDIA_PLAYING;\r
+ type = X_Event.MEDIA_PLAYING;\r
break;\r
\r
case 'durationchange' : // duration属性が更新された場合に発生\r
this.duration = this._rawObject.duration * 1000;\r
} else\r
// Desktop Opera では Infinity, IEM9 では NaN\r
- if( !this.duration && X.Type.isFinite( this._rawObject.duration ) ){\r
+ if( !this.duration && X_Type_isFinite( this._rawObject.duration ) ){\r
\r
//console.log( this._rawObject.duration );\r
\r
if( !this._loaded && ( loaded || e.type === X_Audio_HTMLAudio_playTrigger || e.type === 'loadeddata' ) ){\r
this.autoplay && X.Timer.once( 16, this, this.play );\r
this._loaded = true;\r
- this.proxy.dispatch( X.Event.READY );\r
+ this.proxy.dispatch( X_Event.READY );\r
console.log( 'Loaded! ' + e.type + ' d:' + ( this.duration | 0 ) );\r
return;\r
};\r
\r
\r
if( !this.playing ){\r
- if( X_UA.Chrome ){ // [CHROME][FIX] volume TODO どの version で 修正される?\r
+ if( X_UA[ 'Chrome' ] ){ // [CHROME][FIX] volume TODO どの version で 修正される?\r
// [!] delay\r
X.Timer.once( 0, this, this._fixForChrome );\r
this._rawObject.volume = 0;\r
},\r
\r
// [CHROME][FIX] volume\r
- _fixForChrome : X_UA.Chrome && function(){\r
+ _fixForChrome : X_UA[ 'Chrome' ] && function(){\r
!this._closed && ( this._rawObject.volume = this.volume );\r
},\r
\r
var ok, mineType = 'audio/' + ext;\r
switch( ext ){\r
case 'mp3' :\r
- ok = X_UA.IE || X_UA.Chrome || ( X_UA.Windows && X_UA.Safari );\r
+ ok = X_UA[ 'IE' ] || X_UA[ 'Chrome' ] || ( X_UA[ 'Windows' ] && X_UA[ 'Safari' ] );\r
mineType = 'audio/mpeg';\r
- //if( X_UA.Android && X_UA.Gecko ) mineType = '';\r
+ //if( X_UA[ 'Android' ] && X_UA[ 'Gecko' ] ) mineType = '';\r
break;\r
case 'ogg' :\r
- ok = 15 <= X_UA.Gecko || X_UA.Chrome || X_UA.Opera;\r
- if( X_UA.AndroidBrowser ) mineType = '';\r
+ ok = 15 <= X_UA[ 'Gecko' ] || X_UA[ 'Chrome' ] || X_UA[ 'Opera' ] ;\r
+ if( X_UA[ 'AndroidBrowser' ] ) mineType = '';\r
break;\r
case 'm4a' :\r
- ok = X_UA.IE || X_UA.WebKit;\r
+ ok = X_UA[ 'IE' ] || X_UA[ 'WebKit' ];\r
mineType = 'audio/mp4';\r
break;\r
case 'webm' :\r
- ok = 2 <= X_UA.Gecko || 10.6 <= X_UA.Opera; // firefox4+(Gecko2+)\r
+ ok = 2 <= X_UA[ 'Gecko' ] || 10.6 <= X_UA[ 'Opera' ] ; // firefox4+(Gecko2+)\r
break;\r
case 'wav' :\r
- ok = X_UA.Gecko || X_UA.Opera || ( X_UA.Windows && X_UA.Safari );\r
+ ok = X_UA[ 'Gecko' ] || X_UA[ 'Opera' ] || ( X_UA[ 'Windows' ] && X_UA[ 'Safari' ] );\r
//mineType = 'audio/wav'; // audio/x-wav ?\r
break;\r
default :\r
//console.log( 'HTML Audio ' + ok + ' ext:' + ext );\r
};\r
console.log( 'HTML Audio ' + ok + ' ext:' + ext );\r
- proxy.asyncDispatch( ok ? X_Audio_CAN_PLAY : X_Audio_NOT_PLAY ); */\r
+ */\r
\r
- proxy.asyncDispatch( X_Audio_codecs[ ext ] ? X_Audio_CAN_PLAY : X_Audio_NOT_PLAY );\r
+ proxy.asyncDispatch( { type : X_Event.COMPLETE, canPlay : X_Audio_codecs[ ext ] } );\r
},\r
\r
klass : X_Audio_HTMLAudioWrapper\r
);\r
X_AudioWrapper_updateStates( this, option );\r
\r
- this.listenOnce( X.Event.KILL_INSTANCE );\r
+ this.listenOnce( X_Event.KILL_INSTANCE );\r
},\r
\r
onSLReady : function( sender ){\r
this.playing = false;\r
this._ended = true;\r
this._paused = false;\r
- this.proxy.dispatch( X.Event.ERROR ); // open failed\r
+ this.proxy.dispatch( X_Event.ERROR ); // open failed\r
break;\r
\r
case 'MediaOpened' :\r
//this.proxy.asyncDispatch( 'loadeddata' );\r
//this.proxy.asyncDispatch( 'canplay' );\r
//this.proxy.asyncDispatch( 'canplaythrough' );\r
- this.proxy.asyncDispatch( X.Event.READY );\r
+ this.proxy.asyncDispatch( X_Event.READY );\r
\r
this.autoplay && X.Timer.once( 16, this, this.play );\r
break;\r
case 'Opening' :\r
switch( this._lastUserAction ){\r
case 'play' :\r
- this.proxy.dispatch( X.Event.MEDIA_WAITING );\r
+ this.proxy.dispatch( X_Event.MEDIA_WAITING );\r
break;\r
case 'seek' :\r
- this.proxy.dispatch( X.Event.MEDIA_SEEKING );\r
+ this.proxy.dispatch( X_Event.MEDIA_SEEKING );\r
break;\r
case 'pause' :\r
break;\r
this.playing = false;\r
this._ended = true;\r
this._paused = false;\r
- this.proxy.dispatch( X.Event.ERROR );\r
+ this.proxy.dispatch( X_Event.ERROR );\r
break;\r
\r
// userAction.pause() -> MediaState('Paused') -> x\r
this.seekTime = 0;\r
this._ended = true;\r
this._paused = false;\r
- this.proxy.dispatch( X.Event.MEDIA_ENDED );\r
+ this.proxy.dispatch( X_Event.MEDIA_ENDED );\r
this._currentTime( this.startTime );\r
break;\r
case 'pause':\r
this.playing = true;\r
this._ended = false;\r
this._paused = false;\r
- this.proxy.dispatch( X.Event.MEDIA_PLAYING );\r
+ this.proxy.dispatch( X_Event.MEDIA_PLAYING );\r
break;\r
\r
// stop()\r
};\r
break;\r
\r
- case X.Event.KILL_INSTANCE :\r
+ case X_Event.KILL_INSTANCE :\r
if( this._onload ){\r
// window への delete に ie5 は対応しないが、そもそも ie5 は Silverlight に非対応\r
window[ this._onload ] = null;\r
\r
close : function(){\r
this.playing && this.pause();\r
- this.proxy.dispatch( X.Event.MEDIA_ENDED );\r
+ this.proxy.dispatch( X_Event.MEDIA_ENDED );\r
this.kill();\r
},\r
\r
delete this._interval;\r
return X_Callback_UN_LISTEN;\r
};\r
- this.proxy.dispatch( X.Event.MEDIA_PLAYING );\r
+ this.proxy.dispatch( X_Event.MEDIA_PLAYING );\r
},\r
\r
_onEnded : function(){\r
\r
if( time <= this._beginTime ){\r
console.log( '== waiting' );\r
- this.proxy.dispatch( X.Event.MEDIA_WAITING );\r
+ this.proxy.dispatch( X_Event.MEDIA_WAITING );\r
this._timerID = X.Timer.once( X_AudioWrapper_getEndTime( this ) - this._beginTime, this, this._onEnded );\r
return;\r
};\r
};\r
\r
if( this.loop ){\r
- if( !( this.proxy.dispatch( X.Event.MEDIA_BEFORE_LOOP ) & X.Callback.PREVENT_DEFAULT ) ){\r
+ if( !( this.proxy.dispatch( X_Event.MEDIA_BEFORE_LOOP ) & X.Callback.PREVENT_DEFAULT ) ){\r
this.looped = true;\r
- this.proxy.dispatch( X.Event.MEDIA_LOOPED );\r
+ this.proxy.dispatch( X_Event.MEDIA_LOOPED );\r
this.play();\r
};\r
} else {\r
this.pause();\r
- this.proxy.dispatch( X.Event.MEDIA_ENDED );\r
+ this.proxy.dispatch( X_Event.MEDIA_ENDED );\r
};\r
};\r
},\r
\r
detect : function( proxy, source, ext ){\r
var ok = ext === 'mp3' || ext === 'wma' || ext === 'wav';\r
- proxy.asyncDispatch( ok ? X_Audio_CAN_PLAY : X_Audio_NOT_PLAY ); \r
+ proxy.asyncDispatch( { type : X_Event.COMPLETE, canPlay : ok } ); \r
},\r
\r
klass : X_Audio_SLAudioWrapper\r
* Mobile Opera11 は Audio をサポートするがイベントが取れない\r
* iframe 内で生成して、Audio Sprite の preset で再生できないか?\r
*/\r
-var X_Audio_Sprite_shouldUse = window.HTMLAudioElement && ( X_UA.iOS || X_UA.AndroidBrowser || X_UA.OperaMobile || X_UA.OperaTablet ), // Flash がない\r
- X_Audio_Sprite_useVideoForMulti = 4 <= X_UA.AndroidBrowser && 534.3 < X_UA.AndroidBrowserWebkit, // ドスパラパッドはビデオのインライン再生が不可 \r
+var X_Audio_Sprite_shouldUse = window.HTMLAudioElement && ( X_UA[ 'iOS' ] || X_UA[ 'AndroidBrowser' ] || X_UA[ 'OperaMobile' ] || X_UA[ 'OperaTablet' ] ), // Flash がない\r
+ X_Audio_Sprite_useVideoForMulti = 4 <= X_UA[ 'AndroidBrowser' ] && 534.3 < X_UA[ 'AndroidBrowserWebkit' ], // ドスパラパッドはビデオのインライン再生が不可 \r
X_Audio_Sprite_needTouchAndroid = X_Audio_Sprite_useVideoForMulti, \r
- X_Audio_Sprite_needTouchFirst = X_UA.iOS || X_Audio_Sprite_needTouchAndroid || ( X_UA.WinPhone && X_UA.IE9 ),\r
- X_Audio_Sprite_enableMultiTrack = !( X_UA.iOS && !X_Audio_WebAudio_context ) && !( X_UA.AndroidBrowser4 && X_UA.AndroidBrowserWebkit <= 534.3 ),\r
- X_Audio_Sprite_enableVolume = window.HTMLAudioElement && ( !X_UA.iOS && !X_UA.AndroidBrowser && !X_UA.OperaMobile && !X_UA.OperaTablet ), // TODO fennec は 25以上\r
+ X_Audio_Sprite_needTouchFirst = X_UA[ 'iOS' ] || X_Audio_Sprite_needTouchAndroid || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ),\r
+ X_Audio_Sprite_enableMultiTrack = !( X_UA[ 'iOS' ] && !X_Audio_WebAudio_context ) && !( X_UA[ 'AndroidBrowser4' ] && X_UA[ 'AndroidBrowserWebkit' ] <= 534.3 ),\r
+ X_Audio_Sprite_enableVolume = window.HTMLAudioElement && ( !X_UA[ 'iOS' ] && !X_UA[ 'AndroidBrowser' ] && !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] ), // TODO fennec は 25以上\r
X_Audio_Sprite_maxTracks = !X_Audio_Sprite_enableMultiTrack ? 1 : X_Audio_Sprite_useVideoForMulti ? 2 : 9,\r
X_Audio_Sprite_lengthSilence = 10000, // 一番最初の無音部分の長さ\r
X_Audio_Sprite_lengthDistance = 5000, // 音間の無音の長さ\r
presets : {},\r
BGMs : {},\r
tracks : [],\r
- pauseTracks : [], // X.Event.DEACTIVATE によって pause した再生中のトラックたち。\r
+ pauseTracks : [], // X_Event.DEACTIVATE によって pause した再生中のトラックたち。\r
volume : 1,\r
bgmTrack : null,\r
bgmPosition : 0,\r
X_Audio_Sprite_instance.close();\r
} else {\r
X_Audio_Sprite_instance = X_Class_override( new X.EventDispatcher(), X_Audio_Sprite_members );\r
- X_ViewPort.listen( [ X.Event.VIEW_ACTIVATE, X.Event.VIEW_DEACTIVATE ], X_Audio_Sprite_instance, X_Audio_Sprite_handleEvent );\r
+ X_ViewPort.listen( [ X_Event.VIEW_ACTIVATE, X_Event.VIEW_DEACTIVATE ], X_Audio_Sprite_instance, X_Audio_Sprite_handleEvent );\r
};\r
X_Audio_Sprite_instance.setup( setting );\r
return X_Audio_Sprite_instance;\r
* BGM_02 : [ '56.00', '1:15.230', true ]\r
* }\r
* \r
- * X.Event.BACKEND_READY\r
- * X.Event.BACKEND_NONE\r
+ * X_Event.BACKEND_READY\r
+ * X_Event.BACKEND_NONE\r
* \r
- * X.Event.READY\r
- * X.Event.MEDIA_LOOPED\r
- * X.Event.MEDIA_ENDED\r
+ * X_Event.READY\r
+ * X_Event.MEDIA_LOOPED\r
+ * X_Event.MEDIA_ENDED\r
* \r
*/\r
\r
\r
for( k in setting ){\r
v = setting[ k ];\r
- if( X.Type.isArray( v ) && v !== urls ){\r
+ if( X_Type_isArray( v ) && v !== urls ){\r
v = X.Object.cloneArray( v );\r
for( i = v.length; i; ){\r
--i;\r
tracks.push( X.Audio( urls, X.Object.clone( option ) ) );\r
};\r
\r
- tracks[ n - 1 ].listenOnce( [ X.Event.BACKEND_READY, X.Event.BACKEND_NONE ], this, X_Audio_Sprite_handleEvent );\r
+ tracks[ n - 1 ].listenOnce( [ X_Event.BACKEND_READY, X_Event.BACKEND_NONE ], this, X_Audio_Sprite_handleEvent );\r
\r
X_Audio_Sprite_instance.numTracks = n;\r
},\r
var tracks = X_Audio_Sprite_TEMP.tracks,\r
i = 0, l = tracks.length;\r
for( ; i < l; ++i ){\r
- if( X_UA.WinPhone ){\r
+ if( X_UA[ 'WinPhone' ] ){\r
console.log( 'touch -> play()' );\r
//tracks[ i ].play( 0, X_Audio_Sprite_lengthSilence, true, 0, X_Audio_Sprite_lengthSilence ).seek( 0 );\r
this.pause( i );\r
track = X_Audio_Sprite_TEMP.bgmTrack = tracks[ 0 ];\r
};\r
\r
- if( track.listen( [ X.Event.MEDIA_PLAYING, X.Event.MEDIA_BEFORE_LOOP ], this, X_Audio_Sprite_handleEvent ).isPlaying() ){\r
+ if( track.listen( [ X_Event.MEDIA_PLAYING, X_Event.MEDIA_BEFORE_LOOP ], this, X_Audio_Sprite_handleEvent ).isPlaying() ){\r
track\r
.state( {\r
loop : true,\r
if( 1 < tracks.length ){\r
track = X_Audio_Sprite_getTrackEnded( X_Audio_Sprite_TEMP.bgmPlaying );\r
track\r
- .listen( [ X.Event.MEDIA_PLAYING, X.Event.MEDIA_BEFORE_LOOP ], this, X_Audio_Sprite_handleEvent )\r
+ .listen( [ X_Event.MEDIA_PLAYING, X_Event.MEDIA_BEFORE_LOOP ], this, X_Audio_Sprite_handleEvent )\r
.state( { looped : false } )\r
.play( preset[ 0 ], preset[ 1 ], true, 0, X_Audio_Sprite_lengthSilence );\r
} else {\r
};\r
track = tracks[ 0 ];\r
\r
- if( track.listen( [ X.Event.MEDIA_PLAYING, X.Event.MEDIA_BEFORE_LOOP ], this, X_Audio_Sprite_handleEvent ).isPlaying() ){\r
+ if( track.listen( [ X_Event.MEDIA_PLAYING, X_Event.MEDIA_BEFORE_LOOP ], this, X_Audio_Sprite_handleEvent ).isPlaying() ){\r
track\r
.state( {\r
loop : true,\r
X_Audio_Sprite_TEMP.bgmTrack = null;\r
};\r
track && track.play( 0, X_Audio_Sprite_lengthSilence, true, 0, X_Audio_Sprite_lengthSilence ).seek( 0 );\r
- this.asyncDispatch( X.Event.MEDIA_PAUSED );\r
+ this.asyncDispatch( X_Event.MEDIA_PAUSED );\r
return this;\r
},\r
\r
var i, tracks, track, _e;\r
\r
switch( e.type ){\r
- case X.Event.BACKEND_READY :\r
+ case X_Event.BACKEND_READY :\r
_e = {\r
- type : e.type,\r
+ type : X_Event.BACKEND_READY,\r
source : e.source,\r
backendName : e.backendName\r
};\r
this.asyncDispatch( _e );\r
\r
e.target\r
- .unlisten( X.Event.BACKEND_NONE, this, X_Audio_Sprite_handleEvent )\r
- .listenOnce( X.Event.READY, this, X_Audio_Sprite_handleEvent );\r
+ .unlisten( X_Event.BACKEND_NONE, this, X_Audio_Sprite_handleEvent )\r
+ .listenOnce( X_Event.READY, this, X_Audio_Sprite_handleEvent );\r
\r
// READY, needTouchForPlay, needTouchForLoad\r
if( X_Audio_HTMLAudioWrapper_durationFix ){\r
};\r
break;\r
\r
- case X.Event.BACKEND_NONE :\r
- this.asyncDispatch( X.Event.BACKEND_NONE );\r
- e.target.unlisten( X.Event.BACKEND_READY, this, X_Audio_Sprite_handleEvent );\r
+ case X_Event.BACKEND_NONE :\r
+ this.asyncDispatch( X_Event.BACKEND_NONE );\r
+ e.target.unlisten( X_Event.BACKEND_READY, this, X_Audio_Sprite_handleEvent );\r
break;\r
\r
- case X.Event.READY :\r
+ case X_Event.READY :\r
console.log( 'X.AudioSprite - Ready!' );\r
if( X_Audio_Sprite_needTouchAndroid ){\r
for( i = 0; i < X_Audio_Sprite_TEMP.tracks.length; ++i ){\r
X_Audio_Sprite_instance.pause( i );\r
};\r
- e.target.listenOnce( X.Event.MEDIA_PLAYING, this, this.asyncDispatch, [ X.Event.READY ] ); // Android 標準ブラウザ\r
+ e.target.listenOnce( X_Event.MEDIA_PLAYING, this, this.asyncDispatch, [ X_Event.READY ] ); // Android 標準ブラウザ\r
return;\r
};\r
- this.asyncDispatch( X.Event.READY );\r
+ this.asyncDispatch( X_Event.READY );\r
break;\r
\r
- case X.Event.MEDIA_PLAYING :\r
- ( e.target === X_Audio_Sprite_TEMP.bgmTrack || !e.target.state().looped ) && this.asyncDispatch( X.Event.MEDIA_PLAYING );\r
+ case X_Event.MEDIA_PLAYING :\r
+ ( e.target === X_Audio_Sprite_TEMP.bgmTrack || !e.target.state().looped ) && this.asyncDispatch( X_Event.MEDIA_PLAYING );\r
break;\r
\r
- case X.Event.MEDIA_BEFORE_LOOP :\r
+ case X_Event.MEDIA_BEFORE_LOOP :\r
if( e.target === X_Audio_Sprite_TEMP.bgmTrack ){\r
X_Audio_Sprite_TEMP.bgmLooped = true;\r
- this.asyncDispatch( X.Event.MEDIA_LOOPED ); // TODO uid\r
+ this.asyncDispatch( X_Event.MEDIA_LOOPED ); // TODO uid\r
} else {\r
if( e.target.state().looped ){\r
- //this.asyncDispatch( X.Event.MEDIA_LOOPED ); // TODO uid\r
+ //this.asyncDispatch( X_Event.MEDIA_LOOPED ); // TODO uid\r
} else {\r
- this.asyncDispatch( X.Event.MEDIA_ENDED ); // TODO uid\r
+ this.asyncDispatch( X_Event.MEDIA_ENDED ); // TODO uid\r
};\r
\r
// single track | iOS\r
};\r
break;\r
\r
- case X.Event.VIEW_ACTIVATE :\r
+ case X_Event.VIEW_ACTIVATE :\r
console.log( '■ アクティブ' );\r
// track.play(); or iOS need touch??\r
tracks = X_Audio_Sprite_TEMP.pauseTracks;\r
while( tracks.length ) tracks.pop().play();\r
break;\r
\r
- case X.Event.VIEW_DEACTIVATE :\r
+ case X_Event.VIEW_DEACTIVATE :\r
console.log( '■ デアクティブ' );\r
// track.pause();\r
tracks = X_Audio_Sprite_TEMP.tracks;\r
};\r
break;\r
\r
- case X.Event.KILL_INSTANCE :\r
- X_ViewPort.unlisten( [ X.Event.VIEW_ACTIVATE, X.Event.VIEW_DEACTIVATE ], this, X_Audio_Sprite_handleEvent );\r
+ case X_Event.KILL_INSTANCE :\r
+ X_ViewPort.unlisten( [ X_Event.VIEW_ACTIVATE, X_Event.VIEW_DEACTIVATE ], this, X_Audio_Sprite_handleEvent );\r
this.close();\r
break;\r
};\r
for( p in defs ){\r
if( X_EMPTY_OBJECT[ p ] ) continue;\r
if( p === '_last' ) continue;\r
- if( !X.Type.isArray( def = defs[ p ] ) ) continue;\r
+ if( !X_Type_isArray( def = defs[ p ] ) ) continue;\r
F[ p ] = def;\r
- if( !base || !X.Type.isArray( base[ p ] ) ){\r
+ if( !base || !X_Type_isArray( base[ p ] ) ){\r
def.No = z += n;\r
// add\r
n = def[ 3 ] & X.UI.Attr.Type.QUARTET ? 4 :\r
_START_BUBLEUP : X_Event_last + 0.5, \r
\r
// raw pointing device event\r
- \r
_POINTER_DOWN : ++X_Event_last,\r
_POINTER_UP : ++X_Event_last,\r
_POINTER_MOVE : ++X_Event_last,\r
_POINTER_CANCEL : ++X_Event_last,\r
- _TOUCH_START : ++X_Event_last,\r
- _TOUCH_END : ++X_Event_last,\r
- _TOUCH_MOVE : ++X_Event_last,\r
- _TOUCH_CANCEL : ++X_Event_last,\r
- _MOUSE_DOWN : ++X_Event_last,\r
- _MOUSE_UP : ++X_Event_last,\r
- _MOUSE_MOVE : ++X_Event_last,\r
- _MOUSE_CANCEL : ++X_Event_last,\r
\r
FILE_DRAG : ++X_Event_last,\r
FILE_DRAG_START : ++X_Event_last,\r
NameToID : {}\r
};\r
\r
-// raw pointing device event\r
-//if( X_UA_HID.POINTER ){\r
X.UI.Event.IdToName[ X.UI.Event._POINTER_DOWN ] = 'pointerdown';\r
X.UI.Event.IdToName[ X.UI.Event._POINTER_UP ] = 'pointerup';\r
X.UI.Event.IdToName[ X.UI.Event._POINTER_MOVE ] = 'pointermove';\r
X.UI.Event.IdToName[ X.UI.Event._POINTER_CANCEL ] = 'pointercancel';\r
-/*} else {\r
- \r
- if( X_UA_HID.TOUCH ){\r
- X.UI.Event.IdToName[ X.UI.Event._TOUCH_START ] = 'touchstart';\r
- X.UI.Event.IdToName[ X.UI.Event._TOUCH_END ] = 'touchend';\r
- X.UI.Event.IdToName[ X.UI.Event._TOUCH_MOVE ] = 'touchmove';\r
- X.UI.Event.IdToName[ X.UI.Event._TOUCH_CANCEL ] = 'touchcancel';\r
- };\r
\r
- X.UI.Event.IdToName[ X.UI.Event._MOUSE_DOWN ] = 'mousedown';\r
- X.UI.Event.IdToName[ X.UI.Event._MOUSE_UP ] = 'mouseup';\r
- X.UI.Event.IdToName[ X.UI.Event._MOUSE_MOVE ] = 'mousemove';\r
- X.UI.Event.IdToName[ X.UI.Event._MOUSE_CANCEL ] = 'mouseleave'; // ??\r
-};*/\r
\r
\r
( function( IdToName, NameToID, p ){\r
type |= POINTER;\r
switch( e.pointerType ){\r
case 'touch' :\r
- case 2 : //e.MSPOINTER_TYPE_TOUCH :\r
type |= TOUCH; break;\r
case 'pen' :\r
- case 3 : //e.MSPOINTER_TYPE_PEN :\r
type |= PEN; break;\r
case 'mouse' :\r
- case 4 : //e.MSPOINTER_TYPE_MOUSE :\r
type |= MOUSE; break;\r
default :\r
return;\r
};\r
- } else\r
- if( e.touches ){\r
- type |= TOUCH;\r
- } else {\r
- type |= MOUSE;\r
};\r
\r
// onmouseup, but when touchend has been fired we do nothing.\r
// this is for touchdevices which also fire a mouseup on touchend\r
if( type & MOUSE && touch_triggered ){\r
return X.Callback.STOP_NOW | X.Callback.PREVENT_DEFAULT;\r
- }\r
+ } else\r
// mousebutton must be down or a touch event\r
- else if (\r
- type & TOUCH || //sourceEventType.match(/touch/) || // touch events are always on screen\r
+ if( type & TOUCH || //sourceEventType.match(/touch/) || // touch events are always on screen\r
( type & POINTER && type & START ) || //sourceEventType.match(/pointerdown/) || // pointerevents touch\r
( type & MOUSE && e.button === 0 ) //(sourceEventType.match(/mouse/) && e.which === 1) // mouse is pressed\r
){\r
enable_detect = true;\r
};\r
\r
- console.log( 'Hammer@handleEvent ' + IdToGestureID[ e.type ] + ' ' + e.type + ' ' + X.UI.Event._POINTER_DOWN + ' ' + enable_detect );\r
+ //console.log( 'Hammer@handleEvent ' + IdToGestureID[ e.type ] + ' ' + e.type + ' ' + X.UI.Event._POINTER_DOWN + ' ' + enable_detect );\r
\r
// we are in a touch event, set the touch triggered bool to true,\r
// this for the conflicts that may occur on ios and android\r
Detection.register( Gestures[ name ] );\r
};\r
\r
- //if( X_UA_HID.POINTER ){\r
- Hammer.EVENT_TYPES_START = [ X.UI.Event._POINTER_DOWN ];\r
- types = [ X.UI.Event._POINTER_MOVE, X.UI.Event._POINTER_UP, X.UI.Event._POINTER_CANCEL ];\r
- /*} else\r
- if( X_UA_HID.TOUCH ){\r
- Hammer.EVENT_TYPES_START = [ X.UI.Event._TOUCH_START, X.UI.Event._MOUSE_DOWN ];\r
- types = [ X.UI.Event._MOUSE_MOVE, X.UI.Event._MOUSE_UP, X.UI.Event._MOUSE_CANCEL,\r
- X.UI.Event._TOUCH_MOVE, X.UI.Event._TOUCH_END, X.UI.Event._TOUCH_CANCEL ];\r
- } else {\r
- Hammer.EVENT_TYPES_START = [ X.UI.Event._MOUSE_DOWN ];\r
- types = [ X.UI.Event._MOUSE_MOVE, X.UI.Event._MOUSE_UP, X.UI.Event._MOUSE_CANCEL ];\r
- }; */\r
+ Hammer.EVENT_TYPES_START = [ X.UI.Event._POINTER_DOWN ];\r
+ types = [ X.UI.Event._POINTER_MOVE, X.UI.Event._POINTER_UP, X.UI.Event._POINTER_CANCEL ];\r
\r
// Add touch events on the document\r
Utils.addEvents( uinodeRoot, types, Hammer.prototype.handleEvent );\r
/*\r
* "Android version < 2.2" return ev.touches.length === 1 when touchend, others return ev.touches.length === 0\r
*/\r
- Hammer.DO_TOUCHES_FIX = Hammer.HAS_TOUCHEVENTS && ( X_UA.Android < 2.2 || X_UA.Blink || X_UA.Opera );\r
+ Hammer.DO_TOUCHES_FIX = Hammer.HAS_TOUCHEVENTS && ( X_UA[ 'Android' ] < 2.2 || X_UA[ 'Blink' ] || X_UA[ 'Opera' ] );\r
\r
// detect touchevents\r
Hammer.HAS_POINTEREVENTS = true; // navigator.pointerEnabled || navigator.msPointerEnabled;\r
IdToGestureID[ X.UI.Event._POINTER_UP ] = END;\r
IdToGestureID[ X.UI.Event._POINTER_CANCEL ] = END;\r
\r
- IdToGestureID[ X.UI.Event._TOUCH_START ] = START;\r
- IdToGestureID[ X.UI.Event._TOUCH_MOVE ] = MOVE;\r
- IdToGestureID[ X.UI.Event._TOUCH_END ] = END;\r
- IdToGestureID[ X.UI.Event._TOUCH_CANCEL ] = END;\r
- \r
- IdToGestureID[ X.UI.Event._MOUSE_DOWN ] = START;\r
- IdToGestureID[ X.UI.Event._MOUSE_MOVE ] = MOVE;\r
- IdToGestureID[ X.UI.Event._MOUSE_UP ] = END;\r
- IdToGestureID[ X.UI.Event._MOUSE_CANCEL ] = END;\r
- \r
Utils = {\r
\r
/**\r
quartet = !!( type & X.UI.Attr.Type.QUARTET ),\r
_v, i, l, nodes, root, roots;\r
\r
- if( X.Type.isString( v ) ){\r
+ if( X_Type_isString( v ) ){\r
//v = v.toLowercase();\r
if( url || fontName ){\r
// good\r
if( v.indexOf( ' ' ) !== -1 ){\r
v = v.split( ' ' );\r
} else\r
- if( color && X.Type.isNumber( _v = X_Node_CSS_objToIEFilterText( v ) ) ){\r
+ if( color && X_Type_isNumber( _v = X_Node_CSS_objToIEFilterText( v ) ) ){\r
v = _v;\r
} else {\r
// bad\r
};\r
};\r
\r
- if( ( quartet || combi ) && !X.Type.isArray( v ) ){\r
+ if( ( quartet || combi ) && !X_Type_isArray( v ) ){\r
v = [ v ];\r
};\r
\r
- if( X.Type.isNumber( v ) ){\r
+ if( X_Type_isNumber( v ) ){\r
if( \r
( length && ( 0 <= v ) ) ||\r
( minusLen && ( v <= 0 ) ) ||\r
return;\r
};\r
} else\r
- if( X.Type.isBoolean( v ) && !flag ){\r
+ if( X_Type_isBoolean( v ) && !flag ){\r
return;\r
} else\r
- if( X.Type.isArray( v ) ){\r
+ if( X_Type_isArray( v ) ){\r
if( v.length <= 4 && quartet ){\r
type &= ~X.UI.Attr.Type.QUARTET;\r
switch( v.length ){\r
break;\r
case X.UI.Attr.Support.width.No :\r
this.autoWidth = v === X.UI.Attr.AUTO;\r
- this.percentWidth = X.Type.isString( v );\r
+ this.percentWidth = X_Type_isString( v );\r
break;\r
case X.UI.Attr.Support.height.No :\r
this.autoHeight = v === X.UI.Attr.AUTO;\r
- this.percentHeight = X.Type.isString( v );\r
+ this.percentHeight = X_Type_isString( v );\r
break;\r
};\r
\r
url = !!( type & X.UI.Attr.Type.URL ),\r
fontName = !!( type & X.UI.Attr.Type.FONT_NAME );\r
\r
- if( X.Type.isNumber( v ) ){\r
+ if( X_Type_isNumber( v ) ){\r
if( auto && v === X.UI.Attr.AUTO ) return 'auto';\r
if( length || minusLen ) return v + 'em';\r
if( numerical ) return v;\r
return '#' + v.toString( 16 );\r
};\r
};\r
- if( X.Type.isString( v ) ){\r
+ if( X_Type_isString( v ) ){\r
if( percent || minusPct || url || fontName ) return v;\r
};\r
},\r
list = support[ 4 ];\r
if( list ) return list[ v ];\r
\r
- if( type & X.UI.Attr.Type.COLOR && X.Type.isNumber( v ) ) return v;\r
- if( !( type & X.UI.Attr.Type.NUMERICAL ) && X.Type.isNumber( v ) ) return v + 'em';\r
+ if( type & X.UI.Attr.Type.COLOR && X_Type_isNumber( v ) ) return v;\r
+ if( !( type & X.UI.Attr.Type.NUMERICAL ) && X_Type_isNumber( v ) ) return v + 'em';\r
return v;\r
},\r
\r
this.xnode\r
.css( 'left', x ? x + 'em' : 0 )\r
.css( 'top', y ? y + 'em' : 0 )\r
- .css( 'width', this.contentWidth ? X.UI._AbstractUINode.ceil( this.contentWidth ) + 'em' : 0 )\r
+ .css( 'width', this.contentWidth ? X.UI._AbstractUINode.ceil( this.contentWidth ) + 'em' : 0 )\r
.css( 'height', this.contentHeight ? X.UI._AbstractUINode.ceil( this.contentHeight ) + 'em' : 0 )\r
.css( 'padding', this._createCssText( 'padding' ) )\r
.css( 'borderWidth', this._createCssText( 'borderWidth' ) );\r
++counter[ type ];\r
} else {\r
counter[ type ] = 1; \r
- root.xnodeInteractiveLayer.listen( X.UI.Event.IdToName[ type ], X.UI._eventRellay );\r
+ root.xnodeInteractiveLayer.listen( X.UI.Event.IdToName[ type ], X_UI_eventRellay );\r
};\r
};\r
};\r
if( !counter[ type ] ) return this;\r
--counter[ type ];\r
if( counter[ type ] === 0 ){\r
- root.xnodeInteractiveLayer.unlisten( X.UI.Event.IdToName[ type ], X.UI._eventRellay );\r
+ root.xnodeInteractiveLayer.unlisten( X.UI.Event.IdToName[ type ], X_UI_eventRellay );\r
delete counter[ type ];\r
};\r
};\r
/*\r
* String の場合は必ず %\r
*/ \r
- if( X.Type.isString( styleValue ) ){\r
+ if( X_Type_isString( styleValue ) ){\r
return srcValue * parseFloat( styleValue ) / 100;\r
};\r
- if( !X.Type.isNumber( styleValue ) ) return 0;\r
+ if( !X_Type_isNumber( styleValue ) ) return 0;\r
return styleValue;\r
};\r
\r
attr : function( nameOrObject, valueOrUnit ){\r
var p = X_Class_getPrivate( this ),\r
layout, k, def, attrs, v;\r
- if( nameOrObject && X.Type.isObject( nameOrObject ) ){\r
+ if( nameOrObject && X_Type_isObject( nameOrObject ) ){\r
// setter\r
layout = p.parentData && p.parentData.layout.overrideAttrsForChild; // root には parent がない\r
for( k in nameOrObject ){\r
};\r
};\r
} else\r
- if( X.Type.isString( nameOrObject ) ){\r
+ if( X_Type_isString( nameOrObject ) ){\r
if( valueOrUnit !== undefined ){\r
if( 'em,%'.indexOf( valueOrUnit ) === -1 ){\r
// setter\r
//throw new Error( 'インスタンスはすでに親に追加されています ' + arg );\r
};\r
} else\r
+ if( arg.instanceOf && arg.instanceOf( Node ) ){\r
+ //this.layout = arg;\r
+ } else\r
if( arg.instanceOf && arg.instanceOf( X.UI.Layout.Base ) ){\r
//this.layout = arg;\r
} else\r
- if( X.Type.isObject( arg ) ){\r
+ if( X_Type_isObject( arg ) ){\r
if( attrs ){\r
attrs = X_Class_override( attrs, arg );\r
} else {\r
removeAt : function( from, length ){\r
var uinodes = this.uinodes,\r
i = uinodes.length,\r
- to = from + ( X.Type.isNumber( length ) && 1 <= length ? length : 1 ),\r
+ to = from + ( X_Type_isNumber( length ) && 1 <= length ? length : 1 ),\r
node;\r
for( ; i; ){\r
node = uinodes[ --i ];\r
privateKlass = arg;\r
layout = privateKlass.prototype.layout;\r
} else\r
- if( X.Type.isObject( arg ) ){\r
+ if( X_Type_isObject( arg ) ){\r
if( attrs ){\r
X_Class_override( attrs, arg, true );\r
} else {\r
attrs = arg;\r
};\r
} else\r
- if( X.Type.isString( arg ) ){\r
+ if( X_Type_isString( arg ) ){\r
boxName = arg;\r
};\r
};\r
containerNode : null,\r
\r
Constructor : function( layout, args ){\r
+ var uinodes, i, l, node, after, index = 0;\r
\r
this.Super( layout, args );\r
- \r
- // xnode の追加が可能\r
- \r
- var uinodes = this.uinodes,\r
- i = uinodes.length,\r
- node;\r
+\r
+ uinodes = this.uinodes;\r
+ l = i = uinodes.length;\r
+\r
for( ; i; ){\r
node = uinodes[ --i ];\r
if( node.forContainer === true ){\r
if( !this.containerNode ){\r
//throw new Error( 'ContainerNode が設定されてい\ません!ContainerNode はクロームボックスにひとつ、生成時に設定できます ' );\r
};\r
+ \r
+ for( i = 0, l = args.length; i < l; ++i ){\r
+ node = args[ i ];\r
+ if( node === this.containerNode ){\r
+ after = true;\r
+ index = 0;\r
+ };\r
+ if( node.instanceOf && node.instanceOf( Node ) ){\r
+ \r
+ };\r
+ };\r
}\r
}\r
);\r
\r
-(function(){\r
\r
-var m = Math,\r
- ABS = new Function( 'v', 'return v<0?-v:v' );\r
-\r
- function Options(){};\r
- \r
- X_Class_override( Options.prototype, {\r
- hScroll : true,\r
- vScroll : true,\r
- x : 0,\r
- y : 0,\r
- bounce : true,\r
- bounceLock : false,\r
- momentum : true,\r
- lockDirection : true,\r
- useTransform : true,\r
- useTransition : true,\r
- topOffset : 0,\r
- checkDOMChanges : false, // Experimental\r
- handleClick : true,\r
- \r
- // Scrollbar\r
- hScrollbar : true,\r
- vScrollbar : true,\r
- fixedScrollbar : X_UA.Android,\r
- hideScrollbar : X_UA.iOS,\r
- fadeScrollbar : X_UA.iOS, //&& has3d,\r
- scrollbarClass : '',\r
- \r
- // Zoom\r
- zoom : false,\r
- zoomMin : 1,\r
- zoomMax : 4,\r
- doubleTapZoom : 2,\r
- wheelAction : 'scroll',\r
- \r
- // Snap\r
- snap : false,\r
- snapThreshold : 1 //,\r
- });\r
-\r
- function Scrollbar( owner, dir ){\r
- this.owner = owner;\r
- this.options = owner.options;\r
- this.dir = dir;\r
- if( dir === 'h' ){\r
- this.XorY = 'x';\r
- this.widthOrHeight = 'width';\r
- this.transrateXorY = 'translateX(';\r
- };\r
+function X_UI_ScrollBox_momentum( current, start, time, lowerMargin, wrapperSize, deceleration ){\r
+ var distance = current - start,\r
+ speed = Math.abs( distance ) / time,\r
+ destination,\r
+ duration;\r
+\r
+ deceleration = deceleration === undefined ? 0.0006 : deceleration;\r
+\r
+ destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );\r
+ duration = speed / deceleration;\r
+\r
+ if( destination < lowerMargin ){\r
+ destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin;\r
+ distance = Math.abs( destination - current );\r
+ duration = distance / speed;\r
+ } else\r
+ if ( destination > 0 ) {\r
+ destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;\r
+ distance = Math.abs( current ) + destination;\r
+ duration = distance / speed;\r
};\r
- X_Class_override( Scrollbar.prototype, {\r
- owner : null,\r
- dir : null,\r
- options : null,\r
- XorY : 'y',\r
- widthOrHeight : 'height',\r
- transrateXorY : 'translateY(',\r
- active : false,\r
- xnodeWrapper : null,\r
- xnodeIndicator : null,\r
- wrapperSize : 0,\r
- indicatorSize : 0,\r
- maxScroll : 0,\r
- scrollPercent : 0,\r
- \r
- update : function(){\r
- // remove scrollbar\r
- if( !this.active ){\r
- if( this.xnodeWrapper ){\r
- X.CSS.transform && this.xnodeIndicator.css( 'transform', '' );\r
- this.xnodeWrapper.css( 'display', 'none' );\r
- };\r
- return;\r
- };\r
- \r
- // create scrollbar\r
- if( !this.xnodeWrapper ){\r
- // Create the scrollbar wrapper\r
- this.xnodeWrapper = this.owner.xnodeTarget.create( 'div' )\r
- .className(\r
- this.options.scrollbarClass ?\r
- this.options.scrollbarClass + this.dir.toUpperCase() :\r
- this.dir === 'h' ?\r
- ( this.vScrollbar && this.vScrollbar.active ? 'ScrollBox-Scrollbar-Wrapper-V-withH' : 'ScrollBox-Scrollbar-Wrapper-H' ) :\r
- ( this.hScrollbar && this.hScrollbar.active ? 'ScrollBox-Scrollbar-Wrapper-H-withV' : 'ScrollBox-Scrollbar-Wrapper-V' ) \r
- );\r
- \r
- this.options.fadeScrollbar &&\r
- this.xnodeWrapper.css(\r
- {\r
- opacity : 0,\r
- transitionProperty : 'opacity',\r
- transitionDuration : '350ms'\r
- }\r
- );\r
- \r
- // Create the scrollbar indicator\r
- \r
- this.xnodeIndicator = this.xnodeWrapper.create( 'div' );\r
- \r
- !this.options.scrollbarClass &&\r
- this.xnodeIndicator.className(\r
- this.dir === 'h' ?\r
- 'ScrollBox-Scrollbar-Indicator-H' :\r
- 'ScrollBox-Scrollbar-Indicator-V'\r
- );\r
- //if (this.options.useTransition) bar.style.cssText += ';' + cssVendor + 'transition-timing-function:cubic-bezier(0.33,0.66,0.66,1)';\r
- };\r
- \r
- if( this.dir === 'h' ){\r
- this.wrapperSize = this.hScrollbarWrapper.clientWidth;\r
- this.indicatorSize = m.max( m.round( wrapperSize * wrapperSize / this.owner.scrollerW ), 8 );\r
- //this.hScrollbarIndicator.style.width = this.hScrollbarIndicatorSize + 'px';\r
- this.maxScroll = wrapperSize - indicatorSize;\r
- this.scrollPercent = maxScroll / this.owner.maxScrollX;\r
- } else {\r
- this.wrapperSize = this.vScrollbarWrapper.clientHeight;\r
- this.indicatorSize = m.max( m.round( wrapperSize * wrapperSize / this.owner.scrollerH ), 8);\r
- // this.vScrollbarIndicator.style.height = indicatorSize + 'px';\r
- this.maxScroll = this.vScrollbarSize - indicatorSize;\r
- this.scrollPercent = maxScroll / this.owner.maxScrollY;\r
- }; \r
- this.xnodeIndicator.css( this.widthOrHeight, size + 'px' );\r
- // Reset position\r
- this.updatePosition( this.owner[ this.XorY ], true );\r
- },\r
- \r
- updatePosition : function( pos, hidden ){\r
- var size;\r
- pos = this.scrollPercent * pos;\r
- \r
- if( pos < 0 ){\r
- if( !this.options.fixedScrollbar ){\r
- size = this.indicatorSize + m.round( pos * 3 );\r
- if( size < 8 ) size = 8;\r
- //this.xnodeIndicator.style[dir == 'h' ? 'width' : 'height'] = size + 'px';\r
- this.xnodeIndicator.css( this.widthOrHeight, size + 'px' );\r
- };\r
- pos = 0;\r
- } else\r
- if( this.maxScroll < pos ){\r
- if( !this.options.fixedScrollbar ){\r
- size = this.indicatorSize - m.round( ( pos - this.maxScroll ) * 3 );\r
- if( size < 8 ) size = 8;\r
- //this.xnodeIndicator.style[dir == 'h' ? 'width' : 'height'] = size + 'px';\r
- this.xnodeIndicator.css( this.widthOrHeight, size + 'px' );\r
- pos = this.maxScroll + this.indicatorSize - size;\r
- } else {\r
- pos = this.maxScroll;\r
- };\r
- };\r
- \r
- if (this.options.useTransition){\r
- this.xnodeWrapper.css( {\r
- transitionDelay : '0',\r
- opacity : hidden && this.options.hideScrollbar ? '0' : '1'\r
- });\r
- //this.xnodeIndicator.style[transform] = 'translate(' + (dir == 'h' ? pos + 'px,0)' : '0,' + pos + 'px)') + translateZ;\r
- this.xnodeIndicator.anime( this.dir === 'h' ? { x : pos } : { y : pos } ); \r
- };\r
- }\r
- });\r
-\r
- // Constructor\r
- function iScroll( uinodeRoot, uinodeTarget, xnodeTarget, xnodeScroller, options ){\r
- var i;\r
- \r
- this.uinodeRoot = uinodeRoot;\r
- this.uinodeTarget = uinodeTarget;\r
- this.xnodeTarget = xnodeTarget;\r
- this.xnodeScroller = xnodeScroller;\r
-\r
- // Default options\r
- this.options = new Options();\r
-\r
- // User defined options\r
- if( options ) for (i in options) X_EMPTY_OBJECT[ k ] || ( this.options[i] = options[i] );\r
- \r
- this.options.hScroll && ( this.hScrollbar = new Scrollbar( 'h', this ) );\r
- this.options.vScroll && ( this.vScrollbar = new Scrollbar( 'v', this ) );\r
- \r
- // Set starting position\r
- this.x = this.options.x;\r
- this.y = this.options.y;\r
-\r
- // Normalize options\r
- this.options.useTransform = X.CSS.transform && this.options.useTransform;\r
- this.options.hScrollbar = this.options.hScroll && this.options.hScrollbar;\r
- this.options.vScrollbar = this.options.vScroll && this.options.vScrollbar;\r
- this.options.zoom = this.options.useTransform && this.options.zoom;\r
- this.options.useTransition = X.CSS.transition && this.options.useTransition;\r
-\r
- // Helpers FIX ANDROID BUG!\r
- // translate3d and scale doesn't work together!\r
- // Ignoring 3d ONLY WHEN YOU SET this.options.zoom\r
- //if ( this.options.zoom && X_UA.isAndroid ){\r
- // translateZ = '';\r
- //}\r
- \r
- // Set some default styles\r
\r
- if (this.options.useTransform){\r
- this.scroller.style[X.CSS.transform] = 'translate(' + this.x + 'px,' + this.y + 'px)' + translateZ;\r
- this.scroller.style[X.CSS.transformOrigin] = '0 0';\r
- } else {\r
- this.scroller.style.cssText += ';position:absolute;top:' + this.y + 'px;left:' + this.x + 'px';\r
- };\r
-\r
- if (this.options.useTransition){\r
- this.scroller.style[X.CSS.transition.Property] = this.options.useTransform ? X.CSS.cssVendor + 'transform' : 'top left';\r
- this.scroller.style[X.CSS.transition.Duration] = '0'; \r
- this.scroller.style[X.CSS.transition.TimingFunction] = 'cubic-bezier(0.33,0.66,0.66,1)';\r
- this.options.fixedScrollbar = true;\r
- };\r
-\r
- this.refresh();\r
-\r
- //this._bind(RESIZE_EV, window);\r
- X.Dom.Event.add( window, RESIZE_EV, this );\r
- //this._bind(START_EV);\r
- uinodeTarget.listen( X.UI.Event.DRAG_START, this );\r
+ return {\r
+ destination : Math.round( destination ),\r
+ duration : duration\r
+ };\r
+};\r
+\r
+var X_UI_ScrollBox_SUPPORT_ATTRS = {\r
+ // スクロール開始するために必要な移動距離、縦か横、どちらか制限する場合、より重要\r
+ directionLockThreshold : [ 10, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.LENGTH ],\r
+ scrollX : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+ scrollY : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+ enabled : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+ bounce : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+ bounceTime : [ 600, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.TIME ],\r
+ useWheel : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
+ useKey : [ true, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.BOOLEAN ],\r
};\r
-\r
-// Prototype\r
-X_Class_override( iScroll.prototype, {\r
- uinodeRoot : null,\r
- uinodeTarget : null,\r
- xnodeTarget : null,\r
- xnodeScroller : null,\r
- options : null,\r
- enabled : true,\r
- x : 0,\r
- y : 0,\r
- steps : [],\r
- scale : 1,\r
- currPageX : 0,\r
- currPageY : 0,\r
- pagesX : [],\r
- pagesY : [],\r
- animeTimerID : 0,\r
- wheelZoomCount : 0,\r
- \r
- wrapperW : 0,\r
- wrapperH : 0,\r
- minScrollY : 0,\r
- scrollerW : 0,\r
- scrollerH : 0,\r
- maxScrollX : 0,\r
- maxScrollY : 0,\r
- dirX : 0,\r
- dirY : 0,\r
- hScrollbar : false,\r
- vScrollbar : false,\r
- wrapperOffsetLeft : 0,\r
- wrapperOffsetTop : 0,\r
- \r
- \r
- currPageX : 0,\r
- currPageY : 0,\r
- \r
- moved : false,\r
- animating : false,\r
- zoomed : false,\r
- distX : false,\r
- distY : false,\r
- absDistX : false,\r
- absDistY : false,\r
- absStartX : false, // Needed by snap threshold\r
- absStartY : false,\r
- startX : false,\r
- startY : false,\r
- pointX : false,\r
- pointY : false,\r
- startTime : false,\r
- \r
- handleEvent: function (e) {\r
- switch(e.type) {\r
- case X.UI.Event.DRAG :\r
- return this._move(e);\r
- case X.UI.Event.WHEEL :\r
- return this._wheel(e);\r
- case X.UI.Event.DRAG_START :\r
- //if (!hasTouch && e.button !== 0) return;\r
- return this._start(e);\r
- case X.UI.Event.DRAG_END :\r
- return this._end(e);\r
- case X.UI.Event.ANIME_END :\r
- return this._transitionEnd(e);\r
- case RESIZE_EV :\r
- return this._resize(); \r
- }\r
- },\r
- \r
- _trigger : function( type, e ){\r
- \r
- return this.uinodeTarget.dispatch( );\r
- },\r
- \r
- _resize: function () {\r
- X.Timer.once( X_UA.Android ? 200 : 0, this, this.refresh );\r
- // setTimeout( this.refresh(), isAndroid ? 200 : 0);\r
- },\r
- \r
- _updateScrollPosition: function( x, y, time ){\r
- if (this.zoomed) return;\r
-\r
- this.xnodeScroller.anime({\r
- x : this.x = this.hScrollbar && this.hScrollbar.active ? m.round(x) : 0,\r
- y : this.y = this.vScrollbar && this.vScrollbar.active ? m.round(y) : 0\r
- }, time );\r
-\r
- this.hScrollbar && this.hScrollbar.active && this.hScrollbar.updatePosition( this.x );\r
- this.vScrollbar && this.vScrollbar.active && this.vScrollbar.updatePosition( this.y );\r
- },\r
- \r
- _start: function (e) {\r
- var point = hasTouch ? e.touches[0] : e,\r
- matrix, x, y,\r
- ret;\r
- //c1, c2;\r
-\r
- if (!this.enabled) return;\r
-\r
- //if (this.options.onBeforeScrollStart) this.options.onBeforeScrollStart.call(this, e);\r
- if( ( ret = this._trigger( X.UI.Event.SCROLL_BEFORE_START ) ) & X.Callback.PREVENT_DEFAULT ){\r
- return ret;\r
- };\r
-\r
- //if (this.options.useTransition || this.options.zoom) this._transitionTime(0);\r
-\r
- this.moved = false;\r
- this.animating = false;\r
- this.zoomed = false;\r
- this.distX = 0;\r
- this.distY = 0;\r
- this.absDistX = 0;\r
- this.absDistY = 0;\r
- this.dirX = 0;\r
- this.dirY = 0;\r
-\r
- if (this.options.momentum) {\r
- if (this.options.useTransform) {\r
- // Very lame general purpose alternative to CSSMatrix\r
- matrix = getComputedStyle(this.scroller, null)[transform].replace(/[^0-9\-.,]/g, '').split(',');\r
- x = +(matrix[12] || matrix[4]);\r
- y = +(matrix[13] || matrix[5]);\r
- } else {\r
- x = +getComputedStyle(this.scroller, null).left.replace(/[^0-9-]/g, '');\r
- y = +getComputedStyle(this.scroller, null).top.replace(/[^0-9-]/g, '');\r
- };\r
- \r
- if (x !== this.x || y !== this.y) {\r
- if (this.options.useTransition){\r
- //this._unbind(TRNEND_EV);\r
- X.Dom.Event.remove( this.scroller, TRNEND_EV, this );\r
- } else {\r
- X.Timer.cancelFrame(this.animeTimerID);\r
- };\r
- this.steps = this.steps ? ( this.steps.length = 0 ) : [];\r
- this._updateScrollPosition( x, y, 0 );\r
- //if (this.options.onScrollEnd) this.options.onScrollEnd.call(this);\r
- return this._trigger( X.UI.Event.SCROLL_END, e );\r
- };\r
- };\r
-\r
- this.absStartX = this.x; // Needed by snap threshold\r
- this.absStartY = this.y;\r
-\r
- this.startX = this.x;\r
- this.startY = this.y;\r
- this.pointX = point.pageX;\r
- this.pointY = point.pageY;\r
-\r
- this.startTime = e.timeStamp || X.Timer.now();\r
-\r
- this.uinodeRoot.listen( X.UI.Event.DRAG, this );\r
- this.uinodeRoot.listen( X.UI.Event.DRAG_END, this );\r
-\r
- return this._trigger( X.UI.Event.SCROLL_START, e );\r
- },\r
- \r
- _move: function (e) {\r
- var point = hasTouch ? e.touches[0] : e,\r
- deltaX = point.pageX - this.pointX,\r
- deltaY = point.pageY - this.pointY,\r
- newX = this.x + deltaX,\r
- newY = this.y + deltaY,\r
- c1, c2, scale,\r
- timestamp = e.timeStamp ||X.Timer.now(), ret;\r
-\r
- //if (this.options.onBeforeScrollMove) this.options.onBeforeScrollMove.call(this, e);\r
- if( ( ret = this._trigger( X.UI.Event.SCROLL_BEFORE_MOVE ) ) & X.Callback.PREVENT_DEFAULT ){\r
- return ret;\r
- };\r
-\r
- this.pointX = point.pageX;\r
- this.pointY = point.pageY;\r
-\r
- // Slow down if outside of the boundaries\r
- if (newX > 0 || newX < this.maxScrollX) {\r
- newX = this.options.bounce ? this.x + (deltaX / 2) : newX >= 0 || this.maxScrollX >= 0 ? 0 : this.maxScrollX;\r
- };\r
- if (newY > this.minScrollY || newY < this.maxScrollY) {\r
- newY = this.options.bounce ? this.y + (deltaY / 2) : newY >= this.minScrollY || this.maxScrollY >= 0 ? this.minScrollY : this.maxScrollY;\r
- };\r
-\r
- this.distX += deltaX;\r
- this.distY += deltaY;\r
- this.absDistX = ABS(this.distX);\r
- this.absDistY = ABS(this.distY);\r
-\r
- if (this.absDistX < 6 && this.absDistY < 6) {\r
- return;\r
- };\r
-\r
- // Lock direction\r
- if (this.options.lockDirection) {\r
- if (this.absDistX > this.absDistY + 5) {\r
- newY = this.y;\r
- deltaY = 0;\r
- } else if (this.absDistY > this.absDistX + 5) {\r
- newX = this.x;\r
- deltaX = 0;\r
- };\r
- };\r
-\r
- this.moved = true;\r
- this._updateScrollPosition(newX, newY, 0);\r
- this.dirX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;\r
- this.dirY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;\r
-\r
- if (timestamp - this.startTime > 300) {\r
- this.startTime = timestamp;\r
- this.startX = this.x;\r
- this.startY = this.y;\r
- };\r
- \r
- //if (this.options.onScrollMove) this.options.onScrollMove.call(this, e);\r
- return this._trigger( X.UI.Event.SCROLL_MOVE, e );\r
- },\r
- \r
- _end: function (e) {\r
- if (hasTouch && e.touches.length !== 0) return;\r
-\r
- var point = hasTouch ? e.changedTouches[0] : e,\r
- momentumX = { dist:0, time:0 },\r
- momentumY = { dist:0, time:0 },\r
- duration = ( e.timeStamp ||X.Timer.now() ) - this.startTime,\r
- newPosX = this.x,\r
- newPosY = this.y,\r
- distX, distY,\r
- newDuration,\r
- snap,\r
- scale;\r
-\r
- this.uinodeRoot.unlisten( X.UI.Event.DRAG, this );\r
- this.uinodeRoot.unlisten( X.UI.Event.DRAG_END, this );\r
-\r
- //this._unbind(MOVE_EV, window);\r
- //this._unbind(END_EV, window);\r
- //this._unbind(CANCEL_EV, window);\r
-\r
- //if (this.options.onBeforeScrollEnd) this.options.onBeforeScrollEnd.call(this, e);\r
- \r
-\r
- if (!this.moved) {\r
-\r
-\r
- this._resetPos(400);\r
-\r
- //if (this.options.onTouchEnd) this.options.onTouchEnd.call(this, e);\r
- return;\r
- };\r
-\r
- if (duration < 300 && this.options.momentum) {\r
- momentumX = newPosX ? this._momentum(newPosX - this.startX, duration, -this.x, this.scrollerW - this.wrapperW + this.x, this.options.bounce ? this.wrapperW : 0) : momentumX;\r
- momentumY = newPosY ? this._momentum(newPosY - this.startY, duration, -this.y, (this.maxScrollY < 0 ? this.scrollerH - this.wrapperH + this.y - this.minScrollY : 0), this.options.bounce ? this.wrapperH : 0) : momentumY;\r
-\r
- newPosX = this.x + momentumX.dist;\r
- newPosY = this.y + momentumY.dist;\r
-\r
- if ((this.x > 0 && newPosX > 0) || (this.x < this.maxScrollX && newPosX < this.maxScrollX)) momentumX = { dist:0, time:0 };\r
- if ((this.y > this.minScrollY && newPosY > this.minScrollY) || (this.y < this.maxScrollY && newPosY < this.maxScrollY)) momentumY = { dist:0, time:0 };\r
- \r
- if (momentumX.dist || momentumY.dist) {\r
- newDuration = m.max(m.max(momentumX.time, momentumY.time), 10);\r
- \r
- this.scrollTo(m.round(newPosX), m.round(newPosY), newDuration);\r
- \r
- //if (this.options.onTouchEnd) this.options.onTouchEnd.call(this, e);\r
- return;\r
- }; \r
- };\r
-\r
- this._resetPos(200);\r
- //if (this.options.onTouchEnd) this.options.onTouchEnd.call(this, e);\r
- },\r
- \r
- /*\r
- _onZoomEndEvent : null,\r
- _onZoomEndTimerComplete : function(){\r
- this.options.onZoomEnd.call( this, this._onZoomEndEvent );\r
- },\r
- */\r
- \r
- /*\r
- _onDobleTapTimerPoint : null,\r
- _onDobleTapTimerComplete : function () {\r
- var point = this._onDobleTapTimerPoint,\r
- target, ev;\r
- this.doubleTapTimer = null;\r
-\r
- // Find the last touched element\r
- target = point.target;\r
- while (target.nodeType !== 1) target = target.parentNode;\r
-\r
- if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') {\r
- ev = document.createEvent('MouseEvents');\r
- ev.initMouseEvent('click', true, true, e.view, 1,\r
- point.screenX, point.screenY, point.clientX, point.clientY,\r
- e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,\r
- 0, null);\r
- ev._fake = true;\r
- target.dispatchEvent(ev);\r
- }\r
- },*/\r
- \r
- _resetPos: function (time) {\r
- var resetX =\r
- 0 <= this.x ?\r
- 0 :\r
- this.x < this.maxScrollX ?\r
- this.maxScrollX :\r
- this.x,\r
- resetY =\r
- this.minScrollY <= this.y || 0 < this.maxScrollY ?\r
- this.minScrollY :\r
- this.y < this.maxScrollY ?\r
- this.maxScrollY :\r
- this.y;\r
-\r
- if( resetX === this.x && resetY === this.y ){\r
- if( this.moved ){\r
- this.moved = false;\r
- this._trigger( X.UI.Event.SCROLL_END );\r
- //if (this.options.onScrollEnd) this.options.onScrollEnd.call(this); // Execute custom code on scroll end\r
- };\r
- if( this.options.hideScrollbar ){\r
- this.hScrollbar && this.hScrollbar.active &&\r
- \r
- //if (vendor == 'webkit') this.hScrollbarWrapper.style[transitionDelay] = '300ms';\r
- //this.hScrollbarWrapper.style.opacity = '0';\r
- this.hScrollbar.xnodeWraper.anime( {\r
- opacity : 0\r
- }, 300 );\r
- this.vScrollbar && this.vScrollbar.active &&\r
- //if (vendor == 'webkit') this.vScrollbarWrapper.style[transitionDelay] = '300ms';\r
- //this.vScrollbarWrapper.style.opacity = '0';\r
- this.hScrollbar.xnodeWraper.anime( {\r
- opacity : 0\r
- }, 300 ); \r
- };\r
- return;\r
- };\r
- this.scrollTo(resetX, resetY, time || 0);\r
- },\r
- \r
- _wheel: function (e) {\r
- var wheelDeltaX, wheelDeltaY,\r
- deltaX, deltaY,\r
- deltaScale;\r
-/*\r
- if ('wheelDeltaX' in e) {\r
- wheelDeltaX = e.wheelDeltaX / 12;\r
- wheelDeltaY = e.wheelDeltaY / 12;\r
- } else if('wheelDelta' in e) {\r
- wheelDeltaX = wheelDeltaY = e.wheelDelta / 12;\r
- } else if ('detail' in e) {\r
- wheelDeltaX = wheelDeltaY = -e.detail * 3;\r
- } else {\r
- return;\r
- } */\r
- \r
- deltaX = this.x + e.wheelDeltaX;\r
- deltaY = this.y + e.wheelDeltaY;\r
-\r
- deltaX =\r
- 0 < deltaX ?\r
- 0 :\r
- deltaX < this.maxScrollX ?\r
- this.maxScrollX : deltaX;\r
-\r
- deltaY =\r
- this.minScrollY < deltaY ? \r
- this.minScrollY :\r
- deltaY < this.maxScrollY ?\r
- this.maxScrollY : deltaY;\r
- \r
- this.maxScrollY < 0 && this.scrollTo(deltaX, deltaY, 0);\r
- },\r
- \r
- /*\r
- _wheelTimerCompleteEvent : null,\r
- _wheelTimerComplete : function() {\r
- this.wheelZoomCount--;\r
- if (!this.wheelZoomCount && this.options.onZoomEnd) this.options.onZoomEnd.call(this, this._wheelTimerCompleteEvent );\r
- },\r
- */\r
- \r
- _transitionEnd: function( e ){\r
- if( e.target !== this.xnodeScroller ) return;\r
-\r
- //this._unbind(TRNEND_EV);\r
- //X.Dom.Event.remove( this.scroller, TRNEND_EV, this );\r
- this.animating = false;\r
- \r
- this._startAnime();\r
- \r
- return X.Callback.UN_LISTEN;\r
- },\r
-\r
-\r
- /**\r
- *\r
- * Utilities\r
- *\r
- */\r
- _startAnime: function () {\r
- var startX = this.x,\r
- startY = this.y,\r
- step, animate;\r
-\r
- if (this.animating) return;\r
- \r
- if (!this.steps.length) {\r
- this._resetPos(400);\r
- return;\r
- };\r
- \r
- step = this.steps.shift();\r
- \r
- if( step.x === startX && step.y === startY ) step.time = 0;\r
-\r
- this.animating = true;\r
- this.moved = true;\r
- \r
- //if (this.options.useTransition) {\r
- //this._transitionTime(step.time);\r
- this._updateScrollPosition( step.x, step.y, step.time );\r
- //this.animating = false;\r
- this.xnodeScroller.listenOnce( X.UI.Event.ANIME_END, this );\r
- //step.time ? X.Dom.Event.add( this.scroller, TRNEND_EV, this ) /* this._bind(TRNEND_EV) */ : this._resetPos(0);\r
- //return;\r
- //}\r
- //this._doAnimate( X.Timer.now(), step, startX, startY );\r
- },\r
-\r
-/*\r
- _doAnimate : function( startTime, step, startX, startY ){\r
- var now =X.Timer.now(),\r
- easeOut, newX, newY;\r
-\r
- if (now >= startTime + step.time) {\r
- this._updateScrollPosition(step.x, step.y);\r
- this.animating = false;\r
- //if (this.options.onAnimationEnd) this.options.onAnimationEnd.call( this ); // Execute custom code on animation end\r
- this._startAnime();\r
- return;\r
- };\r
-\r
- now = (now - startTime) / step.time - 1;\r
- easeOut = m.sqrt(1 - now * now);\r
- newX = (step.x - startX) * easeOut + startX;\r
- newY = (step.y - startY) * easeOut + startY;\r
- this._updateScrollPosition(newX, newY);\r
- if( this.animating ) this.animeTimerID = X.Timer.requestFrame( this, this._doAnimate, [ startTime, step, startX, startY ] );\r
- },\r
-*/\r
-\r
- _momentum: function (dist, time, maxDistUpper, maxDistLower, size) {\r
- var deceleration = 0.0006,\r
- speed = ABS(dist) / time,\r
- newDist = (speed * speed) / (2 * deceleration),\r
- newTime = 0, outsideDist = 0;\r
-\r
- // Proportinally reduce speed if we are outside of the boundaries\r
- if (dist > 0 && newDist > maxDistUpper) {\r
- outsideDist = size / (6 / (newDist / speed * deceleration));\r
- maxDistUpper = maxDistUpper + outsideDist;\r
- speed = speed * maxDistUpper / newDist;\r
- newDist = maxDistUpper;\r
- } else if (dist < 0 && newDist > maxDistLower) {\r
- outsideDist = size / (6 / (newDist / speed * deceleration));\r
- maxDistLower = maxDistLower + outsideDist;\r
- speed = speed * maxDistLower / newDist;\r
- newDist = maxDistLower;\r
- }\r
-\r
- newDist = newDist * (dist < 0 ? -1 : 1);\r
- newTime = speed / deceleration;\r
-\r
- return { dist: newDist, time: m.round(newTime) };\r
- },\r
-\r
- _offset: function (el) {\r
- var left = -el.offsetLeft,\r
- top = -el.offsetTop;\r
- \r
- while (el = el.offsetParent) {\r
- left -= el.offsetLeft;\r
- top -= el.offsetTop;\r
- }\r
- \r
- if (el != this.wrapper) {\r
- left *= this.scale;\r
- top *= this.scale;\r
- }\r
-\r
- return { left: left, top: top };\r
- },\r
-\r
- /*\r
- _bind: function (type, el, bubble) {\r
- X.Dom.Event.add( el || this.scroller, type, this );\r
- },\r
-\r
- _unbind: function (type, el, bubble) {\r
- X.Dom.Event.remove( el || this.scroller, type, this );\r
- },\r
- */\r
-\r
- /**\r
- *\r
- * Public methods\r
- *\r
- */\r
- destroy: function () {\r
- this.scroller.style[transform] = '';\r
-\r
- // Remove the scrollbars\r
- this.hScrollbar && this.hScrollbar.destroy();\r
- this.vScrollbar && this.vScrollbar.destroy();\r
-\r
- // Remove the event listeners\r
- X.Dom.Event.add( window, RESIZE_EV, this );\r
- this.uinodeTarget.unlisten( X.UI.Event.DRAG_START, this );\r
- this.uinodeRoot.unlisten( X.UI.Event.DRAG, this );\r
- this.uinodeRoot.unlisten( X.UI.Event.DRAG_END, this );\r
- \r
- //this._unbind(RESIZE_EV, window);\r
- //this._unbind(START_EV);\r
- //this._unbind(MOVE_EV, window);\r
- //this._unbind(END_EV, window);\r
- //this._unbind(CANCEL_EV, window);\r
- \r
- if (!this.options.hasTouch) {\r
- //this._unbind('wheel');\r
- }\r
- \r
- // if (this.options.useTransition) this._unbind(TRNEND_EV);\r
- this.options.useTransition && X.Dom.Event.remove( this.scroller, TRNEND_EV, this );\r
- \r
- //if (this.options.checkDOMChanges) clearInterval(this.checkDOMTime);\r
- \r
- //if (this.options.onDestroy) this.options.onDestroy.call(this);\r
- },\r
-\r
- refresh: function () {\r
- var offset,\r
- i, l,\r
- els,\r
- pos = 0,\r
- page = 0;\r
-\r
- if (this.scale < this.options.zoomMin) this.scale = this.options.zoomMin;\r
- this.wrapperW = this.wrapper.clientWidth || 1;\r
- this.wrapperH = this.wrapper.clientHeight || 1;\r
-\r
- this.minScrollY = -this.options.topOffset || 0;\r
- this.scrollerW = m.round(this.scroller.offsetWidth * this.scale);\r
- this.scrollerH = m.round((this.scroller.offsetHeight + this.minScrollY) * this.scale);\r
- this.maxScrollX = this.wrapperW - this.scrollerW;\r
- this.maxScrollY = this.wrapperH - this.scrollerH + this.minScrollY;\r
- this.dirX = 0;\r
- this.dirY = 0;\r
-\r
- // if (this.options.onRefresh) this.options.onRefresh.call(this);\r
- this._trigger( X.UI.Event.SCROLL_REFRESH, {} );\r
-\r
- this.hScrollbar && ( this.hScrollbar.active = this.maxScrollX < 0 );\r
- this.vScrollbar && ( this.vScrollbar.active = !this.options.bounceLock && !this.hScroll || this.scrollerH > this.wrapperH );\r
- \r
- offset = this._offset(this.wrapper);\r
- this.wrapperOffsetLeft = -offset.left;\r
- this.wrapperOffsetTop = -offset.top;\r
-\r
- // Prepare snap\r
- if (typeof this.options.snap == 'string') {\r
- this.pagesX = [];\r
- this.pagesY = [];\r
- els = this.scroller.querySelectorAll(this.options.snap);\r
- for (i=0, l=els.length; i<l; i++) {\r
- pos = this._offset(els[i]);\r
- pos.left += this.wrapperOffsetLeft;\r
- pos.top += this.wrapperOffsetTop;\r
- this.pagesX[i] = pos.left < this.maxScrollX ? this.maxScrollX : pos.left * this.scale;\r
- this.pagesY[i] = pos.top < this.maxScrollY ? this.maxScrollY : pos.top * this.scale;\r
- }\r
- } else if (this.options.snap) {\r
- this.pagesX = [];\r
- while (pos >= this.maxScrollX) {\r
- this.pagesX[page] = pos;\r
- pos = pos - this.wrapperW;\r
- page++;\r
- }\r
- if (this.maxScrollX%this.wrapperW) this.pagesX[this.pagesX.length] = this.maxScrollX - this.pagesX[this.pagesX.length-1] + this.pagesX[this.pagesX.length-1];\r
-\r
- pos = 0;\r
- page = 0;\r
- this.pagesY = [];\r
- while (pos >= this.maxScrollY) {\r
- this.pagesY[page] = pos;\r
- pos = pos - this.wrapperH;\r
- page++;\r
- }\r
- if (this.maxScrollY%this.wrapperH) this.pagesY[this.pagesY.length] = this.maxScrollY - this.pagesY[this.pagesY.length-1] + this.pagesY[this.pagesY.length-1];\r
- }\r
-\r
- // Prepare the scrollbars\r
- this._scrollbar('h');\r
- this._scrollbar('v');\r
-\r
- if (!this.zoomed) {\r
- this.scroller.style[transitionDuration] = '0';\r
- this._resetPos(400);\r
- }\r
- },\r
-\r
- scrollTo: function (x, y, time, relative) {\r
- var step = x,\r
- i, l;\r
-\r
- this.stop();\r
-\r
- if( !step.length ) step = [{ x: x, y: y, time: time, relative: relative }];\r
- \r
- for( i = 0, l = step.length; i < l; ++i ){\r
- if( step[ i ].relative ){\r
- step[ i ].x = this.x - step[ i ].x;\r
- step[ i ].y = this.y - step[ i ].y;\r
- };\r
- this.steps.push( {\r
- x : step[i].x,\r
- y : step[i].y,\r
- time : step[i].time || 0\r
- });\r
- };\r
-\r
- this._startAnime();\r
- },\r
-\r
- disable: function () {\r
- this.stop();\r
- this._resetPos(0);\r
- this.enabled = false;\r
-\r
- // If disabled after touchstart we make sure that there are no left over events\r
- //this._unbind(MOVE_EV, window);\r
- //this._unbind(END_EV, window);\r
- //this._unbind(CANCEL_EV, window);\r
- this.uinodeRoot.unlisten( X.UI.Event.DRAG, this );\r
- this.uinodeRoot.unlisten( X.UI.Event.DRAG_END, this );\r
- },\r
- \r
- enable: function () {\r
- this.enabled = true;\r
- },\r
- \r
- stop: function () {\r
- //if (this.options.useTransition) this._unbind(TRNEND_EV);\r
- //else X.Timer.cancelFrame( this.animeTimerID );\r
- /*\r
- if (this.options.useTransition){\r
- X.Dom.Event.remove( this.scroller, TRNEND_EV, this );\r
- } else {\r
- X.Timer.cancelFrame(this.animeTimerID);\r
- };\r
- */\r
- this.xnodeScroller.stop();\r
- if( this.steps ) this.steps.length = 0;\r
- this.moved = false;\r
- this.animating = false;\r
- },\r
- \r
- isReady: function () {\r
- return !this.moved && !this.zoomed && !this.animating;\r
- }\r
-} );\r
-\r
\r
\r
X.UI._ScrollBox = X.UI._ChromeBox.inherits(\r
//elmScroller : null,\r
//elmScrollbar : null,\r
\r
+ supportAttrs : X.UI.Attr.createAttrDef( X.UI.Attr.Support, X_UI_ScrollBox_SUPPORT_ATTRS ),\r
+ \r
scrolling : false,\r
- _scrollX : 0,\r
- _scrollY : 0,\r
- scrollXPercent : 0,\r
- scrollYPercent : 0,\r
+ \r
+ initiated : '',\r
+ moved : false,\r
+ distX : 0,\r
+ distY : 0,\r
+ directionX : 0,\r
+ directionY : 0,\r
+ directionLocked : '',\r
+ startTime : 0,\r
+ endTime : 0,\r
+ isAnimating : false,\r
+ startX : 0,\r
+ startY : 0,\r
+ absStartX : 0,\r
+ absStartY : 0,\r
+ pointX : 0,\r
+ pointY : 0,\r
+ maxScrollX : 0,\r
+ maxScrollY : 0,\r
+ hasHScroll : false,\r
+ hasVScroll : false,\r
+\r
+ wrapperOffset : 0,\r
+ wheelTimeout : 0,\r
+ requestFrameID : 0,\r
+ \r
+ _scrollX : 0,\r
+ _scrollY : 0,\r
+ scrollXPercent : 0,\r
+ scrollYPercent : 0,\r
+ \r
+ lastScrollWidth : 0,\r
+ lastScrollHeight : 0,\r
+ lastBoxWidth : 0,\r
+ lastBoxHeight : 0,\r
\r
_containerNode : null,\r
scrollManager : null,\r
\r
Constructor : function( layout, args ){\r
this.Super( layout, args );\r
- this._containerNode = _X_Class_getPrivate( this.containerNode );\r
+ this._containerNode = X_Class_getPrivate( this.containerNode );\r
},\r
\r
creationComplete : function(){\r
- X.UI._AbstractUINode.prototype.creationComplete.call( this, arguments );\r
- this.scrollManager = new iScroll( this.root, this.User, this.rawElement, this._containerNode.rawElement );\r
+ X.UI._Box.prototype.creationComplete.apply( this, arguments );\r
+ this.scrollManager;\r
this._check();\r
},\r
\r
calculate : function(){\r
- X.UI._AbstractUINode.prototype.calculate.call( this, arguments );\r
- this._check();\r
+ this.lastScrollWidth = this.scrollWidth;\r
+ this.lastScrollHeight = this.scrollHeight;\r
+ this.lastBoxWidth = this.boxWidth;\r
+ this.lastBoxHeight = this.boxHeight;\r
+ \r
+ X.UI._Box.prototype.calculate.apply( this, arguments );\r
+ \r
+ if(\r
+ this.lastScrollWidth !== this.scrollWidth || this.lastScrollHeight !== this.scrollHeight ||\r
+ this.lastBoxWidth !== this.boxWidth || this.lastBoxHeight !== this.boxHeight\r
+ ){\r
+ // scroll の停止、GPU の解除\r
+ this._check();\r
+ };\r
+ \r
+ },\r
+ \r
+ scrollBy : function( x, y, opt_time, opt_easing ){\r
+ this.scrollTo( this.x + x, this.y + y, opt_time, opt_easing );\r
+ },\r
+ \r
+ scrollTo : function( x, y, opt_time, opt_easing ){\r
+ opt_time = 0 <= opt_time ? opt_time : 0;\r
+ opt_easing = opt_easing || 'circular';\r
+ \r
+ this.isInTransition = !!opt_time;\r
+ \r
+ this.containerNode.animate(\r
+ {\r
+ x : this.x,\r
+ y : this.y\r
+ },\r
+ {\r
+ x : x,\r
+ y : y\r
+ },\r
+ opt_time, opt_easing, 1000\r
+ );\r
+ \r
+ this.x = x;\r
+ this.y = y;\r
+ \r
+ if( this.indicators ){\r
+ for( i = this.indicators.length; i--; ){\r
+ this.indicators[ i ].updatePosition( opt_time, opt_easing );\r
+ };\r
+ };\r
},\r
\r
_check : function(){\r
- if( this.w < this._containerNode.w || this.h < this._containerNode.h ){\r
+ var needVScroll, needHScroll;\r
+ if( this.boxWidth < this._containerNode.scrollWidth || this.boxHeight < this._containerNode.scrollHeight ){\r
// scroll\r
if( this.scrolling ){\r
// fix scroll position from scrollXPercent, scrollYPercent\r
+ //\r
\r
} else {\r
// create scroller\r
- this.listen( X.UI.Event.POINTER_START, this );\r
+ \r
+ \r
+ this.listen( X.UI.Event.POINTER_START, X_UI_ScrollBox_onStart );\r
\r
\r
this._move( 0, 0 );\r
// no scroll\r
if( this.scrolling ){\r
// remove scroller\r
+ this.unlisten( X.UI.Event.POINTER_START );\r
\r
( this._scrollX !== 0 || this._scrollY !== 0 ) && this._move( 0, 0 );\r
\r
};\r
},\r
\r
- handleEvent : function( e ){\r
- switch( e.type ){\r
- case X.UI.Event.POINTER_START :\r
- this.listen( X.UI.Event.POINTER_MOVE, this );\r
- this.listen( X.UI.Event.POINTER_END, this );\r
- \r
- break;\r
- case X.UI.Event.POINTER_MOVE :\r
- \r
- break;\r
- case X.UI.Event.POINTER_END :\r
- this.unlisten( X.UI.Event.POINTER_MOVE, this );\r
- this.unlisten( X.UI.Event.POINTER_END, this );\r
- \r
- break;\r
- };\r
- },\r
- \r
_move : function( x, y ){\r
\r
},\r
\r
_remove : function(){\r
- X.UI._AbstractUINode.prototype._remove.call( this, arguments );\r
+ X.UI._AbstractUINode.prototype._remove.apply( this, arguments );\r
if( this.scrolling ){\r
// remove scroll\r
};\r
}\r
);\r
\r
-})();\r
+\r
+function X_UI_ScrollBox_onStart( e ){\r
+ var ret = X.Callback.NONE;\r
+ \r
+ // React to left mouse button only\r
+ if( e.pointerType === 'mouse' && e.button !== 0 ){\r
+ return ret;\r
+ };\r
+\r
+ if( !this.enabled || ( this.initiated && e.pointerType !== this.initiated ) ){\r
+ return ret;\r
+ };\r
+\r
+ this.initiated = e.pointerType;\r
+ this.moved = false;\r
+ this.distX = 0;\r
+ this.distY = 0;\r
+ this.directionX = 0;\r
+ this.directionY = 0;\r
+ this.directionLocked = '';\r
+ this.startTime = X_Timer_now();\r
+\r
+ // スクロール中の停止\r
+ if( this.isAnimating ){\r
+ delete this.isAnimating;\r
+ this.dispatch( X.UI.Event.SCROLL_END );\r
+ }; \r
+\r
+ this.startX = this.x;\r
+ this.startY = this.y;\r
+ this.absStartX = this.x;\r
+ this.absStartY = this.y;\r
+ this.pointX = e.pageX;\r
+ this.pointY = e.pageY;\r
+ \r
+ this.listen( X.UI.Event.POINTER_MOVE, X_UI_ScrollBox_onMove );\r
+ this.listen( X.UI.Event.POINTER_END , X_UI_ScrollBox_onEnd );\r
+\r
+ //console.log( 'start : 3' );\r
+ return ret | X.Callback.PREVENT_DEFAULT;\r
+};\r
+\r
+function X_UI_ScrollBox_onMove( e ){\r
+ var ret = X.Callback.NONE,\r
+ deltaX, deltaY, timestamp,\r
+ newX, newY,\r
+ absDistX, absDistY;\r
+ // 規定以上の move でスクロール開始\r
+ \r
+ if( !this.enabled || e.pointerType !== this.initiated ){\r
+ return ret;\r
+ };\r
+\r
+ // gpu の用意\r
+ if( !this.containerNode._anime ){\r
+ console.log( 'gpuレイヤーの用意' );\r
+ this._translate( this.x, this.y );\r
+ return ret;\r
+ };\r
+\r
+ deltaX = e.pageX - this.pointX;\r
+ deltaY = e.pageY - this.pointY;\r
+ timestamp = X_Timer_now();\r
+\r
+ this.pointX = e.pageX;\r
+ this.pointY = e.pageY;\r
+\r
+ this.distX += deltaX;\r
+ this.distY += deltaY;\r
+ absDistX = Math.abs(this.distX);\r
+ absDistY = Math.abs(this.distY);\r
+ \r
+ // We need to move at least 10 pixels for the scrolling to initiate\r
+ if( 300 < timestamp - this.endTime && ( absDistX < 10 && absDistY < 10 ) ){\r
+ return ret;\r
+ };\r
+\r
+ // If you are scrolling in one direction lock the other\r
+ if( !this.directionLocked ){\r
+ if( absDistX > absDistY + this.directionLockThreshold ){\r
+ this.directionLocked = 'h'; // lock horizontally\r
+ } else\r
+ if( absDistY >= absDistX + this.directionLockThreshold ){\r
+ this.directionLocked = 'v'; // lock vertically\r
+ } else {\r
+ this.directionLocked = 'n'; // no lock\r
+ };\r
+ };\r
+\r
+ if( this.directionLocked === 'h' ){\r
+ deltaY = 0;\r
+ } else\r
+ if( this.directionLocked === 'v' ){\r
+ deltaX = 0;\r
+ };\r
+\r
+ deltaX = this.hasHScroll ? deltaX : 0;\r
+ deltaY = this.hasVScroll ? deltaY : 0;\r
+\r
+ if( !this.moved ){\r
+ this.dispatch( X.UI.Event.SCROLL_BEFORE_MOVE );\r
+ this.moved = true;\r
+ this.minusX = deltaX;\r
+ this.minusY = deltaY;\r
+ } else {\r
+ this.dispatch( X.UI.Event.SCROLL_MOVE );\r
+ };\r
+\r
+ newX = this.x + deltaX;// - this.minusX;\r
+ newY = this.y + deltaY;// - this.minusY;\r
+\r
+ // Slow down if outside of the boundaries\r
+ if( 0 < newX || newX < this.maxScrollX ){\r
+ newX = this.bounce ? this.x + ( deltaX ) / 3 : 0 < newX ? 0 : this.maxScrollX;\r
+ };\r
+ if( 0 < newY || newY < this.maxScrollY ){\r
+ newY = this.bounce ? this.y + ( deltaY ) / 3 : 0 < newY ? 0 : this.maxScrollY;\r
+ };\r
+\r
+ this.directionX = 0 < deltaX ? -1 : deltaX < 0 ? 1 : 0;\r
+ this.directionY = 0 < deltaY ? -1 : deltaY < 0 ? 1 : 0;\r
+\r
+ this._translate( newX, newY );\r
+\r
+ if( 300 < timestamp - this.startTime ){\r
+ this.startTime = timestamp;\r
+ this.startX = this.x;\r
+ this.startY = this.y;\r
+ };\r
+ // イベントの拘束\r
+ return ret | X.Callback.PREVENT_DEFAULT | X.Callback.MONOPOLY;\r
+};\r
+\r
+function X_UI_ScrollBox_onEnd( e ){\r
+ var ret = X.Callback.NONE,\r
+ time = 0,\r
+ easing = '',\r
+ newX, newY,\r
+ momentumX, momentumY,\r
+ duration, distanceX, distanceY;\r
+ \r
+ this.unlisten( X.UI.Event.POINTER_MOVE, X_UI_ScrollBox_onMove );\r
+ this.unlisten( X.UI.Event.POINTER_END, X_UI_ScrollBox_onEnd );\r
+ \r
+ if( !this.enabled || e.pointerType !== this.initiated ){\r
+ return ret;\r
+ };\r
+\r
+ delete this.isInTransition;\r
+ delete this.initiated;\r
+ this.endTime = X_Timer_now(); \r
+\r
+ duration = this.endTime - this.startTime;\r
+ newX = Math.round( this.x );\r
+ newY = Math.round( this.y );\r
+ distanceX = Math.abs(newX - this.startX);\r
+ distanceY = Math.abs(newY - this.startY);\r
+\r
+ // reset if we are outside of the boundaries\r
+ if( X_UI_ScrollBox_resetPosition( this, this.options.bounceTime ) ){\r
+ return ret;\r
+ };\r
+\r
+ // we scrolled less than 10 pixels\r
+ if( !this.moved ){\r
+ // this.dispatch( X_Event.CANCELED );\r
+ return ret;\r
+ };\r
+ \r
+ this.scrollTo( newX, newY, 0 ); // ensures that the last position is rounded\r
+\r
+ // start momentum animation if needed\r
+ if( this.options.momentum && duration < 300 ){\r
+ momentumX = this.hasHScroll ?\r
+ X_UI_ScrollBox_momentum( this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration ) :{ destination: newX, duration: 0 };\r
+ momentumY = this.hasVScroll ?\r
+ X_UI_ScrollBox_momentum( this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration ) : { destination: newY, duration: 0 };\r
+ newX = momentumX.destination;\r
+ newY = momentumY.destination;\r
+ time = Math.max( momentumX.duration, momentumY.duration );\r
+ this.isInTransition = 1;\r
+ };\r
+\r
+ if( newX != this.x || newY != this.y ){\r
+ // change easing function when scroller goes out of the boundaries\r
+ if( 0 < newX || newX < this.maxScrollX || 0 < newY || newY < this.maxScrollY ){\r
+ easing = 'quadratic';\r
+ };\r
+\r
+ this.scrollTo( newX, newY, time, easing );\r
+ return ret;\r
+ };\r
+\r
+ this.dispatch( X.UI.Event.SCROLL_END );\r
+ \r
+ return ret;\r
+};\r
+\r
+function X_UI_ScrollBox_resetPosition( that, time ){\r
+ var x = this.x,\r
+ y = this.y;\r
+\r
+ time = time || 0;\r
+\r
+ if( !this.hasHScroll || 0 < this.x ){\r
+ x = 0;\r
+ } else\r
+ if( this.x < this.maxScrollX ){\r
+ x = this.maxScrollX;\r
+ };\r
+\r
+ if( !this.hasVScroll || 0 < this.y ){\r
+ y = 0;\r
+ } else\r
+ if( this.y < this.maxScrollY ){\r
+ y = this.maxScrollY;\r
+ };\r
+\r
+ if( x === this.x && y === this.y ){\r
+ console.log( 'no バウンド' );\r
+ return false;\r
+ };\r
+\r
+ console.log( 'バウンド!' );\r
+ this.scrollTo( x, y, time, this.options.bounceEasing );\r
+\r
+ return true;\r
+};\r
+\r
+function X_UI_ScrollBox_translate( x, y ){\r
+ this.containerNode.animate(\r
+ {\r
+ x : this.x,\r
+ y : this.y\r
+ },\r
+ {\r
+ x : x,\r
+ y : y\r
+ },\r
+ 0, '', 300\r
+ );\r
+ \r
+ this.x = x;\r
+ this.y = y;\r
+ \r
+ if( this.indicators ){\r
+ for( i = this.indicators.length; i--; ){\r
+ this.indicators[ i ].updatePosition();\r
+ };\r
+ };\r
+};\r
+\r
+function X_UI_ScrollBox_refresh( remove ){\r
+ this.maxScrollX = this.boxWidth - this.containerNode.boxWidth;\r
+ this.maxScrollY = this.boxHeight - this.containerNode.boxHeight;\r
+\r
+ this.hasHScroll = this.User.attr( 'scrollX' ) && this.maxScrollX < 0;\r
+ this.hasVScroll = this.User.attr( 'scrollY' ) && this.maxScrollY < 0;\r
+\r
+ if( !this.hasHScroll ){\r
+ this.maxScrollX = 0;\r
+ this.scrollerWidth = this.wrapperWidth;\r
+ };\r
+\r
+ if( !this.hasVScroll ){\r
+ this.maxScrollY = 0;\r
+ this.scrollerHeight = this.wrapperHeight;\r
+ };\r
+\r
+ delete this.endTime;\r
+ delete this.directionX;\r
+ delete this.directionY;\r
+\r
+ this.wrapperOffset = this.xnodeWrapper.offset();\r
+\r
+ //this.dispatch('refresh');\r
+\r
+ X_UI_ScrollBox_resetPosition( this, 0 );\r
+};\r
\r
X.UI.ScrollBox = X.UI.ChromeBox.inherits(\r
'ScrollBox',\r
};\r
this.xnode = X_Doc_create( 'div' );\r
\r
- if( X.Type.isString( content ) && content ){\r
+ if( X_Type_isString( content ) && content ){\r
this.content = content;\r
this.xnode.text( this.content );\r
this.dirty = X.UI.Dirty.CONTENT;\r
{\r
Constructor : function( opt_content, opt_cssObj ){\r
X_Class_newPrivate( this, opt_content );\r
- X.Type.isObject( opt_cssObj = opt_cssObj || opt_content ) && this.attr( opt_cssObj );\r
+ X_Type_isObject( opt_cssObj = opt_cssObj || opt_content ) && this.attr( opt_cssObj );\r
},\r
content : function( v ){\r
var data = X_Class_getPrivate( this );\r
+var X_UI_rootData = null,
+ X_UI_eventBusy = false;
-X.UI._eventRellay = function( e ){
+function X_UI_eventRellay( e ){
var font = X.ViewPort.getBaseFontSize(),
x = e.clientX / font,
y = e.clientY / font,
type = X.UI.Event.NameToID[ e.type ],
i = 0,
- data = X.UI.currentRootData,
+ data = X_UI_rootData,
sysOnly = false,
ret = X.Callback.NONE,
list, parent, _ret;
// mouseup で alert を出すと mouseleave が発生、ということでイベント中のイベント発火を禁止
- if( !data || data._eventBusy ) return ret;
+ if( !data || X_UI_eventBusy ) return ret;
data._eventBusy = true;
- if( type !== '' + X.UI.Event._POINTER_MOVE && type !== '' + X.UI.Event._TOUCH_MOVE && type !== '' + X.UI.Event._MOUSE_MOVE ){
+ if( type !== '' + X.UI.Event._POINTER_MOVE ){
//console.log( e.type + ' ' + type + ' x:' + x + ', y:' + y );
};
e.type = type;
if( data && ( data = data.monopolyNodeData ) && ( ret = data.dispatch( e ) ) & X.Callback.MONOPOLY ){
- delete X.UI.currentRootData._eventBusy;
+ X_UI_eventBusy = false;
return ret | X.Callback.PREVENT_DEFAULT;
};
- list = X.UI.currentRootData.hoverList;
- ( X.UI.currentRootData.targetNodeData = X.UI.currentRootData ).capcher( x, y );
- data = X.UI.currentRootData.targetNodeData;
+ list = X_UI_rootData.hoverList;
+ ( X_UI_rootData.targetNodeData = X_UI_rootData ).capcher( x, y );
+ data = X_UI_rootData.targetNodeData;
- //data !== X.UI.currentRootData && console.log( data.xnode.text() );
+ //data !== X_UI_rootData && console.log( data.xnode.text() );
while( data ){
_ret = data.dispatch( e, sysOnly );
while( parent.parentData && parent === parent.parentData.hitChildData ){
parent = parent.parentData;
};
- if( parent !== X.UI.currentRootData ){
+ if( parent !== X_UI_rootData ){
data.hoverClassName && data.xnode.removeClass( data.hoverClassName );
data._listeners && data._listeners[ X.UI.Event.POINTER_OUT ] && data.dispatch( e, X.UI.Event.POINTER_OUT, false ); // new Event
delete data.hovering;
data.hovering = true;
};
};
- delete X.UI.currentRootData._eventBusy;
+ X_UI_eventBusy = false;
return ret | X.Callback.PREVENT_DEFAULT;
};
eventCounter : null,
cursorStyle : null,
- _eventBusy : false,
-
Constructor : function( layout, args ){
this.Super( layout, args );
- if( X_ViewPort_readyState === X.Event.XDOM_READY ){
+ if( X_ViewPort_readyState === X_Event.XDOM_READY ){
X.Timer.once( 0, this, this.start );
} else {
- X.ViewPort.listenOnce( X.Event.XDOM_READY, this, this.start );
+ X.ViewPort.listenOnce( X_Event.XDOM_READY, this, this.start );
};
this.hoverList = [];
this.eventCounter = {};
- X.UI.currentRootData = this;
+ X_UI_rootData = this;
},
start : function(){
} );
// hover や rollover rollout のための move イベントの追加
- // mouseout, mouseover
- //if( X_UA_HID.POINTER ){
- this.xnodeInteractiveLayer.listen( X.UI.Event.IdToName[ X.UI.Event._POINTER_MOVE ], X.UI._eventRellay );
- if( counter[ X.UI.Event._POINTER_MOVE ] ){
- ++counter[ X.UI.Event._POINTER_MOVE ];
- } else {
- counter[ X.UI.Event._POINTER_MOVE ] = 1;
- };
- /*} else {
- this.xnodeInteractiveLayer.listen( X.UI.Event.IdToName[ X.UI.Event._MOUSE_MOVE ], X.UI._eventRellay );
- if( counter[ X.UI.Event._MOUSE_MOVE ] ){
- ++counter[ X.UI.Event._MOUSE_MOVE ];
- } else {
- counter[ X.UI.Event._MOUSE_MOVE ] = 1;
- };
- };*/
+ this.xnodeInteractiveLayer.listen( X.UI.Event.IdToName[ X.UI.Event._POINTER_MOVE ], X_UI_eventRellay );
+ if( counter[ X.UI.Event._POINTER_MOVE ] ){
+ ++counter[ X.UI.Event._POINTER_MOVE ];
+ } else {
+ counter[ X.UI.Event._POINTER_MOVE ] = 1;
+ };
+
X.Timer.once( 0, this, this.afterAddToView );
},
afterAddToView : function(){
this.calculate();
this.phase = 4;
X.ViewPort
- .listen( X.Event.VIEW_RESIZED, this, this.calculate )
- .listen( X.Event.BASE_FONT_RESIZED, this, this.calculate );
+ .listen( X_Event.VIEW_RESIZED, this, this.calculate )
+ .listen( X_Event.BASE_FONT_RESIZED, this, this.calculate );
},
reserveCalc : function(){