UNPKG

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