ua-parser-js 2.0.0-beta.2 → 2.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -8
- package/dist/ua-parser.min.js +3 -3
- package/dist/ua-parser.pack.js +3 -3
- package/package.json +5 -3
- package/script/cli.js +4 -0
- package/src/enums/ua-parser-enums.js +18 -5
- package/src/enums/ua-parser-enums.mjs +18 -5
- package/src/extensions/ua-parser-extensions.d.ts +4 -3
- package/src/extensions/ua-parser-extensions.js +119 -23
- package/src/extensions/ua-parser-extensions.mjs +119 -23
- package/src/helpers/ua-parser-helpers.d.ts +1 -1
- package/src/helpers/ua-parser-helpers.js +1 -1
- package/src/helpers/ua-parser-helpers.mjs +1 -1
- package/src/main/ua-parser.d.ts +6 -3
- package/src/main/ua-parser.js +67 -42
- package/src/main/ua-parser.mjs +67 -42
package/src/main/ua-parser.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/////////////////////////////////////////////////////////////////////////////////
|
2
|
-
/* UAParser.js v2.0.0-beta.
|
3
|
-
Copyright © 2012-
|
2
|
+
/* UAParser.js v2.0.0-beta.3
|
3
|
+
Copyright © 2012-2024 Faisal Salman <f@faisalman.com>
|
4
4
|
AGPLv3 License *//*
|
5
5
|
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
6
6
|
Supports browser & node.js environment.
|
@@ -19,7 +19,7 @@
|
|
19
19
|
// Constants
|
20
20
|
/////////////
|
21
21
|
|
22
|
-
var LIBVERSION = '2.0.0-beta.
|
22
|
+
var LIBVERSION = '2.0.0-beta.3',
|
23
23
|
EMPTY = '',
|
24
24
|
UNKNOWN = '?',
|
25
25
|
FUNC_TYPE = 'function',
|
@@ -38,11 +38,12 @@
|
|
38
38
|
TABLET = 'tablet',
|
39
39
|
SMARTTV = 'smarttv',
|
40
40
|
WEARABLE = 'wearable',
|
41
|
+
XR = 'xr',
|
41
42
|
EMBEDDED = 'embedded',
|
42
43
|
USER_AGENT = 'user-agent',
|
43
44
|
UA_MAX_LENGTH = 500,
|
44
45
|
BRANDS = 'brands',
|
45
|
-
|
46
|
+
FORMFACTORS = 'formFactors',
|
46
47
|
FULLVERLIST = 'fullVersionList',
|
47
48
|
PLATFORM = 'platform',
|
48
49
|
PLATFORMVER = 'platformVersion',
|
@@ -51,12 +52,12 @@
|
|
51
52
|
CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
|
52
53
|
CH_HEADER_ARCH = CH_HEADER + '-arch',
|
53
54
|
CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS,
|
54
|
-
|
55
|
+
CH_HEADER_FORM_FACTORS = CH_HEADER + '-form-factors',
|
55
56
|
CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE,
|
56
57
|
CH_HEADER_MODEL = CH_HEADER + '-' + MODEL,
|
57
58
|
CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM,
|
58
59
|
CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
|
59
|
-
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE,
|
60
|
+
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS],
|
60
61
|
UA_BROWSER = 'browser',
|
61
62
|
UA_CPU = 'cpu',
|
62
63
|
UA_DEVICE = 'device',
|
@@ -100,12 +101,21 @@
|
|
100
101
|
// Helper
|
101
102
|
//////////
|
102
103
|
|
103
|
-
var extend = function (
|
104
|
-
var
|
105
|
-
|
106
|
-
|
104
|
+
var extend = function (defaultRgx, extensions) {
|
105
|
+
var mergedRgx = {};
|
106
|
+
var extraRgx = extensions;
|
107
|
+
if (!isExtensions(extensions)) {
|
108
|
+
extraRgx = {};
|
109
|
+
for (var i in extensions) {
|
110
|
+
for (var j in extensions[i]) {
|
111
|
+
extraRgx[j] = extensions[i][j].concat(extraRgx[j] ? extraRgx[j] : []);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
}
|
115
|
+
for (var k in defaultRgx) {
|
116
|
+
mergedRgx[k] = extraRgx[k] && extraRgx[k].length % 2 === 0 ? extraRgx[k].concat(defaultRgx[k]) : defaultRgx[k];
|
107
117
|
}
|
108
|
-
return
|
118
|
+
return mergedRgx;
|
109
119
|
},
|
110
120
|
enumerize = function (arr) {
|
111
121
|
var enums = {};
|
@@ -123,9 +133,9 @@
|
|
123
133
|
}
|
124
134
|
return isString(str1) ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
|
125
135
|
},
|
126
|
-
isExtensions = function (obj) {
|
136
|
+
isExtensions = function (obj, deep) {
|
127
137
|
for (var prop in obj) {
|
128
|
-
return /^(browser|cpu|device|engine|os)$/.test(prop);
|
138
|
+
return /^(browser|cpu|device|engine|os)$/.test(prop) || (deep ? isExtensions(obj[prop]) : false);
|
129
139
|
}
|
130
140
|
},
|
131
141
|
isString = function (val) {
|
@@ -269,12 +279,13 @@
|
|
269
279
|
'RT' : 'ARM'
|
270
280
|
},
|
271
281
|
|
272
|
-
|
282
|
+
formFactorsMap = {
|
273
283
|
'embedded' : 'Automotive',
|
274
284
|
'mobile' : 'Mobile',
|
275
285
|
'tablet' : ['Tablet', 'EInk'],
|
276
286
|
'smarttv' : 'TV',
|
277
|
-
'wearable' :
|
287
|
+
'wearable' : 'Watch',
|
288
|
+
'xr' : ['VR', 'XR'],
|
278
289
|
'?' : ['Desktop', 'Unknown'],
|
279
290
|
'*' : undefined
|
280
291
|
};
|
@@ -309,17 +320,20 @@
|
|
309
320
|
/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
|
310
321
|
], [VERSION, [NAME, 'Baidu']], [
|
311
322
|
/(kindle)\/([\w\.]+)/i, // Kindle
|
312
|
-
/(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i,
|
323
|
+
/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
|
324
|
+
// Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
|
313
325
|
// Trident based
|
314
326
|
/(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
|
315
327
|
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
|
316
328
|
|
317
329
|
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
|
318
|
-
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|
|
319
|
-
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo
|
330
|
+
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar)\/([-\w\.]+)/i,
|
331
|
+
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar
|
320
332
|
/(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
|
321
333
|
/(weibo)__([\d\.]+)/i // Weibo
|
322
334
|
], [NAME, VERSION], [
|
335
|
+
/\bddg\/([\w\.]+)/i // DuckDuckGo
|
336
|
+
], [VERSION, [NAME, 'DuckDuckGo']], [
|
323
337
|
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
|
324
338
|
], [VERSION, [NAME, 'UCBrowser']], [
|
325
339
|
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
|
@@ -352,8 +366,10 @@
|
|
352
366
|
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
|
353
367
|
/\bqihu|(qi?ho?o?|360)browser/i // 360
|
354
368
|
], [[NAME, '360' + SUFFIX_BROWSER]], [
|
355
|
-
|
356
|
-
], [[NAME, /(.+)/, '$
|
369
|
+
/\b(qq)\/([\w\.]+)/i // QQ
|
370
|
+
], [[NAME, /(.+)/, '$1Browser'], VERSION], [
|
371
|
+
/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
|
372
|
+
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
|
357
373
|
/samsungbrowser\/([\w\.]+)/i // Samsung Internet
|
358
374
|
], [VERSION, [NAME, SAMSUNG + ' Internet']], [
|
359
375
|
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
|
@@ -366,7 +382,7 @@
|
|
366
382
|
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
|
367
383
|
/m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
|
368
384
|
], [NAME, VERSION], [
|
369
|
-
/(lbbrowser)/i,
|
385
|
+
/(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq
|
370
386
|
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
|
371
387
|
], [NAME], [
|
372
388
|
|
@@ -379,6 +395,7 @@
|
|
379
395
|
/safari (line)\/([\w\.]+)/i, // Line App for iOS
|
380
396
|
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
|
381
397
|
/(alipay)client\/([\w\.]+)/i, // Alipay
|
398
|
+
/(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
|
382
399
|
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
|
383
400
|
], [NAME, VERSION], [
|
384
401
|
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
|
@@ -418,23 +435,24 @@
|
|
418
435
|
], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
|
419
436
|
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
|
420
437
|
], [[NAME, 'Netscape'], VERSION], [
|
438
|
+
/(wolvic)\/([\w\.]+)/i // Wolvic
|
439
|
+
], [NAME, VERSION], [
|
421
440
|
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
|
422
441
|
], [VERSION, [NAME, FIREFOX+' Reality']], [
|
423
442
|
/ekiohf.+(flow)\/([\w\.]+)/i, // Flow
|
424
443
|
/(swiftfox)/i, // Swiftfox
|
425
|
-
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror
|
426
|
-
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
|
444
|
+
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,
|
445
|
+
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
|
427
446
|
/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
|
428
447
|
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
|
429
448
|
/(firefox)\/([\w\.]+)/i, // Other Firefox-based
|
430
449
|
/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
|
431
450
|
|
432
451
|
// Other
|
433
|
-
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|
|
434
|
-
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/
|
435
|
-
/(links) \(([\w\.]+)/i
|
436
|
-
/
|
437
|
-
], [NAME, VERSION], [
|
452
|
+
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
|
453
|
+
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser
|
454
|
+
/(links) \(([\w\.]+)/i // Links
|
455
|
+
], [NAME, [VERSION, /_/g, '.']], [
|
438
456
|
|
439
457
|
/(cobalt)\/([\w\.]+)/i // Cobalt
|
440
458
|
], [NAME, [VERSION, /[^\d\.]+./, EMPTY]]
|
@@ -521,6 +539,8 @@
|
|
521
539
|
/; (\w+) bui.+ oppo/i,
|
522
540
|
/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
|
523
541
|
], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
|
542
|
+
/\b(opd2\d{3}a?) bui/i
|
543
|
+
], [MODEL, [VENDOR, 'OPPO'], [TYPE, TABLET]], [
|
524
544
|
|
525
545
|
// Vivo
|
526
546
|
/vivo (\w+)(?: bui|\))/i,
|
@@ -704,12 +724,17 @@
|
|
704
724
|
], [VENDOR, MODEL, [TYPE, WEARABLE]], [
|
705
725
|
/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
|
706
726
|
], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
|
707
|
-
/droid.+; (glass) \d/i // Google Glass
|
708
|
-
], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [
|
709
727
|
/droid.+; (wt63?0{2,3})\)/i
|
710
728
|
], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
|
711
|
-
|
712
|
-
|
729
|
+
|
730
|
+
///////////////////
|
731
|
+
// XR
|
732
|
+
///////////////////
|
733
|
+
|
734
|
+
/droid.+; (glass) \d/i // Google Glass
|
735
|
+
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
|
736
|
+
/(quest( \d| pro)?)/i // Oculus Quest
|
737
|
+
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
|
713
738
|
|
714
739
|
///////////////////
|
715
740
|
// EMBEDDED
|
@@ -840,7 +865,7 @@
|
|
840
865
|
var defaultProps = (function () {
|
841
866
|
var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
|
842
867
|
setProps.call(props.init, [
|
843
|
-
[UA_BROWSER, [NAME, VERSION, MAJOR]],
|
868
|
+
[UA_BROWSER, [NAME, VERSION, MAJOR, TYPE]],
|
844
869
|
[UA_CPU, [ARCHITECTURE]],
|
845
870
|
[UA_DEVICE, [TYPE, MODEL, VENDOR]],
|
846
871
|
[UA_ENGINE, [NAME, VERSION]],
|
@@ -968,7 +993,7 @@
|
|
968
993
|
[PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
|
969
994
|
[PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
|
970
995
|
[ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
|
971
|
-
[
|
996
|
+
[FORMFACTORS, itemListToArray(uach[CH_HEADER_FORM_FACTORS])],
|
972
997
|
[BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
|
973
998
|
]);
|
974
999
|
} else {
|
@@ -1088,15 +1113,15 @@
|
|
1088
1113
|
this.set(TYPE, CONSOLE)
|
1089
1114
|
.set(VENDOR, MICROSOFT);
|
1090
1115
|
}
|
1091
|
-
if (uaCH[
|
1116
|
+
if (uaCH[FORMFACTORS]) {
|
1092
1117
|
var ff;
|
1093
|
-
if (typeof uaCH[
|
1118
|
+
if (typeof uaCH[FORMFACTORS] !== 'string') {
|
1094
1119
|
var idx = 0;
|
1095
|
-
while (!ff && idx < uaCH[
|
1096
|
-
ff = strMapper(uaCH[
|
1120
|
+
while (!ff && idx < uaCH[FORMFACTORS].length) {
|
1121
|
+
ff = strMapper(uaCH[FORMFACTORS][idx++], formFactorsMap);
|
1097
1122
|
}
|
1098
1123
|
} else {
|
1099
|
-
ff = strMapper(uaCH[
|
1124
|
+
ff = strMapper(uaCH[FORMFACTORS], formFactorsMap);
|
1100
1125
|
}
|
1101
1126
|
this.set(TYPE, ff);
|
1102
1127
|
}
|
@@ -1147,7 +1172,7 @@
|
|
1147
1172
|
function UAParser (ua, extensions, headers) {
|
1148
1173
|
|
1149
1174
|
if (typeof ua === OBJ_TYPE) {
|
1150
|
-
if (isExtensions(ua)) {
|
1175
|
+
if (isExtensions(ua, true)) {
|
1151
1176
|
if (typeof extensions === OBJ_TYPE) {
|
1152
1177
|
headers = extensions; // case UAParser(extensions, headers)
|
1153
1178
|
}
|
@@ -1157,7 +1182,7 @@
|
|
1157
1182
|
extensions = undefined;
|
1158
1183
|
}
|
1159
1184
|
ua = undefined;
|
1160
|
-
} else if (typeof ua === STR_TYPE && !isExtensions(extensions)) {
|
1185
|
+
} else if (typeof ua === STR_TYPE && !isExtensions(extensions, true)) {
|
1161
1186
|
headers = extensions; // case UAParser(ua, headers)
|
1162
1187
|
extensions = undefined;
|
1163
1188
|
}
|
@@ -1218,7 +1243,7 @@
|
|
1218
1243
|
}
|
1219
1244
|
|
1220
1245
|
UAParser.VERSION = LIBVERSION;
|
1221
|
-
UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
|
1246
|
+
UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR, TYPE]);
|
1222
1247
|
UAParser.CPU = enumerize([ARCHITECTURE]);
|
1223
1248
|
UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
|
1224
1249
|
UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
|
package/src/main/ua-parser.mjs
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
// Source: /src/main/ua-parser.js
|
4
4
|
|
5
5
|
/////////////////////////////////////////////////////////////////////////////////
|
6
|
-
/* UAParser.js v2.0.0-beta.
|
7
|
-
Copyright © 2012-
|
6
|
+
/* UAParser.js v2.0.0-beta.3
|
7
|
+
Copyright © 2012-2024 Faisal Salman <f@faisalman.com>
|
8
8
|
AGPLv3 License *//*
|
9
9
|
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
10
10
|
Supports browser & node.js environment.
|
@@ -21,7 +21,7 @@
|
|
21
21
|
// Constants
|
22
22
|
/////////////
|
23
23
|
|
24
|
-
var LIBVERSION = '2.0.0-beta.
|
24
|
+
var LIBVERSION = '2.0.0-beta.3',
|
25
25
|
EMPTY = '',
|
26
26
|
UNKNOWN = '?',
|
27
27
|
FUNC_TYPE = 'function',
|
@@ -40,11 +40,12 @@
|
|
40
40
|
TABLET = 'tablet',
|
41
41
|
SMARTTV = 'smarttv',
|
42
42
|
WEARABLE = 'wearable',
|
43
|
+
XR = 'xr',
|
43
44
|
EMBEDDED = 'embedded',
|
44
45
|
USER_AGENT = 'user-agent',
|
45
46
|
UA_MAX_LENGTH = 500,
|
46
47
|
BRANDS = 'brands',
|
47
|
-
|
48
|
+
FORMFACTORS = 'formFactors',
|
48
49
|
FULLVERLIST = 'fullVersionList',
|
49
50
|
PLATFORM = 'platform',
|
50
51
|
PLATFORMVER = 'platformVersion',
|
@@ -53,12 +54,12 @@
|
|
53
54
|
CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
|
54
55
|
CH_HEADER_ARCH = CH_HEADER + '-arch',
|
55
56
|
CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS,
|
56
|
-
|
57
|
+
CH_HEADER_FORM_FACTORS = CH_HEADER + '-form-factors',
|
57
58
|
CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE,
|
58
59
|
CH_HEADER_MODEL = CH_HEADER + '-' + MODEL,
|
59
60
|
CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM,
|
60
61
|
CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
|
61
|
-
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE,
|
62
|
+
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS],
|
62
63
|
UA_BROWSER = 'browser',
|
63
64
|
UA_CPU = 'cpu',
|
64
65
|
UA_DEVICE = 'device',
|
@@ -102,12 +103,21 @@
|
|
102
103
|
// Helper
|
103
104
|
//////////
|
104
105
|
|
105
|
-
var extend = function (
|
106
|
-
var
|
107
|
-
|
108
|
-
|
106
|
+
var extend = function (defaultRgx, extensions) {
|
107
|
+
var mergedRgx = {};
|
108
|
+
var extraRgx = extensions;
|
109
|
+
if (!isExtensions(extensions)) {
|
110
|
+
extraRgx = {};
|
111
|
+
for (var i in extensions) {
|
112
|
+
for (var j in extensions[i]) {
|
113
|
+
extraRgx[j] = extensions[i][j].concat(extraRgx[j] ? extraRgx[j] : []);
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
for (var k in defaultRgx) {
|
118
|
+
mergedRgx[k] = extraRgx[k] && extraRgx[k].length % 2 === 0 ? extraRgx[k].concat(defaultRgx[k]) : defaultRgx[k];
|
109
119
|
}
|
110
|
-
return
|
120
|
+
return mergedRgx;
|
111
121
|
},
|
112
122
|
enumerize = function (arr) {
|
113
123
|
var enums = {};
|
@@ -125,9 +135,9 @@
|
|
125
135
|
}
|
126
136
|
return isString(str1) ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
|
127
137
|
},
|
128
|
-
isExtensions = function (obj) {
|
138
|
+
isExtensions = function (obj, deep) {
|
129
139
|
for (var prop in obj) {
|
130
|
-
return /^(browser|cpu|device|engine|os)$/.test(prop);
|
140
|
+
return /^(browser|cpu|device|engine|os)$/.test(prop) || (deep ? isExtensions(obj[prop]) : false);
|
131
141
|
}
|
132
142
|
},
|
133
143
|
isString = function (val) {
|
@@ -271,12 +281,13 @@
|
|
271
281
|
'RT' : 'ARM'
|
272
282
|
},
|
273
283
|
|
274
|
-
|
284
|
+
formFactorsMap = {
|
275
285
|
'embedded' : 'Automotive',
|
276
286
|
'mobile' : 'Mobile',
|
277
287
|
'tablet' : ['Tablet', 'EInk'],
|
278
288
|
'smarttv' : 'TV',
|
279
|
-
'wearable' :
|
289
|
+
'wearable' : 'Watch',
|
290
|
+
'xr' : ['VR', 'XR'],
|
280
291
|
'?' : ['Desktop', 'Unknown'],
|
281
292
|
'*' : undefined
|
282
293
|
};
|
@@ -311,17 +322,20 @@
|
|
311
322
|
/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
|
312
323
|
], [VERSION, [NAME, 'Baidu']], [
|
313
324
|
/(kindle)\/([\w\.]+)/i, // Kindle
|
314
|
-
/(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i,
|
325
|
+
/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
|
326
|
+
// Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
|
315
327
|
// Trident based
|
316
328
|
/(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
|
317
329
|
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
|
318
330
|
|
319
331
|
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
|
320
|
-
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|
|
321
|
-
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo
|
332
|
+
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar)\/([-\w\.]+)/i,
|
333
|
+
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar
|
322
334
|
/(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
|
323
335
|
/(weibo)__([\d\.]+)/i // Weibo
|
324
336
|
], [NAME, VERSION], [
|
337
|
+
/\bddg\/([\w\.]+)/i // DuckDuckGo
|
338
|
+
], [VERSION, [NAME, 'DuckDuckGo']], [
|
325
339
|
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
|
326
340
|
], [VERSION, [NAME, 'UCBrowser']], [
|
327
341
|
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
|
@@ -354,8 +368,10 @@
|
|
354
368
|
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
|
355
369
|
/\bqihu|(qi?ho?o?|360)browser/i // 360
|
356
370
|
], [[NAME, '360' + SUFFIX_BROWSER]], [
|
357
|
-
|
358
|
-
], [[NAME, /(.+)/, '$
|
371
|
+
/\b(qq)\/([\w\.]+)/i // QQ
|
372
|
+
], [[NAME, /(.+)/, '$1Browser'], VERSION], [
|
373
|
+
/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
|
374
|
+
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
|
359
375
|
/samsungbrowser\/([\w\.]+)/i // Samsung Internet
|
360
376
|
], [VERSION, [NAME, SAMSUNG + ' Internet']], [
|
361
377
|
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
|
@@ -368,7 +384,7 @@
|
|
368
384
|
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
|
369
385
|
/m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
|
370
386
|
], [NAME, VERSION], [
|
371
|
-
/(lbbrowser)/i,
|
387
|
+
/(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq
|
372
388
|
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
|
373
389
|
], [NAME], [
|
374
390
|
|
@@ -381,6 +397,7 @@
|
|
381
397
|
/safari (line)\/([\w\.]+)/i, // Line App for iOS
|
382
398
|
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
|
383
399
|
/(alipay)client\/([\w\.]+)/i, // Alipay
|
400
|
+
/(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
|
384
401
|
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
|
385
402
|
], [NAME, VERSION], [
|
386
403
|
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
|
@@ -420,23 +437,24 @@
|
|
420
437
|
], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
|
421
438
|
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
|
422
439
|
], [[NAME, 'Netscape'], VERSION], [
|
440
|
+
/(wolvic)\/([\w\.]+)/i // Wolvic
|
441
|
+
], [NAME, VERSION], [
|
423
442
|
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
|
424
443
|
], [VERSION, [NAME, FIREFOX+' Reality']], [
|
425
444
|
/ekiohf.+(flow)\/([\w\.]+)/i, // Flow
|
426
445
|
/(swiftfox)/i, // Swiftfox
|
427
|
-
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror
|
428
|
-
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
|
446
|
+
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,
|
447
|
+
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
|
429
448
|
/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
|
430
449
|
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
|
431
450
|
/(firefox)\/([\w\.]+)/i, // Other Firefox-based
|
432
451
|
/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
|
433
452
|
|
434
453
|
// Other
|
435
|
-
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|
|
436
|
-
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/
|
437
|
-
/(links) \(([\w\.]+)/i
|
438
|
-
/
|
439
|
-
], [NAME, VERSION], [
|
454
|
+
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
|
455
|
+
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser
|
456
|
+
/(links) \(([\w\.]+)/i // Links
|
457
|
+
], [NAME, [VERSION, /_/g, '.']], [
|
440
458
|
|
441
459
|
/(cobalt)\/([\w\.]+)/i // Cobalt
|
442
460
|
], [NAME, [VERSION, /[^\d\.]+./, EMPTY]]
|
@@ -523,6 +541,8 @@
|
|
523
541
|
/; (\w+) bui.+ oppo/i,
|
524
542
|
/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
|
525
543
|
], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
|
544
|
+
/\b(opd2\d{3}a?) bui/i
|
545
|
+
], [MODEL, [VENDOR, 'OPPO'], [TYPE, TABLET]], [
|
526
546
|
|
527
547
|
// Vivo
|
528
548
|
/vivo (\w+)(?: bui|\))/i,
|
@@ -706,12 +726,17 @@
|
|
706
726
|
], [VENDOR, MODEL, [TYPE, WEARABLE]], [
|
707
727
|
/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
|
708
728
|
], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
|
709
|
-
/droid.+; (glass) \d/i // Google Glass
|
710
|
-
], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [
|
711
729
|
/droid.+; (wt63?0{2,3})\)/i
|
712
730
|
], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
|
713
|
-
|
714
|
-
|
731
|
+
|
732
|
+
///////////////////
|
733
|
+
// XR
|
734
|
+
///////////////////
|
735
|
+
|
736
|
+
/droid.+; (glass) \d/i // Google Glass
|
737
|
+
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
|
738
|
+
/(quest( \d| pro)?)/i // Oculus Quest
|
739
|
+
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
|
715
740
|
|
716
741
|
///////////////////
|
717
742
|
// EMBEDDED
|
@@ -842,7 +867,7 @@
|
|
842
867
|
var defaultProps = (function () {
|
843
868
|
var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
|
844
869
|
setProps.call(props.init, [
|
845
|
-
[UA_BROWSER, [NAME, VERSION, MAJOR]],
|
870
|
+
[UA_BROWSER, [NAME, VERSION, MAJOR, TYPE]],
|
846
871
|
[UA_CPU, [ARCHITECTURE]],
|
847
872
|
[UA_DEVICE, [TYPE, MODEL, VENDOR]],
|
848
873
|
[UA_ENGINE, [NAME, VERSION]],
|
@@ -970,7 +995,7 @@
|
|
970
995
|
[PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
|
971
996
|
[PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
|
972
997
|
[ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
|
973
|
-
[
|
998
|
+
[FORMFACTORS, itemListToArray(uach[CH_HEADER_FORM_FACTORS])],
|
974
999
|
[BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
|
975
1000
|
]);
|
976
1001
|
} else {
|
@@ -1090,15 +1115,15 @@
|
|
1090
1115
|
this.set(TYPE, CONSOLE)
|
1091
1116
|
.set(VENDOR, MICROSOFT);
|
1092
1117
|
}
|
1093
|
-
if (uaCH[
|
1118
|
+
if (uaCH[FORMFACTORS]) {
|
1094
1119
|
var ff;
|
1095
|
-
if (typeof uaCH[
|
1120
|
+
if (typeof uaCH[FORMFACTORS] !== 'string') {
|
1096
1121
|
var idx = 0;
|
1097
|
-
while (!ff && idx < uaCH[
|
1098
|
-
ff = strMapper(uaCH[
|
1122
|
+
while (!ff && idx < uaCH[FORMFACTORS].length) {
|
1123
|
+
ff = strMapper(uaCH[FORMFACTORS][idx++], formFactorsMap);
|
1099
1124
|
}
|
1100
1125
|
} else {
|
1101
|
-
ff = strMapper(uaCH[
|
1126
|
+
ff = strMapper(uaCH[FORMFACTORS], formFactorsMap);
|
1102
1127
|
}
|
1103
1128
|
this.set(TYPE, ff);
|
1104
1129
|
}
|
@@ -1149,7 +1174,7 @@
|
|
1149
1174
|
function UAParser (ua, extensions, headers) {
|
1150
1175
|
|
1151
1176
|
if (typeof ua === OBJ_TYPE) {
|
1152
|
-
if (isExtensions(ua)) {
|
1177
|
+
if (isExtensions(ua, true)) {
|
1153
1178
|
if (typeof extensions === OBJ_TYPE) {
|
1154
1179
|
headers = extensions; // case UAParser(extensions, headers)
|
1155
1180
|
}
|
@@ -1159,7 +1184,7 @@
|
|
1159
1184
|
extensions = undefined;
|
1160
1185
|
}
|
1161
1186
|
ua = undefined;
|
1162
|
-
} else if (typeof ua === STR_TYPE && !isExtensions(extensions)) {
|
1187
|
+
} else if (typeof ua === STR_TYPE && !isExtensions(extensions, true)) {
|
1163
1188
|
headers = extensions; // case UAParser(ua, headers)
|
1164
1189
|
extensions = undefined;
|
1165
1190
|
}
|
@@ -1220,7 +1245,7 @@
|
|
1220
1245
|
}
|
1221
1246
|
|
1222
1247
|
UAParser.VERSION = LIBVERSION;
|
1223
|
-
UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
|
1248
|
+
UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR, TYPE]);
|
1224
1249
|
UAParser.CPU = enumerize([ARCHITECTURE]);
|
1225
1250
|
UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
|
1226
1251
|
UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
|