Update version to 2.0.0-beta.2

This commit is contained in:
Faisal Salman 2024-01-28 22:34:46 +07:00
parent b5b5475ab4
commit 4d950db145
18 changed files with 290 additions and 69 deletions

View File

@ -16,10 +16,54 @@
- Provided Extensions submodule `'ua-parser-js/extensions'` - Provided Extensions submodule `'ua-parser-js/extensions'`
- Provided Helpers submodule `'ua-parser-js/helpers'` - Provided Helpers submodule `'ua-parser-js/helpers'`
## Version 2.0.0-beta.2
- Increase UA_MAX_LENGTH to 500
- Add TypeScript declaration file in `ua-parser-js/extensions` submodule
- Improve TypeScript module resolution
- Add new methods in `ua-parser-js/helpers` submodule: `isAppleSilicon()` & `isChromiumBased()`
- Fix misidentified WebView token as device model
- Add new browser: Alipay, Klarna, Opera GX, Smart Lenovo Browser, Vivo Browser
- Rename browser: Avant, Baidu, Samsung Internet, Sogou Explorer, Sogou Mobile, WeChat
- Improve client-hints detection: Edge, Xbox
## Version 2.0.0-beta.1
- Update Client Hints Form-Factor
- Provide in-package type definitions
- Add new device: Ulefone
- Improve device detection: Realme, Xiaomi Redmi
## Version 2.0.0-alpha.3
- Add `withFeatureCheck()` method
- Add `isFrozenUA()` method in `ua-parser-js/helpers` submodule
- Add `MediaPlayers` & `Modules` in `ua-parser-js/extensions` submodule
- Fix issue with ESM import
## Version 2.0.0-alpha.2
- Fix browser result always returning Chromium when using withClientHints()
- Fix infinite-loop when await-ing withClientHints() in non-client-hints browser
## Version 2.0.0-alpha.1
- Initial work on new major version
# Version 0.7 / 1.0 # Version 0.7 / 1.0
Version 1.0.x is basically the equivalent of version 0.7.x. See [#536](https://github.com/faisalman/ua-parser-js/issues/536) for the reason behind this confusion. Version 1.0.x is basically the equivalent of version 0.7.x. See [#536](https://github.com/faisalman/ua-parser-js/issues/536) for the reason behind this confusion.
## Version 0.7.37
- Fix misidentified WebView token as device model
- Increase UA_MAX_LENGTH to 500
- Add new browser: Alipay, Klarna, Smart Lenovo Browser, Vivo Browser
- Add new device: Ulefone
- Improve device detection: Realme, Xiaomi Redmi
- Rename browser: Avant, Baidu, Samsung Internet, Sogou Explorer, Sogou Mobile, WeChat
## Version 0.7.36 / 1.0.36 ## Version 0.7.36 / 1.0.36
- Add new browser: Snapchat - Add new browser: Snapchat
- Add new devices: Infinix, Tecno - Add new devices: Infinix, Tecno

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "ua-parser-js", "name": "ua-parser-js",
"version": "2.0.0-beta.1", "version": "2.0.0-beta.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ua-parser-js", "name": "ua-parser-js",
"version": "2.0.0-beta.1", "version": "2.0.0-beta.2",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",

View File

@ -1,6 +1,6 @@
Package.describe({ Package.describe({
name: 'faisalman:ua-parser-js', name: 'faisalman:ua-parser-js',
version: '2.0.0-beta.1', version: '2.0.0-beta.2',
summary: 'Lightweight JavaScript-based user-agent string parser', summary: 'Lightweight JavaScript-based user-agent string parser',
git: 'https://github.com/faisalman/ua-parser-js.git', git: 'https://github.com/faisalman/ua-parser-js.git',
documentation: 'readme.md' documentation: 'readme.md'

View File

@ -1,7 +1,7 @@
{ {
"title": "UAParser.js", "title": "UAParser.js",
"name": "ua-parser-js", "name": "ua-parser-js",
"version": "2.0.0-beta.1", "version": "2.0.0-beta.2",
"author": "Faisal Salman <f@faisalman.com> (http://faisalman.com)", "author": "Faisal Salman <f@faisalman.com> (http://faisalman.com)",
"description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment",
"keywords": [ "keywords": [

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Enums for UAParser.js v2.0.0-beta.1 /* Enums for UAParser.js v2.0.0-beta.2
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */

View File

@ -3,7 +3,7 @@
// Source: /src/enums/ua-parser-enums.js // Source: /src/enums/ua-parser-enums.js
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Enums for UAParser.js v2.0.0-beta.1 /* Enums for UAParser.js v2.0.0-beta.2
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@ -12,28 +12,137 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
const Browser = Object.freeze({ const Browser = Object.freeze({
_2345_EXPLORER: '2345Explorer',
_360: '360 Browser',
ALIPAY: 'Alipay',
AMAYA: 'Amaya',
ANDROID: 'Android Browser', ANDROID: 'Android Browser',
ARORA: 'Arora',
AVANT: 'Avant',
AVAST: 'Avast Secure Browser',
AVG: 'AVG Secure Browser',
BAIDU: 'Baidu Browser',
BASILISK: 'Basilisk',
BLAZER: 'Blazer',
BOLT: 'Bolt',
BOWSER: 'Bowser',
BRAVE: 'Brave', BRAVE: 'Brave',
CAMINO: 'Camino',
CHIMERA: 'Chimera',
CHROME: 'Chrome', CHROME: 'Chrome',
CHROME_HEADLESS: 'Chrome Headless',
CHROME_MOBILE: 'Mobile Chrome',
CHROME_WEBVIEW: 'Chrome WebView',
CHROMIUM: 'Chromium', CHROMIUM: 'Chromium',
COBALT: 'Cobalt',
COC_COC: 'Coc Coc',
COMODO_DRAGON: 'Comodo Dragon',
CONKEROR: 'Conkeror',
DILLO: 'Dillo',
DOLPHIN: 'Dolphin', DOLPHIN: 'Dolphin',
DORIS: 'Doris',
DUCKDUCKGO: 'DuckDuckGo', DUCKDUCKGO: 'DuckDuckGo',
EDGE: 'Edge', EDGE: 'Edge',
EPIPHANY: 'Epiphany',
FACEBOOK: 'Facebook',
FALKON: 'Falkon',
FIREBIRD: 'Firebird',
FIREFOX: 'Firefox', FIREFOX: 'Firefox',
FOCUS: 'Focus', FIREFOX_FOCUS: 'Firefox Focus',
FIREFOX_MOBILE: 'Mobile Firefox',
FIREFOX_REALITY: 'Firefox Reality',
FENNEC: 'Fennec',
FLOCK: 'Flock',
FLOW: 'Flow',
GO: 'Go Browser',
GOOGLE_SEARCH: 'GSA',
HEYTAP: 'HeyTap',
HUAWEI: 'Huawei Browser',
ICAB: 'iCab',
ICE: 'ICE Browser',
ICEAPE: 'IceApe',
ICECAT: 'IceCat',
ICEDRAGON: 'IceDragon',
ICEWEASEL: 'IceWeasel',
IE: 'IE', IE: 'IE',
INSTAGRAM: 'Instagram',
IRIDIUM: 'Iridium',
IRON: 'Iron',
JASMINE: 'Jasmine',
KONQUEROR: 'Konqueror', KONQUEROR: 'Konqueror',
MOBILE_CHROME: 'Mobile Chrome', KAKAO: 'KakaoTalk',
MOBILE_FIREFOX: 'Mobile Firefox', KHTML: 'KHTML',
MOBILE_SAFARI: 'Mobile Safari', K_MELEON: 'K-Meleon',
KLAR: 'Klar',
KLARNA: 'Klarna',
KINDLE: 'Kindle',
LENOVO: 'Smart Lenovo Browser',
LIEBAO: 'LBBROWSER',
LINE: 'Line',
LINKEDIN: 'LinkedIn',
LINKS: 'Links',
LUNASCAPE: 'Lunascape',
LYNX: 'Lynx',
MAEMO: 'Maemo Browser',
MAXTHON: 'Maxthon',
MIDORI: 'Midori',
MINIMO: 'Minimo',
MIUI: 'MIUI Browser',
MOZILLA: 'Mozilla',
MOSAIC: 'Mosaic',
NAVER: 'Naver',
NETFRONT: 'NetFront',
NETSCAPE: 'Netscape',
NETSURF: 'Netsurf',
NOKIA: 'Nokia Browser',
OBIGO: 'Obigo',
OCULUS: 'Oculus Browser',
OMNIWEB: 'OmniWeb',
OPERA: 'Opera', OPERA: 'Opera',
OPERA_COAST: 'Opera Coast',
OPERA_MINI: 'Opera Mini',
OPERA_MOBI: 'Opera Mobi',
OPERA_TABLET: 'Opera Tablet',
OPERA_TOUCH: 'Opera Touch',
OVI: 'OviBrowser',
PALEMOON: 'PaleMoon', PALEMOON: 'PaleMoon',
PHANTOMJS: 'PhantomJS',
PHOENIX: 'Phoenix',
POLARIS: 'Polaris',
PUFFIN: 'Puffin', PUFFIN: 'Puffin',
QQ: 'QQBrowser', QQ: 'QQBrowser',
QQ_LITE: 'QQBrowserLite',
QUARK: 'Quark',
QUPZILLA: 'QupZilla',
REKONQ: 'rekonq',
ROCKMELT: 'Rockmelt',
SAFARI: 'Safari', SAFARI: 'Safari',
SAFARI_MOBILE: 'Mobile Safari',
SAILFISH: 'Sailfish Browser',
SAMSUNG: 'Samsung Internet', SAMSUNG: 'Samsung Internet',
SEAMONKEY: 'SeaMonkey',
SILK: 'Silk',
SKYFIRE: 'Skyfire',
SLEIPNIR: 'Sleipnir',
SLIMBROWSER: 'SlimBrowser',
SNAPCHAT: 'Snapchat',
SOGOU_EXPLORER: 'Sogou Explorer',
SOGOU_MOBILE: 'Sogou Mobile',
SWIFTFOX: 'Swiftfox',
TESLA: 'Tesla',
TIKTOK: 'TikTok',
TIZEN: 'Tizen Browser',
UC: 'UCBrowser', UC: 'UCBrowser',
UP: 'UP.Browser',
VIERA: 'Viera',
VIVALDI: 'Vivaldi', VIVALDI: 'Vivaldi',
VIVO: 'Vivo Browser',
W3M: 'w3m',
WATERFOX: 'Waterfox',
WEBKIT: 'WebKit',
WECHAT: 'WeChat',
WEIBO: 'Weibo',
WHALE: 'Whale',
YANDEX: 'Yandex' YANDEX: 'Yandex'
// TODO : test! // TODO : test!
@ -41,25 +150,27 @@ const Browser = Object.freeze({
const CPU = Object.freeze({ const CPU = Object.freeze({
ARM : 'arm', ARM : 'arm',
ARM64: 'arm64', ARM_64: 'arm64',
ARMHF: 'armhf', ARM_HF: 'armhf',
AVR: 'avr', AVR: 'avr',
AVR_32: 'avr32',
IA64: 'ia64', IA64: 'ia64',
IRIX: 'irix', IRIX: 'irix',
IRIX64: 'irix64', IRIX_64: 'irix64',
MIPS: 'mips', MIPS: 'mips',
MIPS64: 'mips64', MIPS_64: 'mips64',
MOTO_68K: '68k', M68K: '68k',
PA_RISC: 'pa-risc',
PPC: 'ppc', PPC: 'ppc',
SPARC: 'sparc', SPARC: 'sparc',
SPARC64: 'sparc64', SPARC_64: 'sparc64',
X86: 'ia32', X86: 'ia32',
X86_64: 'amd64' X86_64: 'amd64'
}); });
const Device = Object.freeze({ const Device = Object.freeze({
CONSOLE: 'console', CONSOLE: 'console',
DEKSTOP: 'desktop', DESKTOP: 'desktop',
EMBEDDED: 'embedded', EMBEDDED: 'embedded',
MOBILE: 'mobile', MOBILE: 'mobile',
SMARTTV: 'smarttv', SMARTTV: 'smarttv',
@ -114,6 +225,7 @@ const Vendor = Object.freeze({
SIEMENS: 'Siemens', SIEMENS: 'Siemens',
SONY: 'Sony', SONY: 'Sony',
SPRINT: 'Sprint', SPRINT: 'Sprint',
TECHNISAT: 'TechniSAT',
TECNO: 'Tecno', TECNO: 'Tecno',
TESLA: 'Tesla', TESLA: 'Tesla',
ULEFONE: 'Ulefone', ULEFONE: 'Ulefone',
@ -159,14 +271,15 @@ const OS = Object.freeze({
BLACKBERRY: 'BlackBerry', BLACKBERRY: 'BlackBerry',
CENTOS: 'CentOS', CENTOS: 'CentOS',
CHROME_OS: 'Chrome OS', CHROME_OS: 'Chrome OS',
CHROMECAST: 'Chromecast',
CONTIKI: 'Contiki', CONTIKI: 'Contiki',
FEDORA: 'Fedora',
FIREFOX_OS: 'Firefox OS',
FREEBSD: 'FreeBSD',
DEBIAN: 'Debian', DEBIAN: 'Debian',
DEEPIN: 'Deepin', DEEPIN: 'Deepin',
DRAGONFLY: 'DragonFly', DRAGONFLY: 'DragonFly',
ELEMENTARY_OS: 'elementary OS', ELEMENTARY_OS: 'elementary OS',
FEDORA: 'Fedora',
FIREFOX_OS: 'Firefox OS',
FREEBSD: 'FreeBSD',
FUCHSIA: 'Fuchsia', FUCHSIA: 'Fuchsia',
GENTOO: 'Gentoo', GENTOO: 'Gentoo',
GHOSTBSD: 'GhostBSD', GHOSTBSD: 'GhostBSD',
@ -225,6 +338,7 @@ const OS = Object.freeze({
WINDOWS: 'Windows', WINDOWS: 'Windows',
WINDOWS_MOBILE: 'Windows Mobile', WINDOWS_MOBILE: 'Windows Mobile',
WINDOWS_PHONE: 'Windows Phone', WINDOWS_PHONE: 'Windows Phone',
XBOX: 'Xbox',
ZENWALK: 'Zenwalk' ZENWALK: 'Zenwalk'
// TODO : test! // TODO : test!

View File

@ -1,4 +1,4 @@
// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.1 // Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.2
// Project: https://github.com/faisalman/ua-parser-js // Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman> // Definitions by: Faisal Salman <https://github.com/faisalman>

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Extensions for UAParser.js v2.0.0-beta.1 /* Extensions for UAParser.js v2.0.0-beta.2
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */

View File

@ -3,7 +3,7 @@
// Source: /src/extensions/ua-parser-extensions.js // Source: /src/extensions/ua-parser-extensions.js
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Extensions for UAParser.js v2.0.0-beta.1 /* Extensions for UAParser.js v2.0.0-beta.2
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */

View File

@ -1,4 +1,4 @@
// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.1 // Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.2
// Project: https://github.com/faisalman/ua-parser-js // Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman> // Definitions by: Faisal Salman <https://github.com/faisalman>

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Helpers for UAParser.js v2.0.0-beta.1 /* Helpers for UAParser.js v2.0.0-beta.2
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */

View File

@ -0,0 +1,26 @@
// Generated ESM version of ua-parser-js/helpers
// DO NOT EDIT THIS FILE!
// Source: /src/helpers/ua-parser-helpers.js
///////////////////////////////////////////////
/* Helpers for UAParser.js v2.0.0-beta.2
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */
//////////////////////////////////////////////
/*jshint esversion: 6 */
import { CPU, OS, Engine } from '../enums/ua-parser-enums';
const isAppleSilicon = (res) => res.os.is(OS.MACOS) && res.cpu.is(CPU.ARM);
const isChromiumBased = (res) => res.engine.is(Engine.BLINK);
const isFrozenUA = (ua) => /^Mozilla\/5\.0 \((Windows NT 10\.0; Win64; x64|Macintosh; Intel Mac OS X 10_15_7|X11; Linux x86_64|X11; CrOS x86_64 14541\.0\.0|Fuchsia|Linux; Android 10; K)\) AppleWebKit\/537\.36 \(KHTML, like Gecko\) Chrome\/\d+\.0\.0\.0 (Mobile )?Safari\/537\.36/.test(ua);
export {
isAppleSilicon,
isChromiumBased,
isFrozenUA
}

View File

@ -1,4 +1,4 @@
// Type definitions for UAParser.js v2.0.0-beta.1 // Type definitions for UAParser.js v2.0.0-beta.2
// Project: https://github.com/faisalman/ua-parser-js // Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman> // Definitions by: Faisal Salman <https://github.com/faisalman>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
/* UAParser.js v2.0.0-beta.1 /* UAParser.js v2.0.0-beta.2
Copyright © 2012-2023 Faisal Salman <f@faisalman.com> Copyright © 2012-2023 Faisal Salman <f@faisalman.com>
AGPLv3 License *//* AGPLv3 License *//*
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
@ -19,7 +19,7 @@
// Constants // Constants
///////////// /////////////
var LIBVERSION = '2.0.0-beta.1', var LIBVERSION = '2.0.0-beta.2',
EMPTY = '', EMPTY = '',
UNKNOWN = '?', UNKNOWN = '?',
FUNC_TYPE = 'function', FUNC_TYPE = 'function',

View File

@ -3,7 +3,7 @@
// Source: /src/main/ua-parser.js // Source: /src/main/ua-parser.js
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
/* UAParser.js v2.0.0-beta.1 /* UAParser.js v2.0.0-beta.2
Copyright © 2012-2023 Faisal Salman <f@faisalman.com> Copyright © 2012-2023 Faisal Salman <f@faisalman.com>
AGPLv3 License *//* AGPLv3 License *//*
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
@ -21,8 +21,7 @@
// Constants // Constants
///////////// /////////////
var LIBVERSION = '2.0.0-beta.2',
var LIBVERSION = '2.0.0-beta.1',
EMPTY = '', EMPTY = '',
UNKNOWN = '?', UNKNOWN = '?',
FUNC_TYPE = 'function', FUNC_TYPE = 'function',
@ -43,7 +42,7 @@
WEARABLE = 'wearable', WEARABLE = 'wearable',
EMBEDDED = 'embedded', EMBEDDED = 'embedded',
USER_AGENT = 'user-agent', USER_AGENT = 'user-agent',
UA_MAX_LENGTH = 350, UA_MAX_LENGTH = 500,
BRANDS = 'brands', BRANDS = 'brands',
FORMFACTOR = 'formFactor', FORMFACTOR = 'formFactor',
FULLVERLIST = 'fullVersionList', FULLVERLIST = 'fullVersionList',
@ -72,6 +71,7 @@
BLACKBERRY = 'BlackBerry', BLACKBERRY = 'BlackBerry',
GOOGLE = 'Google', GOOGLE = 'Google',
HUAWEI = 'Huawei', HUAWEI = 'Huawei',
LENOVO = 'Lenovo',
LG = 'LG', LG = 'LG',
MICROSOFT = 'Microsoft', MICROSOFT = 'Microsoft',
MOTOROLA = 'Motorola', MOTOROLA = 'Motorola',
@ -87,9 +87,11 @@
FIREFOX = 'Firefox', FIREFOX = 'Firefox',
OPERA = 'Opera', OPERA = 'Opera',
FACEBOOK = 'Facebook', FACEBOOK = 'Facebook',
SOGOU = 'Sogou',
WINDOWS = 'Windows'; WINDOWS = 'Windows';
var NAVIGATOR = (typeof window !== UNDEF_TYPE && window.navigator) ? var isWindow = typeof window !== UNDEF_TYPE,
NAVIGATOR = (isWindow && window.navigator) ?
window.navigator : window.navigator :
undefined, undefined,
NAVIGATOR_UADATA = (NAVIGATOR && NAVIGATOR.userAgentData) ? NAVIGATOR_UADATA = (NAVIGATOR && NAVIGATOR.userAgentData) ?
@ -121,13 +123,16 @@
} }
return false; return false;
} }
return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false; return isString(str1) ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
}, },
isExtensions = function (obj) { isExtensions = function (obj) {
for (var prop in obj) { for (var prop in obj) {
return /^(browser|cpu|device|engine|os)$/.test(prop); return /^(browser|cpu|device|engine|os)$/.test(prop);
} }
}, },
isString = function (val) {
return typeof val === STR_TYPE;
},
itemListToArray = function (header) { itemListToArray = function (header) {
if (!header) return undefined; if (!header) return undefined;
var arr = []; var arr = [];
@ -137,16 +142,16 @@
var token = trim(tokens[i]).split(';v='); var token = trim(tokens[i]).split(';v=');
arr[i] = { brand : token[0], version : token[1] }; arr[i] = { brand : token[0], version : token[1] };
} else { } else {
arr[i] = tokens[i]; arr[i] = trim(tokens[i]);
} }
} }
return arr; return arr;
}, },
lowerize = function (str) { lowerize = function (str) {
return typeof(str) === STR_TYPE ? str.toLowerCase() : str; return isString(str) ? str.toLowerCase() : str;
}, },
majorize = function (version) { majorize = function (version) {
return typeof(version) === STR_TYPE ? strip(/[^\d\.]/g, version).split('.')[0] : undefined; return isString(version) ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
}, },
setProps = function (arr) { setProps = function (arr) {
for (var i in arr) { for (var i in arr) {
@ -160,15 +165,15 @@
return this; return this;
}, },
strip = function (pattern, str) { strip = function (pattern, str) {
return str.replace(pattern, EMPTY); return isString(str) ? str.replace(pattern, EMPTY) : str;
}, },
stripQuotes = function (val) { stripQuotes = function (str) {
return typeof val === STR_TYPE ? strip(/\\?\"/g, val) : val; return strip(/\\?\"/g, str);
}, },
trim = function (str, len) { trim = function (str, len) {
if (typeof(str) === STR_TYPE) { if (isString(str)) {
str = strip(/^\s\s*/, str); str = strip(/^\s\s*/, str);
return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
} }
}; };
@ -297,15 +302,18 @@
], [NAME, VERSION], [ ], [NAME, VERSION], [
/opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0 /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0
], [VERSION, [NAME, OPERA+' Mini']], [ ], [VERSION, [NAME, OPERA+' Mini']], [
/\bop(?:rg)?x\/([\w\.]+)/i // Opera GX
], [VERSION, [NAME, OPERA+' GX']], [
/\bopr\/([\w\.]+)/i // Opera Webkit /\bopr\/([\w\.]+)/i // Opera Webkit
], [VERSION, [NAME, OPERA]], [ ], [VERSION, [NAME, OPERA]], [
// Mixed // Mixed
/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
], [VERSION, [NAME, 'Baidu']], [
/(kindle)\/([\w\.]+)/i, // Kindle /(kindle)\/([\w\.]+)/i, // Kindle
/(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer
// Trident based // Trident based
/(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser /(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
/(ba?idubrowser)[\/ ]?([\w\.]+)/i, // Baidu Browser
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
@ -317,8 +325,7 @@
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
], [VERSION, [NAME, 'UCBrowser']], [ ], [VERSION, [NAME, 'UCBrowser']], [
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser /microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
/\bqbcore\/([\w\.]+).+microm/i /\bqbcore\/([\w\.]+).+microm/i,
], [VERSION, [NAME, 'WeChat(Win) Desktop']], [
/micromessenger\/([\w\.]+)/i // WeChat /micromessenger\/([\w\.]+)/i // WeChat
], [VERSION, [NAME, 'WeChat']], [ ], [VERSION, [NAME, 'WeChat']], [
/konqueror\/([\w\.]+)/i // Konqueror /konqueror\/([\w\.]+)/i // Konqueror
@ -327,6 +334,8 @@
], [VERSION, [NAME, 'IE']], [ ], [VERSION, [NAME, 'IE']], [
/ya(?:search)?browser\/([\w\.]+)/i // Yandex /ya(?:search)?browser\/([\w\.]+)/i // Yandex
], [VERSION, [NAME, 'Yandex']], [ ], [VERSION, [NAME, 'Yandex']], [
/slbrowser\/([\w\.]+)/i // Smart Lenovo Browser
], [VERSION, [NAME, 'Smart ' + LENOVO + SUFFIX_BROWSER]], [
/(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [ ], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [
/\bfocus\/([\w\.]+)/i // Firefox Focus /\bfocus\/([\w\.]+)/i // Firefox Focus
@ -345,15 +354,20 @@
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [ ], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
/\bqihu|(qi?ho?o?|360)browser/i // 360 /\bqihu|(qi?ho?o?|360)browser/i // 360
], [[NAME, '360' + SUFFIX_BROWSER]], [ ], [[NAME, '360' + SUFFIX_BROWSER]], [
/(oculus|samsung|sailfish|huawei)browser\/([\w\.]+)/i /(oculus|sailfish|huawei|vivo)browser\/([\w\.]+)/i
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Samsung/Sailfish/Huawei Browser ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser
/samsungbrowser\/([\w\.]+)/i // Samsung Internet
], [VERSION, [NAME, SAMSUNG + ' Internet']], [
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
], [[NAME, /_/g, ' '], VERSION], [ ], [[NAME, /_/g, ' '], VERSION], [
/metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
], [VERSION, [NAME, SOGOU + ' Explorer']], [
/(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
], [[NAME, SOGOU + ' Mobile'], VERSION], [
/(electron)\/([\w\.]+) safari/i, // Electron-based App /(electron)\/([\w\.]+) safari/i, // Electron-based App
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
/m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser /m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
], [NAME, VERSION], [ ], [NAME, VERSION], [
/(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser
/(lbbrowser)/i, // LieBao Browser /(lbbrowser)/i, // LieBao Browser
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
], [NAME], [ ], [NAME], [
@ -361,10 +375,12 @@
// WebView // WebView
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
], [[NAME, FACEBOOK], VERSION], [ ], [[NAME, FACEBOOK], VERSION], [
/(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
/safari (line)\/([\w\.]+)/i, // Line App for iOS /safari (line)\/([\w\.]+)/i, // Line App for iOS
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
/(alipay)client\/([\w\.]+)/i, // Alipay
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat /(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
], [NAME, VERSION], [ ], [NAME, VERSION], [
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
@ -496,7 +512,7 @@
/\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|\))/i, // Xiaomi Redmi 'numeric' models /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
/oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
@ -536,7 +552,7 @@
// Lenovo // Lenovo
/(ideatab[-\w ]+)/i, /(ideatab[-\w ]+)/i,
/lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ ], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [
// Nokia // Nokia
/(?:maemo|nokia).*(n900|lumia \d+)/i, /(?:maemo|nokia).*(n900|lumia \d+)/i,
@ -710,7 +726,7 @@
// MIXED (GENERIC) // MIXED (GENERIC)
/////////////////// ///////////////////
/droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors
], [MODEL, [TYPE, MOBILE]], [ ], [MODEL, [TYPE, MOBILE]], [
/droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors
], [MODEL, [TYPE, TABLET]], [ ], [MODEL, [TYPE, TABLET]], [
@ -747,12 +763,12 @@
// Windows // Windows
/microsoft (windows) (vista|xp)/i // Windows (iTunes) /microsoft (windows) (vista|xp)/i // Windows (iTunes)
], [NAME, VERSION], [ ], [NAME, VERSION], [
/(windows) nt 6\.2; (arm)/i, // Windows RT /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i // Windows Phone
/(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, // Windows Phone
/(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i
], [NAME, [VERSION, strMapper, windowsVersionMap]], [ ], [NAME, [VERSION, strMapper, windowsVersionMap]], [
/(win(?=3|9|n)|win 9x )([nt\d\.]+)/i /windows nt 6\.2; (arm)/i, // Windows RT
], [[NAME, WINDOWS], [VERSION, strMapper, windowsVersionMap]], [ /windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i,
/(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i
], [[VERSION, strMapper, windowsVersionMap], [NAME, WINDOWS]], [
// iOS/macOS // iOS/macOS
/ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
@ -1041,15 +1057,16 @@
switch (this.itemType) { switch (this.itemType) {
case UA_BROWSER: case UA_BROWSER:
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS]; var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName;
if (brands) { if (brands) {
for (var i in brands) { for (var i in brands) {
var brandName = brands[i].brand, var brandName = strip(/(Google|Microsoft) /, brands[i].brand || brands[i]),
brandVersion = brands[i].version; brandVersion = brands[i].version;
if (!/not.a.brand/i.test(brandName) && (i < 1 || /chromi/i.test(this.get(NAME)))) { if (!/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && !/chromi/i.test(brandName)))) {
this.set(NAME, strip(GOOGLE+' ', brandName)) this.set(NAME, brandName)
.set(VERSION, brandVersion) .set(VERSION, brandVersion)
.set(MAJOR, majorize(brandVersion)); .set(MAJOR, majorize(brandVersion));
prevName = brandName;
} }
} }
} }
@ -1068,6 +1085,11 @@
if (uaCH[MODEL]) { if (uaCH[MODEL]) {
this.set(MODEL, uaCH[MODEL]); this.set(MODEL, uaCH[MODEL]);
} }
// Xbox-Specific Detection
if (uaCH[MODEL] == 'Xbox') {
this.set(TYPE, CONSOLE)
.set(VENDOR, MICROSOFT);
}
if (uaCH[FORMFACTOR]) { if (uaCH[FORMFACTOR]) {
var ff; var ff;
if (typeof uaCH[FORMFACTOR] !== 'string') { if (typeof uaCH[FORMFACTOR] !== 'string') {
@ -1089,6 +1111,11 @@
this.set(NAME, osName) this.set(NAME, osName)
.set(VERSION, osVersion); .set(VERSION, osVersion);
} }
// Xbox-Specific Detection
if (this.get(NAME) == WINDOWS && uaCH[MODEL] == 'Xbox') {
this.set(NAME, 'Xbox')
.set(VERSION, undefined);
}
break; break;
case UA_RESULT: case UA_RESULT:
var data = this.data; var data = this.data;
@ -1182,7 +1209,7 @@
['getResult', createItemFunc(UA_RESULT)], ['getResult', createItemFunc(UA_RESULT)],
['getUA', function () { return userAgent; }], ['getUA', function () { return userAgent; }],
['setUA', function (ua) { ['setUA', function (ua) {
if (typeof ua === STR_TYPE) if (isString(ua))
userAgent = ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua; userAgent = ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua;
return this; return this;
}] }]

View File

@ -1308,6 +1308,16 @@
"major" : "4" "major" : "4"
} }
}, },
{
"desc" : "Samsung Internet in Redmi 8A",
"ua" : "Mozilla/5.0 (Linux; Android 10; Redmi 8A) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36",
"expect" :
{
"name" : "Samsung Internet",
"version" : "23.0",
"major" : "23"
}
},
{ {
"desc" : "SeaMonkey", "desc" : "SeaMonkey",
"ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b4pre) Gecko/20090405 SeaMonkey/2.0b1pre", "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b4pre) Gecko/20090405 SeaMonkey/2.0b1pre",