X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F01_core%2F02_XUA.js;h=acf31f409a872d86563a5e018fcbc1c3a7ccad49;hb=HEAD;hp=b99223ae60dcd2bee160e20ee04799f95ebf6e0d;hpb=7973f3ff61f1ef5bd9732f527b175010d0c0971b;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/01_core/02_XUA.js b/0.6.x/js/01_core/02_XUA.js index b99223a..acf31f4 100644 --- a/0.6.x/js/01_core/02_XUA.js +++ b/0.6.x/js/01_core/02_XUA.js @@ -10,14 +10,14 @@ * @type {object} */ var X_UA = X[ 'UA' ] = {}, - X_UA_classNameForHTML = 'js-enabled '; + X_UA_classNameForHTML = ''; (function(){ var dua = navigator.userAgent, dav = navigator.appVersion, tv = parseFloat(dav), sys = navigator.platform, - tridentToVer, i, j, v; + tridentToVer, i, j, v, androidBrowserPCMode; console.log( ' userAgent : ' + dua ); console.log( '-' ); @@ -30,7 +30,7 @@ var X_UA = X[ 'UA' ] = {}, if( sys.indexOf( 'iP' ) === 0 ){ - v = dua.split( 'OS ' )[ 1 ].split( '_' ); + v = dav.split( 'OS ' )[ 1 ].split( '_' ); i = window.devicePixelRatio === 1; /** * @alias X.UA.iOSMajor @@ -51,78 +51,81 @@ var X_UA = X[ 'UA' ] = {}, * @alias X.UA.iOS * @type {number} */ - X_UA[ 'iOS' ] = X_UA[ 'iOSMajor' ] + X_UA[ 'iOSMinor' ] / 10; + X_UA[ 'iOS' ] = X_UA[ 'iOSMajor' ] + X_UA[ 'iOSMinor' ] / 10; - if( screen.width === screen.height * 1.5 || screen.width * 1.5 === screen.height ){ - v = true; // 4:3 model - }; - - if( sys === 'iPhone' ){ - /** - * @alias X.UA.iPhone - * @type {boolean} - */ - X_UA[ 'iPhone' ] = true; - if( v ){ + // 4:3 model + v = screen.width === screen.height * 1.5 || screen.width * 1.5 === screen.height; + + switch( sys ){ + case 'iPhone' : + case 'iPhone Simulator' : /** - * iPhone4s以下 - * @alias X.UA.iPhone_4s + * @alias X.UA.iPhone * @type {boolean} */ - X_UA[ 'iPhone_4s' ] = true; - - if( i ){ + X_UA[ 'iPhone' ] = true; + if( v ){ /** - * iPhone3GS以下 - * @alias X.UA.iPhone_3GS + * iPhone4s以下 + * @alias X.UA.iPhone_4s * @type {boolean} */ - X_UA[ 'iPhone_3GS' ] = true; - }; - }; - - //alert( 'iPhone ' + ( X_UA[ 'iPhone_3GS' ] ? '3GS以下' : X_UA[ 'iPhone_4s' ] ? '4s以下' : '5以上' ) ); - }; - if( sys === 'iPad' ){ - /** - * @alias X.UA.iPad - * @type {boolean} - */ - X_UA[ 'iPad' ] = true; - if( i ){ + X_UA[ 'iPhone_4s' ] = true; + + if( i ){ + /** + * iPhone3GS以下 + * @alias X.UA.iPhone_3GS + * @type {boolean} + */ + X_UA[ 'iPhone_3GS' ] = true; + }; + }; + break; + + case 'iPad' : + case 'iPad Simulator' : /** - * iPad2以下または初代iPad mini 以下 - * @alias X.UA.iPad_2Mini1 + * @alias X.UA.iPad * @type {boolean} */ - X_UA[ 'iPad_2Mini1' ] = true; - }; - }; - if( sys === 'iPod' ){ - /** - * @alias X.UA.iPod - * @type {boolean} - */ - X_UA[ 'iPod' ] = true; - - if( v ){ + X_UA[ 'iPad' ] = true; + if( i ){ + /** + * iPad2以下または初代iPad mini 以下 + * @alias X.UA.iPad_2Mini1 + * @type {boolean} + */ + X_UA[ 'iPad_2Mini1' ] = true; + }; + break; + + case 'iPod' : + case 'iPod Simulator' : // 必要?? /** - * iPod4以下 - * @alias X.UA.iPod_4 + * @alias X.UA.iPod * @type {boolean} */ - X_UA[ 'iPod_4' ] = true; - - if( i ){ + X_UA[ 'iPod' ] = true; + + if( v ){ /** - * iPod3以下 - * @alias X.UA.iPod_3 + * iPod4以下 + * @alias X.UA.iPod_4 * @type {boolean} */ - X_UA[ 'iPod_3' ] = true; - }; - }; - //alert( 'iPod touch ' + ( X_UA[ 'iPod_3' ] ? '3以下' : X_UA[ 'iPod_4' ] ? '4以下' : '5以上' ) ); + X_UA[ 'iPod_4' ] = true; + + if( i ){ + /** + * iPod3以下 + * @alias X.UA.iPod_3 + * @type {boolean} + */ + X_UA[ 'iPod_3' ] = true; + }; + }; + break; }; console.log( '>> iOS : ' + X_UA[ 'iOS' ] ); @@ -136,26 +139,65 @@ var X_UA = X[ 'UA' ] = {}, X_UA[ 'webOS' ] = true; // webOS } else if( sys.indexOf( 'Win' ) + 1 ){ - console.log( 'Win' ); - /** - * @alias X.UA.Windows - * @type {boolean} - */ - X_UA[ 'Windows' ] = true; + switch( sys ){ + case 'WinCE' : + /** + * @alias X.UA.WinCE + * @type {boolean} + */ + X_UA[ sys ] = true; + break; case 'Win16' : case 'Win32' : case 'Win64' : - case 'WinCE' : /** * @alias X.UA.Win16 * @alias X.UA.Win32 * @alias X.UA.Win64 - * @alias X.UA.WinCE * @type {boolean} */ X_UA[ sys ] = true; + + if( v = dua.split( 'Windows NT 10' )[ 1 ] ){ + switch( v.substr( 0, 2 ) ){ + case '.0' : v = 10; break; + default : v = '?'; + }; + } else + if( v = dua.split( 'Windows NT ' )[ 1 ] ){ + switch( v.substr( 0, 3 ) ){ + case '6.3' : v = 8.1; break; + case '6.2' : v = 8; break; + case '6.1' : v = 7; break; + case '6.0' : v = 'Vista'; break; + case '5.2' : v = '2003|XP64'; break; + case '5.1' : v = v.indexOf( '5.1; SV1' ) ? 'XP' : 'XPSP2'; break; + case '5.0' : v = v.indexOf( '5.01' ) ? 2000 : '2kSP1'; break; + case '4.0' : v = 'NT'; break; + default : v = '?'; + }; + } else + if( v = dua.split( 'Windows ' )[ 1 ] ){ + switch( v.substr( 0, 2 ) ){ + case '98' : v = v.indexOf( '98; Win 9x 4.90' ) ? '98|98SE' : 'ME'; break; + case '95' : v = 95; break; + case '3.' : v = parseFloat( v ); break; + default : v = '?'; + }; + } else { + v = '?'; + }; + + /** + * 10, 8.1, 8, 7, Vista, 2003|XP64, XPSP2, XP, 2kSP1, 2000, ME, 98|98SE, 95, ? + * @alias X.UA.Windows + * @type {number|string} + */ + X_UA[ 'Windows' ] = v; + break; }; + // winRT } else if( sys.indexOf( 'Mac' ) + 1 ){ @@ -191,9 +233,24 @@ var X_UA = X[ 'UA' ] = {}, * @alias X.UA.Linux * @type {boolean} */ - X_UA[ 'Linux' ] = true; - - if( ( i = dua.indexOf( 'Android' ) ) !== -1 ){ + if( ( v = dua.split( 'Android ' )[ 1 ] ) || + ( v = sys.split( 'Android ' )[ 1 ] ) ){ // PCモードの Android Firefox では platform に Android 0.0.0 が存在 + v = v.split( '.' ); + /** + * @alias X.UA.AndroidMajor + * @type {number} + */ + X_UA[ 'AndroidMajor' ] = parseFloat( v[ 0 ] ) || 0; + /** + * @alias X.UA.AndroidMinor + * @type {number} + */ + X_UA[ 'AndroidMinor' ] = parseFloat( v[ 1 ] ) || 0; + /** + * @alias X.UA.AndroidPatch + * @type {number} + */ + X_UA[ 'AndroidPatch' ] = parseFloat( v[ 2 ] ) || 0; /** * Firefox で Version が取れない! * http://bizmakoto.jp/bizid/articles/1207/31/news004.html @@ -205,187 +262,282 @@ var X_UA = X[ 'UA' ] = {}, * @alias X.UA.Android * @type {number} */ - X_UA[ 'Android' ] = parseFloat( dua.substr( i + 8 ) ) || 0.1; + X_UA[ 'Android' ] = X_UA[ 'AndroidMajor' ] + X_UA[ 'AndroidMinor' ] / 10; console.log( '>> Android : ' + X_UA[ 'Android' ] ); + } else + if( ( sys === 'Linux armv7l' || sys === 'Linux i686' ) && window.ontouchstart !== undefined && ( v = parseFloat( dua.split( 'WebKit\/' )[ 1 ] ) ) ){ + // https://ja.wikipedia.org/wiki/WebKit + // http://www.au.kddi.com/developer/android/kishu/ua/ + // webkit version to Android version... + androidBrowserPCMode = !window.chrome || v < 534.3; // 4.0 & 3.x には chrome がいる... + + if( !window[ 'Int8Array' ] ){ + v = + v < 529 ? 1.5 : // <= 528.5 + v < 531 ? 2.0 : // 530 2.0~2.1 + // 533 2.2~2.3 + v < 534 ? ( window.HTMLAudioElement ? 2.3 : 2.2 ) : 0; + } else { + v = + !navigator[ 'connection' ] ? 4.4 : + Number.isFinite && ( window.history && window.history.pushState ) ? 4.2/* & 4.3 */ : // ここに 4.1, 4.0 も入ってくる... + Number.isFinite ? 4.1 : 4; + // 534 - 3.x~4.x , 534.13=3.x + // 534.30 = 4.0-4.1 + // 535.19 = 4.1 + // 537.36 = 4.4.2-5.x + }; + + if( v ){ + // PC版で見る、にチェックが付いている場合、ユーザーエージェント文字列にも platform にも Android の文字列が存在しない(標準ブラウザ&Chrome) + // Audio でタッチが必要か?の判定にとても困る... + // ua には Linux x86_64 になっている + X_UA[ 'Android' ] = v; + }; }; }; if( window.opera ){ - i = dua.indexOf( 'Opera' ); // Opera/ - j = dua.indexOf( 'Version/' ); + i = dua.split( 'Opera' )[ 1 ]; // Opera/ + j = dua.split( 'Version/' )[ 1 ]; /** * @alias X.UA.Opera * @type {number} */ - X_UA[ 'Opera' ] = v = Math.max( - i !== -1 ? parseFloat( dua.substr( i + 6 ) ) : 0, - j !== -1 ? parseFloat( dua.substr( j + 8 ) ) : 0, - tv ); + X_UA[ 'Opera' ] = v = Math.max( parseFloat( i ) || 0, parseFloat( j ) || 0, tv ); /** * memo:closure compiler で minify するとOpera7で動かない * --compilation_level WHITESPACE_ONLY --formatting pretty_print <- 動く * @alias X.UA.Opera7 * @type {boolean} */ - X_UA[ 'Opera7' ] = v < 8; + X_UA[ 'Opera7' ] = v < 8; /** * @alias X.UA.Opera78 * @type {boolean} */ - X_UA[ 'Opera78' ] = v < 9; - /** - * @alias X.UA.OperaMini - * @type {boolean} - */ - X_UA[ 'OperaMini' ] = 0 < dua.indexOf('Opera Mini'); - /** - * @alias X.UA.OperaMobile - * @type {boolean} - */ - X_UA[ 'OperaMobile' ] = 0 < dua.indexOf('Opera Mobi'); - /** - * @alias X.UA.OperaTablet - * @type {boolean} - */ - X_UA[ 'OperaTablet' ] = 0 < dua.indexOf('Opera Tablet'); - /** - * @alias X.UA.Wii - * @type {boolean} - */ - X_UA[ 'Wii' ] = dua.indexOf( 'Nintendo Wii' ) !== -1; - /** - * @alias X.UA.NDS - * @type {boolean} - */ - X_UA[ 'NDS' ] = dua.indexOf( 'Nitro' ) !== -1; + X_UA[ 'Opera78' ] = v < 9; + + if( 0 < dua.indexOf( 'Opera Mini' ) ) + /** + * @alias X.UA.OperaMini + * @type {boolean} + */ + X_UA[ 'OperaMini' ] = true; + + if( 0 < dua.indexOf( 'Opera Mobi' ) ) + /** + * @alias X.UA.OperaMobile + * @type {boolean} + */ + X_UA[ 'OperaMobile' ] = true; + + if( 0 < dua.indexOf('Opera Tablet') ) + /** + * @alias X.UA.OperaTablet + * @type {boolean} + */ + X_UA[ 'OperaTablet' ] = true; + + // Android Opera12.10 UserAgent:Desktop + // この場合 android version 不明... + if( !X_UA[ 'OperaMini' ] && !X_UA[ 'OperaTablet' ] && !X_UA[ 'OperaMobile' ] && sys === 'Android' ){ + if( screen.width * screen.height < 320000 ){ + X_UA[ 'OperaMobile' ] = true; + } else { + X_UA[ 'OperaTablet' ] = true; + }; + }; + + if( 0 < dua.indexOf( 'Nintendo Wii' ) ) + /** + * @alias X.UA.Wii + * @type {boolean} + */ + X_UA[ 'Wii' ] = true; + + if( 0 < dua.indexOf( 'Nitro' ) ) + /** + * @alias X.UA.NDS + * @type {boolean} + */ + X_UA[ 'NDS' ] = true; + console.log( '>> Opera : ' + v ); - return; - }; - - // Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko - if( document.all || dav.indexOf( 'Trident/' ) !== -1 ){ - /** - * @alias X.UA.ActiveX - * @type {boolean} - */ - X_UA[ 'ActiveX' ] = !!window[ 'ActiveXObject' ]; + } else + if( v = parseFloat( dav.split( 'Edge/' )[ 1 ] ) ){ /** - * documentモードを考慮しないIEのバージョン - * @alias X.UA._IE + * Microsoft Edge + * @alias X.UA.Edge * @type {number} */ - X_UA[ '_IE' ] = parseFloat(dua.split('MSIE ')[1]) || parseFloat(dua.split('rv:')[1]) || parseFloat(dav.split('MSIE ')[1]) || 0; + X_UA[ 'Edge' ] = v; + + if( dav.indexOf( 'Mobile' ) ){ + /** + * Microsoft Edge for Windows 10 Mobile + * @alias X.UA.EdgeMobile + * @type {number} + */ + X_UA[ 'EdgeMobile' ] = v; + }; + + } else + // Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko + if( ( v = dav.split( 'Trident/' )[ 1 ] ) || document.all ){ // .all は Opera にもいるので Opera の判定が先 + if( v = parseFloat( v ) ) /** - * IE11 の互換モードの navigator.appVersion にも Trident/7.0 が書かれているため互換モードか?判定ができる - * 互換モードでは Silverlight でエラーが出る? + * IE11 の互換モードの navigator.appVersion にも Trident/7.0 が書かれているため互換モードか?判定ができるc * @alias X.UA.Trident * @type {number} */ - X_UA[ 'Trident' ] = parseFloat(dav.split('Trident/')[1]) || 0; + X_UA[ 'Trident' ] = v; - tridentToVer = X_UA[ 'Trident' ] ? ( X_UA[ 'Trident' ] + 4 | 0 ) : X_UA[ '_IE' ]; + if( window[ 'ActiveXObject' ] ) /** - * IE10 以上の互換モードを使用している場合、そのバージョン - * @alias X.UA.IEHost - * @type {number} + * @alias X.UA.ActiveX + * @type {boolean} */ - if( tridentToVer !== X_UA[ '_IE' ] ) X_UA[ 'IEHost' ] = tridentToVer; + X_UA[ 'ActiveX' ] = true; + + v = parseFloat( dua.split( 'MSIE ' )[ 1 ] ) || + parseFloat( dua.split( 'rv:' )[ 1 ] ) || 0; + + tridentToVer = X_UA[ 'Trident' ] ? ( X_UA[ 'Trident' ] + 4 | 0 ) : v; + + if( tridentToVer !== v ){ + /** + * IE10 以上の互換モードを使用している場合、そのバージョン + * @alias X.UA.IEHost + * @type {number} + */ + X_UA[ 'IEHost' ] = tridentToVer; + }; /** * documentモードを考慮したIEのバージョン * @alias X.UA.IE * @type {number} */ - X_UA[ 'IE' ] = v = document.documentMode || tridentToVer; - /** - * @alias X.UA.IE4 - * @type {boolean} - */ - if( v && v < 4.5 ) X_UA[ 'IE4' ] = true; - /** - * @alias X.UA.IE45 - * @type {boolean} - */ - if( v && 4.5 <= v && v < 5 ) X_UA[ 'IE45' ] = true; - /** - * @alias X.UA.IE4x - * @type {boolean} - */ - if( X_UA[ 'IE4' ] || X_UA[ 'IE45' ] ) X_UA[ 'IE4x' ] = true; - /** - * @alias X.UA.IE5 - * @type {boolean} - */ - if( 5 <= v && v < 5.5 ) X_UA[ 'IE5' ] = true; - /** - * @alias X.UA.IE55 - * @type {boolean} - */ - if( 5.5 <= v && v < 6 ) X_UA[ 'IE55' ] = true; - /** - * @alias X.UA.IE5x - * @type {boolean} - */ - if( X_UA[ 'IE5' ] || X_UA[ 'IE55' ] ) X_UA[ 'IE5x' ] = true; - /** - * @alias X.UA.IE6 - * @type {boolean} - */ - if( 6 <= v && v < 7 ) X_UA[ 'IE6' ] = true; - /** - * @alias X.UA.IE7 - * @type {boolean} - */ - if( 7 <= v && v < 8 ) X_UA[ 'IE7' ] = true; - /** - * @alias X.UA.IE8 - * @type {boolean} - */ - if( 8 <= v && v < 9 ) X_UA[ 'IE8' ] = true; - /** - * @alias X.UA.IE9 - * @type {boolean} - */ - if( 9 <= v && v < 10 ) X_UA[ 'IE9' ] = true; - /** - * @alias X.UA.MacIE - * @type {boolean} - */ - if( X_UA[ 'Mac' ] ) X_UA[ 'MacIE' ] = true; - /** - * @alias X.UA.IEMobile - * @type {boolean} - */ - if( dua.toLowerCase().indexOf( 'iemobile' ) !== -1 || X_UA[ 'WinCE' ] ) X_UA[ 'IEMobile' ] = true; - /** - * @alias X.UA.WinPhone - * @type {boolean} - */ - if( dua.toLowerCase().indexOf( 'windows phone' ) !== -1 || 0 < dav.indexOf( 'ZuneWP' ) ) X_UA[ 'WinPhone' ] = true; // ZuneWP は IEM のデスクトップモードで登場する + X_UA[ 'IE' ] = v = document.documentMode || tridentToVer; + + if( v < 4.5 ){ + /** + * @alias X.UA.IE4 + * @type {boolean} + */ + X_UA[ 'IE4' ] = true; + } else + if( v < 5 ){ + /** + * @alias X.UA.IE45 + * @type {boolean} + */ + X_UA[ 'IE45' ] = true; + } else + if( v < 5.5 ){ + /** + * @alias X.UA.IE5 + * @type {boolean} + */ + X_UA[ 'IE5' ] = true; + } else + if( v < 6 ){ + /** + * @alias X.UA.IE55 + * @type {boolean} + */ + X_UA[ 'IE55' ] = true; + } else + if( v < 7 ){ + /** + * @alias X.UA.IE6 + * @type {boolean} + */ + X_UA[ 'IE6' ] = true; + } else + if( v < 8 ){ + /** + * @alias X.UA.IE7 + * @type {boolean} + */ + X_UA[ 'IE7' ] = true; + } else + if( v < 9 ){ + /** + * @alias X.UA.IE8 + * @type {boolean} + */ + X_UA[ 'IE8' ] = true; + } else + if( v < 10 ){ + /** + * @alias X.UA.IE9 + * @type {boolean} + */ + X_UA[ 'IE9' ] = true; + }; + + if( X_UA[ 'IE4' ] || X_UA[ 'IE45' ] ){ + /** + * @alias X.UA.IE4x + * @type {boolean} + */ + X_UA[ 'IE4x' ] = true; + }; + + if( X_UA[ 'IE5' ] || X_UA[ 'IE55' ] ){ + /** + * @alias X.UA.IE5x + * @type {boolean} + */ + X_UA[ 'IE5x' ] = true; + }; + + if( X_UA[ 'Mac' ] ){ + /** + * @alias X.UA.MacIE + * @type {boolean} + */ + X_UA[ 'MacIE' ] = true; + }; + + if( 0 < dua.indexOf( 'IEMobile' ) || X_UA[ 'WinCE' ] ){ + /** + * @alias X.UA.IEMobile + * @type {boolean} + */ + X_UA[ 'IEMobile' ] = true; + }; + + if( 0 < dua.indexOf( 'Windows Phone' ) || 0 < dav.indexOf( 'ZuneWP' ) ){ + /** + * @alias X.UA.WinPhone + * @type {boolean} + */ + X_UA[ 'WinPhone' ] = true; // ZuneWP はデスクトップモードで登場する + }; console.log( '>> IE : ' + v + ' ActiveX : ' + X_UA[ 'ActiveX' ] + ' IEHost : ' + X_UA[ 'IEHost' ] ); // TODO XBox360, XBox1, Modern or Desktop, Standalone - return; - }; + } else // - if( ( i = dua.indexOf( 'NetFront\/' ) !== -1 ) ){ + if( v = dua.split( 'NetFront\/' )[ 1 ] ){ /** * http://qa.support.sony.jp/solution/S0812181056444/common/nfb34_dom_200jp/dom_dom0_JP.html * @alias X.UA.NetFront * @type {number} */ - X_UA[ 'NetFront' ] = parseFloat( dua.substr( i + 9 ) ) || 0.1; + X_UA[ 'NetFront' ] = parseFloat( v ) || 0.1; console.log( '>> NetFront : ' + X_UA[ 'NetFront' ] ); - return; - }; + } else if( X_UA[ 'Linux' ] && tv === 2 && dua.indexOf( 'Sony\/COM2\/' ) !== -1 ){ X_UA[ 'NetFront' ] = 3.4; console.log( '>> NetFront : ' + X_UA[ 'NetFront' ] ); - return; - }; + } else - if( ( i = dua.toUpperCase().indexOf( 'PLAYSTATION 3' ) !== -1 ) ){ + if( v = dua.toUpperCase().split( 'PLAYSTATION 3' )[ 1 ] ){ /** * PlayStation 3 システムバージョン 4.10 未満の SONY 独自ブラウザ * http://www.useragentstring.com/pages/Playstation%203/ @@ -396,12 +548,11 @@ var X_UA = X[ 'UA' ] = {}, * @alias X.UA.PS3 * @type {number} */ - X_UA[ 'PS3' ] = parseFloat( dua.substr( i + 15 ) ) || 0.1; + X_UA[ 'PS3' ] = parseFloat( v ) || 0.1; console.log( '>> PS3 : ' + X_UA[ 'PS3' ] ); - return; - }; + } else - if( ( i = dua.indexOf( 'iCab' ) !== -1 ) ){ + if( v = dua.split( 'iCab' )[ 1 ] ){ /** * http://www.useragentstring.com/pages/iCab/ * iCab/3.0.2 (Macintosh; U; PPC Mac OS X) @@ -409,21 +560,19 @@ var X_UA = X[ 'UA' ] = {}, * @alias X.UA.iCab * @type {number} */ - X_UA[ 'iCab' ] = parseFloat( dua.substr( i + 5 ) ) || 0.1; + X_UA[ 'iCab' ] = parseFloat( v ) || 0.1; console.log( '>> iCab : ' + X_UA[ 'iCab' ] ); - return; - }; + } else - if( 0 < dua.indexOf( 'Gecko\/' ) && ( i = dua.indexOf( 'rv:' ) ) ){ - v = dua.substr( i + 3 ).split( '.' ); + if( 0 < dua.indexOf( 'Gecko\/' ) && ( v = dua.split( 'rv:' )[ 1 ] ) ){ + v = v.split( '.' ); /** * メジャーバージョン + マイナーバージョン * @alias X.UA.Gecko * @type {number} */ X_UA[ 'Gecko' ] = parseFloat( v[ 0 ] ) || 0 + - ( parseFloat( v[ 1 ] ) || 0 ) / 10 + - ( parseFloat( v[ 2 ] ) || 0 ) / 100; + ( parseFloat( v[ 1 ] ) || 0 ) / 10; /** * @alias X.UA.GeckoMajor * @type {number} @@ -440,17 +589,33 @@ var X_UA = X[ 'UA' ] = {}, */ X_UA[ 'GeckoPatch' ] = parseFloat( v[ 2 ] ) || 0; + // Fennec41- 用 + // https://developer.mozilla.org/ja/docs/Gecko_user_agent_string_reference + // バージョン 41 以降の Android 版 Firefox では platform トークンに Android バージョンが含まれます。 + // 相互運用性向上のため、Android 4 以前のバージョンでブラウザが動作している場合は 4.4 と出力します。 + // Android バージョン 4 以降では実際のバージョン番号が出力されます。 + // なお、Gecko エンジンはすべての Android バージョンに対して同じ機能を提供しています。 + if( dua.indexOf( 'Android 4.4; Mobile;' ) !== -1 || dua.indexOf( 'Android 4.4; Tablet;' ) !== -1 ){ + X_UA[ 'Android' ] = '2.3+'; + } else + if( dua.indexOf( 'Android;' ) !== -1 ){ + X_UA[ 'Android' ] = '2.2+'; + }; + + // TODO PC版 Fennec もある //Fennec - if( ( i = dua.indexOf( 'Fennec/' ) ) !== -1 ){ + if( v = dua.split( 'Fennec/' )[ 1 ] ){ /** * Mozilla/5.0 (Android; Linux armv7l; rv:9.0) Gecko/20111216 Firefox/9.0 Fennec/9.0 * @alias X.UA.Fennec * @type {number} */ - X_UA[ 'Fennec' ] = parseFloat( dua.substr( i + 7 ) ); + X_UA[ 'Fennec' ] = parseFloat( v ); console.log( '>> Fennec : ' + X_UA[ 'Fennec' ] + ', Gecko : ' + X_UA[ 'Gecko' ] ); - return; - }; + } else + if( X_UA[ 'Android' ] ){ + X_UA[ 'Fennec' ] = X_UA[ 'Gecko' ]; + } else //Firefox //Netscape @@ -467,34 +632,76 @@ var X_UA = X[ 'UA' ] = {}, */ X_UA[ 'NN6' ] = true; console.log( '>> NN : ' + X_UA[ 'NN' ] + ', Gecko : ' + X_UA[ 'Gecko' ] ); - return; } else //Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) //Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20070321 Netscape/8.1.3 - if( ( i = dua.indexOf( 'Netscape/' ) ) !== -1 ){ - X_UA[ 'NN' ] = parseFloat( dua.substr( i + 9 ) ) || 7; + if( v = dua.split( 'Netscape/' )[ 1 ] ){ + X_UA[ 'NN' ] = parseFloat( v ) || 7; console.log( '>> NN : ' + X_UA[ 'NN' ] + ', Gecko : ' + X_UA[ 'Gecko' ] ); - return; } else //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 - if( ( i = dua.indexOf( 'Navigator/' ) ) !== -1 ){ - X_UA[ 'NN' ] = parseFloat( dua.substr( i + 10 ) ) || 9; + if( v = dua.split( 'Navigator/' )[ 1 ] ){ + X_UA[ 'NN' ] = parseFloat( v ) || 9; console.log( '>> NN : ' + X_UA[ 'NN' ] + ', Gecko : ' + X_UA[ 'Gecko' ] ); - return; }; console.log( '>> Gecko : ' + X_UA[ 'Gecko' ] ); - }; + } else - // TODO Blink + // Android 標準ブラウザ AOSP と ChromeWeb View, Sブラウザがある + if( ( v = X_UA[ 'Android' ] ) && ( dua.indexOf( 'Chrome\/' ) < 0 || 0 < dua.indexOf( 'Version\/' ) || androidBrowserPCMode ) ){ // Chrome/ を含まない または Version/ を含む + + /* if( window.chrome ){ // Android3.1 のAOSPブラウザで .chrome がいた、、、 + } else */ + if( dua.indexOf( 'Version\/' ) < 0 && 0 < dua.indexOf( 'Chrome\/' ) && !androidBrowserPCMode ){ + /** + * Android 標準ブラウザ Chrome WebView ブラウザ + * @alias X.UA.ChromeWV + * @type {number} + */ + X_UA[ 'ChromeWV' ] = v; + } else + // http://uupaa.hatenablog.com/entry/2014/04/15/163346 + // Chrome WebView は Android 4.4 の時点では WebGL や WebAudio など一部の機能が利用できません(can i use)。 + // また UserAgent が書き換え可能なため、旧来のAOSPブラウザの UserAgent を偽装した形で配布されているケースがあります。 + // http://caniuse.com/#compare=chrome+40,android+4.2-4.3,android+4.4,android+4.4.3-4.4.4,and_chr+45 + // CustomElement の有無で判定 + if( document[ 'registerElement' ] ){ + // UA が偽装された Chrome WebView + X_UA[ 'ChromeWV' ] = v; + } else { + /** + * Android 標準ブラウザ AOSP + * @alias X.UA.AOSP + * @type {number} + */ + X_UA[ 'AOSP' ] = v; + }; + + /* + * http://www.flexfirm.jp/blog/article/402 + * TODO Sブラウザ + * SC-04E、SC-01F、SC-02F、 SC-04F、SCL22、SCL23など + */ + } else + // Blink Chrome & Blink Opera + if( v = parseFloat( dua.split( 'OPR/' )[ 1 ] ) ){ + /** + * @alias X.UA.BlinkOpera + * @type {number} + */ + X_UA[ 'BlinkOpera' ] = v; + + X_UA[ 'Blink' ] = parseFloat( dua.split( 'Chrome/' )[ 1 ] ); + } else if( window.chrome ){ /** * @alias X.UA.Blink * @type {number} */ - X_UA[ 'Blink' ] = tv; + X_UA[ 'Blink' ] = parseFloat( dua.split( 'Chrome/' )[ 1 ] ); + console.log( '>>Blink : ' + X_UA[ 'Blink' ] ); - } else if( dav.indexOf( 'Konqueror' ) !== -1 ){ /** @@ -505,120 +712,73 @@ var X_UA = X[ 'UA' ] = {}, console.log( '>>Khtml : ' + X_UA[ 'Khtml' ] ); } else - if( ( i = dua.indexOf( 'Android ' ) ) !== -1 ){ - /** - * Android 標準ブラウザ - * @alias X.UA.AndroidBrowser - * @type {number} - */ - X_UA[ 'AndroidBrowser' ] = i = parseFloat( dua.substr( i + 8 ) ) || 0.1; - /** - * @alias X.UA.AndroidBrowser1 - * @type {boolean} - */ - X_UA[ 'AndroidBrowser1' ] = 1 <= i && i < 2; - /** - * @alias X.UA.AndroidBrowser2 - * @type {boolean} - */ - X_UA[ 'AndroidBrowser2' ] = 2 <= i && i < 3; - /** - * @alias X.UA.AndroidBrowser3 - * @type {boolean} - */ - X_UA[ 'AndroidBrowser3' ] = 3 <= i && i < 4; - /** - * @alias X.UA.AndroidBrowser4 - * @type {boolean} - */ - X_UA[ 'AndroidBrowser4' ] = 4 <= i && i < 5; - /** - * @alias X.UA.AndroidBrowser5 - * @type {boolean} - */ - X_UA[ 'AndroidBrowser5' ] = 5 <= i && i < 6; - console.log( '>> AndroidBrowser : ' + X_UA[ 'Android' ] ); - - i = parseFloat(dua.split('WebKit\/')[1]); - /** - * @alias X.UA.AndroidWebkit - * @type {number} - */ - X_UA[ 'AndroidWebkit' ] = i; - alert( 'AudioSprite調査:Android標準ブラウザ Webkit Version ' + i ); - - } else - if( i = parseFloat(dua.split('WebKit\/')[1]) ){ + if( v = parseFloat( dua.split( 'WebKit\/' )[ 1 ] ) ){ /** * @alias X.UA.WebKit * @type {number} */ - X_UA[ 'WebKit' ] = i; + X_UA[ 'WebKit' ] = v; - if( v = parseFloat(dua.split('Chrome\/')[1]) ){ + if( v = parseFloat( dua.split( 'Chrome\/' )[ 1 ] ) ){ /** * @alias X.UA.Chrome * @type {number} */ X_UA[ 'Chrome' ] = v; - }; - - // TODO webkit Opera - - console.log( '>>Webkit : ' + X_UA[ 'WebKit' ] ); - - if( i && !X_UA[ 'Chrome' ] && dua.indexOf( 'Safari' ) !== -1 ){ - if( dav.indexOf( 'Version/' ) !== -1 ){ + } else + if( dua.indexOf( 'Safari' ) !== -1 ){ + if( v = parseFloat( dav.split( 'Version/' )[ 1 ] ) ){ /** * @alias X.UA.Safari * @type {number} */ - X_UA[ 'Safari' ] = parseFloat( dav.split('Version/')[1] ); - } else { - if( i <= 528.16 ){ - X_UA[ 'Safari' ] = i < 73 ? 0.8 : - i < 85 ? 0.9 : - i < 100 ? 1 : - i < 125 ? 1.1 : - i < 312 ? 1.2 : - i < 412 ? 1.3 : - i <= 419.3 ? 2 : - i <= 525.13 ? 3 : - i <= 525.25 ? 3.1 : 3.2; - }; + X_UA[ 'Safari' ] = v; + } else + if( v <= 528.16 ){ + X_UA[ 'Safari' ] = v < 73 ? 0.8 : + v < 85 ? 0.9 : + v < 100 ? 1 : + v < 125 ? 1.1 : + v < 312 ? 1.2 : + v < 412 ? 1.3 : + v <= 419.3 ? 2 : + v <= 525.13 ? 3 : + v <= 525.25 ? 3.1 : 3.2; }; - }; + }; console.log( '>> Webkit : ' + X_UA[ 'WebKit' ] + ' Safari : ' + X_UA[ 'Safari' ] ); - }; - - if( dua.toLowerCase().indexOf( 'iris' ) !== -1 ){ - /** - * http://www.useragentstring.com/pages/Iris/ - * @alias X.UA.Iris - * @type {boolean} - */ - X_UA[ 'Iris' ] = true; - }; - - 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) - dua.indexOf( 'Kobo' ) !== -1 || - // Kindle paperwhite Mozilla/5.0 (X11; U; Linux armv7l like Android; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/533.2+ Kindle/3.0+ - dua.indexOf( 'Kindle' ) !== -1 || - // Sony Reader Mozilla/5.0 (Linux; U; ja-jp; EBRD1101; EXT) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 - dua.indexOf( 'EBRD' ) !== -1 - ){ + + if( dua.toLowerCase().indexOf( 'iris' ) !== -1 ){ /** - * Kobo, Kindle, Sony Reader - * @alias X.UA.EInk + * http://www.useragentstring.com/pages/Iris/ + * @alias X.UA.Iris * @type {boolean} */ - X_UA[ 'EInk' ] = true; + X_UA[ 'Iris' ] = true; }; + + 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) + dua.indexOf( 'Kobo' ) !== -1 || + // Kindle paperwhite Mozilla/5.0 (X11; U; Linux armv7l like Android; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/533.2+ Kindle/3.0+ + dua.indexOf( 'Kindle' ) !== -1 || + // Sony Reader Mozilla/5.0 (Linux; U; ja-jp; EBRD1101; EXT) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 + dua.indexOf( 'EBRD' ) !== -1 + ){ + /** + * Kobo, Kindle, Sony Reader + * @alias X.UA.EInk + * @type {boolean} + */ + X_UA[ 'EInk' ] = true; + }; + }; + })(); (function(){ var k, v; + if( X_UA[ 'IE45' ] || X_UA[ 'IE4' ] ){ if( X_UA[ 'Mac' ] ){ X_UA_classNameForHTML = 'Mac'; @@ -627,29 +787,30 @@ var X_UA = X[ 'UA' ] = {}, // TODO CE3 の ie4 と WM の ie4 の分岐 X_UA_classNameForHTML = 'WinCE'; } else - if( X_UA[ 'Win' ] ){ + if( X_UA[ 'Windows' ] ){ X_UA_classNameForHTML = 'Win'; } else { X_UA_classNameForHTML = 'Other'; }; - X_UA_classNameForHTML += 'IE4'; + X_UA_classNameForHTML += '_IE4'; if( X_UA[ 'IE45' ] ){ X_UA_classNameForHTML += '5'; }; if( X_UA[ 'ActiveX' ] ){ - X_UA_classNameForHTML += 'ActiveX'; + X_UA_classNameForHTML += '_ActiveX'; }; } else { for( k in X_UA ){ v = X_UA[ k ]; if( v ){ - X_UA_classNameForHTML += k + ' '; if( v !== true ){ X_UA_classNameForHTML += k + v + ' '; + } else { + X_UA_classNameForHTML += k + ' '; }; }; }; @@ -684,6 +845,16 @@ if( document.getElementById ){ }; }; +var X_elmHtml = document.documentElement || + X_UA_DOM.W3C ? document.getElementsByTagName( 'html' )[ 0 ] : + X_UA_DOM.IE4 ? document.all.tags( 'html' )[ 0 ] : null, + + X_elmHead = + X_UA_DOM.W3C ? document.getElementsByTagName( 'head' )[ 0 ] : + X_UA_DOM.IE4 ? document.all.tags( 'head' )[ 0 ] : null, + + X_elmBody; + if( navigator.msPointerEnabled || navigator.pointerEnabled ) X_UA_HID.POINTER = true; if( !X_UA_HID.POINTER && window.ontouchstart !== undefined ) X_UA_HID.TOUCH = true; @@ -700,23 +871,6 @@ if( X_UA[ 'Safari' ] && X_UA[ 'WebKit' ] < 525.13 ){ }; };*/ -// TODO 構文のサポート instanceof, in, try catch - -if( X_UA[ 'IE' ] < 7 ){ // error @ NN7.2 - X_UA[ 'IE4' ] || X_UA[ 'MacIE' ] ? - document.execCommand && document.execCommand( 'BackgroundImageCache', false, true ) : - (function(){ - /** - * ie7 以下で実行する document.execCommand( 'BackgroundImageCache', false, true ) の失敗。 - * bonus: hotfix for IE6 SP1 (bug KB823727) - * multipleIEs IE6 standalone 版では不可, IE5.5 は可,,, - * @alias X.UA.ieExeComError */ - X_UA[ 'ieExeComError' ] = eval( 'var a=1;try{document.execCommand&&document.execCommand("BackgroundImageCache",!1,!0)}catch(e){a=0}!a' ); - })(); - - //X_UA[ 'ieExeComError' ] && alert( 'document.execCommand error!' ); -}; - /* * HTML5 に対応しない IE8 以下でも の下に
を作ることができる * その際に
の直前に改行文字が出現するが childNodes は長さ 1 で
だけの模様、、、 @@ -728,4 +882,3 @@ X_UA_ATagWrapDiv = (function( e, h ){ })(); console.log( 'HTML5? ' + X_UA_ATagWrapDiv ); */ -