OSDN Git Service

6f15535e7d68c88851f6959ac3ed88f4fd96976e
[pettanr/clientJs.git] / 0.6.x / js / 01_core / 02_XUA.js
1 \r
2 // ------------------------------------------------------------------------- //\r
3 // ------------ local variables -------------------------------------------- //\r
4 // ------------------------------------------------------------------------- //\r
5 var X_UA = (function( n, undefined ){\r
6         var acme = {},\r
7                 dua  = n.userAgent,\r
8                 dav  = n.appVersion,\r
9                 tv   = parseFloat(dav),\r
10                 sys  = n.platform,\r
11                 tridentToVer, i, j, v;\r
12                 \r
13         console.log( ' userAgent  : ' + dua );\r
14         console.log( '-' );\r
15         console.log( ' appVersion : ' + dav );\r
16         console.log( '-' );\r
17         console.log( ' platform   : ' + sys );\r
18         console.log( '-' );\r
19         \r
20         // TODO 3DS, DSi, WiiU\r
21         \r
22         if( sys.indexOf( 'iP' ) === 0 ){\r
23 \r
24                 v = dua.split( 'OS ' )[ 1 ].split( '_' );\r
25                 i = window.devicePixelRatio === 1;\r
26                 \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
30 \r
31                 acme.iOS = acme.iOSMajor + acme.iOSMinor / 10;\r
32 \r
33                 if( screen.width === screen.height * 1.5 || screen.width * 1.5 === screen.height ){\r
34                         v = true; // 4:3 model\r
35                 };\r
36                 \r
37                 if( sys === 'iPhone' ){\r
38                         acme.iPhone = true;\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
42                 };\r
43                 if( sys === 'iPad' ){\r
44                         acme.iPad   = true;\r
45                         if( i ) acme.iPad_2Mini1 = true;\r
46                 };\r
47                 if( sys === 'iPod' ){\r
48                         acme.iPod   = true;\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
52                 };\r
53                 \r
54                 console.log( '>> iOS : ' + acme.iOS );\r
55         } else\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
59         } else\r
60         if( sys.indexOf( 'Win' ) + 1 ){\r
61                 console.log( 'Win' );\r
62                 acme.Windows = true;\r
63                 switch( sys ){\r
64                         case 'Win16' :\r
65                         case 'Win32' :\r
66                         case 'Win64' :\r
67                         case 'WinCE' :\r
68                                 acme[ sys ] = true;\r
69                 };\r
70                 // winRT\r
71         } else\r
72         if( sys.indexOf( 'Mac' ) + 1 ){\r
73                 console.log( 'Mac' );\r
74                 acme.Mac = true;\r
75                 switch( sys ){\r
76                         case 'MacPowerPC' :\r
77                                 acme.MacPPC = true;\r
78                                 break;\r
79                         case 'MacPPC' :\r
80                         case 'Mac68K' :\r
81                         case 'MacIntel' :\r
82                                 acme[ sys] = true;\r
83                 };\r
84         } else\r
85         if( ( sys.indexOf( 'Linux' ) + 1 ) || ( sys.indexOf( 'Android' ) + 1 ) ){\r
86                 console.log( 'Linux' );\r
87                 acme.Linux = true;\r
88                 \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
92                 };\r
93         };\r
94 \r
95 /*\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
102  */\r
103         \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
110                         tv );\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
121                 return acme;\r
122         };\r
123         \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
148                 return acme;\r
149         };\r
150         \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
155                 return acme;\r
156         };\r
157         \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
161                 return acme;\r
162         };\r
163         \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
172                 return acme;\r
173         };\r
174         \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
181                 return acme;\r
182         };\r
183         \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
189                 \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
193                 \r
194                 //Fennec\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
199                         return acme;\r
200                 };\r
201                 //Firefox\r
202                 \r
203                 //Netscape\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
207                         acme.NN6 = true;\r
208                         console.log( '>> NN : ' + acme.NN + ', Gecko : ' + acme.Gecko );\r
209                         return acme;\r
210                 } else\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
216                         return acme;\r
217                 } else\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
222                         return acme;\r
223                 };\r
224                 \r
225                 console.log( '>> Gecko : ' + acme.Gecko );\r
226         };\r
227         \r
228         // TODO Blink\r
229         if( window.chrome ){\r
230                 acme.Blink = tv;\r
231                 console.log( '>>Blink : ' + acme.Blink );\r
232                 \r
233         } else\r
234         if( dav.indexOf( 'Konqueror' ) !== -1 ){\r
235                 acme.Khtml = tv;\r
236                 console.log( '>>Khtml : ' + acme.Khtml );\r
237                 \r
238         } else\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
247                 \r
248                 i = parseFloat(dua.split('WebKit\/')[1]);\r
249                 acme.AndroidBrowserWebkit = i;\r
250                 alert( 'AudioSprite調査:Android標準ブラウザ Webkit Version ' + i );\r
251                 \r
252         } else\r
253         if( i = parseFloat(dua.split('WebKit\/')[1]) ){\r
254                 acme.WebKit = i;\r
255                 \r
256                 acme.Chrome = parseFloat(dua.split('Chrome\/')[1]) || undefined;\r
257                 \r
258                 // TODO webkit Opera\r
259         \r
260                 console.log( '>>Webkit : ' + acme.WebKit );\r
261         \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
265                         } else {\r
266                                 if( i < 73 ){\r
267                                         acme.Safari = 0.8;\r
268                                 } else\r
269                                 if( i < 85 ){\r
270                                         acme.Safari = 0.9;\r
271                                 } else\r
272                                 if( i < 100 ){\r
273                                         acme.Safari = 1;\r
274                                 } else\r
275                                 if( i < 125 ){\r
276                                         acme.Safari = 1.1;\r
277                                 } else\r
278                                 if( i < 312 ){\r
279                                         acme.Safari = 1.2;\r
280                                 } else\r
281                                 if( i < 412 ){\r
282                                         acme.Safari = 1.3;\r
283                                 } else\r
284                                 if( i <= 419.3 ){\r
285                                         acme.Safari = 2;\r
286                                 } else\r
287                                 if( i <= 525.13 ){\r
288                                         acme.Safari = 3;\r
289                                 } else\r
290                                 if( i <= 525.25 ){\r
291                                         acme.Safari = 3.1;\r
292                                 } else\r
293                                 if( i <= 528.16 ){\r
294                                         acme.Safari = 3.2;\r
295                                 };\r
296                         };\r
297                 };              \r
298                 \r
299                 console.log( '>> Webkit : ' + acme.WebKit + ' Safari : ' + acme.Safari );\r
300         };\r
301         \r
302         //http://www.useragentstring.com/pages/Iris/\r
303         if( dua.toLowerCase().indexOf( 'iris' ) !== -1 ) acme.Iris = true;\r
304         \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
312         \r
313         return acme;\r
314 })( navigator ),\r
315 \r
316 X_UA_DOM   = {},\r
317 X_UA_EVENT = {},\r
318 X_UA_HID   = {};\r
319 //X_UA.IECompat && alert( X_UA.IE + ' ' + X_UA._IE + ' Tri:' + X_UA.Trident );\r
320 \r
321 /*\r
322  * http://d.hatena.ne.jp/t-uchima/20051003/p1\r
323  * MacIEにはattachEventが一応あるけどwindow.attachEventとdocument.attachEventしかなく他の要素にはattachEventはない。\r
324  */\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
328 } else\r
329 if( X_UA.MacIE ){\r
330         X_UA_DOM.W3C  = true;\r
331         X_UA_EVENT.IE = true;\r
332 } else\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
337         } else\r
338         if( document.attachEvent ){\r
339                 X_UA_EVENT.IE = true;\r
340         } else {\r
341                 X_UA_EVENT.DOM0 = true;\r
342         };\r
343 } else\r
344 if( document.layers ){\r
345         \r
346 } else {\r
347         \r
348 };\r
349 \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
352 \r
353 //alert(X_UA.Safari + ' ' + X_UA.WebKit + '\n\n' + navigator.userAgent + '\n\n' + navigator.appVersion + '\n\n' + navigator.platform );\r
354 \r
355 // Safari 3.1 未満は開発コンソールがない!\r
356 // http://shimax.cocolog-nifty.com/search/2006/09/safarijavascrip_c54d.html\r
357 /*\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
362             return true;\r
363         };\r
364 };*/\r
365 \r
366 // ------------------------------------------------------------------------- //\r
367 // --- interface ----------------------------------------------------------- //\r
368 // ------------------------------------------------------------------------- //\r
369 X.UA = X_UA;\r
370 \r
371 // TODO 構文のサポート instanceof, in, try catch\r
372 \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
378                 (function(){\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
380                 })();\r
381         \r
382         X_UA.IE_EXECOM_ERROR && alert( 'document.execCommand error!' );\r
383 };\r
384 \r
385 /*\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
393 })();\r
394 \r
395 console.log( 'HTML5? ' + X_UA_ATagWrapDiv ); */\r
396 \r