ua-parser-js 2.0.0-alpha.3 → 2.0.0-beta.2
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE.md +616 -0
- package/README.md +220 -0
- package/dist/ua-parser.min.js +3 -3
- package/dist/ua-parser.pack.js +3 -3
- package/package.json +44 -11
- package/src/enums/ua-parser-enums.js +321 -74
- package/src/enums/ua-parser-enums.mjs +322 -75
- package/src/extensions/ua-parser-extensions.d.ts +13 -0
- package/src/extensions/ua-parser-extensions.js +2 -2
- package/src/extensions/ua-parser-extensions.mjs +3 -3
- package/src/helpers/ua-parser-helpers.d.ts +15 -0
- package/src/helpers/ua-parser-helpers.js +9 -29
- package/src/helpers/ua-parser-helpers.mjs +10 -30
- package/src/main/ua-parser.d.ts +106 -0
- package/src/main/ua-parser.js +107 -46
- package/src/main/ua-parser.mjs +104 -43
- package/license.md +0 -21
- package/readme.md +0 -653
@@ -0,0 +1,106 @@
|
|
1
|
+
// Type definitions for UAParser.js v2.0.0-beta.2
|
2
|
+
// Project: https://github.com/faisalman/ua-parser-js
|
3
|
+
// Definitions by: Faisal Salman <https://github.com/faisalman>
|
4
|
+
|
5
|
+
declare namespace UAParser {
|
6
|
+
|
7
|
+
interface IData<T> {
|
8
|
+
is(val: string): boolean;
|
9
|
+
toString(): string;
|
10
|
+
withClientHints(): PromiseLike<T> | T;
|
11
|
+
withFeatureCheck(): T;
|
12
|
+
}
|
13
|
+
|
14
|
+
interface IBrowser extends IData<IBrowser> {
|
15
|
+
name?: string;
|
16
|
+
version?: string;
|
17
|
+
major?: string;
|
18
|
+
}
|
19
|
+
|
20
|
+
interface ICPU extends IData<ICPU> {
|
21
|
+
architecture?: 'ia32' | 'ia64' | 'amd64' | 'arm' | 'arm64' | 'armhf' | 'avr' | 'irix' | 'irix64' | 'mips' | 'mips64' | '68k' | 'ppc' | 'sparc' | 'sparc64';
|
22
|
+
}
|
23
|
+
|
24
|
+
interface IDevice extends IData<IDevice> {
|
25
|
+
type?: 'mobile' | 'tablet' | 'console' | 'smarttv' | 'wearable';
|
26
|
+
vendor?: string;
|
27
|
+
model?: string;
|
28
|
+
}
|
29
|
+
|
30
|
+
interface IEngine extends IData<IEngine> {
|
31
|
+
name?: 'Amaya' | 'Blink' | 'EdgeHTML' | 'Flow' | 'Gecko' | 'Goanna' | 'iCab' | 'KHTML' | 'LibWeb' | 'Links' | 'Lynx' | 'NetFront' | 'NetSurf' | 'Presto' | 'Tasman' | 'Trident' | 'w3m' | 'WebKit';
|
32
|
+
version?: string;
|
33
|
+
}
|
34
|
+
|
35
|
+
interface IOS extends IData<IOS> {
|
36
|
+
name?: string;
|
37
|
+
version?: string;
|
38
|
+
}
|
39
|
+
|
40
|
+
interface IResult extends IData<IResult> {
|
41
|
+
ua: string;
|
42
|
+
browser: IBrowser;
|
43
|
+
cpu: ICPU;
|
44
|
+
device: IDevice;
|
45
|
+
engine: IEngine;
|
46
|
+
os: IOS;
|
47
|
+
}
|
48
|
+
|
49
|
+
type RegexMap = ((RegExp | string | (string | RegExp | Function)[])[])[];
|
50
|
+
type UAParserProps = 'browser' | 'cpu' | 'device' | 'engine' | 'os';
|
51
|
+
type UAParserExt = Partial<Record<UAParserProps, RegexMap>>;
|
52
|
+
|
53
|
+
export function UAParser(uastring?: string, extensions?: UAParserExt, headers?: Record<string, string>): IResult;
|
54
|
+
export function UAParser(uastring?: string, headers?: Record<string, string>): IResult;
|
55
|
+
export function UAParser(extensions?: UAParserExt, headers?: Record<string, string>): IResult;
|
56
|
+
export function UAParser(headers?: Record<string, string>): IResult;
|
57
|
+
|
58
|
+
export class UAParser {
|
59
|
+
|
60
|
+
static readonly BROWSER: {
|
61
|
+
NAME: 'name';
|
62
|
+
VERSION: 'version';
|
63
|
+
MAJOR: 'major';
|
64
|
+
};
|
65
|
+
static readonly CPU: {
|
66
|
+
ARCHITECTURE: 'architecture';
|
67
|
+
};
|
68
|
+
static readonly DEVICE: {
|
69
|
+
TYPE: 'type';
|
70
|
+
VENDOR: 'vendor';
|
71
|
+
MODEL: 'model';
|
72
|
+
CONSOLE: 'console';
|
73
|
+
MOBILE: 'mobile';
|
74
|
+
SMARTTV: 'smarttv';
|
75
|
+
TABLET: 'tablet';
|
76
|
+
WEARABLE: 'wearable';
|
77
|
+
EMBEDDED: 'embedded';
|
78
|
+
};
|
79
|
+
static readonly ENGINE: {
|
80
|
+
NAME: 'name';
|
81
|
+
VERSION: 'version';
|
82
|
+
};
|
83
|
+
static readonly OS: {
|
84
|
+
NAME: 'name';
|
85
|
+
VERSION: 'version';
|
86
|
+
};
|
87
|
+
static readonly VERSION: string;
|
88
|
+
|
89
|
+
constructor(uastring?: string, extensions?: UAParserExt, headers?: Record<string, string>);
|
90
|
+
constructor(uastring?: string, headers?: Record<string, string>);
|
91
|
+
constructor(extensions?: UAParserExt, headers?: Record<string, string>);
|
92
|
+
constructor(headers?: Record<string, string>);
|
93
|
+
|
94
|
+
getUA(): string;
|
95
|
+
getBrowser(): IBrowser;
|
96
|
+
getCPU(): ICPU;
|
97
|
+
getDevice(): IDevice;
|
98
|
+
getEngine(): IEngine;
|
99
|
+
getOS(): IOS;
|
100
|
+
getResult(): IResult;
|
101
|
+
setUA(uastring: string): UAParser;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
export as namespace UAParser;
|
106
|
+
export = UAParser;
|
package/src/main/ua-parser.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/////////////////////////////////////////////////////////////////////////////////
|
2
|
-
/* UAParser.js v2.0.0-
|
2
|
+
/* UAParser.js v2.0.0-beta.2
|
3
3
|
Copyright © 2012-2023 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.
|
7
7
|
Demo : https://faisalman.github.io/ua-parser-js
|
@@ -19,8 +19,7 @@
|
|
19
19
|
// Constants
|
20
20
|
/////////////
|
21
21
|
|
22
|
-
|
23
|
-
var LIBVERSION = '2.0.0-alpha.3',
|
22
|
+
var LIBVERSION = '2.0.0-beta.2',
|
24
23
|
EMPTY = '',
|
25
24
|
UNKNOWN = '?',
|
26
25
|
FUNC_TYPE = 'function',
|
@@ -41,8 +40,9 @@
|
|
41
40
|
WEARABLE = 'wearable',
|
42
41
|
EMBEDDED = 'embedded',
|
43
42
|
USER_AGENT = 'user-agent',
|
44
|
-
UA_MAX_LENGTH =
|
43
|
+
UA_MAX_LENGTH = 500,
|
45
44
|
BRANDS = 'brands',
|
45
|
+
FORMFACTOR = 'formFactor',
|
46
46
|
FULLVERLIST = 'fullVersionList',
|
47
47
|
PLATFORM = 'platform',
|
48
48
|
PLATFORMVER = 'platformVersion',
|
@@ -51,11 +51,12 @@
|
|
51
51
|
CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
|
52
52
|
CH_HEADER_ARCH = CH_HEADER + '-arch',
|
53
53
|
CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS,
|
54
|
+
CH_HEADER_FORM_FACTOR = CH_HEADER + '-form-factor',
|
54
55
|
CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE,
|
55
56
|
CH_HEADER_MODEL = CH_HEADER + '-' + MODEL,
|
56
57
|
CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM,
|
57
58
|
CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
|
58
|
-
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, BITNESS],
|
59
|
+
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTOR, BITNESS],
|
59
60
|
UA_BROWSER = 'browser',
|
60
61
|
UA_CPU = 'cpu',
|
61
62
|
UA_DEVICE = 'device',
|
@@ -68,6 +69,7 @@
|
|
68
69
|
BLACKBERRY = 'BlackBerry',
|
69
70
|
GOOGLE = 'Google',
|
70
71
|
HUAWEI = 'Huawei',
|
72
|
+
LENOVO = 'Lenovo',
|
71
73
|
LG = 'LG',
|
72
74
|
MICROSOFT = 'Microsoft',
|
73
75
|
MOTOROLA = 'Motorola',
|
@@ -83,9 +85,11 @@
|
|
83
85
|
FIREFOX = 'Firefox',
|
84
86
|
OPERA = 'Opera',
|
85
87
|
FACEBOOK = 'Facebook',
|
88
|
+
SOGOU = 'Sogou',
|
86
89
|
WINDOWS = 'Windows';
|
87
90
|
|
88
|
-
var
|
91
|
+
var isWindow = typeof window !== UNDEF_TYPE,
|
92
|
+
NAVIGATOR = (isWindow && window.navigator) ?
|
89
93
|
window.navigator :
|
90
94
|
undefined,
|
91
95
|
NAVIGATOR_UADATA = (NAVIGATOR && NAVIGATOR.userAgentData) ?
|
@@ -117,28 +121,35 @@
|
|
117
121
|
}
|
118
122
|
return false;
|
119
123
|
}
|
120
|
-
return
|
124
|
+
return isString(str1) ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
|
121
125
|
},
|
122
126
|
isExtensions = function (obj) {
|
123
127
|
for (var prop in obj) {
|
124
128
|
return /^(browser|cpu|device|engine|os)$/.test(prop);
|
125
129
|
}
|
126
130
|
},
|
131
|
+
isString = function (val) {
|
132
|
+
return typeof val === STR_TYPE;
|
133
|
+
},
|
127
134
|
itemListToArray = function (header) {
|
128
135
|
if (!header) return undefined;
|
129
136
|
var arr = [];
|
130
|
-
var tokens = strip(/\\?\"/g, header).split(',
|
137
|
+
var tokens = strip(/\\?\"/g, header).split(',');
|
131
138
|
for (var i = 0; i < tokens.length; i++) {
|
132
|
-
|
133
|
-
|
139
|
+
if (tokens[i].indexOf(';') > -1) {
|
140
|
+
var token = trim(tokens[i]).split(';v=');
|
141
|
+
arr[i] = { brand : token[0], version : token[1] };
|
142
|
+
} else {
|
143
|
+
arr[i] = trim(tokens[i]);
|
144
|
+
}
|
134
145
|
}
|
135
146
|
return arr;
|
136
147
|
},
|
137
148
|
lowerize = function (str) {
|
138
|
-
return
|
149
|
+
return isString(str) ? str.toLowerCase() : str;
|
139
150
|
},
|
140
151
|
majorize = function (version) {
|
141
|
-
return
|
152
|
+
return isString(version) ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
|
142
153
|
},
|
143
154
|
setProps = function (arr) {
|
144
155
|
for (var i in arr) {
|
@@ -152,15 +163,15 @@
|
|
152
163
|
return this;
|
153
164
|
},
|
154
165
|
strip = function (pattern, str) {
|
155
|
-
return str.replace(pattern, EMPTY);
|
166
|
+
return isString(str) ? str.replace(pattern, EMPTY) : str;
|
156
167
|
},
|
157
|
-
stripQuotes = function (
|
158
|
-
return
|
168
|
+
stripQuotes = function (str) {
|
169
|
+
return strip(/\\?\"/g, str);
|
159
170
|
},
|
160
171
|
trim = function (str, len) {
|
161
|
-
if (
|
172
|
+
if (isString(str)) {
|
162
173
|
str = strip(/^\s\s*/, str);
|
163
|
-
return typeof
|
174
|
+
return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
|
164
175
|
}
|
165
176
|
};
|
166
177
|
|
@@ -237,7 +248,7 @@
|
|
237
248
|
return (i === UNKNOWN) ? undefined : i;
|
238
249
|
}
|
239
250
|
}
|
240
|
-
return str;
|
251
|
+
return map.hasOwnProperty('*') ? map['*'] : str;
|
241
252
|
};
|
242
253
|
|
243
254
|
///////////////
|
@@ -256,6 +267,16 @@
|
|
256
267
|
'8.1' : 'NT 6.3',
|
257
268
|
'10' : ['NT 6.4', 'NT 10.0'],
|
258
269
|
'RT' : 'ARM'
|
270
|
+
},
|
271
|
+
|
272
|
+
formFactorMap = {
|
273
|
+
'embedded' : 'Automotive',
|
274
|
+
'mobile' : 'Mobile',
|
275
|
+
'tablet' : ['Tablet', 'EInk'],
|
276
|
+
'smarttv' : 'TV',
|
277
|
+
'wearable' : ['VR', 'XR', 'Watch'],
|
278
|
+
'?' : ['Desktop', 'Unknown'],
|
279
|
+
'*' : undefined
|
259
280
|
};
|
260
281
|
|
261
282
|
//////////////
|
@@ -279,15 +300,18 @@
|
|
279
300
|
], [NAME, VERSION], [
|
280
301
|
/opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0
|
281
302
|
], [VERSION, [NAME, OPERA+' Mini']], [
|
303
|
+
/\bop(?:rg)?x\/([\w\.]+)/i // Opera GX
|
304
|
+
], [VERSION, [NAME, OPERA+' GX']], [
|
282
305
|
/\bopr\/([\w\.]+)/i // Opera Webkit
|
283
306
|
], [VERSION, [NAME, OPERA]], [
|
284
307
|
|
285
308
|
// Mixed
|
309
|
+
/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
|
310
|
+
], [VERSION, [NAME, 'Baidu']], [
|
286
311
|
/(kindle)\/([\w\.]+)/i, // Kindle
|
287
312
|
/(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer
|
288
313
|
// Trident based
|
289
|
-
/(avant
|
290
|
-
/(ba?idubrowser)[\/ ]?([\w\.]+)/i, // Baidu Browser
|
314
|
+
/(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
|
291
315
|
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
|
292
316
|
|
293
317
|
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
|
@@ -299,8 +323,7 @@
|
|
299
323
|
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
|
300
324
|
], [VERSION, [NAME, 'UCBrowser']], [
|
301
325
|
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
|
302
|
-
/\bqbcore\/([\w\.]+).+microm/i
|
303
|
-
], [VERSION, [NAME, 'WeChat(Win) Desktop']], [
|
326
|
+
/\bqbcore\/([\w\.]+).+microm/i,
|
304
327
|
/micromessenger\/([\w\.]+)/i // WeChat
|
305
328
|
], [VERSION, [NAME, 'WeChat']], [
|
306
329
|
/konqueror\/([\w\.]+)/i // Konqueror
|
@@ -309,6 +332,8 @@
|
|
309
332
|
], [VERSION, [NAME, 'IE']], [
|
310
333
|
/ya(?:search)?browser\/([\w\.]+)/i // Yandex
|
311
334
|
], [VERSION, [NAME, 'Yandex']], [
|
335
|
+
/slbrowser\/([\w\.]+)/i // Smart Lenovo Browser
|
336
|
+
], [VERSION, [NAME, 'Smart ' + LENOVO + SUFFIX_BROWSER]], [
|
312
337
|
/(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
|
313
338
|
], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [
|
314
339
|
/\bfocus\/([\w\.]+)/i // Firefox Focus
|
@@ -327,15 +352,20 @@
|
|
327
352
|
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
|
328
353
|
/\bqihu|(qi?ho?o?|360)browser/i // 360
|
329
354
|
], [[NAME, '360' + SUFFIX_BROWSER]], [
|
330
|
-
/(oculus|
|
331
|
-
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [
|
355
|
+
/(oculus|sailfish|huawei|vivo)browser\/([\w\.]+)/i
|
356
|
+
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser
|
357
|
+
/samsungbrowser\/([\w\.]+)/i // Samsung Internet
|
358
|
+
], [VERSION, [NAME, SAMSUNG + ' Internet']], [
|
332
359
|
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
|
333
360
|
], [[NAME, /_/g, ' '], VERSION], [
|
361
|
+
/metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
|
362
|
+
], [VERSION, [NAME, SOGOU + ' Explorer']], [
|
363
|
+
/(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
|
364
|
+
], [[NAME, SOGOU + ' Mobile'], VERSION], [
|
334
365
|
/(electron)\/([\w\.]+) safari/i, // Electron-based App
|
335
366
|
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
|
336
|
-
/m?(qqbrowser|
|
367
|
+
/m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
|
337
368
|
], [NAME, VERSION], [
|
338
|
-
/(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser
|
339
369
|
/(lbbrowser)/i, // LieBao Browser
|
340
370
|
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
|
341
371
|
], [NAME], [
|
@@ -343,10 +373,12 @@
|
|
343
373
|
// WebView
|
344
374
|
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
|
345
375
|
], [[NAME, FACEBOOK], VERSION], [
|
376
|
+
/(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
|
346
377
|
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
|
347
378
|
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
|
348
379
|
/safari (line)\/([\w\.]+)/i, // Line App for iOS
|
349
380
|
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
|
381
|
+
/(alipay)client\/([\w\.]+)/i, // Alipay
|
350
382
|
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
|
351
383
|
], [NAME, VERSION], [
|
352
384
|
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
|
@@ -478,8 +510,10 @@
|
|
478
510
|
/\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
|
479
511
|
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
|
480
512
|
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
|
513
|
+
/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models
|
481
514
|
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
|
482
515
|
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
|
516
|
+
/oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
|
483
517
|
/\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets
|
484
518
|
],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [
|
485
519
|
|
@@ -494,7 +528,7 @@
|
|
494
528
|
], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [
|
495
529
|
|
496
530
|
// Realme
|
497
|
-
/\b(rmx[
|
531
|
+
/\b(rmx[1-3]\d{3})(?: bui|;|\))/i
|
498
532
|
], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [
|
499
533
|
|
500
534
|
// Motorola
|
@@ -516,7 +550,7 @@
|
|
516
550
|
// Lenovo
|
517
551
|
/(ideatab[-\w ]+)/i,
|
518
552
|
/lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
|
519
|
-
], [MODEL, [VENDOR,
|
553
|
+
], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [
|
520
554
|
|
521
555
|
// Nokia
|
522
556
|
/(?:maemo|nokia).*(n900|lumia \d+)/i,
|
@@ -580,6 +614,10 @@
|
|
580
614
|
/droid.+; (m[1-5] note) bui/i,
|
581
615
|
/\bmz-([-\w]{2,})/i
|
582
616
|
], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [
|
617
|
+
|
618
|
+
// Ulefone
|
619
|
+
/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
|
620
|
+
], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
|
583
621
|
|
584
622
|
// MIXED
|
585
623
|
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i,
|
@@ -686,7 +724,7 @@
|
|
686
724
|
// MIXED (GENERIC)
|
687
725
|
///////////////////
|
688
726
|
|
689
|
-
/droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i
|
727
|
+
/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors
|
690
728
|
], [MODEL, [TYPE, MOBILE]], [
|
691
729
|
/droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors
|
692
730
|
], [MODEL, [TYPE, TABLET]], [
|
@@ -723,12 +761,12 @@
|
|
723
761
|
// Windows
|
724
762
|
/microsoft (windows) (vista|xp)/i // Windows (iTunes)
|
725
763
|
], [NAME, VERSION], [
|
726
|
-
/(windows
|
727
|
-
/(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, // Windows Phone
|
728
|
-
/(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i
|
764
|
+
/(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i // Windows Phone
|
729
765
|
], [NAME, [VERSION, strMapper, windowsVersionMap]], [
|
730
|
-
/
|
731
|
-
|
766
|
+
/windows nt 6\.2; (arm)/i, // Windows RT
|
767
|
+
/windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i,
|
768
|
+
/(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i
|
769
|
+
], [[VERSION, strMapper, windowsVersionMap], [NAME, WINDOWS]], [
|
732
770
|
|
733
771
|
// iOS/macOS
|
734
772
|
/ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
|
@@ -930,6 +968,7 @@
|
|
930
968
|
[PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
|
931
969
|
[PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
|
932
970
|
[ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
|
971
|
+
[FORMFACTOR, itemListToArray(uach[CH_HEADER_FORM_FACTOR])],
|
933
972
|
[BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
|
934
973
|
]);
|
935
974
|
} else {
|
@@ -1011,21 +1050,21 @@
|
|
1011
1050
|
};
|
1012
1051
|
|
1013
1052
|
this.parseCH = function () {
|
1014
|
-
var
|
1015
|
-
uaCH = this.uaCH,
|
1053
|
+
var uaCH = this.uaCH,
|
1016
1054
|
rgxMap = this.rgxMap;
|
1017
1055
|
|
1018
1056
|
switch (this.itemType) {
|
1019
1057
|
case UA_BROWSER:
|
1020
|
-
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS];
|
1058
|
+
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName;
|
1021
1059
|
if (brands) {
|
1022
1060
|
for (var i in brands) {
|
1023
|
-
var brandName = brands[i].brand,
|
1061
|
+
var brandName = strip(/(Google|Microsoft) /, brands[i].brand || brands[i]),
|
1024
1062
|
brandVersion = brands[i].version;
|
1025
|
-
if (!/not.a.brand/i.test(brandName) && (
|
1026
|
-
this.set(NAME,
|
1063
|
+
if (!/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && !/chromi/i.test(brandName)))) {
|
1064
|
+
this.set(NAME, brandName)
|
1027
1065
|
.set(VERSION, brandVersion)
|
1028
1066
|
.set(MAJOR, majorize(brandVersion));
|
1067
|
+
prevName = brandName;
|
1029
1068
|
}
|
1030
1069
|
}
|
1031
1070
|
}
|
@@ -1044,6 +1083,23 @@
|
|
1044
1083
|
if (uaCH[MODEL]) {
|
1045
1084
|
this.set(MODEL, uaCH[MODEL]);
|
1046
1085
|
}
|
1086
|
+
// Xbox-Specific Detection
|
1087
|
+
if (uaCH[MODEL] == 'Xbox') {
|
1088
|
+
this.set(TYPE, CONSOLE)
|
1089
|
+
.set(VENDOR, MICROSOFT);
|
1090
|
+
}
|
1091
|
+
if (uaCH[FORMFACTOR]) {
|
1092
|
+
var ff;
|
1093
|
+
if (typeof uaCH[FORMFACTOR] !== 'string') {
|
1094
|
+
var idx = 0;
|
1095
|
+
while (!ff && idx < uaCH[FORMFACTOR].length) {
|
1096
|
+
ff = strMapper(uaCH[FORMFACTOR][idx++], formFactorMap);
|
1097
|
+
}
|
1098
|
+
} else {
|
1099
|
+
ff = strMapper(uaCH[FORMFACTOR], formFactorMap);
|
1100
|
+
}
|
1101
|
+
this.set(TYPE, ff);
|
1102
|
+
}
|
1047
1103
|
break;
|
1048
1104
|
case UA_OS:
|
1049
1105
|
var osName = uaCH[PLATFORM];
|
@@ -1053,6 +1109,11 @@
|
|
1053
1109
|
this.set(NAME, osName)
|
1054
1110
|
.set(VERSION, osVersion);
|
1055
1111
|
}
|
1112
|
+
// Xbox-Specific Detection
|
1113
|
+
if (this.get(NAME) == WINDOWS && uaCH[MODEL] == 'Xbox') {
|
1114
|
+
this.set(NAME, 'Xbox')
|
1115
|
+
.set(VERSION, undefined);
|
1116
|
+
}
|
1056
1117
|
break;
|
1057
1118
|
case UA_RESULT:
|
1058
1119
|
var data = this.data;
|
@@ -1146,7 +1207,7 @@
|
|
1146
1207
|
['getResult', createItemFunc(UA_RESULT)],
|
1147
1208
|
['getUA', function () { return userAgent; }],
|
1148
1209
|
['setUA', function (ua) {
|
1149
|
-
if (
|
1210
|
+
if (isString(ua))
|
1150
1211
|
userAgent = ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua;
|
1151
1212
|
return this;
|
1152
1213
|
}]
|
@@ -1167,7 +1228,7 @@
|
|
1167
1228
|
//////////
|
1168
1229
|
|
1169
1230
|
// check js environment
|
1170
|
-
if (typeof
|
1231
|
+
if (typeof exports !== UNDEF_TYPE) {
|
1171
1232
|
// nodejs env
|
1172
1233
|
if (typeof module !== UNDEF_TYPE && module.exports) {
|
1173
1234
|
exports = module.exports = UAParser;
|
@@ -1175,11 +1236,11 @@
|
|
1175
1236
|
exports.UAParser = UAParser;
|
1176
1237
|
} else {
|
1177
1238
|
// requirejs env (optional)
|
1178
|
-
if (typeof
|
1239
|
+
if (typeof define === FUNC_TYPE && define.amd) {
|
1179
1240
|
define(function () {
|
1180
1241
|
return UAParser;
|
1181
1242
|
});
|
1182
|
-
} else if (
|
1243
|
+
} else if (isWindow) {
|
1183
1244
|
// browser env
|
1184
1245
|
window.UAParser = UAParser;
|
1185
1246
|
}
|
@@ -1190,7 +1251,7 @@
|
|
1190
1251
|
// In AMD env the global scope should be kept clean, but jQuery is an exception.
|
1191
1252
|
// jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
|
1192
1253
|
// and we should catch that.
|
1193
|
-
var $ =
|
1254
|
+
var $ = isWindow && (window.jQuery || window.Zepto);
|
1194
1255
|
if ($ && !$.ua) {
|
1195
1256
|
var parser = new UAParser();
|
1196
1257
|
$.ua = parser.getResult();
|