2 // ------------------------------------------------------------------------- //
\r
3 // ------------ local variables -------------------------------------------- //
\r
4 // ------------------------------------------------------------------------- //
\r
5 var X_UA = (function( n, undefined ){
\r
9 tv = parseFloat(dav),
\r
11 tridentToVer, i, j, v;
\r
13 console.log( ' userAgent : ' + dua );
\r
15 console.log( ' appVersion : ' + dav );
\r
17 console.log( ' platform : ' + sys );
\r
20 // TODO 3DS, DSi, WiiU
\r
22 if( sys.indexOf( 'iP' ) === 0 ){
\r
24 v = dua.split( 'OS ' )[ 1 ].split( '_' );
\r
25 i = window.devicePixelRatio === 1;
\r
27 acme.iOSMajor = parseFloat( v[ 0 ] ) || 0;
\r
28 acme.iOSMinor = parseFloat( v[ 1 ] ) || 0;
\r
29 acme.iOSPatch = parseFloat( v[ 2 ] ) || 0;
\r
31 acme.iOS = acme.iOSMajor + acme.iOSMinor / 10;
\r
33 if( screen.width === screen.height * 1.5 || screen.width * 1.5 === screen.height ){
\r
34 v = true; // 4:3 model
\r
37 if( sys === 'iPhone' ){
\r
39 if( v ) acme.iPhone_4s = true; // 4s以下
\r
40 if( v && i ) acme.iPhone_3GS = true; // 3GS以下
\r
41 //alert( 'iPhone ' + ( acme.iPhone_3GS ? '3GS以下' : acme.iPhone_4s ? '4s以下' : '5以上' ) );
\r
43 if( sys === 'iPad' ){
\r
45 if( i ) acme.iPad_2Mini1 = true;
\r
47 if( sys === 'iPod' ){
\r
49 if( v ) acme.iPod_4 = true;
\r
50 if( v && i ) acme.iPod_3 = true;
\r
51 //alert( 'iPod touch ' + ( acme.iPod_3 ? '3以下' : acme.iPod_4 ? '4以下' : '5以上' ) );
\r
54 console.log( '>> iOS : ' + acme.iOS );
\r
56 if( dua.indexOf( 'hp-tablet' ) !== -1 || dua.indexOf( 'webOS' ) !== -1 ){
\r
57 // http://user-agent-string.info/list-of-ua/os-detail?os=webOS
\r
58 acme.webOS = true; // webOS
\r
60 if( sys.indexOf( 'Win' ) + 1 ){
\r
61 console.log( 'Win' );
\r
62 acme.Windows = true;
\r
72 if( sys.indexOf( 'Mac' ) + 1 ){
\r
73 console.log( 'Mac' );
\r
85 if( ( sys.indexOf( 'Linux' ) + 1 ) || ( sys.indexOf( 'Android' ) + 1 ) ){
\r
86 console.log( 'Linux' );
\r
89 if( ( i = dua.indexOf( 'Android' ) ) !== -1 ){
\r
90 acme.Android = parseFloat( dua.substr( i + 8 ) ) || 0.1; // Firefox で Version が取れない!
\r
91 console.log( '>> Android : ' + acme.Android );
\r
96 * http://bizmakoto.jp/bizid/articles/1207/31/news004.html
\r
97 Chrome Android 4.0以上 Google
\r
98 Dolphin Browser HD Android 2.0.1以上 Mobotap
\r
99 Firefox Android 2.2以上 Mozilla
\r
100 Opera Mobile Android 1.6以上 Opera Software ASA
\r
101 Sleipnir Mobile Android 2.1以上 Fenrir
\r
104 if( window.opera ){
\r
105 i = dua.indexOf( 'Opera' ); // Opera/
\r
106 j = dua.indexOf( 'Version/' );
\r
107 acme.Opera = Math.max(
\r
108 i !== -1 ? parseFloat( dua.substr( i + 6 ) ) : 0,
\r
109 j !== -1 ? parseFloat( dua.substr( j + 8 ) ) : 0,
\r
111 // closure compiler で minify するとOpera7で動かない
\r
112 // --compilation_level WHITESPACE_ONLY --formatting pretty_print <- 動く
\r
113 acme.Opera7 = acme.Opera < 8;
\r
114 acme.Opera78 = acme.Opera < 9;
\r
115 acme.OperaMini = 0 < dua.indexOf('Opera Mini');
\r
116 acme.OperaMobile = 0 < dua.indexOf('Opera Mobi');
\r
117 acme.OperaTablet = 0 < dua.indexOf('Opera Tablet');
\r
118 acme.Wii = dua.indexOf( 'Nintendo Wii' ) !== -1;
\r
119 acme.NDS = dua.indexOf( 'Nitro' ) !== -1;
\r
120 console.log( '>> Opera : ' + acme.Opera );
\r
124 // Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
\r
125 if( document.all || dav.indexOf( 'Trident/' ) !== -1 ){
\r
126 acme.ActiveX = !!window[ 'ActiveXObject' ];
\r
127 acme._IE = parseFloat(dua.split('MSIE ')[1]) || parseFloat(dua.split('rv:')[1]) || parseFloat(dav.split('MSIE ')[1]) || 0;
\r
128 // IE11 の互換モードの dav にも Trident/7.0 が書かれているため互換モードか?判定ができる
\r
129 // 互換モードでは Silverlight でエラーが出る?
\r
130 acme.Trident = parseFloat(dav.split('Trident/')[1]) || 0;
\r
131 acme.IE = document.documentMode || acme._IE;
\r
132 tridentToVer = acme.Trident ? ( acme.Trident + 4 | 0 ) : acme._IE;
\r
133 acme.IECompat = /* acme.IE !== acme._IE || */ tridentToVer !== acme._IE && tridentToVer;
\r
134 acme.IE4 = acme.IE && acme.IE < 5;
\r
135 acme.IE5678 = 5 <= acme.IE && acme.IE < 9;
\r
136 acme.IE5 = 5 <= acme.IE && acme.IE < 5.5;
\r
137 acme.IE55 = 5.5 <= acme.IE && acme.IE < 6;
\r
138 acme.IE5x = acme.IE5 || acme.IE55;
\r
139 acme.IE6 = 6 <= acme.IE && acme.IE < 7;
\r
140 acme.IE7 = 7 <= acme.IE && acme.IE < 8;
\r
141 acme.IE8 = 8 <= acme.IE && acme.IE < 9;
\r
142 acme.IE9 = 9 <= acme.IE && acme.IE < 10;
\r
143 acme.MacIE = acme.Mac;
\r
144 acme.IEMobile = dua.toLowerCase().indexOf( 'iemobile' ) !== -1 || acme.WinCE;
\r
145 acme.WinPhone = dua.toLowerCase().indexOf( 'windows phone' ) !== -1 || 0 < dav.indexOf( 'ZuneWP' ); // ZuneWP は IEM のデスクトップモードで使用
\r
146 console.log( '>> IE : ' + acme.IE + ' ActiveX : ' + acme.ActiveX );
\r
147 // TODO XBox360, XBox1, Modern or Desktop, Standalone
\r
151 // http://qa.support.sony.jp/solution/S0812181056444/common/nfb34_dom_200jp/dom_dom0_JP.html
\r
152 if( ( i = dua.indexOf( 'NetFront\/' ) !== -1 ) ){
\r
153 acme.NetFront = parseFloat( dua.substr( i + 9 ) ) || 0.1;
\r
154 console.log( '>> NetFront : ' + acme.NetFront );
\r
158 if( acme.Linux && tv === 2 && dua.indexOf( 'Sony\/COM2\/' ) !== -1 ){
\r
159 acme.NetFront = 3.4;
\r
160 console.log( '>> NetFront : ' + acme.NetFront );
\r
164 // http://www.useragentstring.com/pages/Playstation%203/
\r
165 // Mozilla/5.0 (PLAYSTATION 3; 3.55)
\r
166 // Mozilla/4.0 (PS3 (PlayStation 3); 1.00)
\r
167 // https://github.com/Famous/famous/blob/1a02c8084587d80519ea4bd3b55649ab32ee2e65/examples/assets/lib/require.js
\r
168 // PS3 ブラウザのロードイベントについて
\r
169 if( ( i = dua.toUpperCase().indexOf( 'PLAYSTATION 3' ) !== -1 ) ){
\r
170 acme.PS3 = parseFloat( dua.substr( i + 15 ) ) || 0.1;
\r
171 console.log( '>> PS3 : ' + acme.PS3 );
\r
175 // http://www.useragentstring.com/pages/iCab/
\r
176 // iCab/3.0.2 (Macintosh; U; PPC Mac OS X)
\r
177 // Mozilla/5.0 (Macintosh; U; PPC Mac OS; en) iCab 3
\r
178 if( ( i = dua.indexOf( 'iCab' ) !== -1 ) ){
\r
179 acme.iCab = parseFloat( dua.substr( i + 5 ) ) || 0.1;
\r
180 console.log( '>> iCab : ' + acme.iCab );
\r
184 if( 0 < dua.indexOf( 'Gecko\/' ) && ( i = dua.indexOf( 'rv:' ) ) ){
\r
185 v = dua.substr( i + 3 ).split( '.' );
\r
186 acme.Gecko = parseFloat( v[ 0 ] ) || 0 +
\r
187 ( parseFloat( v[ 1 ] ) || 0 ) / 10 +
\r
188 ( parseFloat( v[ 2 ] ) || 0 ) / 100;
\r
190 acme.GeckoMajor = parseFloat( v[ 0 ] ) || 0;
\r
191 acme.GeckoMinor = parseFloat( v[ 1 ] ) || 0;
\r
192 acme.GeckoPatch = parseFloat( v[ 2 ] ) || 0;
\r
195 // Mozilla/5.0 (Android; Linux armv7l; rv:9.0) Gecko/20111216 Firefox/9.0 Fennec/9.0
\r
196 if( ( i = dua.indexOf( 'Fennec/' ) ) !== -1 ){
\r
197 acme.Fennec = parseFloat( dua.substr( i + 7 ) );
\r
198 console.log( '>> Fennec : ' + acme.Fennec + ', Gecko : ' + acme.Gecko );
\r
204 //Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:0.9.4.1) Gecko/20020508 Netscape6/6.2.3
\r
205 if( ( i = dua.indexOf( 'Netscape6/' ) ) !== -1 ){
\r
206 acme.NN = parseFloat( dua.substr( i + 10 ) ) || 6;
\r
208 console.log( '>> NN : ' + acme.NN + ', Gecko : ' + acme.Gecko );
\r
211 //Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax)
\r
212 //Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20070321 Netscape/8.1.3
\r
213 if( ( i = dua.indexOf( 'Netscape/' ) ) !== -1 ){
\r
214 acme.NN = parseFloat( dua.substr( i + 9 ) ) || 7;
\r
215 console.log( '>> NN : ' + acme.NN + ', Gecko : ' + acme.Gecko );
\r
218 //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
219 if( ( i = dua.indexOf( 'Navigator/' ) ) !== -1 ){
\r
220 acme.NN = parseFloat( dua.substr( i + 10 ) ) || 9;
\r
221 console.log( '>> NN : ' + acme.NN + ', Gecko : ' + acme.Gecko );
\r
225 console.log( '>> Gecko : ' + acme.Gecko );
\r
229 if( window.chrome ){
\r
231 console.log( '>>Blink : ' + acme.Blink );
\r
234 if( dav.indexOf( 'Konqueror' ) !== -1 ){
\r
236 console.log( '>>Khtml : ' + acme.Khtml );
\r
239 if( ( i = dua.indexOf( 'Android ' ) ) !== -1 ){
\r
240 acme.AndroidBrowser = i = parseFloat( dua.substr( i + 8 ) ) || 0.1;
\r
241 acme.AndroidBrowser1 = 1 <= i && i < 2;
\r
242 acme.AndroidBrowser2 = 2 <= i && i < 3;
\r
243 acme.AndroidBrowser3 = 3 <= i && i < 4;
\r
244 acme.AndroidBrowser4 = 4 <= i && i < 5;
\r
245 acme.AndroidBrowser5 = 5 <= i && i < 6;
\r
246 console.log( '>> AndroidBrowser : ' + acme.Android );
\r
248 i = parseFloat(dua.split('WebKit\/')[1]);
\r
249 acme.AndroidBrowserWebkit = i;
\r
250 alert( 'AudioSprite調査:Android標準ブラウザ Webkit Version ' + i );
\r
253 if( i = parseFloat(dua.split('WebKit\/')[1]) ){
\r
256 acme.Chrome = parseFloat(dua.split('Chrome\/')[1]) || undefined;
\r
258 // TODO webkit Opera
\r
260 console.log( '>>Webkit : ' + acme.WebKit );
\r
262 if( i && !acme.Chrome && dua.indexOf( 'Safari' ) !== -1 ){
\r
263 if( dav.indexOf( 'Version/' ) !== -1 ){
\r
264 acme.Safari = parseFloat( dav.split('Version/')[1] );
\r
299 console.log( '>> Webkit : ' + acme.WebKit + ' Safari : ' + acme.Safari );
\r
302 //http://www.useragentstring.com/pages/Iris/
\r
303 if( dua.toLowerCase().indexOf( 'iris' ) !== -1 ) acme.Iris = true;
\r
305 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
306 dua.indexOf( 'Kobo' ) !== -1 ||
\r
307 // 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+
\r
308 dua.indexOf( 'Kindle' ) !== -1 ||
\r
309 // Sony Reader Mozilla/5.0 (Linux; U; ja-jp; EBRD1101; EXT) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
\r
310 dua.indexOf( 'EBRD' ) !== -1
\r
311 ) acme.EInk = true;
\r
319 //X_UA.IECompat && alert( X_UA.IE + ' ' + X_UA._IE + ' Tri:' + X_UA.Trident );
\r
322 * http://d.hatena.ne.jp/t-uchima/20051003/p1
\r
323 * MacIEにはattachEventが一応あるけどwindow.attachEventとdocument.attachEventしかなく他の要素にはattachEventはない。
\r
325 if( X_UA.IE4 && X_UA.IE < 5 ){ // ie4 & iemobi4 & macie4.x
\r
326 X_UA_DOM.IE4 = true;
\r
327 X_UA_EVENT.IE4 = true;
\r
330 X_UA_DOM.W3C = true;
\r
331 X_UA_EVENT.IE = true;
\r
333 if( document.getElementById ){
\r
334 X_UA_DOM.W3C = true;
\r
335 if( document.addEventListener ){
\r
336 X_UA_EVENT.W3C = true;
\r
338 if( document.attachEvent ){
\r
339 X_UA_EVENT.IE = true;
\r
341 X_UA_EVENT.DOM0 = true;
\r
344 if( document.layers ){
\r
350 if( navigator.msPointerEnabled || navigator.pointerEnabled ) X_UA_HID.POINTER = true;
\r
351 if( !X_UA_HID.POINTER && window.ontouchstart !== undefined ) X_UA_HID.TOUCH = true;
\r
353 //alert(X_UA.Safari + ' ' + X_UA.WebKit + '\n\n' + navigator.userAgent + '\n\n' + navigator.appVersion + '\n\n' + navigator.platform );
\r
355 // Safari 3.1 未満は開発コンソールがない!
\r
356 // http://shimax.cocolog-nifty.com/search/2006/09/safarijavascrip_c54d.html
\r
358 if( X_UA.Safari && X_UA.WebKit < 525.13 ){
\r
359 window.onerror = function( x, y, z ){
\r
360 var n = String.fromCharCode( 10 );
\r
361 alert('window.onerrorによるエラーの捕捉:' + n + x + n + y + 'の' + z + '行目付近です。');
\r
366 // ------------------------------------------------------------------------- //
\r
367 // --- interface ----------------------------------------------------------- //
\r
368 // ------------------------------------------------------------------------- //
\r
371 // TODO 構文のサポート instanceof, in, try catch
\r
373 if( X_UA.IE < 7 ){ // error @ NN7.2
\r
374 // bonus: hotfix for IE6 SP1 (bug KB823727)
\r
375 // multipleIEs IE6 standalone 版では不可, IE5.5 は可,,,
\r
376 X_UA.IE4 || X_UA.MacIE ?
\r
377 document.execCommand && document.execCommand( 'BackgroundImageCache', false, true ) :
\r
379 X_UA.IE_EXECOM_ERROR = eval( 'var a=1;try{document.execCommand&&document.execCommand("BackgroundImageCache",!1,!0)}catch(e){a=0}!a' );
\r
382 X_UA.IE_EXECOM_ERROR && alert( 'document.execCommand error!' );
\r
386 * HTML5 に対応しない IE8 以下でも <a> の下に <div> を作ることができる
\r
387 * その際に <div> の直前に改行文字が出現するが childNodes は長さ 1 で <div> だけの模様、、、
\r
388 X_UA_ATagWrapDiv = (function( e, h ){
\r
389 e = document.createElement( 'div' );
\r
390 e.innerHTML = h = '<a><div></div></a>';
\r
391 console.log( e.innerHTML.length + '\n' + e.firstChild.tagName );
\r
392 return e.childNodes.length === 1;
\r
395 console.log( 'HTML5? ' + X_UA_ATagWrapDiv ); */
\r