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