ua-parser-js 2.0.0-alpha.2 → 2.0.0-beta.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,27 +1,28 @@
1
- // Generated ESM version of UAParser.js
1
+ // Generated ESM version of ua-parser-js
2
2
  // DO NOT EDIT THIS FILE!
3
- // Source: /src/ua-parser.js
4
-
5
- const window = undefined;
3
+ // Source: /src/main/ua-parser.js
6
4
 
7
5
  /////////////////////////////////////////////////////////////////////////////////
8
- /* UAParser.js v2.0.0-alpha.2
6
+ /* UAParser.js v2.0.0-beta.1
9
7
  Copyright © 2012-2023 Faisal Salman <f@faisalman.com>
10
- MIT License *//*
8
+ AGPLv3 License *//*
11
9
  Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
12
10
  Supports browser & node.js environment.
13
11
  Demo : https://faisalman.github.io/ua-parser-js
14
12
  Source : https://github.com/faisalman/ua-parser-js */
15
13
  /////////////////////////////////////////////////////////////////////////////////
16
14
 
15
+ /* jshint esversion: 6 */
16
+ /* globals window */
17
17
 
18
18
 
19
+
19
20
  //////////////
20
21
  // Constants
21
22
  /////////////
22
23
 
23
24
 
24
- var LIBVERSION = '2.0.0-alpha.2',
25
+ var LIBVERSION = '2.0.0-beta.1',
25
26
  EMPTY = '',
26
27
  UNKNOWN = '?',
27
28
  FUNC_TYPE = 'function',
@@ -44,6 +45,7 @@ const window = undefined;
44
45
  USER_AGENT = 'user-agent',
45
46
  UA_MAX_LENGTH = 350,
46
47
  BRANDS = 'brands',
48
+ FORMFACTOR = 'formFactor',
47
49
  FULLVERLIST = 'fullVersionList',
48
50
  PLATFORM = 'platform',
49
51
  PLATFORMVER = 'platformVersion',
@@ -51,12 +53,13 @@ const window = undefined;
51
53
  CH_HEADER = 'sec-ch-ua',
52
54
  CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
53
55
  CH_HEADER_ARCH = CH_HEADER + '-arch',
54
- CH_HEADER_BITNESS = CH_HEADER + '-bitness',
55
- CH_HEADER_MOBILE = CH_HEADER + '-mobile',
56
- CH_HEADER_MODEL = CH_HEADER + '-model',
57
- CH_HEADER_PLATFORM = CH_HEADER + '-platform',
56
+ CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS,
57
+ CH_HEADER_FORM_FACTOR = CH_HEADER + '-form-factor',
58
+ CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE,
59
+ CH_HEADER_MODEL = CH_HEADER + '-' + MODEL,
60
+ CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM,
58
61
  CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
59
- CH_ALL_VALUES = ['brands', 'fullVersionList', MOBILE, MODEL, 'platform', 'platformVersion', ARCHITECTURE, 'bitness'],
62
+ CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTOR, BITNESS],
60
63
  UA_BROWSER = 'browser',
61
64
  UA_CPU = 'cpu',
62
65
  UA_DEVICE = 'device',
@@ -97,18 +100,7 @@ const window = undefined;
97
100
  // Helper
98
101
  //////////
99
102
 
