UNPKG

4.39 kBJavaScriptView Raw
1
2/*! litejs.com/MIT-LICENSE.txt */
3
4!function(exports) {
5 // http://www.zytrax.com/tech/web/mobile_ids.html
6 exports.ua = ua
7
8 var re = /(\w+)(?:\/| )([^\s;]+)(?:\s*\((.+?)\))?/g
9 , MOBILE = "Mobile"
10 , TABLET = "Tablet"
11 , DESKTOP = "Desktop"
12 , SMART_TV = "SmartTV"
13 , BOT = "Bot"
14 , TOOL = "Tool"
15 , browsers = [
16 "Firefox",
17 "Edge",
18 "Chrome",
19 "Android",
20 "Safari",
21 "IE",
22 "MSIE"
23 ]
24 , alias = {
25 ia_archiver: "Alexa",
26 facebookexternalhit: "Facebook",
27 CriOS: "Chrome",
28 FxiOS: "Firefox",
29 OPiOS: "Opera",
30 MSIE: "IE",
31 AppleWebKit: "Safari",
32 Macintosh: "OS X"
33 }
34 , botList = [
35 "Baiduspider",
36 "Bingbot",
37 "Exabot",
38 "Googlebot",
39 "Yahoo!",
40 "YandexBot"
41 ]
42 , osList = [
43 "AmigaOS",
44 "Windows",
45 "Android",
46 /iP(ad|od|hone)/, "iOS",
47 "Macintosh",
48 "Tizen",
49 /(?:web|hpw)[o0]s/i, "webOS",
50 /CrOS/, "Chromium OS",
51 "Linux",
52 "Fuchsia"
53 ]
54 , ffOs = {
55 "18.0": "1.0.1",
56 "18.1": "1.1",
57 "26.0": "1.2",
58 "28.0": "1.3",
59 "30.0": "1.4",
60 "32.0": "2.0",
61 "34.0": "2.1",
62 "37": "2.2",
63 "44": "2.5"
64 }
65 , winVer = {
66 "4.90":"ME",
67 "5.0":"2000",
68 "5.1":"XP",
69 "5.2":"XP",
70 "6.0":"Vista",
71 "6.1":"7",
72 "6.2":"8",
73 "6.3":"8.1",
74 "6.4":"10"
75 }
76
77 function ua(str) {
78 var _device, match, spi, first
79 , sp = ""
80 , map = {}
81
82 for (; match = re.exec(str);) {
83 if (!first) first = match
84 spi = map[alias[match[1]] || match[1]] = map[match[1]] = {
85 name: alias[match[1]] || match[1],
86 ver: match[2] || "?"
87 }
88 if (match[3]) {
89 spi.sub = match[3]
90 if (sp == "") {
91 sp = match[3].split(/(?:x86_64|[\/;\s])+/)
92 }
93 }
94 }
95 spi = sp.indexOf.bind(sp)
96
97 return {
98 os: scan(osList),
99 browser: scan(browsers),
100 device: _device || (
101 map.Mobile || spi(MOBILE) > -1 ? MOBILE :
102 spi(TABLET) > -1 || spi("Android") > -1 ? TABLET :
103 // On Desktop, geckotrail is the fixed string "20100101"
104 map.Gecko && map.Gecko.ver == "20100101" ||
105 map.Firefox ? DESKTOP :
106 map.Alexa || map.DuckDuckBot || map.Facebook || botList.indexOf(sp[1]) > -1 ? BOT :
107 map.curl || first && first[1] == "Wget" ? TOOL :
108 "?"
109 )
110 }
111
112 function scan(list) {
113 for (var match, name, t, i = 0, len = list.length; !match && i < len; ) {
114 t = alias[name = list[i++]]
115 if (typeof name !== "string") {
116 if (match = name.exec(str)) {
117 t = alias[name = match[0]] = list[i++]
118 } else {
119 name = list[i++]
120 }
121 }
122 if (match = map[name]) {
123 if (name == "Edge" && match.ver < 42) {
124 match.ver = "" + (parseFloat(match.ver) + 25)
125 }
126 if (name == "Safari") {
127 t = parseInt((map.AppleWebKit || match).ver)
128 match.ver = (
129 t < 100 ? "1.0" :
130 t < 124 ? "1.1" :
131 t < 312 ? "1.2" :
132 t < 412 ? "1.3" :
133 t < 420 ? "2.0" :
134 map.Version ? map.Version.ver :
135 "?"
136 )
137 }
138 } else if ((idx = spi(t == "iOS" || t == "OS X" ? "OS" : name)) > -1) {
139 match = {
140 name: alias[name] || name
141 }
142 if (name == "Android") {
143 if (list == browsers && map.Version) {
144 match.name += " Browser"
145 match.ver = map.Version.ver
146 break
147 }
148 }
149 if (name == "Windows") {
150 _device = DESKTOP
151 if (sp[idx + 1] == "ME") {
152 match.ver = "ME"
153 break
154 }
155 if (t = spi("NT") + 1 || spi("9x") + 1) idx = t - 1
156 t = sp[idx + 1]
157 if (t == "Phone" || t == MOBILE || t == "CE") {
158 match.name += " " + t
159 idx += 1 + (sp[idx + 2] == "OS")
160 _device = MOBILE
161 } else {
162 t = name
163 }
164 }
165 if (parseFloat(sp[++idx]) || parseFloat(sp[++idx])) {
166 match.ver = name === t && winVer[sp[idx]] || sp[idx].replace(/_/g, ".")
167 }
168 if (t === "iOS") {
169 _device = name == "iPad" ? TABLET : MOBILE
170 }
171 if (match.name === "webOS") {
172 _device = SMART_TV
173 }
174 }
175 }
176 if (!match) {
177 if (list == osList) {
178 if (map.Gecko) match = {
179 name: "Firefox OS",
180 ver: ffOs[map.Gecko.ver] || "?"
181 }
182 }
183 if (list == browsers) {
184 if (first && first[1] != "Mozilla") {
185 match = { name: alias[first[1]] || first[1] }
186 if (parseFloat(first[2])) match.ver = first[2]
187 }
188 if (sp[0] == "compatible") match = { name: sp[1], ver: sp[2] }
189 }
190 }
191 if (match && match.ver) {
192 match.full = match.ver
193 match.ver = match.ver.split(".")[0]
194 }
195 return match || {name: "?"}
196 }
197 }
198}(this)
199
200