100
- var assignFromEntries = function (arr) {
101
- for (var i in arr) {
102
- var propName = arr[i];
103
- if (typeof propName == OBJ_TYPE && propName.length == 2) {
104
- this[propName[0]] = propName[1];
105
- } else {
106
- this[propName] = undefined;
107
- }
108
- }
109
- return this;
110
- },
111
- extend = function (regexes, extensions) {
103
+ var extend = function (regexes, extensions) {
112
104
  var mergedRegexes = {};
113
105
  for (var i in regexes) {
114
106
  mergedRegexes[i] = extensions[i] && extensions[i].length % 2 === 0 ? extensions[i].concat(regexes[i]) : regexes[i];
@@ -139,10 +131,14 @@ const window = undefined;
139
131
  itemListToArray = function (header) {
140
132
  if (!header) return undefined;
141
133
  var arr = [];
142
- var tokens = strip(/\\?\"/g, header).split(', ');
134
+ var tokens = strip(/\\?\"/g, header).split(',');
143
135
  for (var i = 0; i < tokens.length; i++) {
144
- var token = tokens[i].split(';v=');
145
- arr[i] = { brand : token[0], version : token[1] };
136
+ if (tokens[i].indexOf(';') > -1) {
137
+ var token = trim(tokens[i]).split(';v=');
138
+ arr[i] = { brand : token[0], version : token[1] };
139
+ } else {
140
+ arr[i] = tokens[i];
141
+ }
146
142
  }
147
143
  return arr;
148
144
  },
@@ -152,11 +148,22 @@ const window = undefined;
152
148
  majorize = function (version) {
153
149
  return typeof(version) === STR_TYPE ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
154
150
  },
151
+ setProps = function (arr) {
152
+ for (var i in arr) {
153
+ var propName = arr[i];
154
+ if (typeof propName == OBJ_TYPE && propName.length == 2) {
155
+ this[propName[0]] = propName[1];
156
+ } else {
157
+ this[propName] = undefined;
158
+ }
159
+ }
160
+ return this;
161
+ },
155
162
  strip = function (pattern, str) {
156
163
  return str.replace(pattern, EMPTY);
157
164
  },
158
165
  stripQuotes = function (val) {
159
- return typeof val === STR_TYPE ? strip(/\"/g, val) : val;
166
+ return typeof val === STR_TYPE ? strip(/\\?\"/g, val) : val;
160
167
  },
161
168
  trim = function (str, len) {
162
169
  if (typeof(str) === STR_TYPE) {
@@ -238,25 +245,14 @@ const window = undefined;
238
245
  return (i === UNKNOWN) ? undefined : i;
239
246
  }
240
247
  }
241
- return str;
248
+ return map.hasOwnProperty('*') ? map['*'] : str;
242
249
  };
243
250
 
244
251
  ///////////////
245
252
  // String map
246
253
  //////////////
247
254
 
248
- // Safari < 3.0
249
- var oldSafariMap = {
250
- '1.0' : '/8',
251
- '1.2' : '/1',
252
- '1.3' : '/3',
253
- '2.0' : '/412',
254
- '2.0.2' : '/416',
255
- '2.0.3' : '/417',
256
- '2.0.4' : '/419',
257
- '?' : '/'
258
- },
259
- windowsVersionMap = {
255
+ var windowsVersionMap = {
260
256
  'ME' : '4.90',
261
257
  'NT 3.11' : 'NT3.51',
262
258
  'NT 4.0' : 'NT4.0',
@@ -268,6 +264,16 @@ const window = undefined;
268
264
  '8.1' : 'NT 6.3',
269
265
  '10' : ['NT 6.4', 'NT 10.0'],
270
266
  'RT' : 'ARM'
267
+ },
268
+
269
+ formFactorMap = {
270
+ 'embedded' : 'Automotive',
271
+ 'mobile' : 'Mobile',
272
+ 'tablet' : ['Tablet', 'EInk'],
273
+ 'smarttv' : 'TV',
274
+ 'wearable' : ['VR', 'XR', 'Watch'],
275
+ '?' : ['Desktop', 'Unknown'],
276
+ '*' : undefined
271
277
  };
272
278
 
273
279
  //////////////
@@ -359,7 +365,7 @@ const window = undefined;
359
365
  /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
360
366
  /safari (line)\/([\w\.]+)/i, // Line App for iOS
361
367
  /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
362
- /(chromium|instagram)[\/ ]([-\w\.]+)/i // Chromium/Instagram
368
+ /(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
363
369
  ], [NAME, VERSION], [
364
370
  /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
365
371
  ], [VERSION, [NAME, 'GSA']], [
@@ -388,7 +394,7 @@ const window = undefined;
388
394
  /version\/([\w\.\,]+) .*(safari)/i // Safari
389
395
  ], [VERSION, NAME], [
390
396
  /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
391
- ], [NAME, [VERSION, strMapper, oldSafariMap]], [
397
+ ], [NAME, [VERSION, '1']], [
392
398
 
393
399
  /(webkit|khtml)\/([\w\.]+)/i
394
400
  ], [NAME, VERSION], [
@@ -429,7 +435,7 @@ const window = undefined;
429
435
  /((?:i[346]|x)86)[;\)]/i // IA32 (x86)
430
436
  ], [[ARCHITECTURE, 'ia32']], [
431
437
 
432
- /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64
438
+ /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64
433
439
  ], [[ARCHITECTURE, 'arm64']], [
434
440
 
435
441
  /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF
@@ -486,12 +492,14 @@ const window = undefined;
486
492
  ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
487
493
 
488
494
  // Xiaomi
489
- /\b(poco[\w ]+)(?: bui|\))/i, // Xiaomi POCO
495
+ /\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i, // Xiaomi POCO
490
496
  /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
491
497
  /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
492
498
  /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
499
+ /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|\))/i, // Xiaomi Redmi 'numeric' models
493
500
  /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
494
501
  ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
502
+ /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
495
503
  /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets
496
504
  ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [
497
505
 
@@ -506,7 +514,7 @@ const window = undefined;
506
514
  ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [
507
515
 
508
516
  // Realme
509
- /\b(rmx[12]\d{3})(?: bui|;|\))/i
517
+ /\b(rmx[1-3]\d{3})(?: bui|;|\))/i
510
518
  ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [
511
519
 
512
520
  // Motorola
@@ -592,9 +600,13 @@ const window = undefined;
592
600
  /droid.+; (m[1-5] note) bui/i,
593
601
  /\bmz-([-\w]{2,})/i
594
602
  ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [
603
+
604
+ // Ulefone
605
+ /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
606
+ ], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
595
607
 
596
608
  // MIXED
597
- /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i,
609
+ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i,
598
610
  // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
599
611
  /(hp) ([\w ]+\w)/i, // HP iPAQ
600
612
  /(asus)-?(\w+)/i, // Asus
@@ -639,7 +651,7 @@ const window = undefined;
639
651
  ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [
640
652
  /crkey/i // Google Chromecast
641
653
  ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
642
- /droid.+aft(\w)( bui|\))/i // Fire TV
654
+ /droid.+aft(\w+)( bui|\))/i // Fire TV
643
655
  ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [
644
656
  /\(dtv[\);].+(aquos)/i,
645
657
  /(aquos-tv[\w ]+)\)/i // Sharp
@@ -744,7 +756,7 @@ const window = undefined;
744
756
 
745
757
  // iOS/macOS
746
758
  /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
747
- /ios;fbsv\/([\d\.]+)/i,
759
+ /(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i,
748
760
  /cfnetwork\/.+darwin/i
749
761
  ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
750
762
  /(mac os x) ?([\w\. ]*)/i,
@@ -813,23 +825,23 @@ const window = undefined;
813
825
 
814
826
  var defaultProps = (function () {
815
827
  var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
816
- assignFromEntries.call(props.init, [
828
+ setProps.call(props.init, [
817
829
  [UA_BROWSER, [NAME, VERSION, MAJOR]],
818
830
  [UA_CPU, [ARCHITECTURE]],
819
831
  [UA_DEVICE, [TYPE, MODEL, VENDOR]],
820
832
  [UA_ENGINE, [NAME, VERSION]],
821
833
  [UA_OS, [NAME, VERSION]]
822
834
  ]);
823
- assignFromEntries.call(props.isIgnore, [
835
+ setProps.call(props.isIgnore, [
824
836
  [UA_BROWSER, [VERSION, MAJOR]],
825
837
  [UA_ENGINE, [VERSION]],
826
838
  [UA_OS, [VERSION]]
827
839
  ]);
828
- assignFromEntries.call(props.isIgnoreRgx, [
840
+ setProps.call(props.isIgnoreRgx, [
829
841
  [UA_BROWSER, / ?browser$/i],
830
842
  [UA_OS, / ?os$/i]
831
843
  ]);
832
- assignFromEntries.call(props.toString, [
844
+ setProps.call(props.toString, [
833
845
  [UA_BROWSER, [NAME, VERSION]],
834
846
  [UA_CPU, [ARCHITECTURE]],
835
847
  [UA_DEVICE, [VENDOR, MODEL]],
@@ -839,34 +851,47 @@ const window = undefined;
839
851
  return props;
840
852
  })();
841
853
 
842
- var createUAParserData = function (itemType, ua, rgxMap, uaCH) {
854
+ var createIData = function (item, itemType) {
843
855
 
844
856
  var init_props = defaultProps.init[itemType],
845
857
  is_ignoreProps = defaultProps.isIgnore[itemType] || 0,
846
858
  is_ignoreRgx = defaultProps.isIgnoreRgx[itemType] || 0,
847
859
  toString_props = defaultProps.toString[itemType] || 0;
848
860
 
849
- function UAParserData () {
850
- assignFromEntries.call(this, init_props);
861
+ function IData () {
862
+ setProps.call(this, init_props);
851
863
  }
852
- UAParserData.prototype.withClientHints = function () {
853
-
864
+
865
+ IData.prototype.getItem = function () {
866
+ return item;
867
+ };
868
+
869
+ IData.prototype.withClientHints = function () {
870
+
854
871
  // nodejs / non-client-hints browsers
855
872
  if (!NAVIGATOR_UADATA) {
856
- return new UAParserItem(itemType, ua, rgxMap, uaCH).parseCH().get();
873
+ return item
874
+ .parseCH()
875
+ .get();
857
876
  }
858
877
 
859
878
  // browsers based on chromium 85+
860
879
  return NAVIGATOR_UADATA
861
880
  .getHighEntropyValues(CH_ALL_VALUES)
862
881
  .then(function (res) {
863
- var JS_UACH = new UAParserDataCH(res, false);
864
- return new UAParserItem(itemType, ua, rgxMap, JS_UACH).parseCH().get();
882
+ return item
883
+ .setCH(new UACHData(res, false))
884
+ .parseCH()
885
+ .get();
865
886
  });
866
887
  };
867
888
 
889
+ IData.prototype.withFeatureCheck = function () {
890
+ return item.detectFeature().get();
891
+ };
892
+
868
893
  if (itemType != UA_RESULT) {
869
- UAParserData.prototype.is = function (strToCheck) {
894
+ IData.prototype.is = function (strToCheck) {
870
895
  var is = false;
871
896
  for (var i in this) {
872
897
  if (this.hasOwnProperty(i) && !has(is_ignoreProps, i) && lowerize(is_ignoreRgx ? strip(is_ignoreRgx, this[i]) : this[i]) == lowerize(is_ignoreRgx ? strip(is_ignoreRgx, strToCheck) : strToCheck)) {
@@ -879,7 +904,7 @@ const window = undefined;
879
904
  }
880
905
  return is;
881
906
  };
882
- UAParserData.prototype.toString = function () {
907
+ IData.prototype.toString = function () {
883
908
  var str = EMPTY;
884
909
  for (var i in toString_props) {
885
910
  if (typeof(this[toString_props[i]]) !== UNDEF_TYPE) {
@@ -891,45 +916,45 @@ const window = undefined;
891
916
  }
892
917
 
893
918
  if (!NAVIGATOR_UADATA) {
894
- UAParserData.prototype.then = function (cb) {
919
+ IData.prototype.then = function (cb) {
895
920
  var that = this;
896
- var UAParserDataResolve = function () {
921
+ var IDataResolve = function () {
897
922
  for (var prop in that) {
898
923
  if (that.hasOwnProperty(prop)) {
899
924
  this[prop] = that[prop];
900
925
  }
901
926
  }
902
927
  };
903
- UAParserDataResolve.prototype = {
904
- is : UAParserData.prototype.is,
905
- toString : UAParserData.prototype.toString
928
+ IDataResolve.prototype = {
929
+ is : IData.prototype.is,
930
+ toString : IData.prototype.toString
906
931
  };
907
- var resolveData = new UAParserDataResolve();
932
+ var resolveData = new IDataResolve();
908
933
  cb(resolveData);
909
934
  return resolveData;
910
935
  };
911
936
  }
912
937
 
913
- return new UAParserData();
938
+ return new IData();
914
939
  };
915
940
 
916
941
  /////////////////
917
942
  // Constructor
918
943
  ////////////////
919
944
 
920
- function UAParserDataCH (uach, isHTTP_UACH) {
945
+ function UACHData (uach, isHttpUACH) {
921
946
  uach = uach || {};
922
- assignFromEntries.call(this, CH_ALL_VALUES);
923
- if (isHTTP_UACH) {
924
- assignFromEntries.call(this, [
947
+ setProps.call(this, CH_ALL_VALUES);
948
+ if (isHttpUACH) {
949
+ setProps.call(this, [
925
950
  [BRANDS, itemListToArray(uach[CH_HEADER])],
926
951
  [FULLVERLIST, itemListToArray(uach[CH_HEADER_FULL_VER_LIST])],
927
- [BRANDS, itemListToArray(uach[CH_HEADER])],
928
952
  [MOBILE, /\?1/.test(uach[CH_HEADER_MOBILE])],
929
953
  [MODEL, stripQuotes(uach[CH_HEADER_MODEL])],
930
954
  [PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
931
955
  [PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
932
956
  [ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
957
+ [FORMFACTOR, itemListToArray(uach[CH_HEADER_FORM_FACTOR])],
933
958
  [BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
934
959
  ]);
935
960
  } else {
@@ -937,127 +962,162 @@ const window = undefined;
937
962
  if(this.hasOwnProperty(prop) && typeof uach[prop] !== UNDEF_TYPE) this[prop] = uach[prop];
938
963
  }
939
964
  }
940
- return this;
941
965
  }
942
966
 
943
- function UAParserItem (itemType, ua, rgxMap, uaCH) {
944
- assignFromEntries.call(this, [
967
+ function UAItem (itemType, ua, rgxMap, uaCH) {
968
+
969
+ this.get = function (prop) {
970
+ if (!prop) return this.data;
971
+ return this.data.hasOwnProperty(prop) ? this.data[prop] : undefined;
972
+ };
973
+
974
+ this.set = function (prop, val) {
975
+ this.data[prop] = val;
976
+ return this;
977
+ };
978
+
979
+ this.setCH = function (ch) {
980
+ this.uaCH = ch;
981
+ return this;
982
+ };
983
+
984
+ this.detectFeature = function () {
985
+ if (NAVIGATOR && NAVIGATOR.userAgent == this.ua) {
986
+ switch (this.itemType) {
987
+ case UA_BROWSER:
988
+ // Brave-specific detection
989
+ if (NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave == FUNC_TYPE) {
990
+ this.set(NAME, 'Brave');
991
+ }
992
+ break;
993
+ case UA_DEVICE:
994
+ // Chrome-specific detection: check for 'mobile' value of navigator.userAgentData
995
+ if (!this.get(TYPE) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[MOBILE]) {
996
+ this.set(TYPE, MOBILE);
997
+ }
998
+ // iPadOS-specific detection: identified as Mac, but has some iOS-only properties
999
+ if (this.get(MODEL) == 'Macintosh' && NAVIGATOR && typeof NAVIGATOR.standalone !== UNDEF_TYPE && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 2) {
1000
+ this.set(MODEL, 'iPad')
1001
+ .set(TYPE, TABLET);
1002
+ }
1003
+ break;
1004
+ case UA_OS:
1005
+ // Chrome-specific detection: check for 'platform' value of navigator.userAgentData
1006
+ if (!this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM]) {
1007
+ this.set(NAME, NAVIGATOR_UADATA[PLATFORM]);
1008
+ }
1009
+ break;
1010
+ case UA_RESULT:
1011
+ var data = this.data;
1012
+ var detect = function (itemType) {
1013
+ return data[itemType]
1014
+ .getItem()
1015
+ .detectFeature()
1016
+ .get();
1017
+ };
1018
+ this.set(UA_BROWSER, detect(UA_BROWSER))
1019
+ .set(UA_CPU, detect(UA_CPU))
1020
+ .set(UA_DEVICE, detect(UA_DEVICE))
1021
+ .set(UA_ENGINE, detect(UA_ENGINE))
1022
+ .set(UA_OS, detect(UA_OS));
1023
+ }
1024
+ }
1025
+ return this;
1026
+ };
1027
+
1028
+ this.parseUA = function () {
1029
+ if (this.itemType != UA_RESULT) {
1030
+ rgxMapper.call(this.data, this.ua, this.rgxMap);
1031
+ }
1032
+ if (this.itemType == UA_BROWSER) {
1033
+ this.set(MAJOR, majorize(this.get(VERSION)));
1034
+ }
1035
+ return this;
1036
+ };
1037
+
1038
+ this.parseCH = function () {
1039
+ var uaCH = this.uaCH,
1040
+ rgxMap = this.rgxMap;
1041
+
1042
+ switch (this.itemType) {
1043
+ case UA_BROWSER:
1044
+ var brands = uaCH[FULLVERLIST] || uaCH[BRANDS];
1045
+ if (brands) {
1046
+ for (var i in brands) {
1047
+ var brandName = brands[i].brand,
1048
+ brandVersion = brands[i].version;
1049
+ if (!/not.a.brand/i.test(brandName) && (i < 1 || /chromi/i.test(this.get(NAME)))) {
1050
+ this.set(NAME, strip(GOOGLE+' ', brandName))
1051
+ .set(VERSION, brandVersion)
1052
+ .set(MAJOR, majorize(brandVersion));
1053
+ }
1054
+ }
1055
+ }
1056
+ break;
1057
+ case UA_CPU:
1058
+ var archName = uaCH[ARCHITECTURE];
1059
+ if (archName) {
1060
+ if (archName && uaCH[BITNESS] == '64') archName += '64';
1061
+ rgxMapper.call(this.data, archName + ';', rgxMap);
1062
+ }
1063
+ break;
1064
+ case UA_DEVICE:
1065
+ if (uaCH[MOBILE]) {
1066
+ this.set(TYPE, MOBILE);
1067
+ }
1068
+ if (uaCH[MODEL]) {
1069
+ this.set(MODEL, uaCH[MODEL]);
1070
+ }
1071
+ if (uaCH[FORMFACTOR]) {
1072
+ var ff;
1073
+ if (typeof uaCH[FORMFACTOR] !== 'string') {
1074
+ var idx = 0;
1075
+ while (!ff && idx < uaCH[FORMFACTOR].length) {
1076
+ ff = strMapper(uaCH[FORMFACTOR][idx++], formFactorMap);
1077
+ }
1078
+ } else {
1079
+ ff = strMapper(uaCH[FORMFACTOR], formFactorMap);
1080
+ }
1081
+ this.set(TYPE, ff);
1082
+ }
1083
+ break;
1084
+ case UA_OS:
1085
+ var osName = uaCH[PLATFORM];
1086
+ if(osName) {
1087
+ var osVersion = uaCH[PLATFORMVER];
1088
+ if (osName == WINDOWS) osVersion = (parseInt(majorize(osVersion), 10) >= 13 ? '11' : '10');
1089
+ this.set(NAME, osName)
1090
+ .set(VERSION, osVersion);
1091
+ }
1092
+ break;
1093
+ case UA_RESULT:
1094
+ var data = this.data;
1095
+ var parse = function (itemType) {
1096
+ return data[itemType]
1097
+ .getItem()
1098
+ .setCH(uaCH)
1099
+ .parseCH()
1100
+ .get();
1101
+ };
1102
+ this.set(UA_BROWSER, parse(UA_BROWSER))
1103
+ .set(UA_CPU, parse(UA_CPU))
1104
+ .set(UA_DEVICE, parse(UA_DEVICE))
1105
+ .set(UA_ENGINE, parse(UA_ENGINE))
1106
+ .set(UA_OS, parse(UA_OS));
1107
+ }
1108
+ return this;
1109
+ };
1110
+
1111
+ setProps.call(this, [
945
1112
  ['itemType', itemType],
946
1113
  ['ua', ua],
947
1114
  ['uaCH', uaCH],
948
1115
  ['rgxMap', rgxMap],
949
- ['data', createUAParserData(itemType, ua, rgxMap, uaCH)]
1116
+ ['data', createIData(this, itemType)]
950
1117
  ]);
951
- this.parse();
952
- var isSelfNav = NAVIGATOR && NAVIGATOR.userAgent == ua;
953
- switch(this.itemType) {
954
- case UA_BROWSER:
955
- // Brave-specific detection
956
- if (isSelfNav && NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave == FUNC_TYPE) {
957
- this.set(NAME, 'Brave');
958
- }
959
- this.set(MAJOR, majorize(this.get(VERSION)));
960
- break;
961
- case UA_DEVICE:
962
- if (isSelfNav && !this.get(TYPE) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[MOBILE]) {
963
- this.set(TYPE, MOBILE);
964
- }
965
- // iPadOS-specific detection: identified as Mac, but has some iOS-only properties
966
- if (isSelfNav && this.get(MODEL) == 'Macintosh' && NAVIGATOR && typeof NAVIGATOR.standalone !== UNDEF_TYPE && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 2) {
967
- this.set(MODEL, 'iPad')
968
- .set(TYPE, TABLET);
969
- }
970
- break;
971
- case UA_OS:
972
- if (isSelfNav && !this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM]) {
973
- this.set(NAME, NAVIGATOR_UADATA[PLATFORM]);
974
- }
975
- break;
976
- case UA_RESULT:
977
- var createUAParserItem = function (itemType) {
978
- return new UAParserItem(itemType, ua, rgxMap[itemType], uaCH).get();
979
- };
980
- this.set('ua', ua)
981
- .set(UA_BROWSER, createUAParserItem(UA_BROWSER))
982
- .set(UA_CPU, createUAParserItem(UA_CPU))
983
- .set(UA_DEVICE, createUAParserItem(UA_DEVICE))
984
- .set(UA_ENGINE, createUAParserItem(UA_ENGINE))
985
- .set(UA_OS, createUAParserItem(UA_OS))
986
- .get();
987
- }
1118
+
988
1119
  return this;
989
1120
  }
990
- UAParserItem.prototype.get = function (prop) {
991
- if (!prop) return this.data;
992
- return this.data.hasOwnProperty(prop) ? this.data[prop] : undefined;
993
- };
994
- UAParserItem.prototype.parse = function () {
995
- if (this.itemType != UA_RESULT) {
996
- rgxMapper.call(this.data, this.ua, this.rgxMap);
997
- }
998
- return this;
999
- };
1000
- UAParserItem.prototype.parseCH = function () {
1001
- var ua = this.ua,
1002
- uaCH = this.uaCH,
1003
- rgxMap = this.rgxMap;
1004
-
1005
- switch (this.itemType) {
1006
- case UA_BROWSER:
1007
- var brands = uaCH[FULLVERLIST] || uaCH[BRANDS];
1008
- if (brands) {
1009
- for (var i in brands) {
1010
- var brandName = brands[i].brand,
1011
- brandVersion = brands[i].version;
1012
- if (!/not.a.brand/i.test(brandName) && (i < 1 || /chromi/i.test(this.get(NAME)))) {
1013
- this.set(NAME, strip(GOOGLE+' ', brandName))
1014
- .set(VERSION, brandVersion)
1015
- .set(MAJOR, majorize(brandVersion));
1016
- }
1017
- }
1018
- }
1019
- break;
1020
- case UA_CPU:
1021
- var archName = uaCH[ARCHITECTURE];
1022
- if (archName) {
1023
- if (archName && uaCH[BITNESS] == '64') archName += '64';
1024
- rgxMapper.call(this.data, archName + ';', rgxMap);
1025
- }
1026
- break;
1027
- case UA_DEVICE:
1028
- if (uaCH[MOBILE]) {
1029
- this.set(TYPE, MOBILE);
1030
- }
1031
- if (uaCH[MODEL]) {
1032
- this.set(MODEL, uaCH[MODEL]);
1033
- }
1034
- break;
1035
- case UA_OS:
1036
- var osName = uaCH[PLATFORM];
1037
- if(osName) {
1038
- var osVersion = uaCH[PLATFORMVER];
1039
- if (osName == WINDOWS) osVersion = (parseInt(majorize(osVersion), 10) >= 13 ? '11' : '10');
1040
- this.set(NAME, osName)
1041
- .set(VERSION, osVersion);
1042
- }
1043
- break;
1044
- case UA_RESULT:
1045
- var createUAParserItemWithCH = function (itemType) {
1046
- return new UAParserItem(itemType, ua, rgxMap[itemType], uaCH).parseCH().get();
1047
- };
1048
- this.set('ua', ua)
1049
- .set(UA_BROWSER, createUAParserItemWithCH(UA_BROWSER))
1050
- .set(UA_CPU, createUAParserItemWithCH(UA_CPU))
1051
- .set(UA_DEVICE, createUAParserItemWithCH(UA_DEVICE))
1052
- .set(UA_ENGINE, createUAParserItemWithCH(UA_ENGINE))
1053
- .set(UA_OS, createUAParserItemWithCH(UA_OS));
1054
- }
1055
- return this;
1056
- };
1057
- UAParserItem.prototype.set = function (prop, val) {
1058
- this.data[prop] = val;
1059
- return this;
1060
- };
1061
1121
 
1062
1122
  function UAParser (ua, extensions, headers) {
1063
1123
 
@@ -1081,39 +1141,54 @@ const window = undefined;
1081
1141
  return new UAParser(ua, extensions, headers).getResult();
1082
1142
  }
1083
1143
 
1084
- var userAgent = ua ||
1085
- ((NAVIGATOR && NAVIGATOR.userAgent) ?
1086
- NAVIGATOR.userAgent :
1087
- (headers && headers[USER_AGENT] ?
1088
- headers[USER_AGENT] :
1089
- EMPTY)),
1090
-
1091
- HTTP_UACH = new UAParserDataCH(headers, true),
1144
+ var userAgent = typeof ua === STR_TYPE ? ua : // Passed user-agent string
1145
+ ((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
1146
+ (headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers
1147
+ EMPTY)), // empty string
1092
1148
 
1149
+ httpUACH = new UACHData(headers, true),
1093
1150
  regexMap = extensions ?
1094
1151
  extend(defaultRegexes, extensions) :
1095
1152
  defaultRegexes,
1096
1153
 
1097
- createUAParserItemFunc = function (itemType) {
1098
- return function () {
1099
- return new UAParserItem(itemType, userAgent, itemType == UA_RESULT ? regexMap : regexMap[itemType], HTTP_UACH).get();
1100
- };
1154
+ createItemFunc = function (itemType) {
1155
+ if (itemType == UA_RESULT) {
1156
+ return function () {
1157
+ return new UAItem(itemType, userAgent, regexMap, httpUACH)
1158
+ .set('ua', userAgent)
1159
+ .set(UA_BROWSER, this.getBrowser())
1160
+ .set(UA_CPU, this.getCPU())
1161
+ .set(UA_DEVICE, this.getDevice())
1162
+ .set(UA_ENGINE, this.getEngine())
1163
+ .set(UA_OS, this.getOS())
1164
+ .get();
1165
+ };
1166
+ } else {
1167
+ return function () {
1168
+ return new UAItem(itemType, userAgent, regexMap[itemType], httpUACH)
1169
+ .parseUA()
1170
+ .get();
1171
+ };
1172
+ }
1101
1173
  };
1102
-
1174
+
1103
1175
  // public methods
1104
- assignFromEntries.call(this, [
1105
- ['getBrowser', createUAParserItemFunc(UA_BROWSER)],
1106
- ['getCPU', createUAParserItemFunc(UA_CPU)],
1107
- ['getDevice', createUAParserItemFunc(UA_DEVICE)],
1108
- ['getEngine', createUAParserItemFunc(UA_ENGINE)],
1109
- ['getOS', createUAParserItemFunc(UA_OS)],
1110
- ['getResult', createUAParserItemFunc(UA_RESULT)],
1176
+ setProps.call(this, [
1177
+ ['getBrowser', createItemFunc(UA_BROWSER)],
1178
+ ['getCPU', createItemFunc(UA_CPU)],
1179
+ ['getDevice', createItemFunc(UA_DEVICE)],
1180
+ ['getEngine', createItemFunc(UA_ENGINE)],
1181
+ ['getOS', createItemFunc(UA_OS)],
1182
+ ['getResult', createItemFunc(UA_RESULT)],
1111
1183
  ['getUA', function () { return userAgent; }],
1112
1184
  ['setUA', function (ua) {
1113
- userAgent = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua;
1185
+ if (typeof ua === STR_TYPE)
1186
+ userAgent = ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua;
1114
1187
  return this;
1115
1188
  }]
1116
- ]).setUA(userAgent);
1189
+ ])
1190
+ .setUA(userAgent);
1191
+
1117
1192
  return this;
1118
1193
  }
1119
1194