From cd3ba72b2fe8b72555eac12ff8fea9ad8df1d840 Mon Sep 17 00:00:00 2001 From: Deliaz Date: Mon, 18 Mar 2019 13:17:44 +0700 Subject: [PATCH 001/121] Add Coc Coc browser detection --- src/ua-parser.js | 3 +++ test/browser-test.json | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index d982c4e..42ccf74 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -334,6 +334,9 @@ /android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)*/i // Android Browser ], [VERSION, [NAME, 'Android Browser']], [ + /(coc_coc_browser)\/([\w\.]+)/i // Coc Coc Browser + ], [[NAME, 'Coc Coc'], VERSION], [ + /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [NAME, VERSION], [ diff --git a/test/browser-test.json b/test/browser-test.json index b98db59..954d234 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -199,6 +199,16 @@ "major" : "16" } }, + { + "desc" : "Coc Coc Browser", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) coc_coc_browser/78.0.129 Chrome/72.0.3626.129 Safari/537.36", + "expect" : + { + "name" : "Coc Coc", + "version" : "78.0.129", + "major" : "78" + } + }, { "desc" : "Dillo", "ua" : "Dillo/2.2", From ac123a98de991640e6bc48c6cb49c57eead925ff Mon Sep 17 00:00:00 2001 From: Chad Killingsworth Date: Wed, 4 Dec 2019 07:06:32 -0600 Subject: [PATCH 002/121] Add detection for newer Pixel devices --- src/ua-parser.js | 2 +- test/device-test.json | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index de0579c..713424a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -566,7 +566,7 @@ /android.+;\s(pixel c)[\s)]/i // Google Pixel C ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [ - /android.+;\s(pixel( [23])?( xl)?)[\s)]/i // Google Pixel + /android.+;\s(pixel( [2-9]a?)?( xl)?)[\s)]/i // Google Pixel ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [ /android.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models diff --git a/test/device-test.json b/test/device-test.json index 6074665..edb2d13 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -737,6 +737,42 @@ "type": "mobile" } }, + { + "desc": "Google Pixel 3a", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 3a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3a", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 3a XL", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 3a XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3a XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 4", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 4", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 4 XL", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 4 XL", + "type": "mobile" + } + }, { "desc": "Generic Android Device", "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", From fc08e23f54addee24df1a97eaf687c44ea639c74 Mon Sep 17 00:00:00 2001 From: Tony Tomarchio Date: Tue, 12 Nov 2019 09:36:45 -0800 Subject: [PATCH 003/121] Detect Huawei Mate 20 Pro --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index d284b26..ec6d785 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -490,7 +490,7 @@ ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ /d\/huawei([\w\s-]+)[;\)]/i, - /(nexus\s6p|vog-l29|ane-lx1|eml-l29)/i // Huawei + /(nexus\s6p|vog-l29|ane-lx1|eml-l29|lya-l09)/i // Huawei ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ /android.+(bah2?-a?[lw]\d{2})/i // Huawei MediaPad diff --git a/test/device-test.json b/test/device-test.json index 35d25f5..9d3517e 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1132,5 +1132,14 @@ "model": "EML-L29", "type": "mobile" } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L09", + "type": "mobile" + } } ] From feafa4d0278e1f243cdc94eb5c20a06b5dee4c0d Mon Sep 17 00:00:00 2001 From: Tony Tomarchio Date: Tue, 12 Nov 2019 09:44:12 -0800 Subject: [PATCH 004/121] Detect Huawei P20 Pro --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index ec6d785..75f9eed 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -490,7 +490,7 @@ ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ /d\/huawei([\w\s-]+)[;\)]/i, - /(nexus\s6p|vog-l29|ane-lx1|eml-l29|lya-l09)/i // Huawei + /(nexus\s6p|vog-l29|ane-lx1|eml-l29|lya-l09|clt-l29)/i // Huawei ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ /android.+(bah2?-a?[lw]\d{2})/i // Huawei MediaPad diff --git a/test/device-test.json b/test/device-test.json index 9d3517e..75ae433 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1133,6 +1133,15 @@ "type": "mobile" } }, + { + "desc": "Huawei P20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; CLT-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "CLT-L29", + "type": "mobile" + } + }, { "desc": "Huawei Mate 20 Pro", "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", From b45bd07bab830415b403e4755c8e0f1bd8234883 Mon Sep 17 00:00:00 2001 From: Tony Tomarchio Date: Wed, 4 Dec 2019 16:23:01 -0800 Subject: [PATCH 005/121] Add additional model numbers for Huawei Mate 20 Pro --- src/ua-parser.js | 2 +- test/device-test.json | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 75f9eed..56df865 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -490,7 +490,7 @@ ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ /d\/huawei([\w\s-]+)[;\)]/i, - /(nexus\s6p|vog-l29|ane-lx1|eml-l29|lya-l09|clt-l29)/i // Huawei + /(nexus\s6p|vog-l29|ane-lx1|eml-l29|lya-l09|clt-l29|lya-al00|lya-al10|lya-l0c|lya-l29|lya-tl00)/i // Huawei ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ /android.+(bah2?-a?[lw]\d{2})/i // Huawei MediaPad diff --git a/test/device-test.json b/test/device-test.json index 75ae433..a0bf104 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1150,5 +1150,50 @@ "model": "LYA-L09", "type": "mobile" } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-AL00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-AL10", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L0C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L0C", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-TL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-TL00", + "type": "mobile" + } } ] From a8eac11d823cb1011db91d6dff9da639db654583 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 21 Dec 2019 05:49:32 +0700 Subject: [PATCH 006/121] Simplify Huawei regex --- src/ua-parser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 3a55077..0717e67 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -489,8 +489,8 @@ /(nexus\s9)/i // HTC Nexus 9 ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ - /d\/huawei([\w\s-]+)[;\)]/i, - /(nexus\s6p|vog-l29|ane-lx1|eml-l29|lya-l09|clt-l29|lya-al00|lya-al10|lya-l0c|lya-l29|lya-tl00)/i // Huawei + /d\/huawei([\w\s-]+)[;\)]/i, // Huawei + /android.+\s(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?)/i ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ /android.+(bah2?-a?[lw]\d{2})/i // Huawei MediaPad From 74c973b0d82737813bd9f764ba52be4a52566256 Mon Sep 17 00:00:00 2001 From: insanehong Date: Tue, 7 Jan 2020 17:16:32 +0900 Subject: [PATCH 007/121] Add new browser Whale@Naver Corp. - https://whale.naver.com --- package.json | 3 ++- readme.md | 46 +++++++++++++++++++++--------------------- src/ua-parser.js | 7 +++++-- test/browser-test.json | 12 ++++++++++- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index ac5dac4..3d59ebc 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,8 @@ "Sylvain Gizard ", "szchenghuang ", "Vadim Kurachevsky ", - "Yun Young-jin " + "Yun Young-jin ", + "Insanehong " ], "main": "src/ua-parser.js", "scripts": { diff --git a/readme.md b/readme.md index 5f29a0d..56214fa 100644 --- a/readme.md +++ b/readme.md @@ -27,26 +27,26 @@ ```sh # Possible 'browser.name': -2345Explorer, 360 Browser, Amaya, Android Browser, Arora, Avant, Avast, AVG, -BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, -Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, -Dolphin, Doris, Edge, Epiphany, Facebook, Falkon, Fennec, Firebird, Firefox, -Flock, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, -Iceape, Iceweasel, Iridium, Iron, Jasmine, K-Meleon, Kindle, Konqueror, -LBBROWSER Line, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, -Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, Mozilla, NetFront, -NetSurf, Netfront, Netscape, NokiaBrowser, Oculus Browser, OmniWeb, -Opera Coast, Opera Mini, Opera Mobi, Opera Tablet, Opera, PaleMoon, PhantomJS, -Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, -RockMelt, Safari, Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, -Sleipnir, Slim, SlimBrowser, Swiftfox, Tizen Browser, UCBrowser, Vivaldi, -Waterfox, WeChat, Yandex, baidu, iCab, w3m, ... +2345Explorer, 360 Browser, Amaya, Android Browser, Arora, Avant, Avast, AVG, +BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, +Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, +Dolphin, Doris, Edge, Epiphany, Facebook, Falkon, Fennec, Firebird, Firefox, +Flock, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, +Iceape, Iceweasel, Iridium, Iron, Jasmine, K-Meleon, Kindle, Konqueror, +LBBROWSER Line, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, +Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, Mozilla, NetFront, +NetSurf, Netfront, Netscape, NokiaBrowser, Oculus Browser, OmniWeb, +Opera Coast, Opera Mini, Opera Mobi, Opera Tablet, Opera, PaleMoon, PhantomJS, +Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, +RockMelt, Safari, Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, +Sleipnir, Slim, SlimBrowser, Swiftfox, Tizen Browser, UCBrowser, Vivaldi, +Waterfox, WeChat, Yandex, baidu, iCab, w3m, Whale Browser... # 'browser.version' determined dynamically ``` * `getDevice()` - * returns `{ model: '', type: '', vendor: '' }` + * returns `{ model: '', type: '', vendor: '' }` ```sh # Possible 'device.type': @@ -66,7 +66,7 @@ RIM, Samsung, Sharp, Siemens, Sony[Ericsson], Sprint, Xbox, Xiaomi, ZTE, ... ```sh # Possible 'engine.name' -Amaya, Blink, EdgeHTML, Gecko, Goanna, iCab, KHTML, Links, Lynx, NetFront, +Amaya, Blink, EdgeHTML, Gecko, Goanna, iCab, KHTML, Links, Lynx, NetFront, NetSurf, Presto, Tasman, Trident, w3m, WebKit # 'engine.version' determined dynamically @@ -77,12 +77,12 @@ NetSurf, Presto, Tasman, Trident, w3m, WebKit ```sh # Possible 'os.name' -AIX, Amiga OS, Android, Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, -Contiki, Fedora, Firefox OS, FreeBSD, Debian, DragonFly, Fuchsia, Gentoo, GNU, -Haiku, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Mageia, Mandriva, MeeGo, -Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, -PCLinuxOS, Plan9, Playstation, QNX, RedHat, RIM Tablet OS, RISC OS, Sailfish, -Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, Unix, VectorLinux, +AIX, Amiga OS, Android, Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, +Contiki, Fedora, Firefox OS, FreeBSD, Debian, DragonFly, Fuchsia, Gentoo, GNU, +Haiku, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Mageia, Mandriva, MeeGo, +Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, +PCLinuxOS, Plan9, Playstation, QNX, RedHat, RIM Tablet OS, RISC OS, Sailfish, +Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, Unix, VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... # 'os.version' determined dynamically @@ -245,7 +245,7 @@ $ npm install --save @types/ua-parser-js ## Using jQuery/Zepto ($.ua) -Although written in vanilla js (which means it doesn't depends on jQuery), this library will automatically detect if jQuery/Zepto is present and create `$.ua` object based on browser's user-agent (although in case you need, `window.UAParser` constructor is still present). To get/set user-agent you can use: `$.ua.get()` / `$.ua.set(uastring)`. +Although written in vanilla js (which means it doesn't depends on jQuery), this library will automatically detect if jQuery/Zepto is present and create `$.ua` object based on browser's user-agent (although in case you need, `window.UAParser` constructor is still present). To get/set user-agent you can use: `$.ua.get()` / `$.ua.set(uastring)`. ```js // In browser with default user-agent: 'Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0': diff --git a/src/ua-parser.js b/src/ua-parser.js index 0717e67..88765b2 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -291,6 +291,9 @@ /(brave)\/([\w\.]+)/i // Brave browser ], [[NAME, 'Brave'], VERSION], [ + /(whale)\/([\w\.]+)/i // Whale browser + ], [[NAME, 'Whale'], VERSION], [ + /(qqbrowserlite)\/([\w\.]+)/i // QQBrowserLite ], [NAME, VERSION], [ @@ -583,7 +586,7 @@ /android.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i, // Xiaomi Hongmi - /android.+(mi[\s\-_]*(?:a\d|one|one[\s_]plus|note lte)?[\s_]*(?:\d?\w?)[\s_]*(?:plus)?)\s+build/i, + /android.+(mi[\s\-_]*(?:a\d|one|one[\s_]plus|note lte)?[\s_]*(?:\d?\w?)[\s_]*(?:plus)?)\s+build/i, // Xiaomi Mi /android.+(redmi[\s\-_]*(?:note)?(?:[\s_]*[\w\s]+))\s+build/i // Redmi Phones ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ @@ -685,7 +688,7 @@ ], [VERSION, [NAME, 'Blink']], [ /(presto)\/([\w\.]+)/i, // Presto - /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, + /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna /(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i, // KHTML/Tasman/Links /(icab)[\/\s]([23]\.[\d\.]+)/i // iCab diff --git a/test/browser-test.json b/test/browser-test.json index 9544a47..d60a50d 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1200,7 +1200,7 @@ "expect" : { "name" : "BIDUBrowser", - "version" : "8.7", + "version" : "8.7", "major" : "8" } }, @@ -1233,5 +1233,15 @@ "version" : "4.5.16", "major" : "4" } + }, + { + "desc" : "Whale Browser", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.146 Whale/2.6.90.14 Safari/537.36", + "expect" : + { + "name" : "Whale", + "version" : "2.6.90.14", + "major" : "2" + } } ] From 726a458c84937e07ddea0e3b889afc9b042eaf34 Mon Sep 17 00:00:00 2001 From: Masahiko Sato Date: Fri, 17 Jan 2020 15:42:02 +0900 Subject: [PATCH 008/121] Try to detect Android device models from unidentified vendors. --- src/ua-parser.js | 8 ++++++++ test/device-test.json | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 88765b2..920a1ee 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -668,6 +668,14 @@ /android.+(Gigaset)[\s\-]+(Q\w{1,9})\s+build/i // Gigaset Tablets ], [VENDOR, MODEL, [TYPE, TABLET]], [ + // Android Phones from Unidentified Vendors + /android .+?;\s([^;]+?)(?:\sbuild.+?)?\) applewebkit.+?\smobile\ssafari/i + ], [MODEL, [TYPE, MOBILE]], [ + + // Android Tablets from Unidentified Vendors + /android .+?;\s([^;]+?)(?:\sbuild.+?)?\) applewebkit.+?(?!\smobile)\ssafari/i + ], [MODEL, [TYPE, TABLET]], [ + /\s(tablet|tab)[;\/]/i, // Unidentifiable Tablet /\s(mobile)(?:[;\/]|\ssafari)/i // Unidentifiable Mobile ], [[TYPE, util.lowerize], VENDOR, MODEL], [ diff --git a/test/device-test.json b/test/device-test.json index a0bf104..0ee8440 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -794,12 +794,44 @@ }, { "desc": "Generic Android Device", - "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K)", "expect": { "vendor": "Generic", "model": "Android 6.0.1" } }, + { + "desc": "Android Phone Unidentified Vendor (docomo F-04K)", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; F-04K Build/V15R060P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", + "expect": { + "model": "F-04K", + "type": "mobile" + } + }, + { + "desc": "Android Phone Unidentified Vendor (docomo SH-02M)", + "ua": "Mozilla/5.0 (Linux; Android 9; SH-02M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "model": "SH-02M", + "type": "mobile" + } + }, + { + "desc": "Android Tablet Unidentified Vendor (docomo F-02K)", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; F-02K Build/V44R059G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Safari/537.36", + "expect": { + "model": "F-02K", + "type": "tablet" + } + }, + { + "desc": "Android Tablet Unidentified Vendor (docomo d-02K)", + "ua": "Mozilla/5.0 (Linux; Android 9; d-02K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Safari/537.36", + "expect": { + "model": "d-02K", + "type": "tablet" + } + }, { "desc": "LG VK Series Tablet", "ua": "Mozilla/5.0 (Linux; Android 5.0.2; VK700 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.84 Safari/537.36", From 7568f0a6f53b0bb8b042a2503da47e2dc06303e5 Mon Sep 17 00:00:00 2001 From: Masahiko Sato Date: Mon, 20 Jan 2020 17:15:57 +0900 Subject: [PATCH 009/121] Updated the regexp patterns to be simpler/safer. --- src/ua-parser.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 920a1ee..a9e6c53 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -667,13 +667,11 @@ /android.+(Gigaset)[\s\-]+(Q\w{1,9})\s+build/i // Gigaset Tablets ], [VENDOR, MODEL, [TYPE, TABLET]], [ - // Android Phones from Unidentified Vendors - /android .+?;\s([^;]+?)(?:\sbuild.+?)?\) applewebkit.+?\smobile\ssafari/i + /android .+?; ([^;]+?)(?: build|\) applewebkit).+? mobile safari/i ], [MODEL, [TYPE, MOBILE]], [ - // Android Tablets from Unidentified Vendors - /android .+?;\s([^;]+?)(?:\sbuild.+?)?\) applewebkit.+?(?!\smobile)\ssafari/i + /android .+?;\s([^;]+?)(?: build|\) applewebkit).+?(?! mobile) safari/i ], [MODEL, [TYPE, TABLET]], [ /\s(tablet|tab)[;\/]/i, // Unidentifiable Tablet From bd6dee4a08070815d55b2c867a16b0172df78b9d Mon Sep 17 00:00:00 2001 From: patrick-nurt Date: Sun, 17 May 2020 08:17:30 +0400 Subject: [PATCH 010/121] Update ua-parser.js --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 1a57e88..d89312c 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -490,7 +490,7 @@ ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ /d\/huawei([\w\s-]+)[;\)]/i, - /(nexus\s6p|vog-l29|ane-lx1|eml-l29)/i // Huawei + /(nexus\s6p|vog-l29|ane-lx1|eml-l29|ele-l29)/i // Huawei ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ /android.+(bah2?-a?[lw]\d{2})/i // Huawei MediaPad From cc11bc6a2c828c0ca4f3566761ea3e0646e114ef Mon Sep 17 00:00:00 2001 From: patrick-nurt Date: Sun, 17 May 2020 08:20:27 +0400 Subject: [PATCH 011/121] Update device-test.json --- test/device-test.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/device-test.json b/test/device-test.json index 61e9755..3add728 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1096,5 +1096,14 @@ "model": "EML-L29", "type": "mobile" } - } + }, + { + "desc": "Huawei P30", + "ua": "Mozilla/5.0 (Linux; Android 9; ELE-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "ELE-L29", + "type": "mobile" + } + } ] From 4ca311224fa3128f92e8be5ee79a6fb98e1c3d3e Mon Sep 17 00:00:00 2001 From: nionata Date: Wed, 3 Jun 2020 18:10:56 -0400 Subject: [PATCH 012/121] catch facebook in-app browsers that do not contain versions --- src/ua-parser.js | 5 ++++- test/browser-test.json | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index d89312c..516afe0 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -315,8 +315,11 @@ /xiaomi\/miuibrowser\/([\w\.]+)/i // MIUI Browser ], [VERSION, [NAME, 'MIUI Browser']], [ - /;fbav\/([\w\.]+);/i // Facebook App for iOS & Android + /;fbav\/([\w\.]+);/i // Facebook App for iOS & Android with version ], [VERSION, [NAME, 'Facebook']], [ + + /FBAN\/FBIOS|FB_IAB\/FB4A/i // Facebook App for iOS & Android without version + ], [[NAME, 'Facebook']], [ /safari\s(line)\/([\w\.]+)/i, // Line App for iOS /android.+(line)\/([\w\.]+)\/iab/i // Line App for Android diff --git a/test/browser-test.json b/test/browser-test.json index 9544a47..fb0c5be 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -310,7 +310,7 @@ } }, { - "desc" : "Facebook in-App Browser for Android", + "desc" : "Facebook in-App Browser for Android with version", "ua" : "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.121 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/35.0.0.48.273;]", "expect" : { @@ -320,7 +320,7 @@ } }, { - "desc" : "Facebook in-App Browser for iOS", + "desc" : "Facebook in-App Browser for iOS with version", "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E304 [FBAN/FBIOS;FBAV/91.0.0.41.73;FBBV/57050710;FBDV/iPhone8,1;FBMD/iPhone;FBSN/iOS;FBSV/10.3.1;FBSS/2;FBCR/Telekom.de;FBID/phone;FBLC/de_DE;FBOP/5;FBRV/0])", "expect" : { @@ -329,6 +329,16 @@ "major" : "91" } }, + { + "desc" : "Facebook in-App Browser for iOS without version", + "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone10,2;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect" : + { + "name" : "Facebook", + "version" : "undefined", + "major" : "undefined" + } + }, { "desc" : "Falkon", "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Falkon/3.0.0 Chrome/61.0.3163.140 Safari/537.36", From 8196cb1c43b96e476971ddca54f0d3d02fe3086e Mon Sep 17 00:00:00 2001 From: Ulrich Schmidt Date: Tue, 21 Jul 2020 14:18:50 +0200 Subject: [PATCH 013/121] detect SM-P610 / Samsung Galaxy Tab S6 Lite as tablet --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index a9e6c53..2e29ca2 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -525,7 +525,7 @@ /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ - /android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i, + /android.+((sch-i[89]0\d|shw-m380s|SM-P610|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i, /((SM-T\w+))/i ], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung /smart-tv.+(samsung)/i diff --git a/test/device-test.json b/test/device-test.json index 0ee8440..5d8222b 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -351,6 +351,15 @@ "type": "tablet" } }, + { + "desc": "Samsung Galaxy Tab 6 Lite", + "ua": "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-P610) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/12.0 Chrome/79.0.3945.136 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-P610", + "type": "tablet" + } + }, { "desc": "Samsung SM-T700", "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T700 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", From a8972c7d703fe2228628e1044c09c0818e3c4ab6 Mon Sep 17 00:00:00 2001 From: "roman.savarin" Date: Fri, 31 Jul 2020 17:04:50 +0300 Subject: [PATCH 014/121] Detect Samsung Note 10.1 as a tablet --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index a9e6c53..5d5377f 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -525,7 +525,7 @@ /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ - /android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i, + /android.+((sch-i[89]0\d|shw-m380s|SM-P605|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i, /((SM-T\w+))/i ], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung /smart-tv.+(samsung)/i diff --git a/test/device-test.json b/test/device-test.json index 0ee8440..ba355cc 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -378,6 +378,15 @@ "type": "smarttv" } }, + { + "desc": "Samsung Note 10.1", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SM-P605) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-P605", + "type": "tablet" + } + }, { "desc": "Samsung SmartTV2012", "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2012;;;) WebKit", From 20ceaf9000bdc2d641ca1ff2933ee20c851bebef Mon Sep 17 00:00:00 2001 From: Joey Parrish Date: Wed, 12 Aug 2020 11:00:50 -0700 Subject: [PATCH 015/121] Extract Chromecast firmware version Rather than put the CPU type as the OS version, for Chromecast, the firmware version would be much more useful. For example: Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.81 Safari/537.36 CrKey/1.42.183786 This should produce: os: { name: "Chromecast", version: "1.42.183786" } Instead of: os: { name: "Linux", version: "aarch64" } --- src/ua-parser.js | 4 ++++ test/os-test.json | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index a9e6c53..a6033bb 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -731,6 +731,10 @@ /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS ], [[NAME, 'Firefox OS'], VERSION], [ + // Google Chromecast + /crkey\/([\d\.]+)/i // Google Chromecast + ], [VERSION, [NAME, 'Chromecast']], [ + // Console /(nintendo|playstation)\s([wids34portablevu]+)/i, // Nintendo/Playstation diff --git a/test/os-test.json b/test/os-test.json index b944ac0..ab973c0 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -251,6 +251,15 @@ "version" : "undefined" } }, + { + "desc" : "Google Chromecast", + "ua" : "Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.81 Safari/537.36 CrKey/1.42.183786", + "expect" : + { + "name" : "Chromecast", + "version" : "1.42.183786" + } + }, { "desc" : "Nintendo", "ua" : "", From 233d3bae22a795153a7e6638887ce159c63e557d Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 12 Sep 2020 15:47:15 +0700 Subject: [PATCH 016/121] Fix potential ReDoS vulnerability --- src/ua-parser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index d89312c..3d807e1 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -585,9 +585,9 @@ /android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i, // Xiaomi Hongmi /android.+(mi[\s\-_]*(?:a\d|one|one[\s_]plus|note lte)?[\s_]*(?:\d?\w?)[\s_]*(?:plus)?)\s+build/i, // Xiaomi Mi - /android.+(redmi[\s\-_]*(?:note)?(?:[\s_]*[\w\s]+))\s+build/i // Redmi Phones + /android.+(redmi[\s\-_]*(?:note)?(?:[\s_]?[\w\s]+))\s+build/i // Redmi Phones ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ - /android.+(mi[\s\-_]*(?:pad)(?:[\s_]*[\w\s]+))\s+build/i // Mi Pad tablets + /android.+(mi[\s\-_]*(?:pad)(?:[\s_]?[\w\s]+))\s+build/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [ /android.+;\s(m[1-5]\snote)\sbuild/i // Meizu ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ From e96f95802d1b61e4be391693cbe7d7743fc3e234 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 12 Sep 2020 15:56:30 +0700 Subject: [PATCH 017/121] Refine Xiaomi detection --- src/ua-parser.js | 7 ++-- test/device-test.json | 81 +++++++++++++++++++++++++++++++++---------- 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 7c82f1a..aed8cf5 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -590,11 +590,12 @@ /android.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i, // Xiaomi Hongmi - /android.+(mi[\s\-_]*(?:a\d|one|one[\s_]plus|note lte)?[\s_]*(?:\d?\w?)[\s_]*(?:plus)?)\s+build/i, + /android.+(redmi[\s\-_]*(?:note|k)?(?:[\s_]?[\w\s]+))(?:\s+build|\))/i, + // Xiaomi Redmi + /android.+(mi[\s\-_]*(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]*(?:plus)?)\s+build/i // Xiaomi Mi - /android.+(redmi[\s\-_]*(?:note)?(?:[\s_]?[\w\s]+))\s+build/i // Redmi Phones ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ - /android.+(mi[\s\-_]*(?:pad)(?:[\s_]?[\w\s]+))\s+build/i // Mi Pad tablets + /android.+(mi[\s\-_]*(?:pad)(?:[\s_]?[\w\s]+))(?:\s+build|\))/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [ /android.+;\s(m[1-5]\snote)\sbuild/i // Meizu ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ diff --git a/test/device-test.json b/test/device-test.json index 6880dbf..074194e 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -594,6 +594,69 @@ "type": "mobile" } }, + { + "desc": "Xiaomi MI PAD 2", + "ua": "Mozilla/5.0 (Linux; Android 5.1; MI PAD 2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Safari/537.36 [FB_IAB/FB4A;FBAV/137.0.0.24.91;]", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 2", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 4 PLUS", + "ua": "Mozilla/5.0 (Linux; Android 8.1; MI PAD 4 PLUS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 4 PLUS", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Redmi 4A", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Redmi 4A Build/MMB29M; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi 4A", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi K30 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi K30 5G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi K30 5G", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi K30 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi K30 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi K30 Pro", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi Note 3", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Redmi Note 3 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.116 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Note 3", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi Note 9 Pro Max", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 9 Pro Max) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.99 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Note 9 Pro Max", + "type": "mobile" + } + }, { "desc": "PlayStation 4", "ua": "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", @@ -1129,24 +1192,6 @@ "type": "tablet" } }, - { - "desc": "Redmi Note 3", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Redmi Note 3 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.116 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi Note 3", - "type": "mobile" - } - }, - { - "desc": "MI PAD 2", - "ua": "Mozilla/5.0 (Linux; Android 5.1; MI PAD 2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Safari/537.36 [FB_IAB/FB4A;FBAV/137.0.0.24.91;]", - "expect": { - "vendor": "Xiaomi", - "model": "MI PAD 2", - "type": "tablet" - } - }, { "desc": "HUAWEI MediaPad M3 Lite 10", "ua": "Mozilla/5.0 (Linux; Android 7.0; BAH-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36", From e72371c34de7888b3ed7ca9781f3fee3a1be7b3e Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 12 Sep 2020 16:06:20 +0700 Subject: [PATCH 018/121] bump version to 0.7.22 --- bower.json | 2 +- dist/ua-parser.min.js | 4 ++-- dist/ua-parser.pack.js | 4 ++-- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index c6ab47b..59c63a8 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.21", + "version": "0.7.22", "authors": [ "Faisal Salman " ], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index edd4d7e..f983fef 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,9 @@ /*! - * UAParser.js v0.7.21 + * UAParser.js v0.7.22 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * * Copyright © 2012-2019 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.21",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded";var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){if(typeof str1==="string"){return str2.toLowerCase().indexOf(str1.toLowerCase())!==-1}else{return false}},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str){return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j * Licensed under MIT License */ -!function(i,s){"use strict";var e="0.7.21",o="",r="?",a="function",n="undefined",d="object",t="string",w="major",l="model",u="name",c="type",b="vendor",m="version",p="architecture",g="console",f="mobile",h="tablet",v="smarttv",x="wearable",k="embedded",y={extend:function(i,s){var e={};for(var o in i)s[o]&&s[o].length%2===0?e[o]=s[o].concat(i[o]):e[o]=i[o];return e},has:function(i,s){return"string"==typeof i&&s.toLowerCase().indexOf(i.toLowerCase())!==-1},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i===t?i.replace(/[^\d\.]/g,"").split(".")[0]:s},trim:function(i){return i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}},T={rgx:function(i,e){for(var o,r,n,t,w,l,u=0;u0?2==t.length?typeof t[1]==a?this[t[0]]=t[1].call(this,l):this[t[0]]=t[1]:3==t.length?typeof t[1]!==a||t[1].exec&&t[1].test?this[t[0]]=l?l.replace(t[1],t[2]):s:this[t[0]]=l?t[1].call(this,l,t[2]):s:4==t.length&&(this[t[0]]=l?t[3].call(this,l.replace(t[1],t[2])):s):this[t]=l?l:s;u+=2}},str:function(i,e){for(var o in e)if(typeof e[o]===d&&e[o].length>0){for(var a=0;a0?2==t.length?typeof t[1]==a?this[t[0]]=t[1].call(this,l):this[t[0]]=t[1]:3==t.length?typeof t[1]!==a||t[1].exec&&t[1].test?this[t[0]]=l?l.replace(t[1],t[2]):s:this[t[0]]=l?t[1].call(this,l,t[2]):s:4==t.length&&(this[t[0]]=l?t[3].call(this,l.replace(t[1],t[2])):s):this[t]=l?l:s;u+=2}},str:function(i,e){for(var o in e)if(typeof e[o]===d&&e[o].length>0){for(var a=0;a (http://faisalman.com)", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": [ diff --git a/src/ua-parser.js b/src/ua-parser.js index 3d807e1..07ecc5e 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ /*! - * UAParser.js v0.7.21 + * UAParser.js v0.7.22 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * @@ -16,7 +16,7 @@ ///////////// - var LIBVERSION = '0.7.21', + var LIBVERSION = '0.7.22', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From 1a75bc845fbae23f3ee4b2b8c66f4772694f5f88 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 17 Sep 2020 23:27:09 +0700 Subject: [PATCH 019/121] Fix #444 - Identify unknown Firefox-based browser as "Firefox" rather than "Mozilla" --- src/ua-parser.js | 1 + test/browser-test.json | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index aed8cf5..5c23510 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -386,6 +386,7 @@ /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i, // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix + /(firefox)\/([\w\.]+)\s[\w\s\-]+\/[\w\.]+$/i, // Other Firefox-based /(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla // Other diff --git a/test/browser-test.json b/test/browser-test.json index 23dbb2e..6212ef7 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -369,6 +369,16 @@ "major" : "15" } }, + { + "desc" : "Firefox-based browser", + "ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0 AppName/1.0", + "expect" : + { + "name" : "Firefox", + "version" : "80.0", + "major" : "80" + } + }, { "desc" : "Fennec", "ua" : "Mozilla/5.0 (X11; U; Linux armv61; en-US; rv:1.9.1b2pre) Gecko/20081015 Fennec/1.0a1", From edd84eaa72b11b0f439d370bd73e7d7b52d941f9 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 1 Oct 2020 12:16:54 +0700 Subject: [PATCH 020/121] Fix #447 - Improve identification for LG SmartTV --- src/ua-parser.js | 5 +++-- test/device-test.json | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 5c23510..1084af0 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -554,8 +554,9 @@ ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [ /android\s3\.[\s\w;-]{10}(lg?)-([06cv9]{3,4})/i // LG Tablet ], [[VENDOR, 'LG'], MODEL, [TYPE, TABLET]], [ - /(lg) netcast\.tv/i // LG SmartTV - ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ + /linux;\snetcast.+smarttv/i, // LG SmartTV + /lg\snetcast\.tv-201\d/i + ], [[VENDOR, 'LG'], MODEL, [TYPE, SMARTTV]], [ /(nexus\s[45])/i, // LG /lg[e;\s\/-]+(\w*)/i, /android.+lg(\-?[\d\w]+)\s+build/i diff --git a/test/device-test.json b/test/device-test.json index 074194e..914f293 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -160,6 +160,24 @@ "type": "mobile" } }, + { + "desc": "LG Smart TV", + "ua": "Mozilla/5.0 (DirectFB; U; Linux mips; en) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) LG Browser (; LG NetCast.TV-2011)", + "expect": { + "vendor": "LG", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "LG Smart TV", + "ua": "Mozilla/5.0 (Linux; NetCast; U) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/53.0.2785 34 Safari/537.31 SmartTV/8.5", + "expect": { + "vendor": "LG", + "model": "undefined", + "type": "smarttv" + } + }, { "desc": "Meizu M5 Note", "ua": "Mozilla/5.0 (Linux; Android 6.0; M5 Note Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043024 Safari/537.36 MicroMessenger/6.5.7.1040 NetType/WIFI Language/zh_CN", From da53c35f91eea1d55ced6e1df3927f8434ade4b2 Mon Sep 17 00:00:00 2001 From: dineshks1 Date: Wed, 28 Oct 2020 12:12:40 +0000 Subject: [PATCH 021/121] Adds travis jobs on ppc64le --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index fbc68cd..7e3cc8e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,6 @@ +arch: + - amd64 + - ppc64le language: node_js node_js: - stable From 7b23335d290a9225dcb094652e15677ef3227852 Mon Sep 17 00:00:00 2001 From: Emil Hesslow Date: Mon, 23 Nov 2020 13:38:26 -0800 Subject: [PATCH 022/121] Amazon Fire do not always contain build number --- src/ua-parser.js | 4 ++-- test/device-test.json | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 07ecc5e..9588a85 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -437,9 +437,9 @@ /(dell)\s(strea[kpr\s\d]*[\dko])/i // Dell Streak ], [VENDOR, MODEL, [TYPE, TABLET]], [ - /(kf[A-z]+)\sbuild\/.+silk\//i // Kindle Fire HD + /(kf[A-z]+)(\sbuild\/|\)).+silk\//i // Kindle Fire HD ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ - /(sd|kf)[0349hijorstuw]+\sbuild\/.+silk\//i // Fire Phone + /(sd|kf)[0349hijorstuw]+(\sbuild\/|\)).+silk\//i // Fire Phone ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ /android.+aft([bms])\sbuild/i // Fire TV ], [MODEL, [VENDOR, 'Amazon'], [TYPE, SMARTTV]], [ diff --git a/test/device-test.json b/test/device-test.json index 3add728..1f6f0b9 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -324,6 +324,15 @@ "type": "tablet" } }, + { + "desc": "Kindle Fire HD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true", + "expect": { + "vendor": "Amazon", + "model": "KFTT", + "type": "tablet" + } + }, { "desc": "Samsung Galaxy Note 8", "ua": "Mozilla/5.0 (Linux; Android 4.2.2; GT-N5100 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Safari/537.36", @@ -1025,6 +1034,15 @@ "type": "tablet" } }, + { + "desc": "Amazon Kindle Fire Tablet", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; KFSAWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/3.66 like Chrome/39.0.2171.93 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KFSAWI", + "type": "tablet" + } + }, { "desc": "Amazon Fire TV", "ua": "Mozilla/5.0 (Linux; Android 4.2.2; AFTB Build/JDQ39) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.173 Mobile Safari/537.22", From 4547dbc0b478af6bdcee97693d87d17922d885ca Mon Sep 17 00:00:00 2001 From: Queen Vinyl Darkscratch Date: Sat, 28 Nov 2020 05:42:37 -0800 Subject: [PATCH 023/121] Bump version for all dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 614021f..8b419c5 100644 --- a/package.json +++ b/package.json @@ -115,10 +115,10 @@ ] }, "devDependencies": { - "jshint": "~1.1.0", - "mocha": "~1.8.0", + "jshint": "~2.12.0", + "mocha": "~8.2.0", "requirejs": "^2.3.2", - "uglify-js": "~2.7.5", + "uglify-js": "~3.12.0", "verup": "^1.3.x" }, "repository": { From 9dfa5fc675bb7ab4a4feeff1cca191324fee480a Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 24 Nov 2020 15:49:34 +0700 Subject: [PATCH 024/121] Fix #453 - ReDoS vulnerability in MachSpeed tablets detection as reported by @migueldemoura --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 07ecc5e..26ba60a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -650,7 +650,7 @@ /android.+[;\/]\s*(Le[\s\-]+Pan)[\s\-]+(\w{1,9})\s+build/i // Le Pan Tablets ], [VENDOR, MODEL, [TYPE, TABLET]], [ - /android.+[;\/]\s*(Trio[\s\-]*.*)\s+build/i // MachSpeed Tablets + /android.+[;\/]\s*(Trio[\s\w\-\.]+)\s+build/i // MachSpeed Tablets ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [ /android.+[;\/]\s*(Trinity)[\-\s]*(T\d{3})\s+build/i // Trinity Tablets From 6d1f26df051ba681463ef109d36c9cf0f7e32b18 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 1 Dec 2020 00:50:19 +0700 Subject: [PATCH 025/121] Fix ReDoS vulnerabilities reported by Snyk --- src/ua-parser.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index e522d93..5ea799f 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -222,7 +222,7 @@ // Presto based /(opera\smini)\/([\w\.-]+)/i, // Opera Mini - /(opera\s[mobiletab]+).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet + /(opera\s[mobiletab]{3,6}).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet /(opera).+version\/([\w\.]+)/i, // Opera > 9.80 /(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80 ], [NAME, VERSION], [ @@ -252,7 +252,7 @@ /(konqueror)\/([\w\.]+)/i // Konqueror ], [[NAME, 'Konqueror'], VERSION], [ - /(trident).+rv[:\s]([\w\.]+).+like\sgecko/i // IE11 + /(trident).+rv[:\s]([\w\.]{1,9}).+like\sgecko/i // IE11 ], [[NAME, 'IE'], VERSION], [ /(edge|edgios|edga|edg)\/((\d+)?[\w\.]+)/i // Microsoft Edge @@ -362,13 +362,13 @@ /fxios\/([\w\.-]+)/i // Firefox for iOS ], [VERSION, [NAME, 'Firefox']], [ - /version\/([\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari + /version\/([\w\.]+)\s.*mobile\/\w+\s(safari)/i // Mobile Safari ], [VERSION, [NAME, 'Mobile Safari']], [ - /version\/([\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile + /version\/([\w\.]+)\s.*(mobile\s?safari|safari)/i // Safari & Safari Mobile ], [VERSION, NAME], [ - /webkit.+?(gsa)\/([\w\.]+).+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Google Search Appliance on iOS + /webkit.+?(gsa)\/([\w\.]+)\s.*(mobile\s?safari|safari)(\/[\w\.]+)/i // Google Search Appliance on iOS ], [[NAME, 'GSA'], VERSION], [ /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 @@ -387,7 +387,7 @@ // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix /(firefox)\/([\w\.]+)\s[\w\s\-]+\/[\w\.]+$/i, // Other Firefox-based - /(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla + /(mozilla)\/([\w\.]+)\s.+rv\:.+gecko\/\d+/i, // Mozilla // Other /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i, @@ -487,7 +487,7 @@ /(sprint\s(\w+))/i // Sprint Phones ], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [ - /(htc)[;_\s-]+([\w\s]+(?=\)|\sbuild)|\w+)/i, // HTC + /(htc)[;_\s-]{1,2}([\w\s]+(?=\)|\sbuild)|\w+)/i, // HTC /(zte)-(\w*)/i, // ZTE /(alcatel|geeksphone|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony @@ -591,13 +591,13 @@ ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [ /android.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models - /android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i, // Xiaomi Hongmi - /android.+(redmi[\s\-_]*(?:note|k)?(?:[\s_]?[\w\s]+))(?:\s+build|\))/i, + /android.+(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi + /android.+(redmi[\s\-_]?(?:note|k)?(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i, // Xiaomi Redmi - /android.+(mi[\s\-_]*(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]*(?:plus)?)\s+build/i + /android.+(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ - /android.+(mi[\s\-_]*(?:pad)(?:[\s_]?[\w\s]+))(?:\s+build|\))/i // Mi Pad tablets + /android.+(mi[\s\-_]?(?:pad)(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [ /android.+;\s(m[1-5]\snote)\sbuild/i // Meizu ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ @@ -611,7 +611,7 @@ /android.+[;\/]\s*(RCT[\d\w]+)\s+build/i // RCA Tablets ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [ - /android.+[;\/\s]+(Venue[\d\s]{2,7})\s+build/i // Dell Venue Tablets + /android.+[;\/\s](Venue[\d\s]{2,7})\s+build/i // Dell Venue Tablets ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ /android.+[;\/]\s*(Q[T|M][\d\w]+)\s+build/i // Verizon Tablet @@ -669,8 +669,8 @@ /android.+[;\/]\s*TU_(1491)\s+build/i // Rotor Tablets ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [ - /android.+(KS(.+))\s+build/i // Amazon Kindle Tablets - ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ + //android.+(KS(.+))\s+build/i // Amazon Kindle Tablets + //], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ /android.+(Gigaset)[\s\-]+(Q\w{1,9})\s+build/i // Gigaset Tablets ], [VENDOR, MODEL, [TYPE, TABLET]], [ From c7475db860ff57dcb6697dce7e473132e6c0e559 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 10 Dec 2020 10:45:16 +0700 Subject: [PATCH 026/121] 0.7.23 --- bower.json | 2 +- dist/ua-parser.min.js | 4 ++-- dist/ua-parser.pack.js | 4 ++-- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index 59c63a8..4136799 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.22", + "version": "0.7.23", "authors": [ "Faisal Salman " ], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index f983fef..a63af9d 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,9 @@ /*! - * UAParser.js v0.7.22 + * UAParser.js v0.7.23 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * * Copyright © 2012-2019 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.22",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded";var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){if(typeof str1==="string"){return str2.toLowerCase().indexOf(str1.toLowerCase())!==-1}else{return false}},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str){return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j * Licensed under MIT License */ -!function(i,s){"use strict";var e="0.7.22",o="",r="?",a="function",n="undefined",d="object",t="string",w="major",l="model",u="name",c="type",b="vendor",m="version",p="architecture",g="console",f="mobile",h="tablet",v="smarttv",x="wearable",k="embedded",y={extend:function(i,s){var e={};for(var o in i)s[o]&&s[o].length%2===0?e[o]=s[o].concat(i[o]):e[o]=i[o];return e},has:function(i,s){return"string"==typeof i&&s.toLowerCase().indexOf(i.toLowerCase())!==-1},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i===t?i.replace(/[^\d\.]/g,"").split(".")[0]:s},trim:function(i){return i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}},T={rgx:function(i,e){for(var o,r,n,t,w,l,u=0;u0?2==t.length?typeof t[1]==a?this[t[0]]=t[1].call(this,l):this[t[0]]=t[1]:3==t.length?typeof t[1]!==a||t[1].exec&&t[1].test?this[t[0]]=l?l.replace(t[1],t[2]):s:this[t[0]]=l?t[1].call(this,l,t[2]):s:4==t.length&&(this[t[0]]=l?t[3].call(this,l.replace(t[1],t[2])):s):this[t]=l?l:s;u+=2}},str:function(i,e){for(var o in e)if(typeof e[o]===d&&e[o].length>0){for(var a=0;a0?2==t.length?typeof t[1]==a?this[t[0]]=t[1].call(this,l):this[t[0]]=t[1]:3==t.length?typeof t[1]!==a||t[1].exec&&t[1].test?this[t[0]]=l?l.replace(t[1],t[2]):s:this[t[0]]=l?t[1].call(this,l,t[2]):s:4==t.length&&(this[t[0]]=l?t[3].call(this,l.replace(t[1],t[2])):s):this[t]=l?l:s;u+=2}},str:function(i,e){for(var o in e)if(typeof e[o]===d&&e[o].length>0){for(var a=0;a (http://faisalman.com)", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": [ diff --git a/src/ua-parser.js b/src/ua-parser.js index 62787e9..0e8ffab 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ /*! - * UAParser.js v0.7.22 + * UAParser.js v0.7.23 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * @@ -16,7 +16,7 @@ ///////////// - var LIBVERSION = '0.7.22', + var LIBVERSION = '0.7.23', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From b7d4865afdf1572f8942c905d9494bb6aeed114d Mon Sep 17 00:00:00 2001 From: Amumu Date: Sun, 13 Dec 2020 10:59:01 +0800 Subject: [PATCH 027/121] Update homepage --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4bbd430..a8fcf03 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "jquery-plugin", "ecosystem:jquery" ], - "homepage": "http://github.com/faisalman/ua-parser-js", + "homepage": "https://github.com/faisalman/ua-parser-js", "contributors": [ "Aamir Poonawalla ", "Admas ", From 34e2e800c5651eb01b533cb6417925a76e96e128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Y=C4=B1lmaz?= Date: Thu, 17 Dec 2020 15:39:17 +0300 Subject: [PATCH 028/121] Update ua-parser.js Samsung Tablet SM-P587 must be Tablet device type --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 0e8ffab..0ad4418 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -530,7 +530,7 @@ /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ - /android.+((sch-i[89]0\d|shw-m380s|SM-P605|SM-P610|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i, + /android.+((sch-i[89]0\d|shw-m380s|SM-P605|SM-P610|SM-P587|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i, /((SM-T\w+))/i ], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung /smart-tv.+(samsung)/i From b0f14de2a47c45cdd20cdbe21e7f10d7f06c0fb4 Mon Sep 17 00:00:00 2001 From: Junki-Ishida Date: Tue, 5 Jan 2021 20:56:45 +0900 Subject: [PATCH 029/121] Fix Detection Rule For Amazon Fire TV --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 0e8ffab..9296f25 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -448,7 +448,7 @@ ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ /(sd|kf)[0349hijorstuw]+(\sbuild\/|\)).+silk\//i // Fire Phone ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ - /android.+aft([bms])\sbuild/i // Fire TV + /android.+aft([\w])(\sbuild\/|\))/i // Fire TV ], [MODEL, [VENDOR, 'Amazon'], [TYPE, SMARTTV]], [ /\((ip[honed|\s\w*]+);.+(apple)/i // iPod/iPhone diff --git a/test/device-test.json b/test/device-test.json index 5c2056b..cc5a270 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1219,6 +1219,15 @@ "type": "smarttv" } }, + { + "desc": "Amazon Fire TV", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; AFTT) AppleWebKit/537.36 (KHTML, like Gecko) Silk/86.3.20 like Chrome/86.0.4240.198 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "T", + "type": "smarttv" + } + }, { "desc": "Gigaset Tablet", "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Gigaset QV830 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", From 386ebc29f1d6460900f807b5a5993104b4df1cb4 Mon Sep 17 00:00:00 2001 From: Gerald Host Date: Tue, 5 Jan 2021 12:59:41 +0000 Subject: [PATCH 030/121] feat: update readme playstation Update Playstation to PlayStation as "Playstation" is not a known user agent. --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 91d58fe..bffa2f5 100644 --- a/readme.md +++ b/readme.md @@ -81,7 +81,7 @@ AIX, Amiga OS, Android, Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, Contiki, Fedora, Firefox OS, FreeBSD, Debian, DragonFly, Fuchsia, Gentoo, GNU, Haiku, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Mageia, Mandriva, MeeGo, Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, -PCLinuxOS, Plan9, Playstation, QNX, RedHat, RIM Tablet OS, RISC OS, Sailfish, +PCLinuxOS, Plan9, PlayStation, QNX, RedHat, RIM Tablet OS, RISC OS, Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, Unix, VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... From f543c5ad72436fab77a19b601ac72e5a4b36fb8a Mon Sep 17 00:00:00 2001 From: Dustin Date: Thu, 7 Jan 2021 09:41:20 -0800 Subject: [PATCH 031/121] facebook movile app with no browser info --- src/ua-parser.js | 5 ++++- test/device-test.json | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 0e8ffab..71853b7 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -689,7 +689,10 @@ ], [[TYPE, SMARTTV]], [ /(android[\w\.\s\-]{0,9});.+build/i // Generic Android Device - ], [MODEL, [VENDOR, 'Generic']] + ], [MODEL, [VENDOR, 'Generic']], [ + + /(phone)/i, + ], [[TYPE, MOBILE]] ], engine : [[ diff --git a/test/device-test.json b/test/device-test.json index 5c2056b..ea171b2 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1326,5 +1326,12 @@ "model": "LYA-TL00", "type": "mobile" } + }, + { + "desc": "FaceBook Mobile App", + "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", + "expect": { + "type": "mobile" + } } ] From cd1bfd87c504920b1a34973120d65681beff73a8 Mon Sep 17 00:00:00 2001 From: ruicong <466403866@qq.com> Date: Mon, 18 Jan 2021 17:11:53 +0800 Subject: [PATCH 032/121] FIX: Wechat Desktop for Windows compatible with new version --- src/ua-parser.js | 2 +- test/browser-test.json | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 0e8ffab..4ba83fa 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -282,7 +282,7 @@ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ - /(windowswechat qbcore)\/([\w\.]+)/i // WeChat Desktop for Windows Built-in Browser + /((?:windowswechat)? qbcore)\/([\w\.]+)(?:.+windowswechat)?/i, // WeChat Desktop for Windows Built-in Browser ], [[NAME, 'WeChat(Win) Desktop'], VERSION], [ /(micromessenger)\/([\w\.]+)/i // WeChat diff --git a/test/browser-test.json b/test/browser-test.json index 6212ef7..ba53b02 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1188,6 +1188,16 @@ "major" : "3" } }, + { + "desc" : "WeChat Desktop for Windows Built-in Browser major version in 4", + "ua" : "mozilla/5.0 (windows nt 10.0; wow64) applewebkit/537.36 (khtml, like gecko) chrome/53.0.2785.116 safari/537.36 qbcore/4.0.1301.400 qqbrowser/9.0.2524.400 mozilla/5.0 (windows nt 6.1; wow64) applewebkit/537.36 (khtml, like gecko) chrome/81.0.4044.138 safari/537.36 nettype/wifi micromessenger/7.0.20.1781(0x6700143b) windowswechat", + "expect" : + { + "name" : "WeChat(Win) Desktop", + "version" : "4.0.1301.400", + "major" : "4" + } + }, { "desc" : "GSA on iOS", "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) GSA/30.1.161623614 Mobile/14F89 Safari/602.1", From 7679003f87bec9ceff3d0825b67cda1124454a4b Mon Sep 17 00:00:00 2001 From: Joey Parrish Date: Tue, 9 Feb 2021 12:12:15 -0800 Subject: [PATCH 033/121] fix: Xbox OS detection It is better to detect Xbox devices as having the OS "Xbox". Otherwise, they are detected as "Windows 10", making it difficult to see the difference between Legacy Edge on Windows and the Xbox browser. (Karma (https://github.com/karma-runner/karma) only shows the browser & OS on the status line.) With this change, Xbox 360, Xbox One, Xbox X/S, and Xbox Series X/S are all detected as OS "Xbox" with version "360", "One", etc. --- src/ua-parser.js | 3 +++ test/os-test.json | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index 9890771..e6a7114 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -719,6 +719,9 @@ os : [[ + // Xbox, consider this before other Windows-based devices + /(xbox);\s+xbox\s([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) + // Windows based /microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ diff --git a/test/os-test.json b/test/os-test.json index ab973c0..1b05ddc 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -287,6 +287,42 @@ "version" : "4" } }, + { + "desc" : "Xbox 360", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox 360) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", + "expect" : + { + "name" : "Xbox", + "version" : "360" + } + }, + { + "desc" : "Xbox One", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox One; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19041", + "expect" : + { + "name" : "Xbox", + "version" : "One" + } + }, + { + "desc" : "Xbox X", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02", + "expect" : + { + "name" : "Xbox", + "version" : "X" + } + }, + { + "desc" : "Xbox Series X", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox Series X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02 ", + "expect" : + { + "name" : "Xbox", + "version" : "Series X" + } + }, { "desc" : "Mint", "ua" : "", From 9d154cc41b34a54fac1abf58686f6b0b19e363d0 Mon Sep 17 00:00:00 2001 From: Joey Parrish Date: Tue, 9 Feb 2021 12:42:27 -0800 Subject: [PATCH 034/121] chore: Update build --- dist/ua-parser.min.js | 2 +- dist/ua-parser.pack.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index a63af9d..ca2c111 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2019 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.23",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded";var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){if(typeof str1==="string"){return str2.toLowerCase().indexOf(str1.toLowerCase())!==-1}else{return false}},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str){return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j * Licensed under MIT License */ -!function(i,s){"use strict";var e="0.7.23",o="",r="?",a="function",n="undefined",d="object",t="string",w="major",l="model",u="name",c="type",b="vendor",m="version",p="architecture",f="console",g="mobile",h="tablet",v="smarttv",x="wearable",k="embedded",y={extend:function(i,s){var e={};for(var o in i)s[o]&&s[o].length%2===0?e[o]=s[o].concat(i[o]):e[o]=i[o];return e},has:function(i,s){return"string"==typeof i&&s.toLowerCase().indexOf(i.toLowerCase())!==-1},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i===t?i.replace(/[^\d\.]/g,"").split(".")[0]:s},trim:function(i){return i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}},T={rgx:function(i,e){for(var o,r,n,t,w,l,u=0;u0?2==t.length?typeof t[1]==a?this[t[0]]=t[1].call(this,l):this[t[0]]=t[1]:3==t.length?typeof t[1]!==a||t[1].exec&&t[1].test?this[t[0]]=l?l.replace(t[1],t[2]):s:this[t[0]]=l?t[1].call(this,l,t[2]):s:4==t.length&&(this[t[0]]=l?t[3].call(this,l.replace(t[1],t[2])):s):this[t]=l?l:s;u+=2}},str:function(i,e){for(var o in e)if(typeof e[o]===d&&e[o].length>0){for(var a=0;a Date: Fri, 12 Feb 2021 09:53:26 +0700 Subject: [PATCH 035/121] Fix potential ReDoS vulnerability as reported by Doyensec --- src/ua-parser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index e6a7114..63a9f68 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -620,7 +620,7 @@ /android.+[;\/]\s*(Q[T|M][\d\w]+)\s+build/i // Verizon Tablet ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ - /android.+[;\/]\s+(Barnes[&\s]+Noble\s+|BN[RT])(V?.*)\s+build/i // Barnes & Noble Tablet + /android.+[;\/]\s+(Barnes[&\s]+Noble\s+|BN[RT])(\S(?:.*\S)?)\s+build/i // Barnes & Noble Tablet ], [[VENDOR, 'Barnes & Noble'], MODEL, [TYPE, TABLET]], [ /android.+[;\/]\s+(TM\d{3}.*\b)\s+build/i // Barnes & Noble Tablet @@ -694,7 +694,7 @@ /(android[\w\.\s\-]{0,9});.+build/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']], [ - /(phone)/i, + /(phone)/i ], [[TYPE, MOBILE]] ], From 9999815ac8c969306594c650566695fba3506830 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 12 Feb 2021 09:58:03 +0700 Subject: [PATCH 036/121] Update version number to 0.7.24 --- bower.json | 2 +- dist/ua-parser.min.js | 6 +++--- dist/ua-parser.pack.js | 6 +++--- license.md | 2 +- package.js | 2 +- package.json | 2 +- readme.md | 2 +- src/ua-parser.js | 6 +++--- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/bower.json b/bower.json index 4136799..7a02d39 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.23", + "version": "0.7.24", "authors": [ "Faisal Salman " ], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index ca2c111..c41eeb4 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,9 @@ /*! - * UAParser.js v0.7.23 + * UAParser.js v0.7.24 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * - * Copyright © 2012-2019 Faisal Salman + * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.23",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded";var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){if(typeof str1==="string"){return str2.toLowerCase().indexOf(str1.toLowerCase())!==-1}else{return false}},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str){return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j + * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -!function(r,u){"use strict";var c="function",i="undefined",b="object",s="model",e="name",o="type",a="vendor",n="version",d="architecture",t="console",w="mobile",l="tablet",m="smarttv",p="wearable",f={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return"string"==typeof i&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return"string"==typeof i?i.replace(/[^\d\.]/g,"").split(".")[0]:u},trim:function(i){return i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}},h={rgx:function(i,s){for(var e,o,r,a,n,d=0;d0?2==t.length?typeof t[1]==a?this[t[0]]=t[1].call(this,l):this[t[0]]=t[1]:3==t.length?typeof t[1]!==a||t[1].exec&&t[1].test?this[t[0]]=l?l.replace(t[1],t[2]):s:this[t[0]]=l?t[1].call(this,l,t[2]):s:4==t.length&&(this[t[0]]=l?t[3].call(this,l.replace(t[1],t[2])):s):this[t]=l?l:s;u+=2}},str:function(i,e){for(var o in e)if(typeof e[o]===d&&e[o].length>0){for(var a=0;a> +Copyright (c) 2012-2021 Faisal Salman <> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/package.js b/package.js index 05f9da5..0fa0730 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'faisalman:ua-parser-js', - version: '0.7.23', + version: '0.7.24', summary: 'Lightweight JavaScript-based user-agent string parser', git: 'https://github.com/faisalman/ua-parser-js.git', documentation: 'readme.md' diff --git a/package.json b/package.json index a8fcf03..aa7b064 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "0.7.23", + "version": "0.7.24", "author": "Faisal Salman (http://faisalman.com)", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": [ diff --git a/readme.md b/readme.md index bffa2f5..d18c5a1 100644 --- a/readme.md +++ b/readme.md @@ -317,7 +317,7 @@ Do you use & like UAParser.js but you don’t find a way to show some love? If y MIT License -Copyright (c) 2012-2019 Faisal Salman <> +Copyright (c) 2012-2021 Faisal Salman <> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/ua-parser.js b/src/ua-parser.js index 63a9f68..3c63a04 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,9 +1,9 @@ /*! - * UAParser.js v0.7.23 + * UAParser.js v0.7.24 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * - * Copyright © 2012-2019 Faisal Salman + * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ @@ -16,7 +16,7 @@ ///////////// - var LIBVERSION = '0.7.23', + var LIBVERSION = '0.7.24', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From f661da9d474fe844319c8497e2aba9337bb5cc50 Mon Sep 17 00:00:00 2001 From: David Annez Date: Fri, 26 Feb 2021 10:14:32 +0000 Subject: [PATCH 037/121] Move to check typeof for window for different envs --- src/ua-parser.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 3c63a04..ce74b7a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -811,7 +811,7 @@ return new UAParser(uastring, extensions).getResult(); } - var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); + var ua = uastring || ((typeof window !== 'undefined' && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); var rgxmap = extensions ? util.extend(regexes, extensions) : regexes; this.getBrowser = function () { @@ -907,7 +907,7 @@ define(function () { return UAParser; }); - } else if (window) { + } else if (typeof window !== 'undefined') { // browser env window.UAParser = UAParser; } @@ -918,7 +918,7 @@ // In AMD env the global scope should be kept clean, but jQuery is an exception. // jQuery always exports to global scope, unless jQuery.noConflict(true) is used, // and we should catch that. - var $ = window && (window.jQuery || window.Zepto); + var $ = typeof window !== 'undefined' && (window.jQuery || window.Zepto); if ($ && !$.ua) { var parser = new UAParser(); $.ua = parser.getResult(); From d78a2e0361cc0ce4574f1abb824c14fce1f5f830 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 9 Mar 2021 02:13:31 +0700 Subject: [PATCH 038/121] Fix #413 Bug resulting Motorola model O --- src/ua-parser.js | 3 ++- test/device-test.json | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 3c63a04..5b70666 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -517,7 +517,8 @@ // Motorola /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)[\w\s]+build\//i, - /mot[\s-]?(\w*)/i, + /\smot[\s-](\w*)/i, + /(moto[\s\w\(\)]+(?=\sbuild|\)))/i, /(XT\d{3,4}) build\//i, /(nexus\s6)/i ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [ diff --git a/test/device-test.json b/test/device-test.json index 877d78d..436fac2 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -270,6 +270,33 @@ "type": "mobile" } }, + { + "desc": "Motorola Moto g(6) Play", + "ua": "Mozilla/5.0 (Linux; Android 9; moto g(6) play) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "moto g(6) play", + "type": "mobile" + } + }, + { + "desc": "Motorola Moto g(7) Supra", + "ua": "Mozilla/5.0 (Linux; Android 9; moto g(7) supra Build/PCOS29.114-134-2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/73.0.3683.90 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "moto g(7) supra", + "type": "mobile" + } + }, + { + "desc": "Motorola Moto E", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Moto E (4) Build/NDQS26.69-64-11-7; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "Moto E (4)", + "type": "mobile" + } + }, { "desc": "Nokia3xx", "ua": "Nokia303/14.87 CLDC-1.1", From ec5a864abb4b30c5143c3f870d73d807697cf610 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 9 Mar 2021 02:32:10 +0700 Subject: [PATCH 039/121] Fix #367 #425 Detect Instagram in-app browser --- src/ua-parser.js | 4 ++-- test/browser-test.json | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 5b70666..302a20a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -235,8 +235,8 @@ // Mixed /(kindle)\/([\w\.]+)/i, // Kindle - /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]*)/i, - // Lunascape/Maxthon/Netfront/Jasmine/Blazer + /(lunascape|maxthon|netfront|jasmine|blazer|instagram)[\/\s]?([\w\.]*)/i, + // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Instagram // Trident based /(avant\s|iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser diff --git a/test/browser-test.json b/test/browser-test.json index 0ee4ad1..8d71867 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -349,6 +349,16 @@ "major" : "undefined" } }, + { + "desc" : "Instagram in-App Browser for iOS", + "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 14_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Instagram 142.0.0.22.109 (iPhone12,5; iOS 14_1; en_US; en-US; scale=3.00; 1242x2688; 214888322) NW/1", + "expect" : + { + "name" : "Instagram", + "version" : "142.0.0.22.109", + "major" : "142" + } + }, { "desc" : "Falkon", "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Falkon/3.0.0 Chrome/61.0.3163.140 Safari/537.36", From dce862364b2bfb4fc5db6e8ac51a2f0ab4317e60 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 10 Mar 2021 00:55:26 +0700 Subject: [PATCH 040/121] Add funding support links --- .github/FUNDING.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..3ec50a0 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: ua-parser-js +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: ['https://www.paypal.me/faisalman/'] From 6aa3ff13746b0dd2b95ee6df59ef6cd8038cdd97 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 12 Mar 2021 17:40:07 +0700 Subject: [PATCH 041/121] Fix #450 Sony Xperia Z2 Tablet --- src/ua-parser.js | 6 +++--- test/device-test.json | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 302a20a..9424501 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -471,9 +471,9 @@ /android.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7|padfone|p00c)/i ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [ - /(sony)\s(tablet\s[ps])\sbuild\//i, // Sony - /(sony)?(?:sgp.+)\sbuild\//i - ], [[VENDOR, 'Sony'], [MODEL, 'Xperia Tablet'], [TYPE, TABLET]], [ + /sony\stablet\s[ps]\sbuild\//i, // Sony + /(?:sony)?sgp\w+(?:\sbuild\/|\))/i + ], [[MODEL, 'Xperia Tablet'], [VENDOR, 'Sony'], [TYPE, TABLET]], [ /android.+\s([c-g]\d{4}|so[-l]\w+)(?=\sbuild\/|\).+chrome\/(?![1-6]{0,1}\d\.))/i ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [ diff --git a/test/device-test.json b/test/device-test.json index 436fac2..a0e33c6 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -549,6 +549,15 @@ "type": "tablet" } }, + { + "desc": "Sony Xperia Z2 Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SGP561) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "Xperia Tablet", + "type": "tablet" + } + }, { "desc": "Sony Tablet S", "ua": "Mozilla/5.0 (Linux; U; Android 3.1; Sony Tablet S Build/THMAS10000) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13", From 46615e70db3bd098dd471f75b7b91afa96e819a7 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 12 Mar 2021 19:20:17 +0700 Subject: [PATCH 042/121] Fix #454 Improve Samsung detection --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 9424501..b2ac7f1 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -540,7 +540,7 @@ /smart-tv.+(samsung)/i ], [VENDOR, [TYPE, SMARTTV], MODEL], [ /((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-\w[\w\d]+))/i, - /(sam[sung]*)[\s-]*(\w+-?[\w-]*)/i, + /\s(sam)(?:sung)[\s-]([\w-]+)/i, /sec-((sgh\w+))/i ], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [ diff --git a/test/device-test.json b/test/device-test.json index a0e33c6..29fb151 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1378,5 +1378,14 @@ "expect": { "type": "mobile" } + }, + { + "desc": "Issue #454", + "ua": "Mosamzilla/5.0 (Windows; U; Win98; en-US; rv:1.7.5) Gecko/20050603 Netscape/8.0.2", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "undefined" + } } ] From cdac86782ba42f7d1b0f489f08e2e83b8ecbfea3 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 13 Mar 2021 08:47:06 +0700 Subject: [PATCH 043/121] Add Nintendo Switch --- src/ua-parser.js | 4 ++-- test/device-test.json | 9 +++++++++ test/os-test.json | 8 ++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index b2ac7f1..aea21a7 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -478,7 +478,7 @@ ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [ /\s(ouya)\s/i, // Ouya - /(nintendo)\s([wids3u]+)/i // Nintendo + /(nintendo)\s([wids3utch]+)/i // Nintendo ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ /android.+;\s(shield)\sbuild/i // Nvidia @@ -753,7 +753,7 @@ ], [VERSION, [NAME, 'Chromecast']], [ // Console - /(nintendo|playstation)\s([wids34portablevu]+)/i, // Nintendo/Playstation + /(nintendo|playstation)\s([wids34portablevuch]+)/i, // Nintendo/Playstation // GNU/Linux based /(mint)[\/\s\(]?(\w*)/i, // Mint diff --git a/test/device-test.json b/test/device-test.json index 29fb151..9e5e03d 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -729,6 +729,15 @@ "type": "console" } }, + { + "desc": "Nintendo Switch", + "ua": "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", + "expect": { + "vendor": "Nintendo", + "model": "Switch", + "type": "console" + } + }, { "desc": "Galaxy Nexus", "ua": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19", diff --git a/test/os-test.json b/test/os-test.json index 1b05ddc..ce6ec52 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -261,12 +261,12 @@ } }, { - "desc" : "Nintendo", - "ua" : "", + "desc" : "Nintendo Switch", + "ua" : "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", "expect" : { - "name" : "", - "version" : "" + "name" : "Nintendo", + "version" : "Switch" } }, { From f85dc8cb9abd89ab30d5cfb6d5a0d40fdf8be28a Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 13 Mar 2021 09:22:56 +0700 Subject: [PATCH 044/121] Fix #366 Amazon Alexa Echo Show --- src/ua-parser.js | 1 + test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index aea21a7..3d23428 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -447,6 +447,7 @@ /(dell)\s(strea[kpr\s\d]*[\dko])/i // Dell Streak ], [VENDOR, MODEL, [TYPE, TABLET]], [ + /(alexa)webm/i, /(kf[A-z]+)(\sbuild\/|\)).+silk\//i // Kindle Fire HD ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ /(sd|kf)[0349hijorstuw]+(\sbuild\/|\)).+silk\//i // Fire Phone diff --git a/test/device-test.json b/test/device-test.json index 9e5e03d..84c9e75 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1237,6 +1237,15 @@ "type": "tablet" } }, + { + "desc": "Amazon Alexa Echo Show", + "ua": "AlexaWebMediaPlayer/1.0.200641.0 (Linux;Android 5.1.1)", + "expect": { + "vendor": "Amazon", + "model": "Alexa", + "type": "tablet" + } + }, { "desc": "Amazon Kindle Fire Tablet", "ua": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; KFSAWI Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Silk/3.66 like Chrome/39.0.2171.93 Safari/537.36", From d658ef364bf21a2a9ff3e6a60d8f19f8abcce881 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 13 Mar 2021 09:34:22 +0700 Subject: [PATCH 045/121] Fix #339 Add Weibo --- readme.md | 18 +++++++++--------- src/ua-parser.js | 3 +++ test/browser-test.json | 10 ++++++++++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index d18c5a1..0e7297c 100644 --- a/readme.md +++ b/readme.md @@ -32,15 +32,15 @@ BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, Dolphin, Doris, Edge, Epiphany, Facebook, Falkon, Fennec, Firebird, Firefox, Flock, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, -Iceape, Iceweasel, Iridium, Iron, Jasmine, K-Meleon, Kindle, Konqueror, -LBBROWSER Line, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, -Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, Mozilla, NetFront, -NetSurf, Netfront, Netscape, NokiaBrowser, Oculus Browser, OmniWeb, -Opera Coast, Opera Mini, Opera Mobi, Opera Tablet, Opera, PaleMoon, PhantomJS, -Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, -RockMelt, Safari, Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, -Sleipnir, Slim, SlimBrowser, Swiftfox, Tizen Browser, UCBrowser, Vivaldi, -Waterfox, WeChat, Yandex, baidu, iCab, w3m, Whale Browser... +Iceape, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, Kindle, +Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, +Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, +Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Oculus Browser, +OmniWeb, Opera Coast, Opera Mini, Opera Mobi, Opera Tablet, Opera, PaleMoon, +PhantomJS, Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, +QupZilla, RockMelt, Safari, Sailfish Browser, Samsung Browser, SeaMonkey, Silk, +Skyfire, Sleipnir, Slim, SlimBrowser, Swiftfox, Tizen Browser, UCBrowser, +Vivaldi, Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m, Whale Browser... # 'browser.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 3d23428..526fb4d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -315,6 +315,9 @@ /(LBBROWSER)/i // LieBao Browser ], [NAME], [ + /(weibo)__([\d\.]+)/i // Weibo + ], [NAME, VERSION], [ + /xiaomi\/miuibrowser\/([\w\.]+)/i // MIUI Browser ], [VERSION, [NAME, 'MIUI Browser']], [ diff --git a/test/browser-test.json b/test/browser-test.json index 8d71867..ac50553 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1068,6 +1068,16 @@ "major": "6" } }, + { + "desc": "WeChat on Android", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16A366 Weibo (iPhone8,2__weibo__8.9.3__iphone__os12.0)", + "expect": + { + "name": "weibo", + "version": "8.9.3", + "major": "8" + } + }, { "desc" : "Vivaldi", "ua" : "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.89 Vivaldi/1.0.83.38 Safari/537.36", From 6c87e069ec178691eb13362c81390ac6e0a26c6e Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 13 Mar 2021 11:41:56 +0700 Subject: [PATCH 046/121] Fix #407 ZTE Nubia misidentified as Nextbook Tablet --- src/ua-parser.js | 5 ++++- test/device-test.json | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 526fb4d..5a73446 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -634,6 +634,9 @@ /android.+;\s(k88)\sbuild/i // ZTE K Series Tablet ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [ + /android.+;\s(nx\d{3}j)\sbuild/i // ZTE Nubia + ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [ + /android.+[;\/]\s*(gen\d{3})\s+build.*49h/i // Swiss GEN Mobile ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [ @@ -650,7 +653,7 @@ /android.+[;\/]\s*(NS-?\w{0,9})\sbuild/i // Insignia Tablets ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [ - /android.+[;\/]\s*((NX|Next)-?\w{0,9})\s+build/i // NextBook Tablets + /android.+[;\/]\s*((NXA|Next)-?\w{0,9})\s+build/i // NextBook Tablets ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [ /android.+[;\/]\s*(Xtreme\_)?(V(1[045]|2[015]|30|40|60|7[05]|90))\s+build/i diff --git a/test/device-test.json b/test/device-test.json index 84c9e75..10383bb 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1102,6 +1102,15 @@ "type": "tablet" } }, + { + "desc": "ZTE Nubia Red Magic 3", + "ua": "Mozilla/5.0 (Linux; Android 9; NX629J Build/PKQ1.190321.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/45016 Mobile Safari/537.36 MMWEBID/4064 MicroMessenger/7.0.10.1580(0x27000A34) Process/tools NetType/WIFI Language/zh_CN ABI/arm64", + "expect": { + "vendor": "ZTE", + "model": "NX629J", + "type": "mobile" + } + }, { "desc": "Swizz GEN610", "ua": "Mozilla/5.0 (Linux; Android 4.4.2; GEN610 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Mobile Safari/537.36", From 1cfe34f517124e0454f89ea9bd49cfe8055f0b87 Mon Sep 17 00:00:00 2001 From: ruicong <466403866@qq.com> Date: Sat, 13 Mar 2021 14:26:42 +0800 Subject: [PATCH 047/121] FIX: new wechat desktop's unsafe regex --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 4ba83fa..784e1ad 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -282,7 +282,7 @@ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ - /((?:windowswechat)? qbcore)\/([\w\.]+)(?:.+windowswechat)?/i, // WeChat Desktop for Windows Built-in Browser + /((?:windowswechat)? qbcore)\/([\w\.]+).*(?:windowswechat)?/i, // WeChat Desktop for Windows Built-in Browser ], [[NAME, 'WeChat(Win) Desktop'], VERSION], [ /(micromessenger)\/([\w\.]+)/i // WeChat From d1ea2f0dc4942cd333ee825717900c161193c27b Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 14 Mar 2021 19:07:28 +0700 Subject: [PATCH 048/121] Fix #433 #434 Huawei devices --- src/ua-parser.js | 5 +++-- test/device-test.json | 42 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 98af2f5..1ae3a00 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -282,7 +282,7 @@ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ - /((?:windowswechat)? qbcore)\/([\w\.]+).*(?:windowswechat)?/i, // WeChat Desktop for Windows Built-in Browser + /((?:windowswechat)? qbcore)\/([\w\.]+).*(?:windowswechat)?/i // WeChat Desktop for Windows Built-in Browser ], [[NAME, 'WeChat(Win) Desktop'], VERSION], [ /(micromessenger)\/([\w\.]+)/i // WeChat @@ -504,7 +504,8 @@ ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ /d\/huawei([\w\s-]+)[;\)]/i, // Huawei - /android.+\s(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?)/i + /android.+\s(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?)/i, + /android.+\s((?:A(?:GS2?|KA|LP|N[AE]|QM|RE|SK|TH)|B(?:A(?:C|H2)|G2|KL|LA|MH|Z[AKT])|C(?:AZ|DY|LT|OL|[MOR]R)|DUK|E(?:BG|DI|L[ES]|ML|V[AR])|FRD|G(?:LK|RA)|H(?:D[LN]|MA|LK|RY|WI)|INE|J(?:DN2|MM|NY|SN)|K(?:NT|OB|SA)|L(?:IO|LD|ON|[RY]A)|M(?:AR|ED|[HL]A|ON|RX|T7)|N(?:EO|TS|XT)|OXF|P(?:AR|CT|IC|LK|RA)|R(?:IO|VL)|S(?:C[ML]|EA|HT|PN|TF)|T(?:A[HS]|NY)|V(?:[CI]E|KY|OG|RD)|W(?:AS|LZ)|Y(?:635|AL))-[ATU][LN][01259][019])[;\)\s]/i ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ diff --git a/test/device-test.json b/test/device-test.json index 10383bb..d1192dd 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1391,11 +1391,47 @@ } }, { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-TL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "desc": "Huawei P40", + "ua": "Mozilla/5.0 (Linux; Android 10; ANA-AN00 Build/HUAWEIANA-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/11.26 SP-engine/2.22.0 baiduboxapp/11.26.0.10 (Baidu; P1 10) NABar/1.0", "expect": { "vendor": "Huawei", - "model": "LYA-TL00", + "model": "ANA-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei P40 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; ELS-AN00 Build/HUAWEIELS-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/6.0.0", + "expect": { + "vendor": "Huawei", + "model": "ELS-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei 30 Pro+", + "ua": "Mozilla/5.0 (Linux; Android 10; EBG-AN10 Build/HUAWEIEBG-AN10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.86 Mobile Safari/537.36 EdgA/42.0.0.2741", + "expect": { + "vendor": "Huawei", + "model": "EBG-AN10", + "type": "mobile" + } + }, + { + "desc": "Huawei 30S", + "ua": "Mozilla/5.0 (Linux; Android 10; CDY-AN90 Build/HUAWEICDY-AN90; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/5.8.0", + "expect": { + "vendor": "Huawei", + "model": "CDY-AN90", + "type": "mobile" + } + }, + { + "desc": "Huawei Enjoy10e", + "ua": "Dalvik/2.1.0 (Linux; U; Android 10; MED-AL00 Build/HUAWEIMED-AL00)", + "expect": { + "vendor": "Huawei", + "model": "MED-AL00", "type": "mobile" } }, From fc1d3b0719aed9499d31d41b48975e52db56fed0 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 14 Mar 2021 22:22:04 +0700 Subject: [PATCH 049/121] Fix #475 Nokia version incomplete --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index b710a09..0813f4a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -553,7 +553,7 @@ ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ /(maemo|nokia).*(n900|lumia\s\d+)/i, // Nokia - /(nokia)[\s_-]?([\w-]*)/i + /(nokia)[\s_-]?([\w\.-]*)/i ], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [ /android[x\d\.\s;]+\s([ab][1-7]\-?[0178a]\d\d?)/i // Acer diff --git a/test/device-test.json b/test/device-test.json index d1192dd..8c5b0d9 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -306,6 +306,15 @@ "type": "mobile" } }, + { + "desc": "Nokia 3.2", + "ua": "Mozilla/5.0 (Linux; Android 10; Nokia 3.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Mobile Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "3.2", + "type": "mobile" + } + }, { "desc": "OnePlus One", "ua": "Mozilla/5.0 (Linux; Android 4.4.4; A0001 Build/KTU84Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.59 Mobile Safari/537.36", From e612b44ecd679f151c6c7eba3d04bdae4d7311b4 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 14 Mar 2021 22:47:23 +0700 Subject: [PATCH 050/121] Fix #470 Identify Android TV as SmartTV --- src/ua-parser.js | 8 ++++---- test/device-test.json | 9 +++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 0813f4a..c242e0f 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -603,7 +603,7 @@ /android.+(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi /android.+(redmi[\s\-_]?(?:note|k)?(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i, // Xiaomi Redmi - /android.+(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i + /android.+(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ /android.+(mi[\s\-_]?(?:pad)(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i // Mi Pad tablets @@ -686,6 +686,9 @@ /android.+(Gigaset)[\s\-]+(Q\w{1,9})\s+build/i // Gigaset Tablets ], [VENDOR, MODEL, [TYPE, TABLET]], [ + + /[\s\/\(](android\stv|smart-?tv)[;\)\s]/i // SmartTV from Unidentified Vendors + ], [[TYPE, SMARTTV]], [ // Android Phones from Unidentified Vendors /android .+?; ([^;]+?)(?: build|\) applewebkit).+? mobile safari/i ], [MODEL, [TYPE, MOBILE]], [ @@ -697,9 +700,6 @@ /\s(mobile)(?:[;\/]|\ssafari)/i // Unidentifiable Mobile ], [[TYPE, util.lowerize], VENDOR, MODEL], [ - /[\s\/\(](smart-?tv)[;\)]/i // SmartTV - ], [[TYPE, SMARTTV]], [ - /(android[\w\.\s\-]{0,9});.+build/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']], [ diff --git a/test/device-test.json b/test/device-test.json index 8c5b0d9..247aeb4 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1300,6 +1300,15 @@ "type": "smarttv" } }, + { + "desc": "Android TV", + "ua": "Mozilla/5.0 (Linux; Android 10; 2020/2021 UHD Android TV Build/QTG3.201102.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } + }, { "desc": "Gigaset Tablet", "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Gigaset QV830 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", From e402a6a55c68774322ac541be5a68b8b10ef0e25 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 17 Mar 2021 10:58:50 +0700 Subject: [PATCH 051/121] Latest Xperia lineup --- src/ua-parser.js | 2 +- test/device-test.json | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index c242e0f..22fc18d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -478,7 +478,7 @@ /sony\stablet\s[ps]\sbuild\//i, // Sony /(?:sony)?sgp\w+(?:\sbuild\/|\))/i ], [[MODEL, 'Xperia Tablet'], [VENDOR, 'Sony'], [TYPE, TABLET]], [ - /android.+\s([c-g]\d{4}|so[-l]\w+)(?=\sbuild\/|\).+chrome\/(?![1-6]{0,1}\d\.))/i + /android.+\s([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?=\sbuild\/|\).+chrome\/(?![1-6]{0,1}\d\.))/i ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [ /\s(ouya)\s/i, // Ouya diff --git a/test/device-test.json b/test/device-test.json index 247aeb4..20681e7 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -549,6 +549,42 @@ "type": "mobile" } }, + { + "desc": "Sony Xperia L4", + "ua": "Mozilla/5.0 (Linux; Android 9; XQ-AD51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AD51", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia 1ii", + "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AT51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AT51", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia 10ii", + "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AU52) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AU52", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AQ52) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.185 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AQ52", + "type": "mobile" + } + }, { "desc": "Sony SGP521 (Xperia Z2 Tablet)", "ua": "Mozilla/5.0 (Linux; Android 4.4; SGP521 Build/17.1.A.0.432) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", From d1ba5f591425b8e5406e7faafc9b7cedd7240323 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 18 Mar 2021 00:19:41 +0700 Subject: [PATCH 052/121] Fix #430 Playstation 5 --- src/ua-parser.js | 4 ++-- test/device-test.json | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 22fc18d..4f417dc 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -488,7 +488,7 @@ /android.+;\s(shield)\sbuild/i // Nvidia ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ - /(playstation\s[34portablevi]+)/i // Playstation + /(playstation\s[345portablevi]+)/i // Playstation ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [ /(sprint\s(\w+))/i // Sprint Phones @@ -761,7 +761,7 @@ ], [VERSION, [NAME, 'Chromecast']], [ // Console - /(nintendo|playstation)\s([wids34portablevuch]+)/i, // Nintendo/Playstation + /(nintendo|playstation)\s([wids345portablevuch]+)/i, // Nintendo/Playstation // GNU/Linux based /(mint)[\/\s\(]?(\w*)/i, // Mint diff --git a/test/device-test.json b/test/device-test.json index 20681e7..a544b93 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -774,6 +774,15 @@ "type": "console" } }, + { + "desc": "PlayStation 5", + "ua": "Mozilla/5.0 (Playstation; Playstation 5/1.05) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15", + "expect": { + "vendor": "Sony", + "model": "Playstation 5", + "type": "console" + } + }, { "desc": "Nintendo Switch", "ua": "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", From 1a8cd671abfc7a63aadb69496b7c0405259f49ab Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 18 Mar 2021 02:05:57 +0700 Subject: [PATCH 053/121] Fix #449 Lenovo Tablet --- src/ua-parser.js | 2 +- test/device-test.json | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 4f417dc..16b5e24 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -571,7 +571,7 @@ /android.+lg(\-?[\d\w]+)\s+build/i ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [ - /(lenovo)\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+))/i // Lenovo tablets + /(lenovo)\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+)|[\w-]+)/i // Lenovo tablets ], [VENDOR, MODEL, [TYPE, TABLET]], [ /android.+(ideatab[a-z0-9\-\s]+)/i // Lenovo ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ diff --git a/test/device-test.json b/test/device-test.json index a544b93..4702024 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -142,6 +142,24 @@ "type": "tablet" } }, + { + "desc": "Lenovo Tab 3 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo YT3-X90F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT3-X90F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Lenovo TB-X304F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X304F", + "type": "tablet" + } + }, { "desc": "LG Nexus 4", "ua": "Mozilla/5.0 (Linux; Android 4.2.1; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", From ebccc29d9747970d1c1ff752480b66f2d6d873db Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 18 Mar 2021 18:12:48 +0700 Subject: [PATCH 054/121] Casually save some bytes --- dist/ua-parser.min.js | 2 +- dist/ua-parser.pack.js | 2 +- src/ua-parser.js | 136 +++++++++++++++++------------------------ 3 files changed, 59 insertions(+), 81 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index c41eeb4..7cc3a8b 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.24",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded";var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){if(typeof str1==="string"){return str2.toLowerCase().indexOf(str1.toLowerCase())!==-1}else{return false}},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str){return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j * Licensed under MIT License */ -!function(i,s){"use strict";var e="0.7.24",o="",r="?",a="function",n="undefined",d="object",t="string",w="major",l="model",u="name",c="type",b="vendor",m="version",p="architecture",f="console",h="mobile",g="tablet",v="smarttv",x="wearable",k="embedded",y={extend:function(i,s){var e={};for(var o in i)s[o]&&s[o].length%2===0?e[o]=s[o].concat(i[o]):e[o]=i[o];return e},has:function(i,s){return"string"==typeof i&&s.toLowerCase().indexOf(i.toLowerCase())!==-1},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i===t?i.replace(/[^\d\.]/g,"").split(".")[0]:s},trim:function(i){return i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}},S={rgx:function(i,e){for(var o,r,n,t,w,l,u=0;u0?2==t.length?typeof t[1]==a?this[t[0]]=t[1].call(this,l):this[t[0]]=t[1]:3==t.length?typeof t[1]!==a||t[1].exec&&t[1].test?this[t[0]]=l?l.replace(t[1],t[2]):s:this[t[0]]=l?t[1].call(this,l,t[2]):s:4==t.length&&(this[t[0]]=l?t[3].call(this,l.replace(t[1],t[2])):s):this[t]=l?l:s;u+=2}},str:function(i,e){for(var o in e)if(typeof e[o]===d&&e[o].length>0){for(var a=0;a0?2==t.length?typeof t[1]==a?this[t[0]]=t[1].call(this,l):this[t[0]]=t[1]:3==t.length?typeof t[1]!==a||t[1].exec&&t[1].test?this[t[0]]=l?l.replace(t[1],t[2]):s:this[t[0]]=l?t[1].call(this,l,t[2]):s:4==t.length&&(this[t[0]]=l?t[3].call(this,l.replace(t[1],t[2])):s):this[t]=l?l:s;u+=2}},str:function(i,e){for(var o in e)if(typeof e[o]===d&&e[o].length>0){for(var a=0;a Date: Thu, 18 Mar 2021 21:59:38 +0700 Subject: [PATCH 055/121] Fix #401 Rearrange the order of regexes to improve hit-rate performance --- src/ua-parser.js | 580 +++++++++++++++++++++-------------------------- 1 file changed, 254 insertions(+), 326 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 569dc35..d05b519 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -220,96 +220,90 @@ browser : [[ + /(?:android.+crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS + ], [VERSION, [NAME, 'Chrome']], [ + /(?:edge|edgios|edga|edg)\/((\d+)?[\w\.]+)/i // Microsoft Edge + ], [VERSION, [NAME, 'Edge']], [ + // Presto based /(opera\smini)\/([\w\.-]+)/i, // Opera Mini /(opera\s[mobiletab]{3,6}).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet /(opera).+version\/([\w\.]+)/i, // Opera > 9.80 /(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80 ], [NAME, VERSION], [ - - /(opios)[\/\s]+([\w\.]+)/i // Opera mini on iphone >= 8.0 - ], [[NAME, 'Opera Mini'], VERSION], [ - - /\s(opr)\/([\w\.]+)/i // Opera Webkit - ], [[NAME, 'Opera'], VERSION], [ + /opios[\/\s]+([\w\.]+)/i // Opera mini on iphone >= 8.0 + ], [VERSION, [NAME, 'Opera Mini']], [ + /\sopr\/([\w\.]+)/i // Opera Webkit + ], [VERSION, [NAME, 'Opera']], [ // Mixed /(kindle)\/([\w\.]+)/i, // Kindle - /(lunascape|maxthon|netfront|jasmine|blazer|instagram)[\/\s]?([\w\.]*)/i, - // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Instagram + /(lunascape|maxthon|netfront|jasmine|blazer|instagram)[\/\s]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Instagram // Trident based - /(avant\s|iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i, - // Avant/IEMobile/SlimBrowser - /(bidubrowser|baidubrowser)[\/\s]?([\w\.]+)/i, // Baidu Browser + /(avant\s|iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser + /(ba?idubrowser)[\/\s]?([\w\.]+)/i, // Baidu Browser /(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer // Webkit/KHTML based - /(rekonq)\/([\w\.]*)/i, // Rekonq /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon)\/([\w\.-]+)/i, // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon - /(puffin|brave|whale|qqbrowserlite|qq)\/([\w\.]+)/i // Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ + /(rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ + /(weibo)__([\d\.]+)/i // Weibo ], [NAME, VERSION], [ - - /(konqueror)\/([\w\.]+)/i // Konqueror - ], [[NAME, 'Konqueror'], VERSION], [ - - /(trident).+rv[:\s]([\w\.]{1,9}).+like\sgecko/i // IE11 - ], [[NAME, 'IE'], VERSION], [ - - /(edge|edgios|edga|edg)\/((\d+)?[\w\.]+)/i // Microsoft Edge - ], [[NAME, 'Edge'], VERSION], [ - - /(yabrowser)\/([\w\.]+)/i // Yandex - ], [[NAME, 'Yandex'], VERSION], [ - - /(Avast)\/([\w\.]+)/i // Avast Secure Browser - ], [[NAME, 'Avast Secure Browser'], VERSION], [ - - /(AVG)\/([\w\.]+)/i // AVG Secure Browser - ], [[NAME, 'AVG Secure Browser'], VERSION], [ - - /(focus)\/([\w\.]+)/i // Firefox Focus - ], [[NAME, 'Firefox Focus'], VERSION], [ - - /(opt)\/([\w\.]+)/i // Opera Touch - ], [[NAME, 'Opera Touch'], VERSION], [ - - /((?:[\s\/])uc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser - ], [[NAME, 'UCBrowser'], VERSION], [ - + /(?:[\s\/]uc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser + ], [VERSION, [NAME, 'UCBrowser']], [ + /(?:windowswechat)?\sqbcore\/([\w\.]+).*(?:windowswechat)?/i // WeChat Desktop for Windows Built-in Browser + ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [ + /micromessenger\/([\w\.]+)/i // WeChat + ], [VERSION, [NAME, 'WeChat']], [ + /konqueror\/([\w\.]+)/i // Konqueror + ], [VERSION, [NAME, 'Konqueror']], [ + /trident.+rv[:\s]([\w\.]{1,9}).+like\sgecko/i // IE11 + ], [VERSION, [NAME, 'IE']], [ + /yabrowser\/([\w\.]+)/i // Yandex + ], [VERSION, [NAME, 'Yandex']], [ + /Avast\/([\w\.]+)/i // Avast Secure Browser + ], [VERSION, [NAME, 'Avast Secure Browser']], [ + /AVG\/([\w\.]+)/i // AVG Secure Browser + ], [VERSION, [NAME, 'AVG Secure Browser']], [ + /focus\/([\w\.]+)/i // Firefox Focus + ], [VERSION, [NAME, 'Firefox Focus']], [ + /opt\/([\w\.]+)/i // Opera Touch + ], [VERSION, [NAME, 'Opera Touch']], [ + /coc_coc_browser\/([\w\.]+)/i // Coc Coc Browser + ], [VERSION, [NAME, 'Coc Coc']], [ + /sailfishbrowser\/([\w\.]+)/i // Sailfish Browser + ], [VERSION, [NAME, 'Sailfish Browser']], [ + /dolfin\/([\w\.]+)/i // Dolphin + ], [VERSION, [NAME, 'Dolphin']], [ + /coast\/([\w\.]+)/i // Opera Coast + ], [VERSION, [NAME, 'Opera Coast']], [ + /xiaomi\/miuibrowser\/([\w\.]+)/i // MIUI Browser + ], [VERSION, [NAME, 'MIUI Browser']], [ + /fxios\/([\w\.-]+)/i // Firefox for iOS + ], [VERSION, [NAME, 'Firefox']], [ + /(qihu|qhbrowser|qihoobrowser|360browser)/i // 360 + ], [[NAME, '360 Browser']], [ + /((?:oculus|samsung)browser)\/([\w\.]+)/i + ], [[NAME, /(.+(?:g|us))(.+)/, '$1 $2'], VERSION], [ // Oculus / Samsung Browser /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ - - /((?:windowswechat)? qbcore)\/([\w\.]+).*(?:windowswechat)?/i // WeChat Desktop for Windows Built-in Browser - ], [[NAME, 'WeChat(Win) Desktop'], VERSION], [ - - /(micromessenger)\/([\w\.]+)/i // WeChat - ], [[NAME, 'WeChat'], VERSION], [ - /m?(qqbrowser|baiduboxapp|2345Explorer)[\/\s]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser ], [NAME, VERSION], [ - - /(MetaSr)[\/\s]?([\w\.]+)/i // SouGouBrowser - ], [NAME], [ - + /(MetaSr)[\/\s]?([\w\.]+)/i, // SouGouBrowser /(LBBROWSER)/i // LieBao Browser ], [NAME], [ - /(weibo)__([\d\.]+)/i // Weibo - ], [NAME, VERSION], [ - - /xiaomi\/miuibrowser\/([\w\.]+)/i // MIUI Browser - ], [VERSION, [NAME, 'MIUI Browser']], [ - + // WebView /;fbav\/([\w\.]+);/i // Facebook App for iOS & Android with version - ], [VERSION, [NAME, 'Facebook']], [ - + ], [VERSION, [NAME, 'Facebook']], [ /FBAN\/FBIOS|FB_IAB\/FB4A/i // Facebook App for iOS & Android without version ], [[NAME, 'Facebook']], [ - /safari\s(line)\/([\w\.]+)/i, // Line App for iOS /droid.+(line)\/([\w\.]+)\/iab/i // Line App for Android ], [NAME, VERSION], [ + /webkit.+?gsa\/([\w\.]+)\s.*(mobile\s?safari|safari)(\/[\w\.]+)/i // Google Search Appliance on iOS + ], [VERSION, [NAME, 'GSA']], [ /headlesschrome(?:\/([\w\.]+)|\s)/i // Chrome Headless ], [VERSION, [NAME, 'Chrome Headless']], [ @@ -317,46 +311,16 @@ /\swv\).+(chrome)\/([\w\.]+)/i // Chrome WebView ], [[NAME, /(.+)/, '$1 WebView'], VERSION], [ - /((?:oculus|samsung)browser)\/([\w\.]+)/i - ], [[NAME, /(.+(?:g|us))(.+)/, '$1 $2'], VERSION], [ // Oculus / Samsung Browser - /droid.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)*/i // Android Browser ], [VERSION, [NAME, 'Android Browser']], [ - /(coc_coc_browser)\/([\w\.]+)/i // Coc Coc Browser - ], [[NAME, 'Coc Coc'], VERSION], [ - - /(sailfishbrowser)\/([\w\.]+)/i // Sailfish Browser - ], [[NAME, 'Sailfish Browser'], VERSION], [ - - /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i - // Chrome/OmniWeb/Arora/Tizen/Nokia + /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [NAME, VERSION], [ - /(dolfin)\/([\w\.]+)/i // Dolphin - ], [[NAME, 'Dolphin'], VERSION], [ - - /(qihu|qhbrowser|qihoobrowser|360browser)/i // 360 - ], [[NAME, '360 Browser']], [ - - /((?:android.+)crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS - ], [[NAME, 'Chrome'], VERSION], [ - - /(coast)\/([\w\.]+)/i // Opera Coast - ], [[NAME, 'Opera Coast'], VERSION], [ - - /fxios\/([\w\.-]+)/i // Firefox for iOS - ], [VERSION, [NAME, 'Firefox']], [ - /version\/([\w\.]+)\s.*mobile\/\w+\s(safari)/i // Mobile Safari ], [VERSION, [NAME, 'Mobile Safari']], [ - /version\/([\w\.]+)\s.*(mobile\s?safari|safari)/i // Safari & Safari Mobile ], [VERSION, NAME], [ - - /webkit.+?(gsa)\/([\w\.]+)\s.*(mobile\s?safari|safari)(\/[\w\.]+)/i // Google Search Appliance on iOS - ], [[NAME, 'GSA'], VERSION], [ - /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 ], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [ @@ -370,7 +334,6 @@ /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i, - // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix /(firefox)\/([\w\.]+)\s[\w\s\-]+\/[\w\.]+$/i, // Other Firefox-based /(mozilla)\/([\w\.]+)\s.+rv\:.+gecko\/\d+/i, // Mozilla @@ -412,93 +375,42 @@ ], device : [[ + + // Samsung + /droid.+(sch-i[89]0\d|shw-m380s|SM-P605|SM-P610|SM-P587|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10)/i, + /(SM-T\w+)/i + ], [MODEL, [VENDOR, 'Samsung'], [TYPE, TABLET]], [ + /(s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-\w[\w\d]+)/i, + /\ssamsung[\s-]([\w-]+)/i, + /sec-(sgh\w+)/i + ], [MODEL, [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ - /\((ipad|playbook);[\w\s\),;-]+(rim|apple)/i // iPad/PlayBook + // Apple + /\((ip(?:hone|od)[\s\w]*);/i // iPod/iPhone + ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [ + /\((ipad);[\w\s\),;-]+(apple)/i // iPad ], [MODEL, VENDOR, [TYPE, TABLET]], [ - /applecoremedia\/[\w\.]+ \((ipad)/ // iPad ], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [ - /(apple\s{0,1}tv)/i // Apple TV - ], [[MODEL, 'Apple TV'], [VENDOR, 'Apple'], [TYPE, SMARTTV]], [ - - /(archos)\s(gamepad2?)/i, // Archos - /(hp).+(touchpad)/i, // HP TouchPad - /(hp).+(tablet)/i, // HP Tablet - /(kindle)\/([\w\.]+)/i, // Kindle - /\s(nook)[\w\s]+build\/(\w+)/i, // Nook - /(dell)\s(strea[kpr\s\d]*[\dko])/i // Dell Streak - ], [VENDOR, MODEL, [TYPE, TABLET]], [ - - /(alexa)webm/i, - /(kf[A-z]+)(\sbuild\/|\)).+silk\//i // Kindle Fire HD - ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ - /(sd|kf)[0349hijorstuw]+(\sbuild\/|\)).+silk\//i // Fire Phone - ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ - /droid.+aft([\w])(\sbuild\/|\))/i // Fire TV - ], [MODEL, [VENDOR, 'Amazon'], [TYPE, SMARTTV]], [ - - /\((ip(?:hone|od)[\s\w]*);/i // iPod/iPhone - ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [ - - /(blackberry)[\s-]?(\w+)/i, // BlackBerry - /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[\s_-]?([\w-]*)/i, - // BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron - /(hp)\s([\w\s]+\w)/i, // HP iPAQ - /(asus)-?(\w+)/i // Asus - ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - /\(bb10;\s(\w+)/i // BlackBerry 10 - ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [ - // Asus Tablets - /droid.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7|padfone|p00c)/i - ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [ - - /sony\stablet\s[ps]\sbuild\//i, // Sony - /(?:sony)?sgp\w+(?:\sbuild\/|\))/i - ], [[MODEL, 'Xperia Tablet'], [VENDOR, 'Sony'], [TYPE, TABLET]], [ - /droid.+\s([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?=\sbuild\/|\).+chrome\/(?![1-6]{0,1}\d\.))/i - ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [ - - /\s(ouya)\s/i, // Ouya - /(nintendo)\s([wids3utch]+)/i // Nintendo - ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ - - /droid.+;\s(shield)\sbuild/i // Nvidia - ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ - - /(playstation\s[345portablevi]+)/i // Playstation - ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [ - - /(sprint\s(\w+))/i // Sprint Phones - ], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [ - - /(htc)[;_\s-]{1,2}([\w\s]+(?=\)|\sbuild)|\w+)/i, // HTC - /(zte)-(\w*)/i, // ZTE - /(alcatel|geeksphone|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]*)/i - // Alcatel/GeeksPhone/Nexian/Panasonic/Sony - ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ - - /(nexus\s9)/i // HTC Nexus 9 - ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ - - /d\/huawei([\w\s-]+)[;\)]/i, // Huawei + // Huawei + /d\/huawei([\w\s-]+)[;\)]/i, /droid.+\s(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?)/i, /droid.+\s((?:A(?:GS2?|KA|LP|N[AE]|QM|RE|SK|TH)|B(?:A(?:C|H2)|G2|KL|LA|MH|Z[AKT])|C(?:AZ|DY|LT|OL|[MOR]R)|DUK|E(?:BG|DI|L[ES]|ML|V[AR])|FRD|G(?:LK|RA)|H(?:D[LN]|MA|LK|RY|WI)|INE|J(?:DN2|MM|NY|SN)|K(?:NT|OB|SA)|L(?:IO|LD|ON|[RY]A)|M(?:AR|ED|[HL]A|ON|RX|T7)|N(?:EO|TS|XT)|OXF|P(?:AR|CT|IC|LK|RA)|R(?:IO|VL)|S(?:C[ML]|EA|HT|PN|TF)|T(?:A[HS]|NY)|V(?:[CI]E|KY|OG|RD)|W(?:AS|LZ)|Y(?:635|AL))-[ATU][LN][01259][019])[;\)\s]/i - ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ - /droid.+(bah2?-a?[lw]\d{2})/i // Huawei MediaPad ], [MODEL, [VENDOR, 'Huawei'], [TYPE, TABLET]], [ - /(microsoft);\s(lumia[\s\w]+)/i // Microsoft Lumia - ], [VENDOR, MODEL, [TYPE, MOBILE]], [ + // Xiaomi + /droid.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models + /droid.+(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi + /droid.+(redmi[\s\-_]?(?:note|k)?(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i,// Xiaomi Redmi + /droid.+(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i // Xiaomi Mi + ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ + /droid.+(mi[\s\-_]?(?:pad)(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i // Mi Pad tablets + ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [ - /[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox - ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [ - /(kin\.[onetw]{3})/i // Microsoft Kin - ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ - - // Motorola + // Motorola /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)[\w\s]+build\//i, /\smot[\s-](\w*)/i, /(moto[\s\w\(\)]+(?=\sbuild|\)))/i, @@ -508,179 +420,197 @@ /droid.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [ - /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices - ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [ - - /hbbtv.+maple;(\d+)/i - ], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [ - - /\(dtv[\);].+(aquos)/i // Sharp - ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ - - /droid.+((sch-i[89]0\d|shw-m380s|SM-P605|SM-P610|SM-P587|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i, - /((SM-T\w+))/i - ], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung - /smart-tv.+(samsung)/i - ], [VENDOR, [TYPE, SMARTTV], MODEL], [ - /((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-\w[\w\d]+))/i, - /\s(sam)(?:sung)[\s-]([\w-]+)/i, - /sec-((sgh\w+))/i - ], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [ - - /sie-(\w*)/i // Siemens - ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ - - /(maemo|nokia).*(n900|lumia\s\d+)/i, // Nokia - /(nokia)[\s_-]?([\w\.-]*)/i - ], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [ - - /droid[x\d\.\s;]+\s([ab][1-7]\-?[0178a]\d\d?)/i // Acer - ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [ - - /droid.+([vl]k\-?\d{3})\s+build/i // LG Tablet + // LG + /droid(?:.+([vl]k\-?\d{3})\s+build|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4}))/i ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [ - /droid\s3\.[\s\w;-]{10}(lg?)-([06cv9]{3,4})/i // LG Tablet - ], [[VENDOR, 'LG'], MODEL, [TYPE, TABLET]], [ - /linux;\snetcast.+smarttv/i, // LG SmartTV - /lg\snetcast\.tv-201\d/i - ], [[VENDOR, 'LG'], MODEL, [TYPE, SMARTTV]], [ - /(nexus\s[45])/i, // LG - /lg[e;\s\/-]+(\w*)/i, + /(nexus\s[45])/i, + /lg[e;\s\/-]+((?!browser|netcast)\w+)/i, /droid.+lg(\-?[\d\w]+)\s+build/i ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [ - /(lenovo)\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+)|[\w-]+)/i // Lenovo tablets - ], [VENDOR, MODEL, [TYPE, TABLET]], [ - /droid.+(ideatab[a-z0-9\-\s]+)/i // Lenovo + // Lenovo + /droid.+(ideatab[a-z0-9\-\s]+)/i, + /lenovo\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+)|[\w-]+)/i // Lenovo tablets ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ - /(lenovo)[_\s-]?([\w-]+)/i - ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - /linux;.+((jolla));/i // Jolla - ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - - /((pebble))app\/[\d\.]+\s/i // Pebble - ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ - - /droid.+;\s(oppo)\s?([\w\s]+)\sbuild/i // OPPO - ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - - /crkey/i // Google Chromecast - ], [[MODEL, 'Chromecast'], [VENDOR, 'Google'], [TYPE, SMARTTV]], [ - - /droid.+;\s(glass)\s\d/i // Google Glass - ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [ + // Nokia + /(?:maemo|nokia).*(n900|lumia\s\d+)/i, + /nokia[\s_-]?([\w\.-]*)/i + ], [MODEL, [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ + // Google /droid.+;\s(pixel c)[\s)]/i // Google Pixel C ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [ - /droid.+;\s(pixel( [2-9]a?)?( xl)?)[\s)]/i // Google Pixel ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [ - /droid.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models - /droid.+(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi - /droid.+(redmi[\s\-_]?(?:note|k)?(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i, - // Xiaomi Redmi - /droid.+(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i - // Xiaomi Mi - ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ - /droid.+(mi[\s\-_]?(?:pad)(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i // Mi Pad tablets - ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [ - /droid.+;\s(m[1-5]\snote)\sbuild/i // Meizu - ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ - /(mz)-([\w-]{2,})/i - ], [[VENDOR, 'Meizu'], MODEL, [TYPE, MOBILE]], [ + // Sony + /droid.+\s([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?=\sbuild\/|\).+chrome\/(?![1-6]{0,1}\d\.))/i + ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [ + /sony\stablet\s[ps]\sbuild\//i, + /(?:sony)?sgp\w+(?:\sbuild\/|\))/i + ], [[MODEL, 'Xperia Tablet'], [VENDOR, 'Sony'], [TYPE, TABLET]], [ + // OnePlus /droid.+a000(1)\s+build/i, // OnePlus /droid.+oneplus\s(a\d{4})[\s)]/i ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ - /droid.+[;\/]\s*(RCT[\d\w]+)\s+build/i // RCA Tablets - ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [ + // Amazon + /(alexa)webm/i, + /(kf[A-z]+)(\sbuild\/|\)).+silk\//i // Kindle Fire HD + ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ + /(sd|kf)[0349hijorstuw]+(\sbuild\/|\)).+silk\//i // Fire Phone + ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ - /droid.+[;\/\s](Venue[\d\s]{2,7})\s+build/i // Dell Venue Tablets - ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ + // BlackBerry + /\((playbook);[\w\s\),;-]+(rim)/i // BlackBerry PlayBook + ], [MODEL, VENDOR, [TYPE, TABLET]], [ + /\(bb10;\s(\w+)/i // BlackBerry 10 + ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [ + + // Asus + /droid.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7|padfone|p00c)/i + ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [ - /droid.+[;\/]\s*(Q[T|M][\d\w]+)\s+build/i // Verizon Tablet - ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ + // HTC + /(nexus\s9)/i // HTC Nexus 9 + ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ + /(htc)[;_\s-]{1,2}([\w\s]+(?=\)|\sbuild)|\w+)/i, // HTC - /droid.+[;\/]\s+(Barnes[&\s]+Noble\s+|BN[RT])(\S(?:.*\S)?)\s+build/i - ], [[VENDOR, 'Barnes & Noble'], MODEL, [TYPE, TABLET]], [ + // ZTE + /(zte)-(\w*)/i, + /(alcatel|geeksphone|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony + ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ - /droid.+[;\/]\s+(TM\d{3}.*\b)\s+build/i // Barnes & Noble Tablet - ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [ + // Acer + /droid[x\d\.\s;]+\s([ab][1-7]\-?[0178a]\d\d?)/i + ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [ - /droid.+;\s(k88)\sbuild/i // ZTE K Series Tablet - ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [ + // Meizu + /droid.+;\s(m[1-5]\snote)\sbuild/i, + /mz-([\w-]{2,})/i + ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ - /droid.+;\s(nx\d{3}j)\sbuild/i // ZTE Nubia - ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [ - - /droid.+[;\/]\s*(gen\d{3})\s+build.*49h/i // Swiss GEN Mobile - ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [ - - /droid.+[;\/]\s*(zur\d{3})\s+build/i // Swiss ZUR Tablet - ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ - - /droid.+[;\/]\s*((Zeki)?TB.*\b)\s+build/i // Zeki Tablets - ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ - - /(android).+[;\/]\s+([YR]\d{2})\s+build/i, - /droid.+[;\/]\s+(Dragon[\-\s]+Touch\s+|DT)(\w{5})\sbuild/i // Dragon Touch Tablet - ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [ - - /droid.+[;\/]\s*(NS-?\w{0,9})\sbuild/i // Insignia Tablets - ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [ - - /droid.+[;\/]\s*((NXA|Next)-?\w{0,9})\s+build/i // NextBook Tablets - ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [ - - /droid.+[;\/]\s*(Xtreme\_)?(V(1[045]|2[015]|30|40|60|7[05]|90))\s+build/i - ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ // Voice Xtreme Phones - - /droid.+[;\/]\s*(LVTEL\-)?(V1[12])\s+build/i // LvTel Phones - ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [ - - /droid.+;\s(PH-1)\s/i - ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ // Essential PH-1 - - /droid.+[;\/]\s*(V(100MD|700NA|7011|917G).*\b)\s+build/i // Envizen Tablets - ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [ - - /droid.+[;\/]\s*(Le[\s\-]+Pan)[\s\-]+(\w{1,9})\s+build/i // Le Pan Tablets - ], [VENDOR, MODEL, [TYPE, TABLET]], [ - - /droid.+[;\/]\s*(Trio[\s\w\-\.]+)\s+build/i // MachSpeed Tablets - ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [ - - /droid.+[;\/]\s*(Trinity)[\-\s]*(T\d{3})\s+build/i // Trinity Tablets - ], [VENDOR, MODEL, [TYPE, TABLET]], [ - - /droid.+[;\/]\s*TU_(1491)\s+build/i // Rotor Tablets - ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [ - - //android.+(KS(.+))\s+build/i // Amazon Kindle Tablets - //], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ + // MIXED + /(blackberry)[\s-]?(\w+)/i, // BlackBerry + /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[\s_-]?([\w-]*)/i, + // BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron + /(hp)\s([\w\s]+\w)/i, // HP iPAQ + /(asus)-?(\w+)/i, // Asus + /(microsoft);\s(lumia[\s\w]+)/i, // Microsoft Lumia + /(lenovo)[_\s-]?([\w-]+)/i, // Lenovo + /linux;.+((jolla));/i, // Jolla + /droid.+;\s(oppo)\s?([\w\s]+)\sbuild/i // OPPO + ], [VENDOR, MODEL, [TYPE, MOBILE]], [ + /(archos)\s(gamepad2?)/i, // Archos + /(hp).+(touchpad)/i, // HP TouchPad + /(hp).+(tablet)/i, // HP Tablet + /(kindle)\/([\w\.]+)/i, // Kindle + /\s(nook)[\w\s]+build\/(\w+)/i, // Nook + /(dell)\s(strea[kpr\s\d]*[\dko])/i, // Dell Streak + /droid.+[;\/]\s*(Le[\s\-]+Pan)[\s\-]+(\w{1,9})\s+build/i, // Le Pan Tablets + /droid.+[;\/]\s*(Trinity)[\-\s]*(T\d{3})\s+build/i, // Trinity Tablets /droid.+(Gigaset)[\s\-]+(Q\w{1,9})\s+build/i // Gigaset Tablets ], [VENDOR, MODEL, [TYPE, TABLET]], [ + /sie-(\w*)/i // Siemens + ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ + /droid.+[;\/]\s*(RCT[\d\w]+)\s+build/i // RCA Tablets + ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [ + /droid.+[;\/\s](Venue[\d\s]{2,7})\s+build/i // Dell Venue Tablets + ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ + /droid.+[;\/]\s*(Q[T|M][\d\w]+)\s+build/i // Verizon Tablet + ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ + /droid.+[;\/]\s+(Barnes[&\s]+Noble\s+|BN[RT])(\S(?:.*\S)?)\s+build/i + ], [[VENDOR, 'Barnes & Noble'], MODEL, [TYPE, TABLET]], [ + /droid.+[;\/]\s+(TM\d{3}.*\b)\s+build/i // Barnes & Noble Tablet + ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [ + /droid.+;\s(k88)\sbuild/i // ZTE K Series Tablet + ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [ + /droid.+;\s(nx\d{3}j)\sbuild/i // ZTE Nubia + ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [ + /droid.+[;\/]\s*(gen\d{3})\s+build.*49h/i // Swiss GEN Mobile + ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [ + /droid.+[;\/]\s*(zur\d{3})\s+build/i // Swiss ZUR Tablet + ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ + /droid.+[;\/]\s*((Zeki)?TB.*\b)\s+build/i // Zeki Tablets + ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ + /(droid).+[;\/]\s+([YR]\d{2})\s+build/i, + /droid.+[;\/]\s+(Dragon[\-\s]+Touch\s+|DT)(\w{5})\sbuild/i // Dragon Touch Tablet + ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [ + /droid.+[;\/]\s*(NS-?\w{0,9})\sbuild/i // Insignia Tablets + ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [ + /droid.+[;\/]\s*((NXA|Next)-?\w{0,9})\s+build/i // NextBook Tablets + ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [ + /droid.+[;\/]\s*(Xtreme\_)?(V(1[045]|2[015]|30|40|60|7[05]|90))\s+build/i + ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ // Voice Xtreme Phones + /droid.+[;\/]\s*(LVTEL\-)?(V1[12])\s+build/i // LvTel Phones + ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [ + /droid.+;\s(PH-1)\s/i + ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ // Essential PH-1 + /droid.+[;\/]\s*(V(100MD|700NA|7011|917G).*\b)\s+build/i // Envizen Tablets + ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [ + /droid.+[;\/]\s*(Trio[\s\w\-\.]+)\s+build/i // MachSpeed Tablets + ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [ + /droid.+[;\/]\s*TU_(1491)\s+build/i // Rotor Tablets + ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [ + //android.+(KS(.+))\s+build/i // Amazon Kindle Tablets + //], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ + /(sprint\s(\w+))/i // Sprint Phones + ], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [ + /(kin\.[onetw]{3})/i // Microsoft Kin + ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ + + // CONSOLES + /\s(ouya)\s/i, // Ouya + /(nintendo)\s([wids3utch]+)/i // Nintendo + ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ + /droid.+;\s(shield)\sbuild/i // Nvidia + ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ + /(playstation\s[345portablevi]+)/i // Playstation + ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [ + /[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox + ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [ + + // SMARTTVS + /smart-tv.+(samsung)/i // Samsung + ], [VENDOR, [TYPE, SMARTTV], MODEL], [ + /hbbtv.+maple;(\d+)/i + ], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [ + /linux;\snetcast.+smarttv/i, // LG SmartTV + /lg\snetcast\.tv-201\d/i + ], [[VENDOR, 'LG'], MODEL, [TYPE, SMARTTV]], [ + /(apple)\s?tv/i // Apple TV + ], [VENDOR, [MODEL, 'Apple TV'], [TYPE, SMARTTV]], [ + /crkey/i // Google Chromecast + ], [[MODEL, 'Chromecast'], [VENDOR, 'Google'], [TYPE, SMARTTV]], [ + /droid.+aft([\w])(\sbuild\/|\))/i // Fire TV + ], [MODEL, [VENDOR, 'Amazon'], [TYPE, SMARTTV]], [ + /\(dtv[\);].+(aquos)/i // Sharp + ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ + /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices + ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [ /[\s\/\(](android\stv|smart-?tv)[;\)\s]/i // SmartTV from Unidentified Vendors ], [[TYPE, SMARTTV]], [ - // Android Phones from Unidentified Vendors - /droid .+?; ([^;]+?)(?: build|\) applewebkit).+? mobile safari/i - ], [MODEL, [TYPE, MOBILE]], [ - // Android Tablets from Unidentified Vendors - /droid .+?;\s([^;]+?)(?: build|\) applewebkit).+?(?! mobile) safari/i - ], [MODEL, [TYPE, TABLET]], [ + // WEARABLES + /((pebble))app\/[\d\.]+\s/i // Pebble + ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ + /droid.+;\s(glass)\s\d/i // Google Glass + ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [ + + // OTHERS + /droid .+?; ([^;]+?)(?: build|\) applewebkit).+? mobile safari/i // Android Phones from Unidentified Vendors + ], [MODEL, [TYPE, MOBILE]], [ + /droid .+?;\s([^;]+?)(?: build|\) applewebkit).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors + ], [MODEL, [TYPE, TABLET]], [ /\s(tablet|tab)[;\/]/i, // Unidentifiable Tablet /\s(mobile)(?:[;\/]|\ssafari)/i // Unidentifiable Mobile - ], [[TYPE, util.lowerize], VENDOR, MODEL], [ - + ], [[TYPE, util.lowerize]], [ /(android[\w\.\s\-]{0,9});.+build/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']], [ - /(phone)/i ], [[TYPE, MOBILE]] ], @@ -706,27 +636,32 @@ os : [[ - // Xbox, consider this before other Windows-based devices - /(xbox);\s+xbox\s([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) - - // Windows based + // Windows /microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ /(windows)\snt\s6\.2;\s(arm)/i, // Windows RT /(windows\sphone(?:\sos)*)[\s\/]?([\d\.\s\w]*)/i, // Windows Phone - /(windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i + /(windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)(?!.+xbox)/i ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [ /(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [ - // Mobile/Embedded OS + // iOS/macOS + /ip[honead]{2,4}(?:.*os\s([\w]+)\slike\smac|;\sopera)/i, // iOS + /cfnetwork\/.+darwin/i + ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ + /(mac\sos\sx)\s?([\w\s\.]*)/i, + /(macintosh|mac(?=_powerpc)\s)(?!.+haiku)/i // Mac OS + ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ + + // Mobile OSes + /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, + // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS + /(blackberry)\w*\/?([\w\.]*)/i, // Blackberry + /(tizen|kaios)[\/\s]([\w\.]+)/i // Tizen/KaiOS + ], [NAME, VERSION], [ /\((bb)(10);/i // BlackBerry 10 ], [[NAME, 'BlackBerry'], VERSION], [ - /(blackberry)\w*\/?([\w\.]*)/i, // Blackberry - /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS - /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i - // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS - ], [NAME, VERSION], [ /(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]*)/i // Symbian ], [[NAME, 'Symbian'], VERSION], [ /\((series40);/i // Series 40 @@ -740,6 +675,7 @@ // Console /(nintendo|playstation)\s([wids345portablevuch]+)/i, // Nintendo/Playstation + /(xbox);\s+xbox\s([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) // GNU/Linux based /(mint)[\/\s\(]?(\w*)/i, // Mint @@ -765,14 +701,6 @@ /(haiku)\s(\w+)/i // Haiku ], [NAME, VERSION],[ - /cfnetwork\/.+darwin/i, - /ip[honead]{2,4}(?:.*os\s([\w]+)\slike\smac|;\sopera)/i // iOS - ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ - - /(mac\sos\sx)\s?([\w\s\.]*)/i, - /(macintosh|mac(?=_powerpc)\s)/i // Mac OS - ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ - // Other /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris /(aix)\s((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX From bb16473fac73030500a79875802767a23584c720 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 19 Mar 2021 19:09:24 +0700 Subject: [PATCH 056/121] Fix #427 - Trying GitHub Actions --- .github/run-test.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/run-test.yml diff --git a/.github/run-test.yml b/.github/run-test.yml new file mode 100644 index 0000000..4c0eab2 --- /dev/null +++ b/.github/run-test.yml @@ -0,0 +1,17 @@ +name: ua-parser-js-run-test + +on: [push, pull_request] + +jobs: + run-test: + runs-on: ubuntu-latest + strategy: + matrix: + arch: [amd64, ppc64le] + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + - name: Run the test + run: | + npm install + npm test From db381cad920b6b9f517c347025f1e116630c8cca Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 19 Mar 2021 19:16:36 +0700 Subject: [PATCH 057/121] Change mocha reporter for CI --- .github/run-test.yml | 2 +- .travis.yml | 2 ++ package.json | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/run-test.yml b/.github/run-test.yml index 4c0eab2..ab126d2 100644 --- a/.github/run-test.yml +++ b/.github/run-test.yml @@ -14,4 +14,4 @@ jobs: - name: Run the test run: | npm install - npm test + npm run test-ci diff --git a/.travis.yml b/.travis.yml index 7e3cc8e..0f87fc3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,3 +14,5 @@ cache: - node_modules sudo: false + +script: npm run test-ci \ No newline at end of file diff --git a/package.json b/package.json index aa7b064..8035f40 100644 --- a/package.json +++ b/package.json @@ -101,6 +101,7 @@ "scripts": { "build": "uglifyjs src/ua-parser.js -o dist/ua-parser.min.js --comments '/UAParser\\.js/' && uglifyjs src/ua-parser.js -o dist/ua-parser.pack.js --comments '/UAParser\\.js/' --compress --mangle", "test": "jshint src/ua-parser.js && mocha -R nyan test/test.js", + "test-ci": "jshint src/ua-parser.js && mocha -R spec test/test.js", "verup": "node ./node_modules/verup", "version": "node ./node_modules/verup 0" }, From 10475761cf8e2e69cb897c507445e6b3944930dd Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 19 Mar 2021 19:29:11 +0700 Subject: [PATCH 058/121] Action doesn't work, should be under /.github/workflows folder perhaps --- .github/{ => workflows}/run-test.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{ => workflows}/run-test.yml (100%) diff --git a/.github/run-test.yml b/.github/workflows/run-test.yml similarity index 100% rename from .github/run-test.yml rename to .github/workflows/run-test.yml From e1905168a856ba7a759a572c95f3401513ea9abe Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 20 Mar 2021 07:53:30 +0700 Subject: [PATCH 059/121] Fix #438 Add Zebra devices --- readme.md | 2 +- src/ua-parser.js | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 0e7297c..75783d9 100644 --- a/readme.md +++ b/readme.md @@ -56,7 +56,7 @@ console, mobile, tablet, smarttv, wearable, embedded Acer, Alcatel, Amazon, Apple, Archos, Asus, BenQ, BlackBerry, Dell, Essential, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, Ouya, Palm, Panasonic, Pebble, Polytron, -RIM, Samsung, Sharp, Siemens, Sony[Ericsson], Sprint, Xbox, Xiaomi, ZTE, ... +RIM, Samsung, Sharp, Siemens, Sony[Ericsson], Sprint, Xbox, Xiaomi, Zebra, ZTE, ... # 'device.model' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index d05b519..45e67b4 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -563,6 +563,13 @@ /(kin\.[onetw]{3})/i // Microsoft Kin ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ + /droid\s[\d\.]+;\s(cc6{3,4}|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra + ], [MODEL, [VENDOR, 'Zebra'], [TYPE, TABLET]], [ + /droid\s[\d\.]+;\s(ec30|ps20|tc[2-8]\d[kx])\)/i + ], [MODEL, [VENDOR, 'Zebra'], [TYPE, MOBILE]], [ + /droid\s[\d\.]+;\s(wt63?0{2,3})\)/i + ], [MODEL, [VENDOR, 'Zebra'], [TYPE, WEARABLE]], [ + // CONSOLES /\s(ouya)\s/i, // Ouya /(nintendo)\s([wids3utch]+)/i // Nintendo From 1667f5f2b2561e210cf992c041b82b09febedcd4 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 21 Mar 2021 03:35:39 +0700 Subject: [PATCH 060/121] Update README contents & structures --- readme.md | 160 ++++++++++++++++++++++-------------------------------- 1 file changed, 64 insertions(+), 96 deletions(-) diff --git a/readme.md b/readme.md index 0e7297c..9b3a606 100644 --- a/readme.md +++ b/readme.md @@ -1,18 +1,49 @@ +

+ +

+ +

+ + + +

+ # UAParser.js - A JavaScript-based User-Agent string parser. Can be used either in browser (client-side) or in node.js (server-side) environment. Also available as jQuery/Zepto plugin, Bower/Meteor package, & RequireJS/AMD module. This library aims to identify detailed type of web browser, layout engine, operating system, cpu architecture, and device type/model, entirely from user-agent string with a relatively small footprint (~17KB when minified / ~6KB gzipped). Written in vanilla JavaScript, which means it doesn't require any other library and can be used independently. However, it's not recommended to use this library as browser detection since the result may not be more accurate than using feature detection. - -[![Build Status](https://travis-ci.org/faisalman/ua-parser-js.svg?branch=master)](https://travis-ci.org/faisalman/ua-parser-js) -[![NPM downloads](https://img.shields.io/npm/dw/ua-parser-js.svg)](https://www.npmjs.com/package/ua-parser-js) -[![NPM](https://img.shields.io/npm/v/ua-parser-js.svg)](https://www.npmjs.com/package/ua-parser-js) -[![Bower](https://img.shields.io/bower/v/ua-parser-js.svg)](https://bower.io/) -[![CDNJS](https://img.shields.io/cdnjs/v/UAParser.js.svg)](https://cdnjs.com/libraries/UAParser.js) +JavaScript library with relatively small footprint (~17KB minified, ~6KB gzipped) that can be used either in browser (client-side) or node.js (server-side) to detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. * Author : Faisal Salman <> * Demo : http://faisalman.github.io/ua-parser-js * Source : https://github.com/faisalman/ua-parser-js -# Constructor + +# Development + +## Sponsors + + + + + +## Contributors + + + + + +Made with [contributors-img](https://contrib.rocks). + +## How To Contribute + +* Fork and clone this repository +* Make some changes as required +* Write unit test to showcase its functionality +* Run the test suites to make sure it's not breaking anything `$ npm test` +* Submit a pull request under `develop` branch + +# Documentation + +## Constructor * `new UAParser([uastring][,extensions])` * returns new instance @@ -20,7 +51,7 @@ * `UAParser([uastring][,extensions])` * returns result object `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }` -# Methods +## Methods * `getBrowser()` * returns `{ name: '', version: '' }` @@ -103,11 +134,12 @@ WebOS, Windows [Phone/Mobile], Zenwalk, ... * returns UA string of current instance * `setUA(uastring)` - * set UA string to parse + * set UA string to be parsed * returns current instance +# Usage -# Example +## Using HTML ```html @@ -117,16 +149,15 @@ WebOS, Windows [Phone/Mobile], Zenwalk, ... -``` - -## Using bower - -```sh -$ bower install ua-parser-js -``` - -## Using meteor - -```sh -$ meteor add faisalman:ua-parser-js -``` - ## Using TypeScript ```sh @@ -245,18 +242,18 @@ $ npm install --save @types/ua-parser-js ## Using jQuery/Zepto ($.ua) -Although written in vanilla js (which means it doesn't depends on jQuery), this library will automatically detect if jQuery/Zepto is present and create `$.ua` object based on browser's user-agent (although in case you need, `window.UAParser` constructor is still present). To get/set user-agent you can use: `$.ua.get()` / `$.ua.set(uastring)`. +Although written in vanilla js, this library will automatically detect if jQuery/Zepto is present and create `$.ua` object (with values based on its User-Agent) along with `window.UAParser` constructor. To get/set user-agent you can use: `$.ua.get()` / `$.ua.set(uastring)`. ```js -// In browser with default user-agent: 'Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0': +// Say we are in a browser with default user-agent: 'Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0': -// Do some tests +// Get the details console.log($.ua.device); // {vendor: "HTC", model: "Evo Shift 4G", type: "mobile"} console.log($.ua.os); // {name: "Android", version: "2.3.4"} console.log($.ua.os.name); // "Android" console.log($.ua.get()); // "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0" -// reset to custom user-agent +// Now lets try to reset to another custom user-agent $.ua.set('Mozilla/5.0 (Linux; U; Android 3.0.1; en-us; Xoom Build/HWI69) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13'); // Test again @@ -270,49 +267,20 @@ console.log(parseInt($.ua.browser.version.split('.')[0], 10)); // 4 $('body').addClass('ua-browser-' + $.ua.browser.name + ' ua-devicetype-' + $.ua.device.type); ``` -## Extending regex patterns +## Using Extension * `UAParser([uastring,] extensions)` -Pass your own regexes to extend the limited matching rules. - ```js // Example: -var myOwnRegex = [[/(myownbrowser)\/([\w\.]+)/i], [UAParser.BROWSER.NAME, UAParser.BROWSER.VERSION]]; -var myParser = new UAParser({ browser: myOwnRegex }); -var uaString = 'Mozilla/5.0 MyOwnBrowser/1.3'; -console.log(myParser.setUA(uaString).getBrowser()); // {name: "MyOwnBrowser", version: "1.3"} +var myOwnListOfBrowsers = [ + [/(mybrowser)\/([\w\.]+)/i], [UAParser.BROWSER.NAME, UAParser.BROWSER.VERSION] +]; +var myParser = new UAParser({ browser: myOwnListOfBrowsers }); +var myUA = 'Mozilla/5.0 MyBrowser/1.3'; +console.log(myParser.setUA(myUA).getBrowser()); // {name: "MyBrowser", version: "1.3"} ``` - -# Development - -## Contribute - -* Fork and clone this repository -* Make some changes as required -* Write a unit test to showcase your feature -* Run the test suites to make sure the changes you made didn't break anything `$ npm run test` -* Commit and push to your own repository -* Submit a pull request to this repository under `develop` branch -* Profit? $$$ - -## Build - -Build a minified & packed script - -```sh -$ npm run build -``` - - -# Donate - -Do you use & like UAParser.js but you don’t find a way to show some love? If yes, please consider donating to support this project. Otherwise, no worries, regardless of whether there is support or not, I will keep maintaining this project. Still, if you buy me a cup of coffee I would be more than happy though :) - -[![Support via PayPal](https://cdn.rawgit.com/twolfson/paypal-github-button/1.0.0/dist/button.svg)](https://www.paypal.me/faisalman/) - - # License MIT License From 8c2b84fc31f62a4de9f8b1a6742097af4b73cf08 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 20 Mar 2021 07:53:30 +0700 Subject: [PATCH 061/121] Enforce maximum limit to user-agent input --- readme.md | 2 +- src/ua-parser.js | 80 ++++++++++++++++++++++++++---------------------- test/test.js | 31 +++++++++++++------ 3 files changed, 65 insertions(+), 48 deletions(-) diff --git a/readme.md b/readme.md index 0e7297c..75783d9 100644 --- a/readme.md +++ b/readme.md @@ -56,7 +56,7 @@ console, mobile, tablet, smarttv, wearable, embedded Acer, Alcatel, Amazon, Apple, Archos, Asus, BenQ, BlackBerry, Dell, Essential, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, Ouya, Palm, Panasonic, Pebble, Polytron, -RIM, Samsung, Sharp, Siemens, Sony[Ericsson], Sprint, Xbox, Xiaomi, ZTE, ... +RIM, Samsung, Sharp, Siemens, Sony[Ericsson], Sprint, Xbox, Xiaomi, Zebra, ZTE, ... # 'device.model' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index d05b519..e00be6a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -35,7 +35,8 @@ TABLET = 'tablet', SMARTTV = 'smarttv', WEARABLE = 'wearable', - EMBEDDED = 'embedded'; + EMBEDDED = 'embedded', + UA_MAX_LENGTH = 255; /////////// @@ -56,11 +57,7 @@ return mergedRegexes; }, has : function (str1, str2) { - if (typeof str1 === "string") { - return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1; - } else { - return false; - } + return typeof str1 === STR_TYPE ? str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1 : false; }, lowerize : function (str) { return str.toLowerCase(); @@ -68,8 +65,9 @@ major : function (version) { return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g,'').split(".")[0] : undefined; }, - trim : function (str) { - return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + trim : function (str, len) { + str = str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); } }; @@ -563,6 +561,13 @@ /(kin\.[onetw]{3})/i // Microsoft Kin ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ + /droid\s[\d\.]+;\s(cc6{3,4}|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra + ], [MODEL, [VENDOR, 'Zebra'], [TYPE, TABLET]], [ + /droid\s[\d\.]+;\s(ec30|ps20|tc[2-8]\d[kx])\)/i + ], [MODEL, [VENDOR, 'Zebra'], [TYPE, MOBILE]], [ + /droid\s[\d\.]+;\s(wt63?0{2,3})\)/i + ], [MODEL, [VENDOR, 'Zebra'], [TYPE, WEARABLE]], [ + // CONSOLES /\s(ouya)\s/i, // Ouya /(nintendo)\s([wids3utch]+)/i // Nintendo @@ -715,45 +720,45 @@ ///////////////// // Constructor //////////////// - var UAParser = function (uastring, extensions) { + var UAParser = function (ua, extensions) { - if (typeof uastring === 'object') { - extensions = uastring; - uastring = undefined; + if (typeof ua === 'object') { + extensions = ua; + ua = undefined; } - + if (!(this instanceof UAParser)) { - return new UAParser(uastring, extensions).getResult(); + return new UAParser(ua, extensions).getResult(); } - - var ua = uastring || ((typeof window !== 'undefined' && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); - var rgxmap = extensions ? util.extend(regexes, extensions) : regexes; - + + var _ua; + var _rgxmap = extensions ? util.extend(regexes, extensions) : regexes; + this.getBrowser = function () { - var browser = { name: undefined, version: undefined }; - mapper.rgx.call(browser, ua, rgxmap.browser); - browser.major = util.major(browser.version); // deprecated - return browser; + var _browser = { name: undefined, version: undefined }; + mapper.rgx.call(_browser, _ua, _rgxmap.browser); + _browser.major = util.major(_browser.version); // deprecated + return _browser; }; this.getCPU = function () { - var cpu = { architecture: undefined }; - mapper.rgx.call(cpu, ua, rgxmap.cpu); - return cpu; + var _cpu = { architecture: undefined }; + mapper.rgx.call(_cpu, _ua, _rgxmap.cpu); + return _cpu; }; this.getDevice = function () { - var device = { vendor: undefined, model: undefined, type: undefined }; - mapper.rgx.call(device, ua, rgxmap.device); - return device; + var _device = { vendor: undefined, model: undefined, type: undefined }; + mapper.rgx.call(_device, _ua, _rgxmap.device); + return _device; }; this.getEngine = function () { - var engine = { name: undefined, version: undefined }; - mapper.rgx.call(engine, ua, rgxmap.engine); - return engine; + var _engine = { name: undefined, version: undefined }; + mapper.rgx.call(_engine, _ua, _rgxmap.engine); + return _engine; }; this.getOS = function () { - var os = { name: undefined, version: undefined }; - mapper.rgx.call(os, ua, rgxmap.os); - return os; + var _os = { name: undefined, version: undefined }; + mapper.rgx.call(_os, _ua, _rgxmap.os); + return _os; }; this.getResult = function () { return { @@ -766,12 +771,13 @@ }; }; this.getUA = function () { - return ua; + return _ua; }; - this.setUA = function (uastring) { - ua = uastring; + this.setUA = function (ua) { + _ua = ua.length > UA_MAX_LENGTH ? util.trim(ua, UA_MAX_LENGTH) : ua; return this; }; + this.setUA(ua || ((typeof window !== 'undefined' && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY)); return this; }; diff --git a/test/test.js b/test/test.js index 99e53ff..b0e699c 100644 --- a/test/test.js +++ b/test/test.js @@ -41,7 +41,7 @@ var methods = [ describe('UAParser()', function () { var ua = 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6'; - assert.deepEqual(UAParser(ua), new UAParser().setUA(ua).getResult()); + assert.deepStrictEqual(UAParser(ua), new UAParser().setUA(ua).getResult()); }); for (var i in methods) { @@ -55,7 +55,7 @@ for (var i in methods) { methods[i]['properties'].forEach(function(m) { it('should return ' + methods[i]['label'] + ' ' + m + ': ' + expect[m], function () { - assert.equal(result[m], expect[m] != 'undefined' ? expect[m] : undefined); + assert.strictEqual(result[m], expect[m] != 'undefined' ? expect[m] : undefined); }); }); }); @@ -67,7 +67,7 @@ for (var i in methods) { describe('Returns', function () { it('getResult() should returns JSON', function(done) { - assert.deepEqual(new UAParser('').getResult(), + assert.deepStrictEqual(new UAParser('').getResult(), { ua : '', browser: { name: undefined, version: undefined, major: undefined }, @@ -85,15 +85,26 @@ describe('Extending Regex', function () { var myOwnBrowser = [[/(myownbrowser)\/((\d+)?[\w\.]+)/i], [UAParser.BROWSER.NAME, UAParser.BROWSER.VERSION, UAParser.BROWSER.MAJOR]]; var parser1 = new UAParser(uaString, {browser: myOwnBrowser}); - assert.equal(parser1.getBrowser().name, 'MyOwnBrowser'); - assert.equal(parser1.getBrowser().version, '1.3'); - assert.equal(parser1.getBrowser().major, '1'); + assert.strictEqual(parser1.getBrowser().name, 'MyOwnBrowser'); + assert.strictEqual(parser1.getBrowser().version, '1.3'); + assert.strictEqual(parser1.getBrowser().major, '1'); var parser2 = new UAParser({browser: myOwnBrowser}); - assert.equal(parser2.getBrowser().name, undefined); + assert.strictEqual(parser2.getBrowser().name, undefined); parser2.setUA(uaString); - assert.equal(parser2.getBrowser().name, 'MyOwnBrowser'); - assert.equal(parser1.getBrowser().version, '1.3'); + assert.strictEqual(parser2.getBrowser().name, 'MyOwnBrowser'); + assert.strictEqual(parser1.getBrowser().version, '1.3'); +}); + +describe('User-agent length', function () { + var UA_MAX_LENGTH = 255; + + // Real data from https://stackoverflow.com/questions/654921/how-big-can-a-user-agent-string-get#answer-6595973 + var uaString = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; (R1 1.6); SLCC1; .NET CLR 2.0.50727; InfoPath.2; OfficeLiveConnector.1.3; OfficeLivePatch.0.0; .NET CLR 3.5.30729; .NET CLR 3.0.30618; 66760635803; runtime 11.00294; 876906799603; 97880703; 669602703; 9778063903; 877905603; 89670803; 96690803; 8878091903; 7879040603; 999608065603; 799808803; 6666059903; 669602102803; 888809342903; 696901603; 788907703; 887806555703; 97690214703; 66760903; 968909903; 796802422703; 8868026703; 889803611803; 898706903; 977806408603; 976900799903; 9897086903; 88780803; 798802301603; 9966008603; 66760703; 97890452603; 9789064803; 96990759803; 99960107703; 8868087903; 889801155603; 78890703; 8898070603; 89970603; 89970539603; 89970488703; 8789007603; 87890903; 877904603; 9887077703; 798804903; 97890264603; 967901703; 87890703; 97690420803; 79980706603; 9867086703; 996602846703; 87690803; 6989010903; 977809603; 666601903; 876905337803; 89670603; 89970200903; 786903603; 696901911703; 788905703; 896709803; 96890703; 998601903; 88980703; 666604769703; 978806603; 7988020803; 996608803; 788903297903; 98770043603; 899708803; 66960371603; 9669088903; 69990703; 99660519903; 97780603; 888801803; 9867071703; 79780803; 9779087603; 899708603; 66960456803; 898706824603; 78890299903; 99660703; 9768079803; 977901591603; 89670605603; 787903608603; 998607934903; 799808573903; 878909603; 979808146703; 9996088603; 797803154903; 69790603; 99660565603; 7869028603; 896707703; 97980965603; 976907191703; 88680703; 888809803; 69690903; 889805523703; 899707703; 997605035603; 89970029803; 9699094903; 877906803; 899707002703; 786905857603; 69890803; 97980051903; 997603978803; 9897097903; 66960141703; 7968077603; 977804603; 88980603; 989700803; 999607887803; 78690772803; 96990560903; 98970961603; 9996032903; 9699098703; 69890655603; 978903803; 698905066803; 977806903; 9789061703; 967903747703; 976900550903; 88980934703; 8878075803; 8977028703; 97980903; 9769006603; 786900803; 98770682703; 78790903; 878906967903; 87690399603; 99860976703; 796805703; 87990603; 968906803; 967904724603; 999606603; 988705903; 989702842603; 96790603; 99760703; 88980166703; 9799038903; 98670903; 697905248603; 7968043603; 66860703; 66860127903; 9779048903; 89670123903; 78890397703; 97890603; 87890803; 8789030603; 69990603; 88880763703; 9769000603; 96990203903; 978900405903; 7869022803; 699905422903; 97890703; 87990903; 878908703; 7998093903; 898702507603; 97780637603; 966907903; 896702603; 9769004803; 7869007903; 99660158803; 7899099603; 8977055803; 99660603; 7889080903; 66660981603; 997604603; 6969089803; 899701903; 9769072703; 666603903; 99860803; 997608803; 69790903; 88680756703; 979805677903; 9986047703; 89970803; 66660603; 96690903; 8997051603; 789901209803; 8977098903; 968900326803; 87790703; 98770024803; 697901794603; 69990803; 887805925803; 968908903; 97880603; 897709148703; 877909476903; 66760197703; 977908603; 698902703; 988706504803; 977802026603; 88680964703; 8878068703; 987705107903; 978902878703; 8898069803; 9768031703; 79680803; 79980803; 669609328703; 89870238703; 99960593903; 969904218703; 78890603; 9788000703; 69690630903; 889800982903; 988709748803; 7968052803; 99960007803; 969900800803; 668604817603; 66960903; 78790734603; 8868007703; 79780034903; 8878085903; 976907603; 89670830803; 877900903; 969904889703; 7978033903; 8987043903; 99860703; 979805903; 667603803; 976805348603; 999604127603; 97790701603; 78990342903; 98770672903; 87990253903; 9877027703; 97790803; 877901895603; 8789076903; 896708595603; 997601903; 799806903; 97690603; 87790371703; 667605603; 99760303703; 97680283803; 788902750803; 787909803; 79780603; 79880866903; 9986050903; 87890543903; 979800803; 97690179703; 876901603; 699909903; 96990192603; 878904903; 877904734903; 796801446903; 977904803; 9887044803; 797805565603; 98870789703; 7869093903; 87790727703; 797801232803; 666604803; 9778071903; 9799086703; 6969000903; 89670903; 8799075903; 897708903; 88680903; 97980362603; 97980503903; 889803256703; 88980388703; 789909376803; 69690703; 6969025903; 89970309903; 96690703; 877901847803; 968901903; 96690603; 88680607603; 7889001703; 789904761803; 976807703; 976902903; 878907889703; 9897014903; 896707046603; 696909903; 666603998903; 969902703; 79680421803; 9769075603; 798800192703; 97990903; 9689024903; 668604803; 969908671903; 9996094703; 69990642703; 97890895903; 977805619903; 79980859903; 88980443803; 98970649603; 997602703; 888802169903; 699907803; 667602028803; 786903283903; 997607703; 969909803; 798809925903; 9976045603; 97790903; 9789001903; 966903603; 9789069603; 968906603; 6989091803; 896701603; 6979059803; 978803903; 997606362603; 88980803; 98970803; 88880921703; 8997065703; 899700703; 698908703; 797801027903; 7889050903; 87890603; 78690703; 99660069703; 97980309903; 976800603; 666606803; 898707703; 79880019803; 66960250803; 7978049803; 88780602603; 79680903; 88880792703; 96990903; 667608603; 87790730903; 98970903; 9699032903; 8987004803; 88880703; 89770046603; 978800803; 969908903; 9798022603; 696901903; 799803703; 989703703; 668605903; 79780903; 998601371703; 796803339703; 87890922603; 898708903; 9966061903; 66960891903; 96790903; 8779050803; 98870858803; 976909298603; 9887029903; 669608703; 979806903; 878903803; 99960703; 9789086703; 979801803; 66960008703; 979806830803; 99760212703; 786906603; 797807603; 789907297703; 96990703; 786901603; 796807766603; 896702651603; 789902585603; 66660925903; 9986085703; 66960302703; 69890703; 789900703; 89970903; 9679060703; 9789002903; 979908821603; 986708140803; 976809828703; 7988082803; 79680997903; 99960803; 9788081903; 979805703; 787908603; 66960602803; 9887098703; 978803237703; 888806804603; 999604703; 977904703; 966904635703; 97680291703; 977809345603; 8878046703; 988709803; 976900773603; 989703903; 88780198603; 87790603; 986708703; 78890604703; 87790544803; 976809850903; 887806703; 987707527603; 79880803; 9897059603; 897709820603; 97880804803; 66960026703; 9789062803; 9867090803; 669600603; 8967087703; 78890903; 89770903; 97980703; 976802687603; 66860400803; 979901288603; 96990160903; 99860228903; 966900703; 66760603; 9689035703; 9779064703; 7968023603; 87890791903; 98770870603; 9798005803; 6969087903; 9779097903; 6979065703; 699903252603; 79780989703; 87690901803; 978905763903; 977809703; 97790369703; 899703269603; 8878012703; 78790803; 87690395603; 8888042803; 667607689903; 8977041803; 6666085603; 6999080703; 69990797803; 88680721603; 99660519803; 889807603; 87890146703; 699906325903; 89770603; 669608615903; 9779028803; 88880603; 97790703; 79780703; 97680355603; 6696024803; 78790784703; 97880329903; 9699077703; 89870803; 79680227903; 976905852703; 8997098903; 896704796703; 66860598803; 9897036703; 66960703; 9699094703; 9699008703; 97780485903; 999603179903; 89770834803; 96790445603; 79680460903; 9867009603; 89870328703; 799801035803; 989702903; 66960758903; 66860150803; 6686088603; 9877092803; 96990603; 99860603; 987703663603; 98870903; 699903325603; 87790803; 97680703; 8868030703; 9799030803; 89870703; 97680803; 9669054803; 6979097603; 987708046603; 999608603; 878904803; 998607408903; 968903903; 696900703; 977907491703; 6686033803; 669601803; 99960290603; 887809169903; 979803703; 69890903; 699901447903; 8987064903; 799800603; 98770903; 8997068703; 967903603; 66760146803; 978805087903; 697908138603; 799801603; 88780964903; 989708339903; 8967048603; 88880981603; 789909703; 796806603; 977905977603; 989700603; 97780703; 9669062603; 88980714603; 897709545903; 988701916703; 667604694903; 786905664603; 877900803; 886805490903; 89970559903; 99960531803; 7998033903; 98770803; 78890418703; 669600872803; 996605216603; 78690962703; 667604903; 996600903; 999608903; 9699083803; 787901803; 97780707603; 787905312703; 977805803; 8977033703; 97890708703; 989705521903; 978800703; 698905703; 78890376903; 878907703; 999602903; 986705903; 668602719603; 979901803; 997606903; 66760393903; 987703603; 78790338903; 96890803; 97680596803; 666601603; 977902178803; 877902803; 78790038603; 8868075703; 99960060603)'; + + it('greater than ' + UA_MAX_LENGTH + ' should be trimmed down', function () { + assert.strictEqual(UAParser(uaString).ua.length, UA_MAX_LENGTH); + }); }); describe('Using Require.js', function () { @@ -106,7 +117,7 @@ describe('Using Require.js', function () { }); requirejs(['ua-parser-js'], function(ua) { var parser = new ua('Dillo/1.0'); - assert.deepEqual(parser.getBrowser().name, 'Dillo'); + assert.deepStrictEqual(parser.getBrowser().name, 'Dillo'); done(); }); }); From daeb118543dabad9c8d50ae51b87e63a82cf8de9 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 23 Mar 2021 20:31:09 +0700 Subject: [PATCH 062/121] Move documentation upwards and..mAkE tHe LoG0 BiG99eR!!1!1! --- readme.md | 53 ++++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/readme.md b/readme.md index 9b3a606..4969fee 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,5 @@

- +

@@ -10,37 +10,12 @@ # UAParser.js -JavaScript library with relatively small footprint (~17KB minified, ~6KB gzipped) that can be used either in browser (client-side) or node.js (server-side) to detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. +JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data with relatively small footprint (~17KB minified, ~6KB gzipped) that can be used either in browser (client-side) or node.js (server-side). * Author : Faisal Salman <> * Demo : http://faisalman.github.io/ua-parser-js * Source : https://github.com/faisalman/ua-parser-js - -# Development - -## Sponsors - - - - - -## Contributors - - - - - -Made with [contributors-img](https://contrib.rocks). - -## How To Contribute - -* Fork and clone this repository -* Make some changes as required -* Write unit test to showcase its functionality -* Run the test suites to make sure it's not breaking anything `$ npm test` -* Submit a pull request under `develop` branch - # Documentation ## Constructor @@ -281,6 +256,30 @@ var myUA = 'Mozilla/5.0 MyBrowser/1.3'; console.log(myParser.setUA(myUA).getBrowser()); // {name: "MyBrowser", version: "1.3"} ``` +# Development + +## Sponsors + + + + + +## Contributors + + + + + +Made with [contributors-img](https://contrib.rocks). + +## How To Contribute + +* Fork and clone this repository +* Make some changes as required +* Write unit test to showcase its functionality +* Run the test suites to make sure it's not breaking anything `$ npm test` +* Submit a pull request under `develop` branch + # License MIT License From 4d94c6b3e3bbd88c2c54ea040468d7870d60700b Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 23 Mar 2021 21:43:46 +0700 Subject: [PATCH 063/121] Add CDN links & insert npm fund --- package.json | 12 +++++++++++- readme.md | 8 +++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 8035f40..4514820 100644 --- a/package.json +++ b/package.json @@ -138,5 +138,15 @@ }, "bugs": "https://github.com/faisalman/ua-parser-js/issues", "demo": "https://faisalman.github.io/ua-parser-js", - "download": "https://raw.github.com/faisalman/ua-parser-js/master/dist/ua-parser.min.js" + "download": "https://raw.github.com/faisalman/ua-parser-js/master/dist/ua-parser.min.js", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ] } diff --git a/readme.md b/readme.md index 4969fee..3c8dda0 100644 --- a/readme.md +++ b/readme.md @@ -3,9 +3,11 @@

- - - + + + + +

# UAParser.js From effd766e3b2256f63e5cbfe4322bc7b2498a80e5 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 23 Mar 2021 23:37:43 +0700 Subject: [PATCH 064/121] Fix #422 Add ARMHF in CPU Arch detection --- readme.md | 2 +- src/ua-parser.js | 8 +++++++- test/cpu-test.json | 42 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 75783d9..8042448 100644 --- a/readme.md +++ b/readme.md @@ -93,7 +93,7 @@ WebOS, Windows [Phone/Mobile], Zenwalk, ... ```sh # Possible 'cpu.architecture' -68k, amd64, arm[64], avr, ia[32/64], irix[64], mips[64], pa-risc, ppc, sparc[64] +68k, amd64, arm[64/hf], avr, ia[32/64], irix[64], mips[64], pa-risc, ppc, sparc[64] ``` * `getResult()` diff --git a/src/ua-parser.js b/src/ua-parser.js index e00be6a..0b8f6c4 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -357,6 +357,12 @@ /((?:i[346]|x)86)[;\)]/i // IA32 ], [[ARCHITECTURE, 'ia32']], [ + /\b(aarch64|armv?8e?l?)\b/i // ARM64 + ], [[ARCHITECTURE, 'arm64']], [ + + /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF + ], [[ARCHITECTURE, 'armhf']], [ + // PocketPC mistakenly identified as PowerPC /windows\s(ce|mobile);\sppc;/i ], [[ARCHITECTURE, 'arm']], [ @@ -367,7 +373,7 @@ /(sun4\w)[;\)]/i // SPARC ], [[ARCHITECTURE, 'sparc']], [ - /((?:avr32|ia64(?=;))|68k(?=\))|arm(?:64|(?=v\d+[;l]))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i + /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?:64|(?=v(?:[1-7]|[5-7]1)l?|;))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC ], [[ARCHITECTURE, util.lowerize]] ], diff --git a/test/cpu-test.json b/test/cpu-test.json index f42ee76..a495ad1 100644 --- a/test/cpu-test.json +++ b/test/cpu-test.json @@ -40,7 +40,15 @@ } }, { - "desc" : "ARMv6", + "desc" : "ARM", + "ua" : "Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 635) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537", + "expect" : + { + "architecture" : "arm" + } + }, + { + "desc" : "ARMv61", "ua" : "Mozilla/5.0 (X11; U; Linux armv61; en-US; rv:1.9.1b2pre) Gecko/20081015 Fennec/1.0a1", "expect" : { @@ -49,12 +57,44 @@ }, { "desc" : "ARMv7", + "ua" : "Mozilla/5.0 (Linux ARMv7) WebKitGTK+/3.4.9 vimprobable2", + "expect" : + { + "architecture" : "arm" + } + }, + { + "desc" : "ARMv7l", + "ua" : "Mozilla/5.0 (SMART-TV; X11; Linux armv7l) AppleWebKit/537.42 (KHTML, like Gecko) Chromium/25.0.1349.2 Chrome/25.0.1349.2 Safari/537.42", + "expect" : + { + "architecture" : "arm" + } + }, + { + "desc" : "ARMv7l", "ua" : "Mozilla/5.0 (X11; CrOS armv7l 9765.85.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.123 Safari/537.36", "expect" : { "architecture" : "arm" } }, + { + "desc" : "ARMv8", + "ua" : "Mozilla/5.0 (X11; Linux armv8l; rv:45.0) Gecko/20100101 Firefox/45.0", + "expect" : + { + "architecture" : "arm64" + } + }, + { + "desc" : "AARCH64", + "ua" : "Mozilla/5.0 (X11; CrOS aarch64 13310.93.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.133 Safari/537.36", + "expect" : + { + "architecture" : "arm64" + } + }, { "desc" : "Pocket PC", "ua" : "Opera/9.7 (Windows Mobile; PPC; Opera Mobi/35166; U; en) Presto/2.2.1", From dff9746527a9778826442693b7a25851633b868e Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 24 Mar 2021 00:09:49 +0700 Subject: [PATCH 065/121] Fix #279 Remap old Edge versions <= 44 as suggested by @mikemaccana @callaginn --- src/ua-parser.js | 13 ++++++++++++- test/browser-test.json | 26 +++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 0b8f6c4..afcf232 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -169,6 +169,17 @@ '2.0.4' : '/419', '?' : '/' } + }, + oldEdge : { + version : { + '0.1' : '12.', + '21' : '13.', + '31' : '14.', + '39' : '15.', + '41' : '16.', + '42' : '17.', + '44' : '18.' + } } }, @@ -221,7 +232,7 @@ /(?:android.+crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS ], [VERSION, [NAME, 'Chrome']], [ /(?:edge|edgios|edga|edg)\/((\d+)?[\w\.]+)/i // Microsoft Edge - ], [VERSION, [NAME, 'Edge']], [ + ], [[VERSION, mapper.str, maps.browser.oldEdge.version], [NAME, 'Edge']], [ // Presto based /(opera\smini)\/([\w\.-]+)/i, // Opera Mini diff --git a/test/browser-test.json b/test/browser-test.json index 6ab7b57..99de839 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1109,13 +1109,33 @@ } }, { - "desc" : "Microsoft Edge", + "desc" : "Microsoft Edge 0.1", "ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0", "expect" : { "name" : "Edge", - "version" : "12.0", - "major" : "12" + "version" : "0.1", + "major" : "0" + } + }, + { + "desc" : "Microsoft Edge 44", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134", + "expect" : + { + "name" : "Edge", + "version" : "42", + "major" : "42" + } + }, + { + "desc" : "Microsoft Edge 44", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763", + "expect" : + { + "name" : "Edge", + "version" : "44", + "major" : "44" } }, { From 14e7dd3f864b696923aebd3c53bdae944976cc6b Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 24 Mar 2021 00:44:14 +0700 Subject: [PATCH 066/121] Fix #448 Add AT&T & Vodafone devices --- readme.md | 9 +++++---- src/ua-parser.js | 8 ++++++-- test/device-test.json | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 8042448..a6be6b9 100644 --- a/readme.md +++ b/readme.md @@ -53,10 +53,11 @@ Vivaldi, Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m, Whale Browser... console, mobile, tablet, smarttv, wearable, embedded # Possible 'device.vendor': -Acer, Alcatel, Amazon, Apple, Archos, Asus, BenQ, BlackBerry, Dell, Essential, -GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, Meizu, Microsoft, Motorola, -Nexian, Nintendo, Nokia, Nvidia, OnePlus, Ouya, Palm, Panasonic, Pebble, Polytron, -RIM, Samsung, Sharp, Siemens, Sony[Ericsson], Sprint, Xbox, Xiaomi, Zebra, ZTE, ... +Acer, Alcatel, Amazon, Apple, Archos, Asus, AT&T, BenQ, BlackBerry, Dell, +Essential, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, Meizu, +Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, Ouya, Palm, +Panasonic, Pebble, Polytron, RIM, Samsung, Sharp, Siemens, Sony[Ericsson], +Sprint, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... # 'device.model' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 0b8f6c4..8546d9a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -516,9 +516,13 @@ /(dell)\s(strea[kpr\s\d]*[\dko])/i, // Dell Streak /droid.+[;\/]\s*(Le[\s\-]+Pan)[\s\-]+(\w{1,9})\s+build/i, // Le Pan Tablets /droid.+[;\/]\s*(Trinity)[\-\s]*(T\d{3})\s+build/i, // Trinity Tablets - /droid.+(Gigaset)[\s\-]+(Q\w{1,9})\s+build/i // Gigaset Tablets + /droid.+(Gigaset)[\s\-]+(Q\w{1,9})\s+build/i, // Gigaset Tablets + /droid.+(vodafone)\s([\w\s]+)\)/i // Vodafone ], [VENDOR, MODEL, [TYPE, TABLET]], [ + + /\s(U304AA)\sbuild/i // AT&T + ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ /sie-(\w*)/i // Siemens ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ /droid.+[;\/]\s*(RCT[\d\w]+)\s+build/i // RCA Tablets @@ -603,7 +607,7 @@ ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [ - /[\s\/\(](android\stv|smart-?tv)[;\)\s]/i // SmartTV from Unidentified Vendors + /[\s\/\(](android\stv|smart[-\s]?tv)[;\)\s]/i // SmartTV from Unidentified Vendors ], [[TYPE, SMARTTV]], [ // WEARABLES diff --git a/test/device-test.json b/test/device-test.json index 4702024..2e3d5c6 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1516,6 +1516,42 @@ "type": "mobile" } }, + { + "desc": "Amazon Fire 7", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; KFAUWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/80.5.3 like Chrome/80.0.3987.162 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KFAUWI", + "type": "tablet" + } + }, + { + "desc": "AT&T Radiant Core U304AA", + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; U304AA Build/P00610)", + "expect": { + "vendor": "AT&T", + "model": "U304AA", + "type": "mobile" + } + }, + { + "desc": "Vodafone Smart Tab 4G", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; Vodafone Smart Tab 4G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", + "expect": { + "vendor": "Vodafone", + "model": "Smart Tab 4G", + "type": "tablet" + } + }, + { + "desc": "4ife 4K Smart TV Box", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; 4ife 4K Smart TV Box Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36 Vinebre", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } + }, { "desc": "FaceBook Mobile App", "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", From 94d3550844437665ffaf1a9a2403768c9f4378cf Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 24 Mar 2021 01:09:34 +0700 Subject: [PATCH 067/121] Fix #209 Add CHANGELOG --- changelog.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelog.md diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..05fc6b9 --- /dev/null +++ b/changelog.md @@ -0,0 +1,3 @@ +# UAParser.js Changelog + +## Version 0.8.0 \ No newline at end of file From 73fb12b379e4f86c95bed7ade9d4175e2d7142a6 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 24 Mar 2021 02:15:50 +0700 Subject: [PATCH 068/121] Add Electron --- readme.md | 8 ++++---- src/ua-parser.js | 1 + test/browser-test.json | 10 ++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index a6be6b9..5fe0940 100644 --- a/readme.md +++ b/readme.md @@ -30,10 +30,10 @@ 2345Explorer, 360 Browser, Amaya, Android Browser, Arora, Avant, Avast, AVG, BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, -Dolphin, Doris, Edge, Epiphany, Facebook, Falkon, Fennec, Firebird, Firefox, -Flock, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, -Iceape, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, Kindle, -Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, +Dolphin, Doris, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, Firebird, +Firefox, Flock, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, IceCat, +IceDragon, Iceape, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, +Kindle, Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Oculus Browser, OmniWeb, Opera Coast, Opera Mini, Opera Mobi, Opera Tablet, Opera, PaleMoon, diff --git a/src/ua-parser.js b/src/ua-parser.js index 8546d9a..9cc9a7d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -297,6 +297,7 @@ ], [VERSION, [NAME, 'Facebook']], [ /FBAN\/FBIOS|FB_IAB\/FB4A/i // Facebook App for iOS & Android without version ], [[NAME, 'Facebook']], [ + /\s(electron)\/([\w\.]+)\ssafari/i, // Electron-based App /safari\s(line)\/([\w\.]+)/i, // Line App for iOS /droid.+(line)\/([\w\.]+)\/iab/i // Line App for Android ], [NAME, VERSION], [ diff --git a/test/browser-test.json b/test/browser-test.json index 6ab7b57..5f5c736 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1303,5 +1303,15 @@ "version" : "2.6.90.14", "major" : "2" } + }, + { + "desc" : "Electron", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Atom/1.41.0 Chrome/69.0.3497.128 Electron/4.2.7 Safari/537.36", + "expect" : + { + "name" : "Electron", + "version" : "4.2.7", + "major" : "4" + } } ] From a0b40be04faea42a77a3d6725e1e346bef354e0b Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 24 Mar 2021 15:37:20 +0700 Subject: [PATCH 069/121] Simplify Huawei detection --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 9cc9a7d..6b6f73a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -401,7 +401,7 @@ // Huawei /d\/huawei([\w\s-]+)[;\)]/i, /droid.+\s(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?)/i, - /droid.+\s((?:A(?:GS2?|KA|LP|N[AE]|QM|RE|SK|TH)|B(?:A(?:C|H2)|G2|KL|LA|MH|Z[AKT])|C(?:AZ|DY|LT|OL|[MOR]R)|DUK|E(?:BG|DI|L[ES]|ML|V[AR])|FRD|G(?:LK|RA)|H(?:D[LN]|MA|LK|RY|WI)|INE|J(?:DN2|MM|NY|SN)|K(?:NT|OB|SA)|L(?:IO|LD|ON|[RY]A)|M(?:AR|ED|[HL]A|ON|RX|T7)|N(?:EO|TS|XT)|OXF|P(?:AR|CT|IC|LK|RA)|R(?:IO|VL)|S(?:C[ML]|EA|HT|PN|TF)|T(?:A[HS]|NY)|V(?:[CI]E|KY|OG|RD)|W(?:AS|LZ)|Y(?:635|AL))-[ATU][LN][01259][019])[;\)\s]/i + /droid.+\s(\w{2,4}-[ATU][LN][01259][019])[;\)\s]/i ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ /droid.+(bah2?-a?[lw]\d{2})/i // Huawei MediaPad ], [MODEL, [VENDOR, 'Huawei'], [TYPE, TABLET]], [ From 3da59cef3d6666de913a0c3056b6fa6378207d60 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 24 Mar 2021 15:51:45 +0700 Subject: [PATCH 070/121] Release as 0.7.25 --- bower.json | 2 +- dist/ua-parser.min.js | 6 +++--- dist/ua-parser.pack.js | 6 +++--- package.js | 2 +- package.json | 4 ++-- src/ua-parser.js | 6 +++--- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/bower.json b/bower.json index 7a02d39..16869f0 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.24", + "version": "0.7.25", "authors": [ "Faisal Salman " ], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 7cc3a8b..f5c7c32 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,9 @@ -/*! - * UAParser.js v0.7.24 +/*!@license + * UAParser.js v0.7.25 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.24",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded";var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){if(typeof str1==="string"){return str2.toLowerCase().indexOf(str1.toLowerCase())!==-1}else{return false}},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str){return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j * Licensed under MIT License */ -!function(i,s){"use strict";var e="0.7.24",o="",r="?",a="function",n="undefined",d="object",t="string",w="major",l="model",u="name",c="type",b="vendor",m="version",p="architecture",f="console",h="mobile",g="tablet",v="smarttv",x="wearable",k="embedded",A={extend:function(i,s){var e={};for(var o in i)s[o]&&s[o].length%2===0?e[o]=s[o].concat(i[o]):e[o]=i[o];return e},has:function(i,s){return"string"==typeof i&&s.toLowerCase().indexOf(i.toLowerCase())!==-1},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i===t?i.replace(/[^\d\.]/g,"").split(".")[0]:s},trim:function(i){return i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}},T={rgx:function(i,e){for(var o,r,n,t,w,l,u=0;u0?2==t.length?typeof t[1]==a?this[t[0]]=t[1].call(this,l):this[t[0]]=t[1]:3==t.length?typeof t[1]!==a||t[1].exec&&t[1].test?this[t[0]]=l?l.replace(t[1],t[2]):s:this[t[0]]=l?t[1].call(this,l,t[2]):s:4==t.length&&(this[t[0]]=l?t[3].call(this,l.replace(t[1],t[2])):s):this[t]=l?l:s;u+=2}},str:function(i,e){for(var o in e)if(typeof e[o]===d&&e[o].length>0){for(var a=0;a (http://faisalman.com)", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": [ @@ -99,7 +99,7 @@ ], "main": "src/ua-parser.js", "scripts": { - "build": "uglifyjs src/ua-parser.js -o dist/ua-parser.min.js --comments '/UAParser\\.js/' && uglifyjs src/ua-parser.js -o dist/ua-parser.pack.js --comments '/UAParser\\.js/' --compress --mangle", + "build": "uglifyjs src/ua-parser.js -o dist/ua-parser.min.js --comments && uglifyjs src/ua-parser.js -o dist/ua-parser.pack.js --comments --compress --mangle", "test": "jshint src/ua-parser.js && mocha -R nyan test/test.js", "test-ci": "jshint src/ua-parser.js && mocha -R spec test/test.js", "verup": "node ./node_modules/verup", diff --git a/src/ua-parser.js b/src/ua-parser.js index 569dc35..e0d1f00 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ -/*! - * UAParser.js v0.7.24 +/*!@license + * UAParser.js v0.7.25 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * @@ -16,7 +16,7 @@ ///////////// - var LIBVERSION = '0.7.24', + var LIBVERSION = '0.7.25', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From ef4eeadcd85af64fa613434f96c366a99e5ac377 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 25 Mar 2021 00:00:30 +0700 Subject: [PATCH 071/121] Refine some OS detection --- src/ua-parser.js | 24 +++---- test/cpu-test.json | 8 +++ test/os-test.json | 155 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 148 insertions(+), 39 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 6b6f73a..0dd59e6 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -676,14 +676,16 @@ /(blackberry)\w*\/?([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/\s]([\w\.]+)/i // Tizen/KaiOS ], [NAME, VERSION], [ - /\((bb)(10);/i // BlackBerry 10 - ], [[NAME, 'BlackBerry'], VERSION], [ - /(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]*)/i // Symbian - ], [[NAME, 'Symbian'], VERSION], [ + /\(bb(10);/i // BlackBerry 10 + ], [VERSION, [NAME, 'BlackBerry']], [ + /(?:symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]*)/i // Symbian + ], [VERSION, [NAME, 'Symbian']], [ /\((series40);/i // Series 40 ], [NAME], [ /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS - ], [[NAME, 'Firefox OS'], VERSION], [ + ], [[NAME, 'Firefox OS']], [ + /\bhpwos\/([\w\.]+)/i // WebOS + ], [VERSION, [NAME, 'WebOS']], [ // Google Chromecast /crkey\/([\d\.]+)/i // Google Chromecast @@ -694,9 +696,9 @@ /(xbox);\s+xbox\s([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) // GNU/Linux based - /(mint)[\/\s\(]?(\w*)/i, // Mint + /(mint)[\/\s\(\)]?(\w*)/i, // Mint /(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux - /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|(?=\s)arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?(?!chrom)([\w\.-]*)/i, + /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?=\slinux)|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)(?:\sgnu\/linux)?(?:\slinux)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus /(hurd|linux)\s?([\w\.]*)/i, // Hurd/Linux @@ -711,7 +713,7 @@ ], [[NAME, 'Solaris'], VERSION], [ // BSD based - /\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]*)/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly + /\s([frentopc-]{0,4}bsd|dragonfly)\s?(?!amd|[ix346]{1,2}86)([\w\.]*)/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly ], [NAME, VERSION],[ /(haiku)\s(\w+)/i // Haiku @@ -742,9 +744,9 @@ return new UAParser(ua, extensions).getResult(); } - var _ua; + var _ua = ua || ((typeof window !== 'undefined' && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); var _rgxmap = extensions ? util.extend(regexes, extensions) : regexes; - + this.getBrowser = function () { var _browser = { name: undefined, version: undefined }; mapper.rgx.call(_browser, _ua, _rgxmap.browser); @@ -788,7 +790,7 @@ _ua = ua.length > UA_MAX_LENGTH ? util.trim(ua, UA_MAX_LENGTH) : ua; return this; }; - this.setUA(ua || ((typeof window !== 'undefined' && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY)); + this.setUA(_ua); return this; }; diff --git a/test/cpu-test.json b/test/cpu-test.json index a495ad1..b92cf52 100644 --- a/test/cpu-test.json +++ b/test/cpu-test.json @@ -135,6 +135,14 @@ "architecture" : "sparc" } }, + { + "desc" : "sparc64", + "ua" : "ELinks (0.4.3; NetBSD 3.0.2PATCH sparc64; 141x19)", + "expect" : + { + "architecture" : "sparc64" + } + }, { "desc" : "QuickTime", "ua" : "QuickTime/7.5.6 (qtver=7.5.6;cpu=IA32;os=Mac 10.5.8)", diff --git a/test/os-test.json b/test/os-test.json index ce6ec52..3c324a8 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -181,11 +181,11 @@ }, { "desc" : "WebOS", - "ua" : "", + "ua" : "Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.5; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/234.83 Safari/534.6 TouchPad/1.0", "expect" : { - "name" : "", - "version" : "" + "name" : "WebOS", + "version" : "3.0.5" } }, { @@ -325,11 +325,29 @@ }, { "desc" : "Mint", - "ua" : "", + "ua" : "Opera/9.80 (X11; Linux x86_64; Edition Linux Mint) Presto/2.12.388 Version/12.16", "expect" : { - "name" : "", - "version" : "" + "name" : "Mint", + "version" : "undefined" + } + }, + { + "desc" : "Mint", + "ua" : "Opera/9.64 (X11; Linux i686; U; Linux Mint; nb) Presto/2.1.1", + "expect" : + { + "name" : "Mint", + "version" : "undefined" + } + }, + { + "desc" : "Mint", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.5) Gecko/2008121622 Linux Mint/6 (Felicia) Firefox/3.0.4", + "expect" : + { + "name" : "Mint", + "version" : "6" } }, { @@ -360,21 +378,75 @@ } }, { - "desc" : "Debian", - "ua" : "", + "desc" : "Kubuntu", + "ua" : "Mozilla/5.0 (compatible; Konqueror/4.4; Linux 2.6.32-22-generic; X11; en_US) KHTML/4.4.3 (like Gecko) Kubuntu", "expect" : { - "name" : "", - "version" : "" + "name" : "Kubuntu", + "version" : "undefined" + } + }, + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.7 (like Gecko) (Debian)", + "expect" : + { + "name" : "Debian", + "version" : "undefined" + } + }, + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (X11; Linux x86_64; Debian GNU/Linux 8.1 (jessie)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.0 Maxthon/1.0.5.3 Safari/537.36", + "expect" : + { + "name" : "Debian", + "version" : "8.1" + } + }, + { + "desc" : "Debian", + "ua" : "ELinks/0.12~pre5-4 (textmode; Debian; Linux 3.2.0-4-amd64 x86_64 192x47-2)", + "expect" : + { + "name" : "Debian", + "version" : "undefined" + } + }, + { + "desc" : "Debian", + "ua" : "w3m/0.5.3+debian-19", + "expect" : + { + "name" : "debian", + "version" : "19" + } + }, + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.3) Gecko/2008092814 (Debian-3.0.1-1)", + "expect" : + { + "name" : "Debian", + "version" : "3.0.1-1" + } + }, + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux 2.6.24.4; X11) KHTML/3.5.9 (like Gecko) (Debian package 4:3.5.9.dfsg.1-2+b1)", + "expect" : + { + "name" : "Debian", + "version" : "undefined" } }, { "desc" : "OpenSUSE", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110420 SUSE/3.6.17-0.2.1 Firefox/3.6.17", "expect" : { - "name" : "", - "version" : "" + "name" : "SUSE", + "version" : "3.6.17-0.2.1" } }, { @@ -388,11 +460,11 @@ }, { "desc" : "Arch", - "ua" : "", + "ua" : "Uzbl (Webkit 1.1.10) (Arch Linux)", "expect" : { - "name" : "", - "version" : "" + "name" : "Arch", + "version" : "undefined" } }, { @@ -406,11 +478,29 @@ }, { "desc" : "Fedora", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0", "expect" : { - "name" : "", - "version" : "" + "name" : "Fedora", + "version" : "undefined" + } + }, + { + "desc" : "Fedora", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:2.0) Gecko/20110404 Fedora/16-dev Firefox/4.0", + "expect" : + { + "name" : "Fedora", + "version" : "16-dev" + } + }, + { + "desc" : "Fedora", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; sk; rv:1.9.0.4) Gecko/2008111217 Fedora/3.0.4-1.fc10 Firefox/3.0.4", + "expect" : + { + "name" : "Fedora", + "version" : "3.0.4-1.fc10" } }, { @@ -514,29 +604,29 @@ }, { "desc" : "FreeBSD", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; FreeBSD x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16", "expect" : { - "name" : "", - "version" : "" + "name" : "FreeBSD", + "version" : "undefined" } }, { "desc" : "OpenBSD", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; OpenBSD i386; en-US; rv:1.9.1) Gecko/20090702 Firefox/3.5", "expect" : { - "name" : "", - "version" : "" + "name" : "OpenBSD", + "version" : "undefined" } }, { "desc" : "NetBSD", - "ua" : "", + "ua" : "ELinks (0.4.3; NetBSD 3.0.2PATCH sparc64; 141x19)", "expect" : { - "name" : "", - "version" : "" + "name" : "NetBSD", + "version" : "3.0.2PATCH" } }, { @@ -709,5 +799,14 @@ "name" : "Android", "version" : "4.2.1" } + }, + { + "desc" : "Solaris", + "ua" : "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)", + "expect" : + { + "name" : "Solaris", + "version" : "4.1.4" + } } ] From afe62e915d57beb71f4a0f47467639a2bdc8c174 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 25 Mar 2021 00:06:12 +0700 Subject: [PATCH 072/121] Add new OS: Raspbian --- readme.md | 6 +++--- src/ua-parser.js | 2 +- test/os-test.json | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 5fe0940..925a164 100644 --- a/readme.md +++ b/readme.md @@ -82,9 +82,9 @@ AIX, Amiga OS, Android, Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, Contiki, Fedora, Firefox OS, FreeBSD, Debian, DragonFly, Fuchsia, Gentoo, GNU, Haiku, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Mageia, Mandriva, MeeGo, Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, -PCLinuxOS, Plan9, PlayStation, QNX, RedHat, RIM Tablet OS, RISC OS, Sailfish, -Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, Unix, VectorLinux, -WebOS, Windows [Phone/Mobile], Zenwalk, ... +PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, RISC OS, +Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, Unix, +VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... # 'os.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 0dd59e6..abffc81 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -698,7 +698,7 @@ // GNU/Linux based /(mint)[\/\s\(\)]?(\w*)/i, // Mint /(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux - /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?=\slinux)|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)(?:\sgnu\/linux)?(?:\slinux)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, + /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?=\slinux)|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus|raspbian)(?:\sgnu\/linux)?(?:\slinux)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus /(hurd|linux)\s?([\w\.]*)/i, // Hurd/Linux diff --git a/test/os-test.json b/test/os-test.json index 3c324a8..fb13c14 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -808,5 +808,23 @@ "name" : "Solaris", "version" : "4.1.4" } + }, + { + "desc" : "Raspbian", + "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Raspbian Chromium/72.0.3626.121 HeadlessChrome/72.0.3626.121 Safari/537.36", + "expect" : + { + "name" : "Raspbian", + "version" : "undefined" + } + }, + { + "desc" : "Raspbian", + "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/538.15 (KHTML, like Gecko) Version/8.0 Safari/538.15 Raspbian/9.0 (1:3.8.2.0-0rpi28) Epiphany/3.8.2", + "expect" : + { + "name" : "Raspbian", + "version" : "9.0" + } } ] From cd61aef07d4b25795ed1bf9a0665f8bbab19a565 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 25 Mar 2021 00:10:32 +0700 Subject: [PATCH 073/121] Add Device: Surface Duo --- src/ua-parser.js | 3 ++- test/device-test.json | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index abffc81..b3fc74d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -521,7 +521,8 @@ /droid.+(vodafone)\s([\w\s]+)\)/i // Vodafone ], [VENDOR, MODEL, [TYPE, TABLET]], [ - + /\s(surface\sduo)\s/i // Surface Duo + ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, TABLET]], [ /\s(U304AA)\sbuild/i // AT&T ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ /sie-(\w*)/i // Siemens diff --git a/test/device-test.json b/test/device-test.json index 2e3d5c6..b0c35d6 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -214,6 +214,15 @@ "type": "mobile" } }, + { + "desc": "Microsoft Surface Duo", + "ua": "Dalvik/2.1.0 (Linux; U; Android 10; Surface Duo Build/2020.1014.61)", + "expect": { + "vendor": "Microsoft", + "model": "Surface Duo", + "type": "tablet" + } + }, { "desc": "Motorola Moto X", "ua": "Mozilla/5.0 (Linux; Android 4.4.4; XT1097 Build/KXE21.187-38) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.109 Mobile Safari/537.36", From 62cb5a2e54a68e17ad21a5a96aefcfed1cf0cd40 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 25 Mar 2021 01:50:08 +0700 Subject: [PATCH 074/121] Add some test cases for Samsung, Huawei, Xiaomi --- src/ua-parser.js | 3 +- test/device-test.json | 132 +++++++++++++++++++++++++++++------------- 2 files changed, 95 insertions(+), 40 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index b3fc74d..ace0a2d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -400,13 +400,14 @@ // Huawei /d\/huawei([\w\s-]+)[;\)]/i, - /droid.+\s(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?)/i, + /droid.+\s(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, /droid.+\s(\w{2,4}-[ATU][LN][01259][019])[;\)\s]/i ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ /droid.+(bah2?-a?[lw]\d{2})/i // Huawei MediaPad ], [MODEL, [VENDOR, 'Huawei'], [TYPE, TABLET]], [ // Xiaomi + /\b(poco\s\w+)\b/i, /droid.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /droid.+(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi /droid.+(redmi[\s\-_]?(?:note|k)?(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i,// Xiaomi Redmi diff --git a/test/device-test.json b/test/device-test.json index b0c35d6..c861027 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -415,12 +415,48 @@ } }, { - "desc": "Samsung Galaxy Note 8", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; GT-N5100 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Safari/537.36", + "desc": "Samsung Galaxy A50", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-A505F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.105 Mobile Safari/537.36", "expect": { "vendor": "Samsung", - "model": "GT-N5100", - "type": "tablet" + "model": "SM-A505F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A80", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-A805F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.112 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A805F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Fold", + "ua": "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-F900U Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.2 Chrome/67.0.3396.87 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-F900U", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy S10E", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-G970F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-G970F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Note 10+", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-N976V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.89 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-N976V", + "type": "mobile" } }, { @@ -432,6 +468,15 @@ "type": "mobile" } }, + { + "desc": "Samsung Galaxy Note 8", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; GT-N5100 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "GT-N5100", + "type": "tablet" + } + }, { "desc": "Samsung SM-T231", "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T231 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", @@ -468,15 +513,6 @@ "type": "tablet" } }, - { - "desc": "Samsung SmartTV2011", - "ua": "HbbTV/1.1.1 (;;;;;) Maple;2011", - "expect": { - "vendor": "Samsung", - "model": "SmartTV2011", - "type": "smarttv" - } - }, { "desc": "Samsung Note 10.1", "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SM-P605) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", @@ -486,6 +522,15 @@ "type": "tablet" } }, + { + "desc": "Samsung SmartTV2011", + "ua": "HbbTV/1.1.1 (;;;;;) Maple;2011", + "expect": { + "vendor": "Samsung", + "model": "SmartTV2011", + "type": "smarttv" + } + }, { "desc": "Samsung SmartTV2012", "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2012;;;) WebKit", @@ -747,6 +792,15 @@ "type": "tablet" } }, + { + "desc": "Xiaomi POCO X2", + "ua": "Mozilla/5.0 (Linux; Android 10; POCO X2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "POCO X2", + "type": "mobile" + } + }, { "desc": "Xiaomi Redmi 4A", "ua": "Mozilla/5.0 (Linux; Android 6.0; Redmi 4A Build/MMB29M; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", @@ -1400,11 +1454,11 @@ } }, { - "desc": "Huawei P30 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; VOG-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", + "desc": "Huawei Mate 10 Pro", + "ua": "Mozilla/5.0 (Linux; Android 8.0; BLA-L29 Build/HUAWEIBLA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3236.6 Mobile Safari/537.36", "expect": { "vendor": "Huawei", - "model": "VOG-L29", + "model": "BLA-L29", "type": "mobile" } }, @@ -1435,6 +1489,15 @@ "type": "mobile" } }, + { + "desc": "Huawei Mate 20 X", + "ua": "Mozilla/5.0 (Linux; Android 9; EVR-L29 Build/HUAWEIEVR-L29; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "EVR-L29", + "type": "mobile" + } + }, { "desc": "Huawei Mate 20 Pro", "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", @@ -1454,31 +1517,22 @@ } }, { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-AL10", - "type": "mobile" - } + "desc": "Huawei P30", + "ua": "Mozilla/5.0 (Linux; Android 9; ELE-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "ELE-L29", + "type": "mobile" + } }, { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L0C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-L0C", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-L29", - "type": "mobile" - } + "desc": "Huawei P30 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; VOG-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "VOG-L29", + "type": "mobile" + } }, { "desc": "Huawei P40", From 59d947dcab8ffe393ab2cc96b40cc17bb0b87574 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 25 Mar 2021 01:56:19 +0700 Subject: [PATCH 075/121] Detect ARMEABI as ARM --- src/ua-parser.js | 2 +- test/cpu-test.json | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index ace0a2d..669e21f 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -374,7 +374,7 @@ /(sun4\w)[;\)]/i // SPARC ], [[ARCHITECTURE, 'sparc']], [ - /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?:64|(?=v(?:[1-7]|[5-7]1)l?|;))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i + /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?:64|(?=v(?:[1-7]|[5-7]1)l?|;|eabi))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC ], [[ARCHITECTURE, util.lowerize]] ], diff --git a/test/cpu-test.json b/test/cpu-test.json index b92cf52..871ddd9 100644 --- a/test/cpu-test.json +++ b/test/cpu-test.json @@ -79,6 +79,14 @@ "architecture" : "arm" } }, + { + "desc" : "ARMEABI", + "ua" : "[FBAN/FB4A;FBAV/237.0.0.44.120;FBBV/170693408;FBDM/{density=1.75,width=720,height=1280};FBLC/en_US;FBRV/172067074;FBCR/ ;FBMF/samsung;FBBD/samsung;FBPN/com.facebook.katana;FBDV/SM-S367VL;FBSV/9;FBBK/1;FBOP/19;FBCA/armeabi-v7a:armeabi;]", + "expect" : + { + "architecture" : "arm" + } + }, { "desc" : "ARMv8", "ua" : "Mozilla/5.0 (X11; Linux armv8l; rv:45.0) Gecko/20100101 Firefox/45.0", From 69a568ae49258374fab48af87412c13163401477 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 25 Mar 2021 15:45:18 +0700 Subject: [PATCH 076/121] Casually save some bytes --- src/ua-parser.js | 158 ++++++++++++++++++++---------------------- test/device-test.json | 4 +- 2 files changed, 79 insertions(+), 83 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 669e21f..07f2114 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,4 +1,4 @@ -/*! +/*!@license * UAParser.js v0.7.24 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js @@ -158,7 +158,8 @@ var maps = { browser : { - oldsafari : { + // Safari < 3.0 + oldSafari : { version : { '1.0' : '/8', '1.2' : '/1', @@ -172,23 +173,6 @@ } }, - device : { - amazon : { - model : { - 'Fire Phone' : ['SD', 'KF'] - } - }, - sprint : { - model : { - 'Evo Shift 4G' : '7373KT' - }, - vendor : { - 'HTC' : 'APA', - 'Sprint' : 'Sprint' - } - } - }, - os : { windows : { version : { @@ -218,7 +202,7 @@ browser : [[ - /(?:android.+crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS + /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS ], [VERSION, [NAME, 'Chrome']], [ /(?:edge|edgios|edga|edg)\/((\d+)?[\w\.]+)/i // Microsoft Edge ], [VERSION, [NAME, 'Edge']], [ @@ -270,20 +254,18 @@ ], [VERSION, [NAME, 'Opera Touch']], [ /coc_coc_browser\/([\w\.]+)/i // Coc Coc Browser ], [VERSION, [NAME, 'Coc Coc']], [ - /sailfishbrowser\/([\w\.]+)/i // Sailfish Browser - ], [VERSION, [NAME, 'Sailfish Browser']], [ /dolfin\/([\w\.]+)/i // Dolphin ], [VERSION, [NAME, 'Dolphin']], [ /coast\/([\w\.]+)/i // Opera Coast - ], [VERSION, [NAME, 'Opera Coast']], [ - /xiaomi\/miuibrowser\/([\w\.]+)/i // MIUI Browser + ], [VERSION, [NAME, 'Opera Coast']], + [/xiaomi\/miuibrowser\/([\w\.]+)/i // MIUI Browser ], [VERSION, [NAME, 'MIUI Browser']], [ /fxios\/([\w\.-]+)/i // Firefox for iOS ], [VERSION, [NAME, 'Firefox']], [ /(qihu|qhbrowser|qihoobrowser|360browser)/i // 360 ], [[NAME, '360 Browser']], [ - /((?:oculus|samsung)browser)\/([\w\.]+)/i - ], [[NAME, /(.+(?:g|us))(.+)/, '$1 $2'], VERSION], [ // Oculus / Samsung Browser + /(oculus|samsung|sailfish)browser\/([\w\.]+)/i + ], [[NAME, /(.+)/, '$1 Browser'], VERSION], [ // Oculus/Samsung/Sailfish Browser /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ /m?(qqbrowser|baiduboxapp|2345Explorer)[\/\s]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser @@ -299,18 +281,18 @@ ], [[NAME, 'Facebook']], [ /\s(electron)\/([\w\.]+)\ssafari/i, // Electron-based App /safari\s(line)\/([\w\.]+)/i, // Line App for iOS - /droid.+(line)\/([\w\.]+)\/iab/i // Line App for Android + /\b(line)\/([\w\.]+)\/iab/i // Line App for Android ], [NAME, VERSION], [ - /webkit.+?gsa\/([\w\.]+)\s.*(mobile\s?safari|safari)(\/[\w\.]+)/i // Google Search Appliance on iOS + /\bgsa\/([\w\.]+)\s.*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, 'GSA']], [ /headlesschrome(?:\/([\w\.]+)|\s)/i // Chrome Headless ], [VERSION, [NAME, 'Chrome Headless']], [ /\swv\).+(chrome)\/([\w\.]+)/i // Chrome WebView - ], [[NAME, /(.+)/, '$1 WebView'], VERSION], [ + ], [[NAME, 'Chrome WebView'], VERSION], [ - /droid.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)*/i // Android Browser + /droid.+\sversion\/([\w\.]+).+(?:mobile\ssafari|safari)/i // Android Browser ], [VERSION, [NAME, 'Android Browser']], [ /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia @@ -321,7 +303,7 @@ /version\/([\w\.]+)\s.*(mobile\s?safari|safari)/i // Safari & Safari Mobile ], [VERSION, NAME], [ /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 - ], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [ + ], [NAME, [VERSION, mapper.str, maps.browser.oldSafari.version]], [ /(webkit|khtml)\/([\w\.]+)/i ], [NAME, VERSION], [ @@ -349,13 +331,13 @@ cpu : [[ - /(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\)]/i // AMD64 + /(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\)]/i // AMD64 (x64) ], [[ARCHITECTURE, 'amd64']], [ /(ia32(?=;))/i // IA32 (quicktime) ], [[ARCHITECTURE, util.lowerize]], [ - /((?:i[346]|x)86)[;\)]/i // IA32 + /((?:i[346]|x)86)[;\)]/i // IA32 (x86) ], [[ARCHITECTURE, 'ia32']], [ /\b(aarch64|armv?8e?l?)\b/i // ARM64 @@ -381,8 +363,12 @@ device : [[ + ////////////////////// + // MOBILES & TABLETS + ///////////////////// + // Samsung - /droid.+(sch-i[89]0\d|shw-m380s|SM-P605|SM-P610|SM-P587|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10)/i, + /\b(sch-i[89]0\d|shw-m380s|SM-P605|SM-P610|SM-P587|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10)/i, /(SM-T\w+)/i ], [MODEL, [VENDOR, 'Samsung'], [TYPE, TABLET]], [ /(s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-\w[\w\d]+)/i, @@ -400,20 +386,20 @@ // Huawei /d\/huawei([\w\s-]+)[;\)]/i, - /droid.+\s(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, - /droid.+\s(\w{2,4}-[ATU][LN][01259][019])[;\)\s]/i + /\b(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, + /\b(\w{2,4}-[ATU][LN][01259][019])[;\)\s]/i ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ - /droid.+(bah2?-a?[lw]\d{2})/i // Huawei MediaPad + /\b(bah2?-a?[lw]\d{2})/i // Huawei MediaPad ], [MODEL, [VENDOR, 'Huawei'], [TYPE, TABLET]], [ // Xiaomi - /\b(poco\s\w+)\b/i, - /droid.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models - /droid.+(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi - /droid.+(redmi[\s\-_]?(?:note|k)?(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i,// Xiaomi Redmi - /droid.+(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i // Xiaomi Mi + /\b(poco\s\w+)\b/i, // Xiaomi POCO + /\b;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models + /\b(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi + /\b(redmi[\s\-_]?(?:note|k)?(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i, // Xiaomi Redmi + /\b(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ - /droid.+(mi[\s\-_]?(?:pad)(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i // Mi Pad tablets + /\b(mi[\s\-_]?(?:pad)(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [ // Motorola @@ -423,19 +409,19 @@ /(XT\d{3,4}) build\//i, /(nexus\s6)/i ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [ - /droid.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i + /\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [ // LG - /droid(?:.+([vl]k\-?\d{3})\s+build|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4}))/i + /((?=lg)?[vl]k\-?\d{3})\s+build|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [ /(nexus\s[45])/i, /lg[e;\s\/-]+((?!browser|netcast)\w+)/i, - /droid.+lg(\-?[\d\w]+)\s+build/i + /\blg(\-?[\d\w]+)\s+build/i ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [ // Lenovo - /droid.+(ideatab[a-z0-9\-\s]+)/i, + /(ideatab[\w\-\s]+)/i, /lenovo\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+)|[\w-]+)/i // Lenovo tablets ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ @@ -458,8 +444,8 @@ ], [[MODEL, 'Xperia Tablet'], [VENDOR, 'Sony'], [TYPE, TABLET]], [ // OnePlus - /droid.+a000(1)\s+build/i, // OnePlus - /droid.+oneplus\s(a\d{4})[\s)]/i + /\ba000(1)\s+build/i, // OnePlus + /\boneplus\s(a\d{4})[\s)]/i ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ // Amazon @@ -467,7 +453,7 @@ /(kf[A-z]+)(\sbuild\/|\)).+silk\//i // Kindle Fire HD ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ /(sd|kf)[0349hijorstuw]+(\sbuild\/|\)).+silk\//i // Fire Phone - ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ + ], [[MODEL, 'Fire Phone'], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ // BlackBerry /\((playbook);[\w\s\),;-]+(rim)/i // BlackBerry PlayBook @@ -476,7 +462,7 @@ ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [ // Asus - /droid.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7|padfone|p00c)/i + /\b(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7|padfone|p00c)/i ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [ // HTC @@ -516,61 +502,59 @@ /(kindle)\/([\w\.]+)/i, // Kindle /\s(nook)[\w\s]+build\/(\w+)/i, // Nook /(dell)\s(strea[kpr\s\d]*[\dko])/i, // Dell Streak - /droid.+[;\/]\s*(Le[\s\-]+Pan)[\s\-]+(\w{1,9})\s+build/i, // Le Pan Tablets - /droid.+[;\/]\s*(Trinity)[\-\s]*(T\d{3})\s+build/i, // Trinity Tablets - /droid.+(Gigaset)[\s\-]+(Q\w{1,9})\s+build/i, // Gigaset Tablets - /droid.+(vodafone)\s([\w\s]+)\)/i // Vodafone + /[;\/]\s*(le[\s\-]+pan)[\s\-]+(\w{1,9})\s+build/i, // Le Pan Tablets + /[;\/]\s*(trinity)[\-\s]*(t\d{3})\s+build/i, // Trinity Tablets + /\b(gigaset)[\s\-]+(Q\w{1,9})\s+build/i, // Gigaset Tablets + /\b(vodafone)\s([\w\s]+)\)/i // Vodafone ], [VENDOR, MODEL, [TYPE, TABLET]], [ /\s(surface\sduo)\s/i // Surface Duo ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, TABLET]], [ - /\s(U304AA)\sbuild/i // AT&T + /\s(u304aa)\sbuild/i // AT&T ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ /sie-(\w*)/i // Siemens ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ - /droid.+[;\/]\s*(RCT[\d\w]+)\s+build/i // RCA Tablets + /[;\/]\s*(rct[\d\w]+)\s+build/i // RCA Tablets ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [ - /droid.+[;\/\s](Venue[\d\s]{2,7})\s+build/i // Dell Venue Tablets + /[;\/\s](venue[\d\s]{2,7})\s+build/i // Dell Venue Tablets ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ - /droid.+[;\/]\s*(Q[T|M][\d\w]+)\s+build/i // Verizon Tablet + /[;\/]\s*(Q[T|M][\d\w]+)\s+build/i // Verizon Tablet ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ - /droid.+[;\/]\s+(Barnes[&\s]+Noble\s+|BN[RT])(\S(?:.*\S)?)\s+build/i + /[;\/]\s+(barnes[&\s]+noble\s+|bn[rt])(\S(?:.*\S)?)\s+build/i ], [[VENDOR, 'Barnes & Noble'], MODEL, [TYPE, TABLET]], [ - /droid.+[;\/]\s+(TM\d{3}.*\b)\s+build/i // Barnes & Noble Tablet + /[;\/]\s+(TM\d{3}.*\b)\s+build/i // Barnes & Noble Tablet ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [ - /droid.+;\s(k88)\sbuild/i // ZTE K Series Tablet + /;\s(k88)\sbuild/i // ZTE K Series Tablet ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [ - /droid.+;\s(nx\d{3}j)\sbuild/i // ZTE Nubia + /;\s(nx\d{3}j)\sbuild/i // ZTE Nubia ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [ - /droid.+[;\/]\s*(gen\d{3})\s+build.*49h/i // Swiss GEN Mobile + /[;\/]\s*(gen\d{3})\s+build.*49h/i // Swiss GEN Mobile ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [ - /droid.+[;\/]\s*(zur\d{3})\s+build/i // Swiss ZUR Tablet + /[;\/]\s*(zur\d{3})\s+build/i // Swiss ZUR Tablet ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ - /droid.+[;\/]\s*((Zeki)?TB.*\b)\s+build/i // Zeki Tablets + /[;\/]\s*((zeki)?TB.*\b)\s+build/i // Zeki Tablets ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ - /(droid).+[;\/]\s+([YR]\d{2})\s+build/i, - /droid.+[;\/]\s+(Dragon[\-\s]+Touch\s+|DT)(\w{5})\sbuild/i // Dragon Touch Tablet + /[;\/]\s+([yr]\d{2})\s+build/i, + /[;\/]\s+(dragon[\-\s]+touch\s+|dt)(\w{5})\sbuild/i // Dragon Touch Tablet ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [ - /droid.+[;\/]\s*(NS-?\w{0,9})\sbuild/i // Insignia Tablets + /[;\/]\s*(ns-?\w{0,9})\sbuild/i // Insignia Tablets ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [ - /droid.+[;\/]\s*((NXA|Next)-?\w{0,9})\s+build/i // NextBook Tablets + /[;\/]\s*((nxa|Next)-?\w{0,9})\s+build/i // NextBook Tablets ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [ - /droid.+[;\/]\s*(Xtreme\_)?(V(1[045]|2[015]|30|40|60|7[05]|90))\s+build/i + /[;\/]\s*(xtreme\_)?(V(1[045]|2[015]|30|40|60|7[05]|90))\s+build/i ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ // Voice Xtreme Phones - /droid.+[;\/]\s*(LVTEL\-)?(V1[12])\s+build/i // LvTel Phones + /[;\/]\s*(lvtel\-)?(V1[12])\s+build/i // LvTel Phones ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [ - /droid.+;\s(PH-1)\s/i + /;\s(PH-1)\s/i ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ // Essential PH-1 - /droid.+[;\/]\s*(V(100MD|700NA|7011|917G).*\b)\s+build/i // Envizen Tablets + /[;\/]\s*(V(100MD|700NA|7011|917G).*\b)\s+build/i // Envizen Tablets ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [ - /droid.+[;\/]\s*(Trio[\s\w\-\.]+)\s+build/i // MachSpeed Tablets + /[;\/]\s*(Trio[\s\w\-\.]+)\s+build/i // MachSpeed Tablets ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [ - /droid.+[;\/]\s*TU_(1491)\s+build/i // Rotor Tablets + /[;\/]\s*TU_(1491)\s+build/i // Rotor Tablets ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [ - //android.+(KS(.+))\s+build/i // Amazon Kindle Tablets - //], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ - /(sprint\s(\w+))/i // Sprint Phones - ], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [ + /(sprint)\s(\w+)/i // Sprint Phones + ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kin\.[onetw]{3})/i // Microsoft Kin ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ @@ -581,7 +565,10 @@ /droid\s[\d\.]+;\s(wt63?0{2,3})\)/i ], [MODEL, [VENDOR, 'Zebra'], [TYPE, WEARABLE]], [ + /////////////////// // CONSOLES + /////////////////// + /\s(ouya)\s/i, // Ouya /(nintendo)\s([wids3utch]+)/i // Nintendo ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ @@ -592,7 +579,10 @@ /[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [ + /////////////////// // SMARTTVS + /////////////////// + /smart-tv.+(samsung)/i // Samsung ], [VENDOR, [TYPE, SMARTTV], MODEL], [ /hbbtv.+maple;(\d+)/i @@ -613,13 +603,19 @@ /[\s\/\(](android\stv|smart[-\s]?tv)[;\)\s]/i // SmartTV from Unidentified Vendors ], [[TYPE, SMARTTV]], [ + /////////////////// // WEARABLES + /////////////////// + /((pebble))app\/[\d\.]+\s/i // Pebble ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ /droid.+;\s(glass)\s\d/i // Google Glass ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [ - // OTHERS + //////////////////// + // MIXED (GENERIC) + /////////////////// + /droid .+?; ([^;]+?)(?: build|\) applewebkit).+? mobile safari/i // Android Phones from Unidentified Vendors ], [MODEL, [TYPE, MOBILE]], [ /droid .+?;\s([^;]+?)(?: build|\) applewebkit).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors diff --git a/test/device-test.json b/test/device-test.json index c861027..8280b97 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -65,8 +65,8 @@ "desc": "HTC Evo Shift 4G", "ua": "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0", "expect": { - "vendor": "HTC", - "model": "Evo Shift 4G", + "vendor": "Sprint", + "model": "APA7373KT", "type": "mobile" } }, From 8d5685771d1e3f3f4661b117a62e2201d60c1847 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 25 Mar 2021 23:18:46 +0700 Subject: [PATCH 077/121] Refine some detection with more test cases --- src/ua-parser.js | 43 +++--- test/cpu-test.json | 8 ++ test/device-test.json | 162 +++++++++++++++++++++ test/os-test.json | 319 ++++++++++++++++++++++++------------------ 4 files changed, 376 insertions(+), 156 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 07f2114..722244e 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -356,7 +356,7 @@ /(sun4\w)[;\)]/i // SPARC ], [[ARCHITECTURE, 'sparc']], [ - /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?:64|(?=v(?:[1-7]|[5-7]1)l?|;|eabi))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i + /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?:64|(?=v(?:[1-7]|[5-7]1)l?|;|eabi))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC ], [[ARCHITECTURE, util.lowerize]] ], @@ -402,6 +402,10 @@ /\b(mi[\s\-_]?(?:pad)(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [ + // OPPO + /;\s(\w+)\sbuild.+\soppo/i + ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ + // Motorola /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)[\w\s]+build\//i, /\smot[\s-](\w*)/i, @@ -492,7 +496,7 @@ /(asus)-?(\w+)/i, // Asus /(microsoft);\s(lumia[\s\w]+)/i, // Microsoft Lumia /(lenovo)[_\s-]?([\w-]+)/i, // Lenovo - /linux;.+((jolla));/i, // Jolla + /linux;.+(jolla);/i, // Jolla /droid.+;\s(oppo)\s?([\w\s]+)\sbuild/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ @@ -505,7 +509,7 @@ /[;\/]\s*(le[\s\-]+pan)[\s\-]+(\w{1,9})\s+build/i, // Le Pan Tablets /[;\/]\s*(trinity)[\-\s]*(t\d{3})\s+build/i, // Trinity Tablets /\b(gigaset)[\s\-]+(Q\w{1,9})\s+build/i, // Gigaset Tablets - /\b(vodafone)\s([\w\s]+)\)/i // Vodafone + /\b(vodafone)\s([\w\s]+)(?:\)|\sbuild)/i // Vodafone ], [VENDOR, MODEL, [TYPE, TABLET]], [ /\s(surface\sduo)\s/i // Surface Duo @@ -518,11 +522,11 @@ ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [ /[;\/\s](venue[\d\s]{2,7})\s+build/i // Dell Venue Tablets ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ - /[;\/]\s*(Q[T|M][\d\w]+)\s+build/i // Verizon Tablet + /[;\/]\s*(q[t|m][\d\w]+)\s+build/i // Verizon Tablet ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ /[;\/]\s+(barnes[&\s]+noble\s+|bn[rt])(\S(?:.*\S)?)\s+build/i ], [[VENDOR, 'Barnes & Noble'], MODEL, [TYPE, TABLET]], [ - /[;\/]\s+(TM\d{3}.*\b)\s+build/i // Barnes & Noble Tablet + /[;\/]\s+(tm\d{3}.*\b)\s+build/i // Barnes & Noble Tablet ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [ /;\s(k88)\sbuild/i // ZTE K Series Tablet ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [ @@ -532,7 +536,7 @@ ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [ /[;\/]\s*(zur\d{3})\s+build/i // Swiss ZUR Tablet ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ - /[;\/]\s*((zeki)?TB.*\b)\s+build/i // Zeki Tablets + /[;\/]\s*((zeki)?tb.*\b)\s+build/i // Zeki Tablets ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ /[;\/]\s+([yr]\d{2})\s+build/i, /[;\/]\s+(dragon[\-\s]+touch\s+|dt)(\w{5})\sbuild/i // Dragon Touch Tablet @@ -541,29 +545,28 @@ ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [ /[;\/]\s*((nxa|Next)-?\w{0,9})\s+build/i // NextBook Tablets ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [ - /[;\/]\s*(xtreme\_)?(V(1[045]|2[015]|30|40|60|7[05]|90))\s+build/i + /[;\/]\s*(xtreme\_)?(v(1[045]|2[015]|30|40|60|7[05]|90))\s+build/i ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ // Voice Xtreme Phones - /[;\/]\s*(lvtel\-)?(V1[12])\s+build/i // LvTel Phones + /[;\/]\s*(lvtel\-)?(v1[12])\s+build/i // LvTel Phones ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [ /;\s(PH-1)\s/i ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ // Essential PH-1 - /[;\/]\s*(V(100MD|700NA|7011|917G).*\b)\s+build/i // Envizen Tablets + /[;\/]\s*(V(100md|700na|7011|917g).*\b)\s+build/i // Envizen Tablets ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [ - /[;\/]\s*(Trio[\s\w\-\.]+)\s+build/i // MachSpeed Tablets + /[;\/]\s*(trio[\s\w\-\.]+)\s+build/i // MachSpeed Tablets ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [ - /[;\/]\s*TU_(1491)\s+build/i // Rotor Tablets + /[;\/]\s*tu_(1491)\s+build/i // Rotor Tablets ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [ + /(shield[\w\s]+)\sbuild/i // Nvidia Shield Tablets + ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [ /(sprint)\s(\w+)/i // Sprint Phones ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kin\.[onetw]{3})/i // Microsoft Kin ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ - /droid\s[\d\.]+;\s(cc6{3,4}|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra ], [MODEL, [VENDOR, 'Zebra'], [TYPE, TABLET]], [ /droid\s[\d\.]+;\s(ec30|ps20|tc[2-8]\d[kx])\)/i ], [MODEL, [VENDOR, 'Zebra'], [TYPE, MOBILE]], [ - /droid\s[\d\.]+;\s(wt63?0{2,3})\)/i - ], [MODEL, [VENDOR, 'Zebra'], [TYPE, WEARABLE]], [ /////////////////// // CONSOLES @@ -576,7 +579,7 @@ ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ /(playstation\s[345portablevi]+)/i // Playstation ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [ - /[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox + /[\s\(;](xbox(?:\sone)?(?!;\sxbox))[\s\);]/i // Microsoft Xbox ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [ /////////////////// @@ -600,7 +603,7 @@ ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [ - /[\s\/\(](android\stv|smart[-\s]?tv)[;\)\s]/i // SmartTV from Unidentified Vendors + /[\s\/\(](android\s|smart[-\s]?|opera\s)tv[;\)\s]/i // SmartTV from Unidentified Vendors ], [[TYPE, SMARTTV]], [ /////////////////// @@ -611,6 +614,8 @@ ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ /droid.+;\s(glass)\s\d/i // Google Glass ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [ + /droid\s[\d\.]+;\s(wt63?0{2,3})\)/i + ], [MODEL, [VENDOR, 'Zebra'], [TYPE, WEARABLE]], [ //////////////////// // MIXED (GENERIC) @@ -676,14 +681,14 @@ ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 ], [VERSION, [NAME, 'BlackBerry']], [ - /(?:symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]*)/i // Symbian + /(?:symbian\s?os|symbos|s60(?=;)|series60)[\/\s-]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ /\((series40);/i // Series 40 ], [NAME], [ /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS ], [[NAME, 'Firefox OS']], [ - /\bhpwos\/([\w\.]+)/i // WebOS - ], [VERSION, [NAME, 'WebOS']], [ + /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS + ], [VERSION, [NAME, 'webOS']], [ // Google Chromecast /crkey\/([\d\.]+)/i // Google Chromecast diff --git a/test/cpu-test.json b/test/cpu-test.json index 871ddd9..773c9f6 100644 --- a/test/cpu-test.json +++ b/test/cpu-test.json @@ -166,5 +166,13 @@ { "architecture" : "amd64" } + }, + { + "desc" : "IRIX64", + "ua" : "Mozilla/4.8C-SGI [en] (X11; U; IRIX64 6.5 IP27", + "expect" : + { + "architecture" : "irix64" + } } ] diff --git a/test/device-test.json b/test/device-test.json index 8280b97..667bd7b 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -169,6 +169,15 @@ "type": "mobile" } }, + { + "desc": "LG Nexus 4", + "ua": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; Google Nexus 4 - 4.3 - API 18 - 768x1280 Build/JLS36G) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "LG", + "model": "Nexus 4", + "type": "mobile" + } + }, { "desc": "LG Nexus 5", "ua": "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", @@ -342,6 +351,15 @@ "type": "mobile" } }, + { + "desc": "Nokia N9", + "ua": "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", + "expect": { + "vendor": "Nokia", + "model": "N9", + "type": "mobile" + } + }, { "desc": "OnePlus One", "ua": "Mozilla/5.0 (Linux; Android 4.4.4; A0001 Build/KTU84Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.59 Mobile Safari/537.36", @@ -351,6 +369,15 @@ "type": "mobile" } }, + { + "desc": "OnePlus One", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; OnePlus One A0001 Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "1", + "type": "mobile" + } + }, { "desc": "OnePlus 3", "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ONEPLUS A3000 Build/NMF26F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36", @@ -378,6 +405,15 @@ "type": "mobile" } }, + { + "desc": "OPPO Neo", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; R831T Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 OppoBrowser/3.3.2 Mobile Safari/534.30", + "expect": { + "vendor": "OPPO", + "model": "R831T", + "type": "mobile" + } + }, { "desc": "OPPO R7s", "ua": "Mozilla/5.0 (Linux; U; Android 4.4.4; zh-cn; OPPO R7s Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/7.1 Mobile Safari/537.36", @@ -864,6 +900,15 @@ "type": "console" } }, + { + "desc": "PlayStation Vita", + "ua": "Mozilla/5.0 (PlayStation Vita 3.52) AppleWebKit/537.73 (KHTML, like Gecko) Silk/3.2", + "expect": { + "vendor": "Sony", + "model": "PlayStation Vita", + "type": "console" + } + }, { "desc": "Nintendo Switch", "ua": "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", @@ -873,6 +918,42 @@ "type": "console" } }, + { + "desc": "Nintendo WiiU", + "ua": "Mozilla/5.0 (Nintendo WiiU) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.4.2.9 NintendoBrowser/4.2.0.11146.EU", + "expect": { + "vendor": "Nintendo", + "model": "WiiU", + "type": "console" + } + }, + { + "desc": "Nintendo Wii", + "ua": "Opera/9.10 (Nintendo Wii; U; ; 1621; en)", + "expect": { + "vendor": "Nintendo", + "model": "Wii", + "type": "console" + } + }, + { + "desc": "Nintendo 3DS", + "ua": "Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7610.EU", + "expect": { + "vendor": "Nintendo", + "model": "3DS", + "type": "console" + } + }, + { + "desc": "Nintendo 3DS", + "ua": "Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.15 Mobile NintendoBrowser/1.3.10126.EU", + "expect": { + "vendor": "Nintendo", + "model": "3DS", + "type": "console" + } + }, { "desc": "Galaxy Nexus", "ua": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19", @@ -1228,6 +1309,24 @@ "type": "tablet" } }, + { + "desc": "ZTE-Z431", + "ua": "ZTE-Z431/1.4.0 NetFront/4.2 QTV5.1 Profile/MIDP-2.1 Configuration/CLDC-1.1", + "expect": { + "vendor": "ZTE", + "model": "Z431", + "type": "mobile" + } + }, + { + "desc": "ZTE", + "ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; ZTE-Z740G Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "ZTE", + "model": "Z740G", + "type": "mobile" + } + }, { "desc": "ZTE K Series Tablet", "ua": "Mozilla/5.0 (Linux; Android 6.0.1; K88 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", @@ -1606,6 +1705,15 @@ "type": "tablet" } }, + { + "desc": "Vodafone Smart ultra 6", + "ua": "Mozilla/5.0 (Linux; Android 5.0.2; Vodafone Smart ultra 6 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "Vodafone", + "model": "Smart ultra 6", + "type": "tablet" + } + }, { "desc": "4ife 4K Smart TV Box", "ua": "Mozilla/5.0 (Linux; Android 4.4.2; 4ife 4K Smart TV Box Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36 Vinebre", @@ -1630,5 +1738,59 @@ "model": "undefined", "type": "undefined" } + }, + { + "desc": "Alcatel", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ALCATEL A564C Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "ALCATEL", + "model": "A564C", + "type": "mobile" + } + }, + { + "desc": "Jolla", + "ua": "Mozilla/5.0 (Maemo; Linux; U; Jolla; Sailfish; Mobile; rv:31.0) Gecko/31.0 Firefox/31.0 SailfishBrowser/1.0", + "expect": { + "vendor": "Jolla", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Xbox One", + "ua": "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; Xbox; Xbox One)", + "expect": { + "vendor": "Microsoft", + "model": "Xbox One", + "type": "console" + } + }, + { + "desc": "Xbox", + "ua": "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Xbox)", + "expect": { + "vendor": "Microsoft", + "model": "Xbox", + "type": "console" + } + }, + { + "desc": "Nvidia Shield Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SHIELD Tablet Build/LVY48E; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.19 Safari/537.36", + "expect": { + "vendor": "Nvidia", + "model": "SHIELD Tablet", + "type": "tablet" + } + }, + { + "desc": "Ouya", + "ua": "Mozilla/5.0 (Linux; Android 4.1.2; OUYA Console Build/JZO54L-OUYA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.84 Safari/537.36", + "expect": { + "vendor": "OUYA", + "model": "undefined", + "type": "console" + } } ] diff --git a/test/os-test.json b/test/os-test.json index fb13c14..b249831 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -152,6 +152,15 @@ "version" : "10" } }, + { + "desc" : "Tizen", + "ua" : "Mozilla/5.0 (SMART-TV; Linux; Tizen 2.3) AppleWebkit/538.1 (KHTML, like Gecko) SamsungBrowser/1.0 TV Safari/538.1", + "expect" : + { + "name" : "Tizen", + "version" : "2.3" + } + }, { "desc" : "Tizen", "ua" : "Mozilla/5.0 (Linux; Tizen 2.3; SAMSUNG SM-Z130H) AppleWebKit/537.3 (KHTML, like Gecko) Version/2.3 Mobile Safari/537.3", @@ -184,62 +193,80 @@ "ua" : "Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.5; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/234.83 Safari/534.6 TouchPad/1.0", "expect" : { - "name" : "WebOS", + "name" : "webOS", "version" : "3.0.5" } }, { - "desc" : "Palm OS", - "ua" : "", + "desc" : "WebOS", + "ua" : "Mozilla/5.0 (webOS/1.4.5; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pre/1.0", "expect" : { - "name" : "", - "version" : "" + "name" : "webOS", + "version" : "1.4.5" } }, { "desc" : "QNX", - "ua" : "", + "ua" : "Mozilla/5.0 (Photon; U; QNX x86pc; en-US; rv:1.8.1.20) Gecko/20090127 BonEcho/2.0.0.20", "expect" : { - "name" : "", - "version" : "" + "name" : "QNX", + "version" : "x86pc" } }, { "desc" : "Bada", - "ua" : "", + "ua" : "Mozilla/5.0 (SAMSUNG; SAMSUNG-GT-S5253/S5253DDKC1; U; Bada/1.0; en-us) AppleWebKit/533.1 (KHTML, like Gecko) Dolfin/2.0 Mobile WQVGA SMM-MMS/1.2.0 OPN-B", "expect" : { - "name" : "", - "version" : "" + "name" : "Bada", + "version" : "1.0" } }, { "desc" : "RIM Tablet OS", - "ua" : "", + "ua" : "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+", "expect" : { - "name" : "", - "version" : "" + "name" : "RIM Tablet OS", + "version" : "2.1.0" } }, { "desc" : "MeeGo", - "ua" : "", + "ua" : "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", "expect" : { - "name" : "", - "version" : "" + "name" : "MeeGo", + "version" : "undefined" } }, { "desc" : "Symbian", - "ua" : "", + "ua" : "Nokia5250/10.0.011 (SymbianOS/9.4; U; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Safari/525 3gpp-gba", "expect" : { - "name" : "", - "version" : "" + "name" : "Symbian", + "version" : "9.4" + } + }, + { + "desc" : "Symbian", + "ua" : "Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaC7-00/024.001; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.37 Mobile Safari/533.4 3gpp-gba", + "expect" : + { + "name" : "Symbian", + "version" : "5.2" + } + }, + { + "desc" : "Series40", + "ua" : "Mozilla/5.0 (Series40; Nokia2055/03.20; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/2.2.0.0.34", + "expect" : + { + "name" : "Series40", + "version" : "undefined" } }, { @@ -269,15 +296,6 @@ "version" : "Switch" } }, - { - "desc" : "PlayStation", - "ua" : "", - "expect" : - { - "name" : "", - "version" : "" - } - }, { "desc" : "PlayStation 4", "ua" : "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", @@ -350,15 +368,6 @@ "version" : "6" } }, - { - "desc" : "Joli", - "ua" : "", - "expect" : - { - "name" : "", - "version" : "" - } - }, { "desc" : "Ubuntu", "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.22+ (KHTML, like Gecko) Chromium/17.0.963.56 Chrome/17.0.963.56 Safari/535.22+ Ubuntu/12.04 (3.4.1-0ubuntu1) Epiphany/3.4.1", @@ -451,11 +460,38 @@ }, { "desc" : "Gentoo", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.16) Gecko/20080716 (Gentoo) Galeon/2.0.6", "expect" : { - "name" : "", - "version" : "" + "name" : "Gentoo", + "version" : "undefined" + } + }, + { + "desc" : "Gentoo", + "ua" : "Xombrero (X11; U; Gentoo Linux amd64; en-US) Webkit/2.8.5", + "expect" : + { + "name" : "Gentoo", + "version" : "amd64" + } + }, + { + "desc" : "Gentoo", + "ua" : "Xombrero/1.6.4 (Linux amd64; en; Gentoo)", + "expect" : + { + "name" : "Gentoo", + "version" : "undefined" + } + }, + { + "desc" : "Gentoo", + "ua" : "Links (2.8; Linux 3.17.2-gentoo-x86 i686; GNU C 4.8.2; x)", + "expect" : + { + "name" : "gentoo", + "version" : "x86" } }, { @@ -505,74 +541,11 @@ }, { "desc" : "Mandriva", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.22) Gecko/20110907 Mandriva Linux/1.9.2.22-0.1mdv2010.2 (2010.2) Firefox/3.6.22", "expect" : { - "name" : "", - "version" : "" - } - }, - { - "desc" : "CentOS", - "ua" : "", - "expect" : - { - "name" : "", - "version" : "" - } - }, - { - "desc" : "PCLinuxOS", - "ua" : "", - "expect" : - { - "name" : "", - "version" : "" - } - }, - { - "desc" : "RedHat", - "ua" : "", - "expect" : - { - "name" : "", - "version" : "" - } - }, - { - "desc" : "Zenwalk", - "ua" : "", - "expect" : - { - "name" : "", - "version" : "" - } - }, - { - "desc" : "Hurd", - "ua" : "", - "expect" : - { - "name" : "", - "version" : "" - } - }, - { - "desc" : "Linux", - "ua" : "", - "expect" : - { - "name" : "", - "version" : "" - } - }, - { - "desc" : "GNU", - "ua" : "", - "expect" : - { - "name" : "", - "version" : "" + "name" : "Mandriva", + "version" : "1.9.2.22-0.1mdv2010.2" } }, { @@ -692,6 +665,60 @@ "version" : "2.5" } }, + { + "desc" : "iTunes Windows Vista", + "ua" : "iTunes/10.7 (Windows; Microsoft Windows Vista Home Premium Edition Service Pack 1 (Build 6001)) AppleWebKit/536.26.9", + "expect" : + { + "name" : "Windows", + "version" : "Vista" + } + }, + { + "desc" : "iOS BE App", + "ua" : "APP-BE Test/1.0 (iPad; Apple; CPU iPhone OS 7_0_2 like Mac OS X)", + "expect" : + { + "name" : "iOS", + "version" : "7.0.2" + } + }, + { + "desc" : "KTB-Nexus 5", + "ua" : "APP-My App/1.0 (Linux; Android 4.2.1; Nexus 5 Build/JOP40D)", + "expect" : + { + "name" : "Android", + "version" : "4.2.1" + } + }, + { + "desc" : "Solaris", + "ua" : "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)", + "expect" : + { + "name" : "Solaris", + "version" : "4.1.4" + } + }, + { + "desc" : "Raspbian", + "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Raspbian Chromium/72.0.3626.121 HeadlessChrome/72.0.3626.121 Safari/537.36", + "expect" : + { + "name" : "Raspbian", + "version" : "undefined" + } + }, + { + "desc" : "Raspbian", + "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/538.15 (KHTML, like Gecko) Version/8.0 Safari/538.15 Raspbian/9.0 (1:3.8.2.0-0rpi28) Epiphany/3.8.2", + "expect" : + { + "name" : "Raspbian", + "version" : "9.0" + } + }, { "desc" : "AIX", "ua" : "", @@ -765,16 +792,7 @@ } }, { - "desc" : "iTunes Windows Vista", - "ua" : "iTunes/10.7 (Windows; Microsoft Windows Vista Home Premium Edition Service Pack 1 (Build 6001)) AppleWebKit/536.26.9", - "expect" : - { - "name" : "Windows", - "version" : "Vista" - } - }, - { - "desc" : "", + "desc" : "Joli", "ua" : "", "expect" : { @@ -783,48 +801,75 @@ } }, { - "desc" : "iOS BE App", - "ua" : "APP-BE Test/1.0 (iPad; Apple; CPU iPhone OS 7_0_2 like Mac OS X)", + "desc" : "CentOS", + "ua" : "", "expect" : { - "name" : "iOS", - "version" : "7.0.2" + "name" : "", + "version" : "" } }, { - "desc" : "KTB-Nexus 5", - "ua" : "APP-My App/1.0 (Linux; Android 4.2.1; Nexus 5 Build/JOP40D)", + "desc" : "PCLinuxOS", + "ua" : "", "expect" : { - "name" : "Android", - "version" : "4.2.1" + "name" : "", + "version" : "" } }, { - "desc" : "Solaris", - "ua" : "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)", + "desc" : "RedHat", + "ua" : "", "expect" : { - "name" : "Solaris", - "version" : "4.1.4" + "name" : "", + "version" : "" } }, { - "desc" : "Raspbian", - "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Raspbian Chromium/72.0.3626.121 HeadlessChrome/72.0.3626.121 Safari/537.36", + "desc" : "Zenwalk", + "ua" : "", "expect" : { - "name" : "Raspbian", - "version" : "undefined" + "name" : "", + "version" : "" } }, { - "desc" : "Raspbian", - "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/538.15 (KHTML, like Gecko) Version/8.0 Safari/538.15 Raspbian/9.0 (1:3.8.2.0-0rpi28) Epiphany/3.8.2", + "desc" : "Hurd", + "ua" : "", "expect" : { - "name" : "Raspbian", - "version" : "9.0" + "name" : "", + "version" : "" + } + }, + { + "desc" : "Linux", + "ua" : "", + "expect" : + { + "name" : "", + "version" : "" + } + }, + { + "desc" : "GNU", + "ua" : "", + "expect" : + { + "name" : "", + "version" : "" + } + }, + { + "desc" : "Palm OS", + "ua" : "", + "expect" : + { + "name" : "", + "version" : "" } } ] From 536b9e8d9d4e4a7c12f57c0607c9e499fc8e5f35 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 26 Mar 2021 15:53:46 +0700 Subject: [PATCH 078/121] Add new device.vendor: Vivo --- readme.md | 2 +- src/ua-parser.js | 5 +++++ test/device-test.json | 45 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 925a164..f8f90e2 100644 --- a/readme.md +++ b/readme.md @@ -57,7 +57,7 @@ Acer, Alcatel, Amazon, Apple, Archos, Asus, AT&T, BenQ, BlackBerry, Dell, Essential, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, Ouya, Palm, Panasonic, Pebble, Polytron, RIM, Samsung, Sharp, Siemens, Sony[Ericsson], -Sprint, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... +Sprint, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... # 'device.model' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 722244e..0ff6ca0 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -406,6 +406,11 @@ /;\s(\w+)\sbuild.+\soppo/i ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ + // Vivo + /\svivo\s(\w+)\sbuild/i, + /droid\s[\d\.]+;\s(v(?:1[89]|20)\d\d\w?[at])(?:\sbuild|;)/i + ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ + // Motorola /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)[\w\s]+build\//i, /\smot[\s-](\w*)/i, diff --git a/test/device-test.json b/test/device-test.json index 667bd7b..b53721d 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1792,5 +1792,50 @@ "model": "undefined", "type": "console" } + }, + { + "desc": "Vivo Y52s", + "ua": "Mozilla/5.0 (Linux; Android 10; V2057A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.10 SP-engine/2.28.0 baiduboxapp/12.10.0.10 (Baidu; P1 10) NABar/1.0", + "expect": { + "vendor": "Vivo", + "model": "V2057A", + "type": "mobile" + } + }, + { + "desc": "Vivo X60", + "ua": "Mozilla/5.0 (Linux; Android 11; V2046A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/8.8.71.0", + "expect": { + "vendor": "Vivo", + "model": "V2046A", + "type": "mobile" + } + }, + { + "desc": "Vivo Y79A", + "ua": "Mozilla/5.0 (Linux; Android 7.1.2; vivo Y79A Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", + "expect": { + "vendor": "Vivo", + "model": "Y79A", + "type": "mobile" + } + }, + { + "desc": "Vivo Y97", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; V1813T Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", + "expect": { + "vendor": "Vivo", + "model": "V1813T", + "type": "mobile" + } + }, + { + "desc": "Vivo iQOO Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; V1916A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.1.10.6", + "expect": { + "vendor": "Vivo", + "model": "V1916A", + "type": "mobile" + } } ] From 2cfd792d245146e2b2882b23494788711b66bea1 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 26 Mar 2021 19:39:00 +0700 Subject: [PATCH 079/121] Fix #342 - Enforce all regexes to comply with safe-regex as a safeguard against possible ReDoS vulnerability --- package.json | 1 + test/test.js | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5612171..2400f23 100644 --- a/package.json +++ b/package.json @@ -120,6 +120,7 @@ "jshint": "~2.12.0", "mocha": "~8.2.0", "requirejs": "^2.3.2", + "safe-regex": "^2.1.1", "uglify-js": "~3.12.0", "verup": "^1.3.x" }, diff --git a/test/test.js b/test/test.js index b0e699c..5b55ade 100644 --- a/test/test.js +++ b/test/test.js @@ -1,3 +1,5 @@ +var fs = require('fs'); +var safe = require('safe-regex'); var assert = require('assert'); var requirejs = require('requirejs'); var UAParser = require('./../src/ua-parser'); @@ -121,4 +123,29 @@ describe('Using Require.js', function () { done(); }); }); -}); \ No newline at end of file +}); + +describe('Testing regexes', function () { + + var regexes; + + // todo: use AST-based instead of grep + before('Read main js file', function (done) { + fs.readFile('src/ua-parser.js', 'utf8', function (err, data) { + regexes = data.match(/(\/.+\/[ig]+)(?=[,\s\n])/g); + done(); + }); + }); + + describe('Begin testing', function () { + it('all regexes in main file', function () { + regexes.forEach(function (regex) { + describe('Test against `safe-regex` : ' + regex, function () { + it('should be safe from potentially vulnerable regex', function () { + assert.strictEqual(safe(regex), true); + }); + }); + }); + }); + }); +}) \ No newline at end of file From 4f27489ccfdaca6f93c4fe273a6530750c45c980 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 26 Mar 2021 21:17:35 +0700 Subject: [PATCH 080/121] Fix regexes that were marked as unsafe by safe-regex module --- src/ua-parser.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index d1eb603..5ba5fc0 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -204,7 +204,7 @@ /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS ], [VERSION, [NAME, 'Chrome']], [ - /(?:edge|edgios|edga|edg)\/((\d+)?[\w\.]+)/i // Microsoft Edge + /(?:edge|edgios|edga|edg)\/([\w\.]+)/i // Microsoft Edge ], [VERSION, [NAME, 'Edge']], [ // Presto based @@ -442,7 +442,7 @@ // Google /droid.+;\s(pixel c)[\s)]/i // Google Pixel C ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [ - /droid.+;\s(pixel( [2-9]a?)?( xl)?)[\s)]/i // Google Pixel + /droid.+;\s(pixel[\s\daxl]{0,6})(?:\sbuild|\))/i // Google Pixel ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [ // Sony @@ -529,8 +529,8 @@ ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ /[;\/]\s*(q[t|m][\d\w]+)\s+build/i // Verizon Tablet ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ - /[;\/]\s+(barnes[&\s]+noble\s+|bn[rt])(\S(?:.*\S)?)\s+build/i - ], [[VENDOR, 'Barnes & Noble'], MODEL, [TYPE, TABLET]], [ + /[;\/]\s(?:barnes[&\s]+noble\s|bn[rt])([\w\s\+]*)\sbuild/i + ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [ /[;\/]\s+(tm\d{3}.*\b)\s+build/i // Barnes & Noble Tablet ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [ /;\s(k88)\sbuild/i // ZTE K Series Tablet From 3b703a6379f404dba2163d432c9fbaac7a4227c7 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 27 Mar 2021 00:10:55 +0700 Subject: [PATCH 081/121] Refine device detection with more test cases --- dist/ua-parser.min.js | 2 +- dist/ua-parser.pack.js | 2 +- readme.md | 6 +- src/ua-parser.js | 103 ++++++------- test/device-test.json | 324 +++++++++++++++++++++++++++++++++++++++-- 5 files changed, 372 insertions(+), 65 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index f5c7c32..6dae2b6 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.25",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded";var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){if(typeof str1==="string"){return str2.toLowerCase().indexOf(str1.toLowerCase())!==-1}else{return false}},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str){return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index abf260b..3a37870 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -6,4 +6,4 @@ * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -!function(r,u){"use strict";var c="function",i="undefined",b="object",s="model",e="name",o="type",a="vendor",n="version",d="architecture",t="console",w="mobile",l="tablet",m="smarttv",p="wearable",h={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return"string"==typeof i&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return"string"==typeof i?i.replace(/[^\d\.]/g,"").split(".")[0]:u},trim:function(i){return i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}},g={rgx:function(i,s){for(var e,o,r,a,n,d=0;d 9.80 /(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80 ], [NAME, VERSION], [ @@ -234,20 +234,18 @@ ], [NAME, VERSION], [ /(?:[\s\/]uc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser ], [VERSION, [NAME, 'UCBrowser']], [ - /(?:windowswechat)?\sqbcore\/([\w\.]+).*(?:windowswechat)?/i // WeChat Desktop for Windows Built-in Browser + /(?:windowswechat)?\sqbcore\/([\w\.]+)\b.*(?:windowswechat)?/i // WeChat Desktop for Windows Built-in Browser ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [ /micromessenger\/([\w\.]+)/i // WeChat ], [VERSION, [NAME, 'WeChat']], [ /konqueror\/([\w\.]+)/i // Konqueror ], [VERSION, [NAME, 'Konqueror']], [ - /trident.+rv[:\s]([\w\.]{1,9}).+like\sgecko/i // IE11 + /trident.+rv[:\s]([\w\.]{1,9})\b.+like\sgecko/i // IE11 ], [VERSION, [NAME, 'IE']], [ /yabrowser\/([\w\.]+)/i // Yandex ], [VERSION, [NAME, 'Yandex']], [ - /Avast\/([\w\.]+)/i // Avast Secure Browser - ], [VERSION, [NAME, 'Avast Secure Browser']], [ - /AVG\/([\w\.]+)/i // AVG Secure Browser - ], [VERSION, [NAME, 'AVG Secure Browser']], [ + /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser + ], [[NAME, /(.+)/, '$1 Secure Browser'], VERSION], [ /focus\/([\w\.]+)/i // Firefox Focus ], [VERSION, [NAME, 'Firefox Focus']], [ /opt\/([\w\.]+)/i // Opera Touch @@ -292,7 +290,7 @@ /\swv\).+(chrome)\/([\w\.]+)/i // Chrome WebView ], [[NAME, 'Chrome WebView'], VERSION], [ - /droid.+\sversion\/([\w\.]+).+(?:mobile\ssafari|safari)/i // Android Browser + /droid.+\sversion\/([\w\.]+)\b.+(?:mobile\ssafari|safari)/i // Android Browser ], [VERSION, [NAME, 'Android Browser']], [ /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia @@ -368,8 +366,7 @@ ///////////////////// // Samsung - /\b(sch-i[89]0\d|shw-m380s|SM-P605|SM-P610|SM-P587|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10)/i, - /(SM-T\w+)/i + /\b(sch-i[89]0\d|shw-m380s|sm-p(?:605|610|587)|sm-t\w+|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus\s10)/i, ], [MODEL, [VENDOR, 'Samsung'], [TYPE, TABLET]], [ /(s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-\w[\w\d]+)/i, /\ssamsung[\s-]([\w-]+)/i, @@ -381,41 +378,42 @@ ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [ /\((ipad);[\w\s\),;-]+(apple)/i // iPad ], [MODEL, VENDOR, [TYPE, TABLET]], [ - /applecoremedia\/[\w\.]+ \((ipad)/ // iPad + /applecoremedia\/[\w\.]+\s\((ipad)/i ], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [ // Huawei /d\/huawei([\w\s-]+)[;\)]/i, /\b(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, - /\b(\w{2,4}-[ATU][LN][01259][019])[;\)\s]/i + /\b(\w{2,4}-[atu][ln][01259][019])[;\)\s]/i ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ /\b(bah2?-a?[lw]\d{2})/i // Huawei MediaPad ], [MODEL, [VENDOR, 'Huawei'], [TYPE, TABLET]], [ // Xiaomi - /\b(poco\s\w+)\b/i, // Xiaomi POCO + /\b(poco[\s\w]+)(?:\sbuild|\))/i, // Xiaomi POCO /\b;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /\b(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi - /\b(redmi[\s\-_]?(?:note|k)?(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i, // Xiaomi Redmi + /\b(redmi[\s\-_]?(?:note|k)?[\w\s_]+)(?:\sbuild|\))/i, // Xiaomi Redmi /\b(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ - /\b(mi[\s\-_]?(?:pad)(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i // Mi Pad tablets + /\b(mi[\s\-_]?(?:pad)(?:[\w\s_]+))(?:\sbuild|\))/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [ // OPPO - /;\s(\w+)\sbuild.+\soppo/i + /;\s(\w+)\sbuild.+\soppo/i, + /\s(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007)\b/i ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ // Vivo - /\svivo\s(\w+)\sbuild/i, - /droid\s[\d\.]+;\s(v(?:1[89]|20)\d\d\w?[at])(?:\sbuild|;)/i + /\svivo\s(\w+)(?:\sbuild|\))/i, + /\s(v(?:1[89]|20)\d\d\w?[at])(?:\sbuild|;)/i ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ // Motorola - /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)[\w\s]+build\//i, + /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)\b[\w\s]+build\//i, /\smot[\s-](\w*)/i, /(moto[\s\w\(\)]+(?=\sbuild|\)))/i, - /(XT\d{3,4}) build\//i, + /(xt\d{3,4})\sbuild\//i, /(nexus\s6)/i ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [ /\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i @@ -431,7 +429,7 @@ // Lenovo /(ideatab[\w\-\s]+)/i, - /lenovo\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+)|[\w-]+)/i // Lenovo tablets + /lenovo\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+)|[\w-]+)/i // Lenovo tablets ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ // Nokia @@ -440,7 +438,7 @@ ], [MODEL, [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ // Google - /droid.+;\s(pixel c)[\s)]/i // Google Pixel C + /droid.+;\s(pixel\sc)[\s)]/i // Google Pixel C ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [ /droid.+;\s(pixel[\s\daxl]{0,6})(?:\sbuild|\))/i // Google Pixel ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [ @@ -453,13 +451,14 @@ ], [[MODEL, 'Xperia Tablet'], [VENDOR, 'Sony'], [TYPE, TABLET]], [ // OnePlus + /\s(kb2005|in20[12]5|be20[12][59])\b/i, /\ba000(1)\s+build/i, // OnePlus /\boneplus\s(a\d{4})[\s)]/i ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ // Amazon /(alexa)webm/i, - /(kf[A-z]+)(\sbuild\/|\)).+silk\//i // Kindle Fire HD + /(kf[a-z]+)(\sbuild\/|\)).+silk\//i // Kindle Fire HD ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ /(sd|kf)[0349hijorstuw]+(\sbuild\/|\)).+silk\//i // Fire Phone ], [[MODEL, 'Fire Phone'], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ @@ -471,8 +470,10 @@ ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [ // Asus - /\b(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7|padfone|p00c)/i - ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [ + /\b(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus\s7|padfone|p00c)/i + ], [MODEL, [VENDOR, 'ASUS'], [TYPE, TABLET]], [ + /\s(z[es]6[027][01][km][ls]|zenfone\s\d\w?)\b/i + ], [MODEL, [VENDOR, 'ASUS'], [TYPE, MOBILE]], [ // HTC /(nexus\s9)/i // HTC Nexus 9 @@ -490,7 +491,7 @@ // Meizu /droid.+;\s(m[1-5]\snote)\sbuild/i, - /mz-([\w-]{2,})/i + /\bmz-([\w-]{2,})/i ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ // MIXED @@ -511,9 +512,9 @@ /(kindle)\/([\w\.]+)/i, // Kindle /\s(nook)[\w\s]+build\/(\w+)/i, // Nook /(dell)\s(strea[kpr\s\d]*[\dko])/i, // Dell Streak - /[;\/]\s*(le[\s\-]+pan)[\s\-]+(\w{1,9})\s+build/i, // Le Pan Tablets - /[;\/]\s*(trinity)[\-\s]*(t\d{3})\s+build/i, // Trinity Tablets - /\b(gigaset)[\s\-]+(Q\w{1,9})\s+build/i, // Gigaset Tablets + /[;\/]\s?(le[\s\-]+pan)[\s\-]+(\w{1,9})\sbuild/i, // Le Pan Tablets + /[;\/]\s?(trinity)[\-\s]*(t\d{3})\sbuild/i, // Trinity Tablets + /\b(gigaset)[\s\-]+(q\w{1,9})\sbuild/i, // Gigaset Tablets /\b(vodafone)\s([\w\s]+)(?:\)|\sbuild)/i // Vodafone ], [VENDOR, MODEL, [TYPE, TABLET]], [ @@ -523,44 +524,44 @@ ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ /sie-(\w*)/i // Siemens ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ - /[;\/]\s*(rct[\d\w]+)\s+build/i // RCA Tablets + /[;\/]\s?(rct\w+)\sbuild/i // RCA Tablets ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [ - /[;\/\s](venue[\d\s]{2,7})\s+build/i // Dell Venue Tablets + /[;\/\s](venue[\d\s]{2,7})\sbuild/i // Dell Venue Tablets ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ - /[;\/]\s*(q[t|m][\d\w]+)\s+build/i // Verizon Tablet + /[;\/]\s?(q(?:mv|ta)\w+)\sbuild/i // Verizon Tablet ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ - /[;\/]\s(?:barnes[&\s]+noble\s|bn[rt])([\w\s\+]*)\sbuild/i + /[;\/]\s(?:barnes[&\s]+noble\s|bn[rt])([\w\s\+]*)\sbuild/i // Barnes & Noble Tablet ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [ - /[;\/]\s+(tm\d{3}.*\b)\s+build/i // Barnes & Noble Tablet + /[;\/]\s(tm\d{3}\w+)\sbuild/i ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [ /;\s(k88)\sbuild/i // ZTE K Series Tablet ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [ /;\s(nx\d{3}j)\sbuild/i // ZTE Nubia ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [ - /[;\/]\s*(gen\d{3})\s+build.*49h/i // Swiss GEN Mobile + /[;\/]\s?(gen\d{3})\sbuild.*49h/i // Swiss GEN Mobile ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [ - /[;\/]\s*(zur\d{3})\s+build/i // Swiss ZUR Tablet + /[;\/]\s?(zur\d{3})\sbuild/i // Swiss ZUR Tablet ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ - /[;\/]\s*((zeki)?tb.*\b)\s+build/i // Zeki Tablets + /[;\/]\s?((zeki)?tb.*\b)\sbuild/i // Zeki Tablets ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ - /[;\/]\s+([yr]\d{2})\s+build/i, - /[;\/]\s+(dragon[\-\s]+touch\s+|dt)(\w{5})\sbuild/i // Dragon Touch Tablet + /[;\/]\s([yr]\d{2})\sbuild/i, + /[;\/]\s(dragon[\-\s]+touch\s|dt)(\w{5})\sbuild/i // Dragon Touch Tablet ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [ - /[;\/]\s*(ns-?\w{0,9})\sbuild/i // Insignia Tablets + /[;\/]\s?(ns-?\w{0,9})\sbuild/i // Insignia Tablets ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [ - /[;\/]\s*((nxa|Next)-?\w{0,9})\s+build/i // NextBook Tablets + /[;\/]\s?((nxa|Next)-?\w{0,9})\sbuild/i // NextBook Tablets ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [ - /[;\/]\s*(xtreme\_)?(v(1[045]|2[015]|30|40|60|7[05]|90))\s+build/i + /[;\/]\s?(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05]))\sbuild/i ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ // Voice Xtreme Phones - /[;\/]\s*(lvtel\-)?(v1[12])\s+build/i // LvTel Phones + /[;\/]\s?(lvtel\-)?(v1[12])\sbuild/i // LvTel Phones ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [ - /;\s(PH-1)\s/i + /;\s(ph-1)\s/i ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ // Essential PH-1 - /[;\/]\s*(V(100md|700na|7011|917g).*\b)\s+build/i // Envizen Tablets + /[;\/]\s?(v(100md|700na|7011|917g).*\b)\sbuild/i // Envizen Tablets ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [ - /[;\/]\s*(trio[\s\w\-\.]+)\s+build/i // MachSpeed Tablets + /[;\/]\s?(trio[\s\w\-\.]+)\sbuild/i // MachSpeed Tablets ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [ - /[;\/]\s*tu_(1491)\s+build/i // Rotor Tablets + /[;\/]\s?tu_(1491)\sbuild/i // Rotor Tablets ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [ /(shield[\w\s]+)\sbuild/i // Nvidia Shield Tablets ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [ @@ -568,7 +569,7 @@ ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kin\.[onetw]{3})/i // Microsoft Kin ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ - /droid\s[\d\.]+;\s(cc6{3,4}|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra + /droid\s[\d\.]+;\s(cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra ], [MODEL, [VENDOR, 'Zebra'], [TYPE, TABLET]], [ /droid\s[\d\.]+;\s(ec30|ps20|tc[2-8]\d[kx])\)/i ], [MODEL, [VENDOR, 'Zebra'], [TYPE, MOBILE]], [ @@ -654,7 +655,7 @@ /(icab)[\/\s]([23]\.[\d\.]+)/i // iCab ], [NAME, VERSION], [ - /rv\:([\w\.]{1,9}).+(gecko)/i // Gecko + /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko ], [VERSION, NAME] ], @@ -671,7 +672,7 @@ ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [ // iOS/macOS - /ip[honead]{2,4}(?:.*os\s([\w]+)\slike\smac|;\sopera)/i, // iOS + /ip[honead]{2,4}\b(?:.*os\s([\w]+)\slike\smac|;\sopera)/i, // iOS /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ /(mac\sos\sx)\s?([\w\s\.]*)/i, @@ -681,7 +682,7 @@ // Mobile OSes /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS - /(blackberry)\w*\/?([\w\.]*)/i, // Blackberry + /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/\s]([\w\.]+)/i // Tizen/KaiOS ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 diff --git a/test/device-test.json b/test/device-test.json index b53721d..3a7da03 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1,30 +1,129 @@ [{ - "desc": "Asus Nexus 7", + "desc": "ASUS Nexus 7", "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 7 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", "expect": { - "vendor": "Asus", + "vendor": "ASUS", "model": "Nexus 7", "type": "tablet" } }, { - "desc": "Asus Padfone", + "desc": "ASUS Padfone", "ua": "Mozilla/5.0 (Linux; Android 4.1.1; PadFone 2 Build/JRO03L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Safari/537.36", "expect": { - "vendor": "Asus", + "vendor": "ASUS", "model": "PadFone", "type": "tablet" } }, { - "desc": "Asus ZenPad 10", + "desc": "ASUS ZenPad 10", "ua": "Mozilla/5.0 (Linux; Android 6.0; P00C Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Safari/537.36", "expect": { - "vendor": "Asus", + "vendor": "ASUS", "model": "P00C", "type": "tablet" } }, + { + "desc": "ASUS ROG", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ZS600KL Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZS600KL", + "type": "mobile" + } + }, + { + "desc": "ASUS ROG II", + "ua": "Mozilla/5.0 (Linux; Android 9; ASUS_I001DA Build/PKQ1.190414.001; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "I001DA", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 2", + "ua": "Mozilla/5.0 (Linux; Android 5.0; ASUS ZenFone 2 Build/LRX22C) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZenFone 2", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 3 Deluxe", + "ua": "Mozilla/5.0 (Linux; Android 6.0; ASUS_Z016D Build/MXB48T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.132 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "Z016D", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 5", + "ua": "Mozilla/5.0 (Linux; Android 8.0; ZE620KL Build/OPR1.170623.032) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.158 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZE620KL", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 7", + "ua": "Mozilla/5.0 (Linux; Android 10; ASUS_I002D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.81 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "I002D", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 7 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; ZS671KS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZS671KS", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Max Pro (M1)", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X00TD Build/OPM1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X00TD", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Max M2", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X01AD) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X01AD", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Max Pro M2", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X01BDA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X01BDA", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Go", + "ua": "Mozilla/5.0 (Linux; Android 6.0; ASUS_X009DA Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X009DA", + "type": "mobile" + } + }, { "desc": "Acer Iconia A1-810", "ua": "Mozilla/5.0 (Linux; Android 4.2.2; A1-810 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Safari/537.36", @@ -124,6 +223,15 @@ "type": "tablet" } }, + { + "desc": "iPad Air", + "ua": "Mozilla/5.0 (iPad; CPU OS 12_4_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPad4,1;FBMD/iPad;FBSN/iOS;FBSV/12.4.5;FBSS/2;FBID/tablet;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPad", + "type": "tablet" + } + }, { "desc": "iPod", "ua": "Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53", @@ -160,6 +268,15 @@ "type": "tablet" } }, + { + "desc": "LG K500", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; LG-K500 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "K500", + "type": "mobile" + } + }, { "desc": "LG Nexus 4", "ua": "Mozilla/5.0 (Linux; Android 4.2.1; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", @@ -289,7 +406,34 @@ } }, { - "desc": "Motorola Droid RAZR 4G", + "desc": "iPhone SE", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone8,4;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPhone 11 Pro Max", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone12,5;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPhone XS", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone11,2;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPod touch", "ua": "Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_2 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A501 Safari/9537.53", "expect": { "vendor": "Apple", @@ -405,6 +549,42 @@ "type": "mobile" } }, + { + "desc": "OnePlus 8T", + "ua": "Mozilla/5.0 (Linux; Android 11; KB2005) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "KB2005", + "type": "mobile" + } + }, + { + "desc": "OnePlus 8 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; IN2025) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.119 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "IN2025", + "type": "mobile" + } + }, + { + "desc": "OnePlus Nord N100", + "ua": "Mozilla/5.0 (Linux; Android 10; BE2015 Build/QKQ1.200719.002; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "BE2015", + "type": "mobile" + } + }, + { + "desc": "OnePlus Nord N10 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; BE2029) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.185 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "BE2029", + "type": "mobile" + } + }, { "desc": "OPPO Neo", "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; R831T Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 OppoBrowser/3.3.2 Mobile Safari/534.30", @@ -423,6 +603,87 @@ "type": "mobile" } }, + { + "desc": "OPPO A3s", + "ua": "Mozilla/5.0 (Linux; Android 8.1; CPH1803 Build/OPM1.171019.026; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "CPH1803", + "type": "mobile" + } + }, + { + "desc": "OPPO A12", + "ua": "Mozilla/5.0 (Linux; Android 9; CPH2083) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "CPH2083", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno", + "ua": "Mozilla/5.0 (Linux; Android 9; PCAT00 Build/PKQ1.190101.001; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PCAT00", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno3 Pro 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; PCLM50) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.117 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PCLM50", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno4 SE", + "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; PEAM00 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PEAM00", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno4 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; PDPM00 Build/QKQ1.200216.002; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PDPM00", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno4 Pro 5G", + "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; PDNT00 Build/QKQ1.200216.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PDNT00", + "type": "mobile" + } + }, + { + "desc": "OPPO Find X", + "ua": "Mozilla/5.0 (Linux; Android 8.1; PAFM00 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PAFM00", + "type": "mobile" + } + }, + { + "desc": "OPPO Find 7a", + "ua": "Mozilla/5.0 (Linux; U; Android 4.3; xx-xx; X9007 Build/JLS36C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "OPPO", + "model": "X9007", + "type": "mobile" + } + }, { "desc": "Philips SmartTV", "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", @@ -450,6 +711,24 @@ "type": "tablet" } }, + { + "desc": "Samsung Galaxy A21s", + "ua": "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-A217F) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.0 Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A217F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A31", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-A315G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A315G", + "type": "mobile" + } + }, { "desc": "Samsung Galaxy A50", "ua": "Mozilla/5.0 (Linux; Android 9; SM-A505F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.105 Mobile Safari/537.36", @@ -532,7 +811,16 @@ } }, { - "desc": "Samsung SM-T700", + "desc": "Samsung Galaxy Tab S7", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-T870) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T870", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab S", "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T700 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", "expect": { "vendor": "Samsung", @@ -541,7 +829,7 @@ } }, { - "desc": "Samsung SM-T520", + "desc": "Samsung Galaxy Tab Pro 10.1", "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T520 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", "expect": { "vendor": "Samsung", @@ -1152,6 +1440,15 @@ "type": "mobile" } }, + { + "desc": "Google Pixel 4a", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 4a", + "type": "mobile" + } + }, { "desc": "Google Pixel 4 XL", "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", @@ -1161,6 +1458,15 @@ "type": "mobile" } }, + { + "desc": "Google Pixel 5", + "ua": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.120 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 5", + "type": "mobile" + } + }, { "desc": "Generic Android Device", "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K)", From 0e70fc4044e19c6fef9a3c0d7fcacfc3e09d07e2 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 27 Mar 2021 02:21:18 +0700 Subject: [PATCH 082/121] Add new device.vendor: Realme --- src/ua-parser.js | 6 +++++- test/device-test.json | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 7277945..84418d2 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -406,8 +406,12 @@ // Vivo /\svivo\s(\w+)(?:\sbuild|\))/i, - /\s(v(?:1[89]|20)\d\d\w?[at])(?:\sbuild|;)/i + /\s(v[12]\d{3}\w?[at])(?:\sbuild|;)/i ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ + + // Realme + /\s(rmx[12]\d{3})(?:\sbuild|;)/i + ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [ // Motorola /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)\b[\w\s]+build\//i, diff --git a/test/device-test.json b/test/device-test.json index 3a7da03..378efb5 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -684,6 +684,24 @@ "type": "mobile" } }, + { + "desc": "Realme C1", + "ua": "Mozilla/5.0 (Linux; Android 8.1; RMX1811 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX1811", + "type": "mobile" + } + }, + { + "desc": "Realme Narzo 20", + "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; RMX2193 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX2193", + "type": "mobile" + } + }, { "desc": "Philips SmartTV", "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", From a6b0c165c4882b62c430284f77cbd231c497d892 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 27 Mar 2021 02:43:24 +0700 Subject: [PATCH 083/121] Release as 0.7.26 --- bower.json | 2 +- dist/ua-parser.min.js | 4 ++-- dist/ua-parser.pack.js | 4 ++-- package.js | 2 +- package.json | 2 +- readme.md | 4 ++-- src/ua-parser.js | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/bower.json b/bower.json index 16869f0..2d80d5c 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.25", + "version": "0.7.26", "authors": [ "Faisal Salman " ], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 6dae2b6..4d9e963 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,9 @@ /*!@license - * UAParser.js v0.7.25 + * UAParser.js v0.7.26 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.25",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file +(function(window,undefined){"use strict";var LIBVERSION="0.7.26",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index 3a37870..ad78bbf 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,9 +1,9 @@ /*!@license - * UAParser.js v0.7.25 + * UAParser.js v0.7.26 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -!function(r,b){"use strict";var u="function",e="undefined",c="object",o="string",i="model",s="name",a="type",n="vendor",t="version",l="architecture",w="console",d="mobile",m="tablet",p="smarttv",h="wearable",g={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return typeof i==o&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i==o?i.replace(/[^\d\.]/g,"").split(".")[0]:b},trim:function(i,s){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof s==e?i:i.substring(0,255)}},f={rgx:function(i,s){for(var e,o,r,a,n,t=0;t (http://faisalman.com)", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": [ diff --git a/readme.md b/readme.md index 4e0e056..62373d5 100644 --- a/readme.md +++ b/readme.md @@ -64,8 +64,8 @@ console, mobile, tablet, smarttv, wearable, embedded Acer, Alcatel, Amazon, Apple, Archos, ASUS, AT&T, BenQ, BlackBerry, Dell, Essential, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, OPPO, Ouya, -Palm, Panasonic, Pebble, Polytron, RIM, Samsung, Sharp, Siemens, Sony[Ericsson], -Sprint, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... +Palm, Panasonic, Pebble, Polytron, Realme, RIM, Samsung, Sharp, Siemens, +Sony[Ericsson], Sprint, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... # 'device.model' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 86f4f16..b463e32 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ /*!@license - * UAParser.js v0.7.25 + * UAParser.js v0.7.26 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * @@ -16,7 +16,7 @@ ///////////// - var LIBVERSION = '0.7.25', + var LIBVERSION = '0.7.26', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From 91fa6dd5cc3f3f86f6fb5c708651f9f51aec2eee Mon Sep 17 00:00:00 2001 From: sUP Date: Mon, 29 Mar 2021 15:42:44 +0300 Subject: [PATCH 084/121] Better tablet detection: - Huawei MediaPad M/T - Galaxy Tab SM-P - Kindle Fire without Silk --- dist/ua-parser.min.js | 2 +- dist/ua-parser.pack.js | 2 +- src/ua-parser.js | 23 +++++++++++---------- test/device-test.json | 45 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 12 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 4d9e963..2a6b60e 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.26",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file +(function(window,undefined){"use strict";var LIBVERSION="0.7.26",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index ad78bbf..fcc1d58 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -6,4 +6,4 @@ * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -!function(r,b){"use strict";var u="function",e="undefined",c="object",o="string",i="model",s="name",a="type",n="vendor",t="version",l="architecture",w="console",d="mobile",m="tablet",p="smarttv",h="wearable",g={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return typeof i==o&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i==o?i.replace(/[^\d\.]/g,"").split(".")[0]:b},trim:function(i,s){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof s==e?i:i.substring(0,255)}},f={rgx:function(i,s){for(var e,o,r,a,n,t=0;t Date: Mon, 29 Mar 2021 16:04:00 +0300 Subject: [PATCH 085/121] Better tablet detection: - Fix lenovo phone / tablet detection --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index c56b67b..91969c2 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -448,7 +448,7 @@ // Lenovo /(ideatab[\w\-\s]+)/i, - /lenovo\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+)|[\w-]+)/i // Lenovo tablets + /lenovo\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+)|yt[\d\w-]{6}|tb[\d\w-]{6})/i // Lenovo tablets ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ // Nokia diff --git a/test/device-test.json b/test/device-test.json index 6431f6b..e5f6aa6 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -250,6 +250,15 @@ "type": "tablet" } }, + { + "desc": "Lenovo Phone", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Lenovo PB2-650M Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.105 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/311.0.0.44.117;]", + "expect": { + "vendor": "Lenovo", + "model": "PB2-650M", + "type": "mobile" + } + }, { "desc": "Lenovo Tab 3 Pro", "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo YT3-X90F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", From d72de26ef95dbdccb748e3e593670a5e66eeaa2b Mon Sep 17 00:00:00 2001 From: sUP Date: Mon, 29 Mar 2021 16:17:18 +0300 Subject: [PATCH 086/121] Better tablet detection - Build. --- dist/ua-parser.min.js | 2 +- dist/ua-parser.pack.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 2a6b60e..38ca626 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.26",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file +(function(window,undefined){"use strict";var LIBVERSION="0.7.26",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index fcc1d58..0a1ce41 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -6,4 +6,4 @@ * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -!function(r,b){"use strict";var u="function",e="undefined",c="object",o="string",i="model",s="name",a="type",n="vendor",t="version",l="architecture",w="console",d="mobile",m="tablet",p="smarttv",h="wearable",g={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return typeof i==o&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i==o?i.replace(/[^\d\.]/g,"").split(".")[0]:b},trim:function(i,s){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof s==e?i:i.substring(0,255)}},f={rgx:function(i,s){for(var e,o,r,a,n,t=0;t Date: Mon, 29 Mar 2021 18:40:41 +0300 Subject: [PATCH 087/121] Better tablet detection: - iPad using Facebook browser on some occasions - More Huawei tablets - Asus ZenPad Z8s (P00J) --- dist/ua-parser.min.js | 2 +- dist/ua-parser.pack.js | 2 +- src/ua-parser.js | 9 ++++++--- test/device-test.json | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 38ca626..20f8f73 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.26",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file +(function(window,undefined){"use strict";var LIBVERSION="0.7.26",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index 0a1ce41..f85564c 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -6,4 +6,4 @@ * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -!function(r,b){"use strict";var u="function",e="undefined",c="object",o="string",i="model",s="name",a="type",n="vendor",t="version",l="architecture",w="console",d="mobile",m="tablet",p="smarttv",h="wearable",g={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return typeof i==o&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i==o?i.replace(/[^\d\.]/g,"").split(".")[0]:b},trim:function(i,s){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof s==e?i:i.substring(0,255)}},f={rgx:function(i,s){for(var e,o,r,a,n,t=0;t Date: Thu, 1 Apr 2021 16:22:51 +0700 Subject: [PATCH 088/121] Small refactor --- src/ua-parser.js | 80 +++++++++++++++++-------------------------- test/device-test.json | 11 +++++- 2 files changed, 41 insertions(+), 50 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index bf75300..ed14fe9 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -223,8 +223,7 @@ // Presto based /(opera\smini)\/([\w\.-]+)/i, // Opera Mini /(opera\s[mobiletab]{3,6})\b.+version\/([\w\.-]+)/i, // Opera Mobi/Tablet - /(opera).+version\/([\w\.]+)/i, // Opera > 9.80 - /(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80 + /(opera)(?:.+version\/|[\/\s]+)([\w\.]+)/i, // Opera ], [NAME, VERSION], [ /opios[\/\s]+([\w\.]+)/i // Opera mini on iphone >= 8.0 ], [VERSION, [NAME, 'Opera Mini']], [ @@ -374,14 +373,15 @@ device : [[ - ////////////////////// + ////////////////////////// // MOBILES & TABLETS - ///////////////////// + // Ordered by popularity + ///////////////////////// // Samsung - /\b(sch-i[89]0\d|shw-m380s|sm-p(?:605|610|587)|sm-t\w+|sm-p\w+|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus\s10)/i, + /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus\s10)/i ], [MODEL, [VENDOR, 'Samsung'], [TYPE, TABLET]], [ - /(s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-\w[\w\d]+)/i, + /\b((?:s[cgp]h|gt|sm)-\w+|galaxy\snexus)/i, /\ssamsung[\s-]([\w-]+)/i, /sec-(sgh\w+)/i ], [MODEL, [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ @@ -389,18 +389,13 @@ // Apple /\((ip(?:hone|od)[\s\w]*);/i // iPod/iPhone ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [ - /\((ipad);[\w\s\),;-]+(apple)/i // iPad - ], [MODEL, VENDOR, [TYPE, TABLET]], [ + /\((ipad);[\w\s\),;-]+apple/i, // iPad /applecoremedia\/[\w\.]+\s\((ipad)/i, + /\b(ipad)\d\d?,\d\d?[;\]].+ios/i ], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [ - /(iPad;FBSN\/iOS)/i - ], [[MODEL, 'iPad'], [VENDOR, 'Apple'], [TYPE, TABLET]], [ // Huawei - /\b(bah2?-a?[lw]\d{2})/i, // Huawei M Lite - /\b(sht?-a?[lw]\d{2})/i, // Huawei M - /\b(ags(2|3)?-a?[lw]\d{2})/i, // Huawei T - /\b(agr-a?[lw]\d{2})/i // Huawei T s + /\b((?:agr|ags[23]|bah2?|sht?)-a?[lw]\d{2})/i, ], [MODEL, [VENDOR, 'Huawei'], [TYPE, TABLET]], [ /d\/huawei([\w\s-]+)[;\)]/i, /\b(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, @@ -408,8 +403,8 @@ ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ // Xiaomi - /\b(poco[\s\w]+)(?:\sbuild|\))/i, // Xiaomi POCO - /\b;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models + /\b(poco[\s\w]+)(?:\sbuild|\))/i, // Xiaomi POCO + /\b;\s(\w+)\sbuild\/hm\1/i, // Xiaomi Hongmi 'numeric' models /\b(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi /\b(redmi[\s\-_]?(?:note|k)?[\w\s_]+)(?:\sbuild|\))/i, // Xiaomi Redmi /\b(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i // Xiaomi Mi @@ -434,19 +429,17 @@ // Motorola /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)\b[\w\s]+build\//i, /\smot[\s-](\w*)/i, - /(moto[\s\w\(\)]+(?=\sbuild|\)))/i, - /(xt\d{3,4})\sbuild\//i, - /(nexus\s6)/i + /((?:moto[\s\w\(\)]+|xt\d{3,4}|nexus\s6)(?=\sbuild|\)))/i ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [ /\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [ // LG - /((?=lg)?[vl]k\-?\d{3})\s+build|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4})/i + /((?=lg)?[vl]k\-?\d{3})\sbuild|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [ /(nexus\s[45])/i, /lg[e;\s\/-]+((?!browser|netcast)\w+)/i, - /\blg(\-?[\d\w]+)\s+build/i + /\blg(\-?[\d\w]+)\sbuild/i ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [ // Lenovo @@ -474,7 +467,7 @@ // OnePlus /\s(kb2005|in20[12]5|be20[12][59])\b/i, - /\ba000(1)\s+build/i, // OnePlus + /\ba000(1)\sbuild/i, // OnePlus /\boneplus\s(a\d{4})[\s)]/i ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ @@ -493,7 +486,7 @@ ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [ // Asus - /\b(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus\s7|padfone|p00c|asus_p00j)/i + /(?:\b|asus_)(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus\s7|padfone|p00[cj])/i ], [MODEL, [VENDOR, 'ASUS'], [TYPE, TABLET]], [ /\s(z[es]6[027][01][km][ls]|zenfone\s\d\w?)\b/i ], [MODEL, [VENDOR, 'ASUS'], [TYPE, MOBILE]], [ @@ -530,8 +523,7 @@ ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(archos)\s(gamepad2?)/i, // Archos - /(hp).+(touchpad)/i, // HP TouchPad - /(hp).+(tablet)/i, // HP Tablet + /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(kindle)\/([\w\.]+)/i, // Kindle /\s(nook)[\w\s]+build\/(\w+)/i, // Nook /(dell)\s(strea[kpr\s\d]*[\dko])/i, // Dell Streak @@ -616,12 +608,11 @@ /////////////////// /smart-tv.+(samsung)/i // Samsung - ], [VENDOR, [TYPE, SMARTTV], MODEL], [ + ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i ], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [ - /linux;\snetcast.+smarttv/i, // LG SmartTV - /lg\snetcast\.tv-201\d/i - ], [[VENDOR, 'LG'], MODEL, [TYPE, SMARTTV]], [ + /(?:linux;\snetcast.+smarttv|lg\snetcast\.tv-201\d)/i, // LG SmartTV + ], [[VENDOR, 'LG'], [TYPE, SMARTTV]], [ /(apple)\s?tv/i // Apple TV ], [VENDOR, [MODEL, 'Apple TV'], [TYPE, SMARTTV]], [ /crkey/i // Google Chromecast @@ -702,18 +693,16 @@ /(macintosh|mac(?=_powerpc)\s)(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ - // Mobile OSes + // Mobile OSes // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, - // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS /(blackberry)\w*\/([\w\.]*)/i, // Blackberry - /(tizen|kaios)[\/\s]([\w\.]+)/i // Tizen/KaiOS + /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS + /\((series40);/i // Series 40 ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 ], [VERSION, [NAME, 'BlackBerry']], [ /(?:symbian\s?os|symbos|s60(?=;)|series60)[\/\s-]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ - /\((series40);/i // Series 40 - ], [NAME], [ /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS ], [[NAME, 'Firefox OS']], [ /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS @@ -722,6 +711,8 @@ // Google Chromecast /crkey\/([\d\.]+)/i // Google Chromecast ], [VERSION, [NAME, 'Chromecast']], [ + /(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS + ], [[NAME, 'Chromium OS'], VERSION],[ // Console /(nintendo|playstation)\s([wids345portablevuch]+)/i, // Nintendo/Playstation @@ -734,28 +725,19 @@ // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus /(hurd|linux)\s?([\w\.]*)/i, // Hurd/Linux - /(gnu)\s?([\w\.]*)/i // GNU - ], [NAME, VERSION], [ - - /(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS - ], [[NAME, 'Chromium OS'], VERSION],[ - - // Solaris - /(sunos)\s?([\w\.\d]*)/i // Solaris - ], [[NAME, 'Solaris'], VERSION], [ + /(gnu)\s?([\w\.]*)/i, // GNU // BSD based - /\s([frentopc-]{0,4}bsd|dragonfly)\s?(?!amd|[ix346]{1,2}86)([\w\.]*)/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly - ], [NAME, VERSION],[ - + /\s([frentopc-]{0,4}bsd|dragonfly)\s?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly /(haiku)\s(\w+)/i // Haiku - ], [NAME, VERSION],[ + ], [NAME, VERSION], [ // Other + /(sunos)\s?([\w\.\d]*)/i // Solaris + ], [[NAME, 'Solaris'], VERSION], [ /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris /(aix)\s((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX - /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms|fuchsia)/i, - // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia + /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms|fuchsia)/i, // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia /(unix)\s?([\w\.]*)/i // UNIX ], [NAME, VERSION] ] diff --git a/test/device-test.json b/test/device-test.json index b5d9f84..c30cf8b 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -30,7 +30,7 @@ "ua": "Mozilla/5.0 (Linux; Android 7.0; ASUS_P00J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Safari/537.36\n", "expect": { "vendor": "ASUS", - "model": "ASUS_P00J", + "model": "P00J", "type": "tablet" } }, @@ -441,6 +441,15 @@ "type": "mobile" } }, + { + "desc": "iPhone SE using Facebook App", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone8,4;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, { "desc": "iPhone 11 Pro Max", "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone12,5;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", From 8bea5c552aa784bee06818a8dc8b21b5b33ff7e4 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 2 Apr 2021 00:15:20 +0700 Subject: [PATCH 089/121] Add new Engine & Browser: Flow --- readme.md | 4 ++-- src/ua-parser.js | 5 +++-- test/browser-test.json | 10 ++++++++++ test/engine-test.json | 9 +++++++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 62373d5..9582d5f 100644 --- a/readme.md +++ b/readme.md @@ -39,7 +39,7 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, Dolphin, Doris, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, Firebird, -Firefox, Flock, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, IceCat, +Firefox, Flock, Flow, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, Iceape, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, Kindle, Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, @@ -75,7 +75,7 @@ Sony[Ericsson], Sprint, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... ```sh # Possible 'engine.name' -Amaya, Blink, EdgeHTML, Gecko, Goanna, iCab, KHTML, Links, Lynx, NetFront, +Amaya, Blink, EdgeHTML, Flow, Gecko, Goanna, iCab, KHTML, Links, Lynx, NetFront, NetSurf, Presto, Tasman, Trident, w3m, WebKit # 'engine.version' determined dynamically diff --git a/src/ua-parser.js b/src/ua-parser.js index ed14fe9..3e5f0ac 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -321,6 +321,7 @@ // Gecko based /(navigator|netscape)\/([\w\.-]+)/i // Netscape ], [[NAME, 'Netscape'], VERSION], [ + /ekiohf.+(flow)\/([\w\.]+)/i, // Flow /(swiftfox)/i, // Swiftfox /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror @@ -663,8 +664,8 @@ ], [VERSION, [NAME, 'Blink']], [ /(presto)\/([\w\.]+)/i, // Presto - /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, - // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna + /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna + /ekioh(flow)\/([\w\.]+)/i, // Flow /(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i, // KHTML/Tasman/Links /(icab)[\/\s]([23]\.[\d\.]+)/i // iCab ], [NAME, VERSION], [ diff --git a/test/browser-test.json b/test/browser-test.json index 3b38881..99f9d08 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -289,6 +289,16 @@ "major" : "1" } }, + { + "desc" : "Flow", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) EkiohFlow/5.7.4.30559 Flow/5.7.4 (like Gecko Firefox/53.0 rv:53.0)", + "expect" : + { + "name" : "Flow", + "version" : "5.7.4", + "major" : "5" + } + }, { "desc" : "Waterfox", "ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.2.2 Waterfox/55.2.2", diff --git a/test/engine-test.json b/test/engine-test.json index 9f54d31..0630338 100644 --- a/test/engine-test.json +++ b/test/engine-test.json @@ -17,6 +17,15 @@ "version" : "12.0" } }, + { + "desc" : "Flow", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) EkiohFlow/5.7.4.30559 Flow/5.7.4 (like Gecko Firefox/53.0 rv:53.0)", + "expect" : + { + "name" : "Flow", + "version" : "5.7.4.30559" + } + }, { "desc" : "Gecko", "ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:2.0b9pre) Gecko/20110111 Firefox/4.0b9pre", From c937400e8ec5c686824875bad172a316769bed12 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 2 Apr 2021 01:00:50 +0700 Subject: [PATCH 090/121] Add new browser: Firefox Reality --- readme.md | 14 +++++++------- src/ua-parser.js | 2 ++ test/browser-test.json | 10 ++++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/readme.md b/readme.md index 9582d5f..7ade87f 100644 --- a/readme.md +++ b/readme.md @@ -39,16 +39,16 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, Dolphin, Doris, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, Firebird, -Firefox, Flock, Flow, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, IceCat, -IceDragon, Iceape, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, +Firefox [Reality], Flock, Flow, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, +IceCat, IceDragon, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, Kindle, Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Oculus Browser, -OmniWeb, Opera Coast, Opera Mini, Opera Mobi, Opera Tablet, Opera, PaleMoon, -PhantomJS, Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, -QupZilla, RockMelt, Safari, Sailfish Browser, Samsung Browser, SeaMonkey, Silk, -Skyfire, Sleipnir, Slim, SlimBrowser, Swiftfox, Tizen Browser, UCBrowser, -Vivaldi, Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m, Whale Browser... +OmniWeb, Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, +Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, Safari, +Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim, +SlimBrowser, Swiftfox, Tizen Browser, UCBrowser, Vivaldi, Waterfox, WeChat, Weibo, +Yandex, baidu, iCab, w3m, Whale Browser... # 'browser.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 3e5f0ac..fb1af22 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -321,6 +321,8 @@ // Gecko based /(navigator|netscape)\/([\w\.-]+)/i // Netscape ], [[NAME, 'Netscape'], VERSION], [ + /ile\svr;\srv:([\w\.]+)\).+firefox/i // Firefox Reality + ], [VERSION, [NAME, 'Firefox Reality']], [ /ekiohf.+(flow)\/([\w\.]+)/i, // Flow /(swiftfox)/i, // Swiftfox /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, diff --git a/test/browser-test.json b/test/browser-test.json index 99f9d08..01d7abb 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -399,6 +399,16 @@ "major" : "15" } }, + { + "desc" : "Firefox Reality", + "ua" : "Mozilla/5.0 (Android 7.1.2; Mobile VR; rv:65.0) Gecko/65.0 Firefox/65.0", + "expect" : + { + "name" : "Firefox Reality", + "version" : "65.0", + "major" : "65" + } + }, { "desc" : "Firefox-based browser", "ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0 AppName/1.0", From 9d431cfdddf02a6733ef926290289bba3e751056 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 2 Apr 2021 10:10:47 +0700 Subject: [PATCH 091/121] Add new device: Fairphone --- readme.md | 4 ++-- src/ua-parser.js | 2 ++ test/device-test.json | 9 +++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 7ade87f..d320c86 100644 --- a/readme.md +++ b/readme.md @@ -62,8 +62,8 @@ console, mobile, tablet, smarttv, wearable, embedded # Possible 'device.vendor': Acer, Alcatel, Amazon, Apple, Archos, ASUS, AT&T, BenQ, BlackBerry, Dell, -Essential, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, Meizu, -Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, OPPO, Ouya, +Essential, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, +Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, OPPO, Ouya, Palm, Panasonic, Pebble, Polytron, Realme, RIM, Samsung, Sharp, Siemens, Sony[Ericsson], Sprint, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... diff --git a/src/ua-parser.js b/src/ua-parser.js index fb1af22..8e5e877 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -538,6 +538,8 @@ /\s(surface\sduo)\s/i // Surface Duo ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, TABLET]], [ + /droid\s[\d\.]+;\s(fp\du?)\sbuild/i + ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ /\s(u304aa)\sbuild/i // AT&T ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ /sie-(\w*)/i // Siemens diff --git a/test/device-test.json b/test/device-test.json index c30cf8b..f9aeb75 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -160,6 +160,15 @@ "type": "mobile" } }, + { + "desc": "Fairphone 1U", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; FP1U Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Fairphone", + "model": "FP1U", + "type": "mobile" + } + }, { "desc": "HTC Desire 820", "ua": "Mozilla/5.0 (Linux; Android 6.0.1; HTC Desire 820 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", From 0868e372e0e1d2d8645d51e38a7c34b6647ce3eb Mon Sep 17 00:00:00 2001 From: "o.drapeza" Date: Fri, 2 Apr 2021 12:52:30 +0300 Subject: [PATCH 092/121] Add string check to setUA method --- src/ua-parser.js | 2 +- test/test.js | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index fb1af22..98ae765 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -804,7 +804,7 @@ return _ua; }; this.setUA = function (ua) { - _ua = ua.length > UA_MAX_LENGTH ? util.trim(ua, UA_MAX_LENGTH) : ua; + _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? util.trim(ua, UA_MAX_LENGTH) : ua; return this; }; this.setUA(_ua); diff --git a/test/test.js b/test/test.js index 5b55ade..ad54ef4 100644 --- a/test/test.js +++ b/test/test.js @@ -46,6 +46,14 @@ describe('UAParser()', function () { assert.deepStrictEqual(UAParser(ua), new UAParser().setUA(ua).getResult()); }); +describe('UAParser() constructor does not throw with undefined ua argument', function () { + assert.doesNotThrow(() => new UAParser(undefined).getResult()); +}); + +describe('UAParser.setUA method does not throw with undefined ua argument', function () { + assert.doesNotThrow(() => new UAParser().setUA(undefined).getResult()); +}); + for (var i in methods) { describe(methods[i]['title'], function () { for (var j in methods[i]['list']) { From f95aced43b1879bc03fe198a80bcd3d3f3750d86 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 2 Apr 2021 18:17:03 +0700 Subject: [PATCH 093/121] Release as 0.7.27 --- bower.json | 2 +- dist/ua-parser.min.js | 4 ++-- dist/ua-parser.pack.js | 4 ++-- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index 2d80d5c..54662ef 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.26", + "version": "0.7.27", "authors": [ "Faisal Salman " ], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 20f8f73..89a39e6 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,9 @@ /*!@license - * UAParser.js v0.7.26 + * UAParser.js v0.7.27 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.26",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file +(function(window,undefined){"use strict";var LIBVERSION="0.7.27",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index f85564c..67612af 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,9 +1,9 @@ /*!@license - * UAParser.js v0.7.26 + * UAParser.js v0.7.27 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -!function(r,b){"use strict";var u="function",e="undefined",c="object",o="string",i="model",s="name",a="type",n="vendor",t="version",l="architecture",w="console",d="mobile",m="tablet",p="smarttv",g="wearable",h={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return typeof i==o&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i==o?i.replace(/[^\d\.]/g,"").split(".")[0]:b},trim:function(i,s){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof s==e?i:i.substring(0,255)}},f={rgx:function(i,s){for(var e,o,r,a,n,t=0;t (http://faisalman.com)", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": [ diff --git a/src/ua-parser.js b/src/ua-parser.js index ca1b97c..66f31fe 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ /*!@license - * UAParser.js v0.7.26 + * UAParser.js v0.7.27 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * @@ -16,7 +16,7 @@ ///////////// - var LIBVERSION = '0.7.26', + var LIBVERSION = '0.7.27', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From 557cc2198d88068892eec6b61f2b2f4fe6e96314 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 4 Apr 2021 13:12:55 +0700 Subject: [PATCH 094/121] More test for latest phones with unique form factor (fold/flip/qwerty/swivel) --- src/ua-parser.js | 7 +-- test/device-test.json | 108 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index fb1af22..8f47553 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -431,7 +431,7 @@ // Motorola /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)\b[\w\s]+build\//i, - /\smot[\s-](\w*)/i, + /\smot(?:orola)?[\s-](\w*)/i, /((?:moto[\s\w\(\)]+|xt\d{3,4}|nexus\s6)(?=\sbuild|\)))/i ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [ /\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i @@ -440,7 +440,7 @@ // LG /((?=lg)?[vl]k\-?\d{3})\sbuild|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [ - /(nexus\s[45])/i, + /(lm-?f100[nv]?|nexus\s[45])/i, /lg[e;\s\/-]+((?!browser|netcast)\w+)/i, /\blg(\-?[\d\w]+)\sbuild/i ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [ @@ -453,7 +453,7 @@ // Nokia /(?:maemo|nokia).*(n900|lumia\s\d+)/i, /nokia[\s_-]?([\w\.-]*)/i - ], [MODEL, [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ + ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ // Google /droid.+;\s(pixel\sc)[\s)]/i // Google Pixel C @@ -485,6 +485,7 @@ // BlackBerry /\((playbook);[\w\s\),;-]+(rim)/i // BlackBerry PlayBook ], [MODEL, VENDOR, [TYPE, TABLET]], [ + /((?:bb[a-f]|st[hv])100-\d)/i, /\(bb10;\s(\w+)/i // BlackBerry 10 ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [ diff --git a/test/device-test.json b/test/device-test.json index c30cf8b..575f281 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -142,6 +142,42 @@ "type": "tablet" } }, + { + "desc": "BlackBerry Priv", + "ua": "User-Agent: Mozilla/5.0 (Linux; Android 5.1.1; STV100-1 Build/LMY47V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/46.0.2490.76 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "STV100-1", + "type": "mobile" + } + }, + { + "desc": "BlackBerry Keyone", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BBB100-1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "BBB100-1", + "type": "mobile" + } + }, + { + "desc": "BlackBerry Key2", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BBF100-1 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "BBF100-1", + "type": "mobile" + } + }, + { + "desc": "BlackBerry Key2 LE", + "ua": "User-Agent: Mozilla/5.0 (Linux; Android 8.1.0; BBE100-1 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "BBE100-1", + "type": "mobile" + } + }, { "desc": "Desktop (IE11 with Tablet string)", "ua": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Tablet PC 2.0; GWX:MANAGED; rv:11.0) like Gecko", @@ -331,6 +367,15 @@ "type": "mobile" } }, + { + "desc": "LG Wing", + "ua": "Mozilla/5.0 (Linux; Android 10; LM-F100N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.101 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-F100N", + "type": "mobile" + } + }, { "desc": "LG Smart TV", "ua": "Mozilla/5.0 (DirectFB; U; Linux mips; en) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) LG Browser (; LG NetCast.TV-2011)", @@ -423,6 +468,15 @@ "type": "mobile" } }, + { + "desc": "Motorola RAZR 2019", + "ua": "Mozilla/5.0 (Linux; Android 9; motorola razr) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.1 Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "razr", + "type": "mobile" + } + }, { "desc": "iPhone", "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53", @@ -540,6 +594,15 @@ "type": "mobile" } }, + { + "desc": "Nokia 2720 Flip", + "ua": "Mozilla/5.0 (Mobile; Nokia_2720_Flip; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5.2", + "expect": { + "vendor": "Nokia", + "model": "2720 Flip", + "type": "mobile" + } + }, { "desc": "OnePlus One", "ua": "Mozilla/5.0 (Linux; Android 4.4.4; A0001 Build/KTU84Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.59 Mobile Safari/537.36", @@ -810,6 +873,24 @@ "type": "mobile" } }, + { + "desc": "Samsung Galaxy Z Flip", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-F700N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-F700N", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Z Fold2", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-F916B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-F916B", + "type": "mobile" + } + }, { "desc": "Samsung Galaxy S10E", "ua": "Mozilla/5.0 (Linux; Android 9; SM-G970F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", @@ -1984,6 +2065,24 @@ "type": "mobile" } }, + { + "desc": "Huawei Mate X", + "ua": "Mozilla/5.0 (Linux; Android 9; TAH-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "TAH-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate X2", + "ua": "Mozilla/5.0 (Linux; Android 10; TET-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "TET-AN00", + "type": "mobile" + } + }, { "desc": "Huawei P20 Lite", "ua": "Mozilla/5.0 (Linux; Android 8.0.0; ANE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", @@ -2171,6 +2270,15 @@ "type": "mobile" } }, + { + "desc": "Alcatel Go Flip", + "ua": "Mozilla/5.0 (Mobile; ALCATEL4044T; rv:37.0) Gecko/37.0 Firefox/37.0 KaiOS/1.0", + "expect": { + "vendor": "ALCATEL", + "model": "4044T", + "type": "mobile" + } + }, { "desc": "Jolla", "ua": "Mozilla/5.0 (Maemo; Linux; U; Jolla; Sailfish; Mobile; rv:31.0) Gecko/31.0 Firefox/31.0 SailfishBrowser/1.0", From 09aa9105dc370ded9275f70eae1f4eb67394966c Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 4 Apr 2021 13:47:17 +0700 Subject: [PATCH 095/121] Add new device & browser: Tesla --- readme.md | 6 +++--- src/ua-parser.js | 16 +++++++++++++--- test/browser-test.json | 20 ++++++++++++++++++++ test/device-test.json | 20 ++++++++++++++++++++ 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 7ade87f..4422b53 100644 --- a/readme.md +++ b/readme.md @@ -47,8 +47,8 @@ Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Oculus Browser, OmniWeb, Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, Safari, Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim, -SlimBrowser, Swiftfox, Tizen Browser, UCBrowser, Vivaldi, Waterfox, WeChat, Weibo, -Yandex, baidu, iCab, w3m, Whale Browser... +SlimBrowser, Swiftfox, Tesla, Tizen Browser, UCBrowser, Vivaldi, Waterfox, WeChat, +Weibo, Yandex, baidu, iCab, w3m, Whale Browser... # 'browser.version' determined dynamically ``` @@ -65,7 +65,7 @@ Acer, Alcatel, Amazon, Apple, Archos, ASUS, AT&T, BenQ, BlackBerry, Dell, Essential, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, OPPO, Ouya, Palm, Panasonic, Pebble, Polytron, Realme, RIM, Samsung, Sharp, Siemens, -Sony[Ericsson], Sprint, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... +Sony[Ericsson], Sprint, Tesla, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... # 'device.model' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 8f47553..e34462f 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -239,8 +239,8 @@ /(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer // Webkit/KHTML based - /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon)\/([\w\.-]+)/i, - // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon + /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon)\/([\w\.-]+)/i, + // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon /(rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ /(weibo)__([\d\.]+)/i // Weibo ], [NAME, VERSION], [ @@ -291,7 +291,10 @@ ], [[NAME, 'Facebook']], [ /\s(electron)\/([\w\.]+)\ssafari/i, // Electron-based App /safari\s(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 + /(tesla)(?:\sqtcarbrowser|\/(20[12]\d\.[\w\.-]+))/i, // Tesla + + /(chromium)\/([\w\.-]+)/i // Chromium ], [NAME, VERSION], [ /\bgsa\/([\w\.]+)\s.*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, 'GSA']], [ @@ -641,6 +644,13 @@ /droid\s[\d\.]+;\s(wt63?0{2,3})\)/i ], [MODEL, [VENDOR, 'Zebra'], [TYPE, WEARABLE]], [ + /////////////////// + // EMBEDDED + /////////////////// + + /(tesla)(?:\sqtcarbrowser|\/20[12]\d\.[\w\.-]+)/i // Tesla + ], [VENDOR, [TYPE, EMBEDDED]], [ + //////////////////// // MIXED (GENERIC) /////////////////// diff --git a/test/browser-test.json b/test/browser-test.json index 01d7abb..1947fe0 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -998,6 +998,26 @@ "major" : "undefined" } }, + { + "desc" : "Tesla", + "ua" : "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/601.1 (KHTML, like Gecko) Tesla QtCarBrowser Safari/601.1", + "expect" : + { + "name" : "Tesla", + "version" : "undefined", + "major" : "undefined" + } + }, + { + "desc" : "Tesla", + "ua" : "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/537.36 (KHTML, like Gecko) Chromium/79.0.3945.130 Chrome/79.0.3945.130 Safari/537.36 Tesla/2020.16.2.1-e99c70fff409", + "expect" : + { + "name" : "Tesla", + "version" : "2020.16.2.1-e99c70fff409", + "major" : "2020" + } + }, { "desc" : "Tizen Browser", "ua" : "Mozilla/5.0 (Linux; U; Tizen/1.0 like Android; en-us; AppleWebKit/534.46 (KHTML, like Gecko) Tizen Browser/1.0 Mobile", diff --git a/test/device-test.json b/test/device-test.json index 575f281..ac3ddb2 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1161,6 +1161,26 @@ "type": "tablet" } }, + { + "desc" : "Tesla", + "ua" : "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/601.1 (KHTML, like Gecko) Tesla QtCarBrowser Safari/601.1", + "expect" : + { + "vendor": "Tesla", + "model": "undefined", + "type": "embedded" + } + }, + { + "desc" : "Tesla", + "ua" : "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/537.36 (KHTML, like Gecko) Chromium/79.0.3945.130 Chrome/79.0.3945.130 Safari/537.36 Tesla/2020.16.2.1-e99c70fff409", + "expect" : + { + "vendor": "Tesla", + "model": "undefined", + "type": "embedded" + } + }, { "desc": "Xiaomi 2013023", "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; en-US; 2013023 Build/HM2013023) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/10.0.1.512 U3/0.8.0 Mobile Safari/533.1", From 7c8aa435b26cb14537423cd5fe4ce077e0661db2 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 4 Apr 2021 14:37:13 +0700 Subject: [PATCH 096/121] Minor rearrangement --- src/ua-parser.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index e34462f..c369460 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -232,7 +232,7 @@ // Mixed /(kindle)\/([\w\.]+)/i, // Kindle - /(lunascape|maxthon|netfront|jasmine|blazer|instagram)[\/\s]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Instagram + /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer // Trident based /(avant\s|iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser /(ba?idubrowser)[\/\s]?([\w\.]+)/i, // Baidu Browser @@ -278,6 +278,8 @@ ], [[NAME, /(.+)/, '$1 Browser'], VERSION], [ // Oculus/Samsung/Sailfish Browser /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ + /\s(electron)\/([\w\.]+)\ssafari/i, // Electron-based App + /(tesla)(?:\sqtcarbrowser|\/(20[12]\d\.[\w\.-]+))/i, // Tesla /m?(qqbrowser|baiduboxapp|2345Explorer)[\/\s]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser ], [NAME, VERSION], [ /(MetaSr)[\/\s]?([\w\.]+)/i, // SouGouBrowser @@ -289,12 +291,9 @@ ], [VERSION, [NAME, 'Facebook']], [ /FBAN\/FBIOS|FB_IAB\/FB4A/i // Facebook App for iOS & Android without version ], [[NAME, 'Facebook']], [ - /\s(electron)\/([\w\.]+)\ssafari/i, // Electron-based App /safari\s(line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android - /(tesla)(?:\sqtcarbrowser|\/(20[12]\d\.[\w\.-]+))/i, // Tesla - - /(chromium)\/([\w\.-]+)/i // Chromium + /(chromium|instagram)[\/\s]([\w\.-]+)/i // Chromium/Instagram ], [NAME, VERSION], [ /\bgsa\/([\w\.]+)\s.*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, 'GSA']], [ From 383ca587ef9b8daffcf652ac39fc9b8f3708572e Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 4 Apr 2021 16:32:30 +0700 Subject: [PATCH 097/121] More test for tablet devices --- test/device-test.json | 99 +++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 27 deletions(-) diff --git a/test/device-test.json b/test/device-test.json index ac3ddb2..6058bf8 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -331,6 +331,33 @@ "type": "tablet" } }, + { + "desc": "Lenovo Tab 4", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Lenovo TAB 2 A7-30HC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TAB 2 A7", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 7 Essential", + "ua": "Mozilla/5.0 (Linux; Android 7.0; Lenovo TB-7304X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-7304X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo TB-X606F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 YaBrowser/20.9.4.99.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X606F", + "type": "tablet" + } + }, { "desc": "LG K500", "ua": "Mozilla/5.0 (Linux; Android 6.0.1; LG-K500 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", @@ -954,6 +981,15 @@ "type": "tablet" } }, + { + "desc": "Samsung Galaxy Tab A 10.1", + "ua": " Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-T515) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/13.0 Chrome/83.0.4103.106 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T515", + "type": "tablet" + } + }, { "desc": "Samsung Galaxy Tab S7", "ua": "Mozilla/5.0 (Linux; Android 10; SM-T870) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36", @@ -2076,6 +2112,15 @@ "type": "tablet" } }, + { + "desc": "Huawei MatePad T 10", + "ua": "Mozilla/5.0 (Linux; Android 10; AGR-L09; HMSCore 5.0.4.301) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 HuaweiBrowser/11.0.3.304 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGR-L09", + "type": "tablet" + } + }, { "desc": "Huawei Mate 10 Pro", "ua": "Mozilla/5.0 (Linux; Android 8.0; BLA-L29 Build/HUAWEIBLA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3236.6 Mobile Safari/537.36", @@ -2103,6 +2148,33 @@ "type": "mobile" } }, + { + "desc": "Huawei Mate 20 X", + "ua": "Mozilla/5.0 (Linux; Android 9; EVR-L29 Build/HUAWEIEVR-L29; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "EVR-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L09", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-AL00", + "type": "mobile" + } + }, { "desc": "Huawei P20 Lite", "ua": "Mozilla/5.0 (Linux; Android 8.0.0; ANE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", @@ -2130,33 +2202,6 @@ "type": "mobile" } }, - { - "desc": "Huawei Mate 20 X", - "ua": "Mozilla/5.0 (Linux; Android 9; EVR-L29 Build/HUAWEIEVR-L29; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "EVR-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-L09", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-AL00", - "type": "mobile" - } - }, { "desc": "Huawei P30", "ua": "Mozilla/5.0 (Linux; Android 9; ELE-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", From acc0b91ff5defa2ca9a722874e27277879292907 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 5 Apr 2021 23:32:15 +0700 Subject: [PATCH 098/121] Update contributor list --- package.json | 55 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 8eadf76..3d75aff 100644 --- a/package.json +++ b/package.json @@ -20,82 +20,125 @@ "Aamir Poonawalla ", "Admas ", "algenon ", - "Alvin Portillo ", + "Alvin Portillo ", + "Amumu ", "Andrea Vaghi ", "Anton Zhiyanov ", "Arturo Mejia ", "Arun Rama Reddy ", "Austin Pray ", + "Bendeguz ", "Benjamin Bertrand ", "Benjamin Urban ", "boneyao ", "Carl C Von Lewin ", "CESAR RAMOS ", + "Chad Killingsworth ", "Christopher De Cairos ", + "Cyrille David ", "Dario Vladovic ", + "David Annez ", "Davit Barbakadze ", "ddivernois ", + "Deliaz ", "Demis Palma ", "dhoko ", "dianhe ", + "dineshks1 ", "Dmitry Tyschenko ", "Douglas Li ", "Dumitru Uzun ", + "Dustin ", + "Elchin Valiyev ", + "Emil Hesslow ", + "Eric Redon ", "Eric Schrenker ", "Erik Hesselink ", "Fabian Becker ", - "Faisal Salman ", + "Faisal Salman ", "Frédéric Camblor ", + "Frederik Ring ", + "Gerald Host ", "Germán M. Bravo ", "Grigory Dmitrenko ", + "gulpin ", "Hendrik Helwich ", "Hermann Ebert ", + "hr6r ", + "Igor Topal ", + "Ildar Kamalov ", + "insanehong ", "jackpoll ", "Jake Mc ", + "JBYoshi <12983479+JBYoshi@users.noreply.github.com>", + "Joey Parrish ", "John Tantalo ", "John Yanarella ", "Jon Buckley ", + "Josh Goldberg ", + "Junki-Ishida ", "Kendall Buchanan ", "Lee Treveil ", "leonardo ", "Levente Balogh ", "Liam Quinn ", "Lithin ", + "ll-syber <670159357@qq.com>", "Loris Guignard ", "Lukas Drgon ", "Lukas Eipert ", "Malash ", "Martynas ", + "Masahiko Sato ", "Matt Brophy ", - "Max Maurer ", + "Matthew Origer ", "Maximilian Haupt ", + "Max Maurer ", + "Max Nordlund ", "Michael Hess ", + "MimyyK ", "naoh ", + "Nicholas Ionata ", + "Nikhil Motiani ", "Nik Rolls ", - "Nikhil Motiani ", + "nionata ", "niris ", "Nobuo Okada ", + "o.drapeza ", "otakuSiD ", + "patrick-nurt ", + "Pavel Studeny ", "Peter Dave Hello ", "philippsimon ", "Pieter Hendrickx ", "Piper Chester ", + "Queen Vinyl Darkscratch ", + "Raine Makelainen ", + "Raman Savaryn ", "Robert Tod ", + "roman.savarin ", "Ron Korland ", "Ross Noble ", + "ruicong <466403866@qq.com>", "Sandro Sonntag ", "sgautrea ", "Shane Gautreau ", "Shane Thacker ", - "shchotse ", + "Shreedhar ", "Simon Eisenmann ", "Simon Lang ", "Stiekel ", + "sUP ", "Sylvain Gizard ", "szchenghuang ", + "Tanguy Krotoff ", + "Tony Tomarchio ", + "Ulrich Schmidt ", "Vadim Kurachevsky ", + "Yılmaz ", + "yuanyang ", "Yun Young-jin ", - "Insanehong " + "Zach Bjornson " ], "main": "src/ua-parser.js", "scripts": { From 642c0399e831e27c5c86c3b7afee02e876250d01 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 6 Apr 2021 14:56:23 +0700 Subject: [PATCH 099/121] Fix #492 LG TV WebOS detection --- src/ua-parser.js | 1 + test/engine-test.json | 45 +++++++++++++++++++++++++++++++++++++++++++ test/os-test.json | 45 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index 49c309e..6128560 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -720,6 +720,7 @@ ], [VERSION, [NAME, 'Symbian']], [ /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS ], [[NAME, 'Firefox OS']], [ + /web0s;.+rt(tv)/i, /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS ], [VERSION, [NAME, 'webOS']], [ diff --git a/test/engine-test.json b/test/engine-test.json index 0630338..6726d27 100644 --- a/test/engine-test.json +++ b/test/engine-test.json @@ -106,5 +106,50 @@ "name" : "WebKit", "version" : "537.36" } + }, + { + "desc" : "WebOS TV 5.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "Blink", + "version" : "68.0.3440.106" + } + }, + { + "desc" : "WebOS TV 4.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.34 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "Blink", + "version" : "53.0.2785.34" + } + }, + { + "desc" : "WebOS TV 3.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.2.1 Chrome/38.0.2125.122 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "Blink", + "version" : "38.0.2125.122" + } + }, + { + "desc" : "WebOS TV 2.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/538.2 (KHTML, like Gecko) Large Screen WebAppManager Safari/538.2", + "expect" : + { + "name" : "WebKit", + "version" : "538.2" + } + }, + { + "desc" : "WebOS TV 1.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.41 (KHTML, like Gecko) Large Screen WebAppManager Safari/537.41", + "expect" : + { + "name" : "WebKit", + "version" : "537.41" + } } ] diff --git a/test/os-test.json b/test/os-test.json index b249831..27c5427 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -206,6 +206,51 @@ "version" : "1.4.5" } }, + { + "desc" : "WebOS TV 5.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 4.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.34 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 3.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.2.1 Chrome/38.0.2125.122 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 2.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/538.2 (KHTML, like Gecko) Large Screen WebAppManager Safari/538.2", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 1.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.41 (KHTML, like Gecko) Large Screen WebAppManager Safari/537.41", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, { "desc" : "QNX", "ua" : "Mozilla/5.0 (Photon; U; QNX x86pc; en-US; rv:1.8.1.20) Gecko/20090127 BonEcho/2.0.0.20", From 535f11bd2403910f29dabe6f90adb014ad016747 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 7 Apr 2021 21:42:13 +0700 Subject: [PATCH 100/121] Delete redundant code --- src/ua-parser.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 6128560..2dbdf7e 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -517,9 +517,8 @@ ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ // MIXED - /(blackberry)[\s-]?(\w+)/i, // BlackBerry /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[\s_-]?([\w-]*)/i, - // BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron + // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron /(hp)\s([\w\s]+\w)/i, // HP iPAQ /(asus)-?(\w+)/i, // Asus /(microsoft);\s(lumia[\s\w]+)/i, // Microsoft Lumia From 6c671dd24688dab98da40f3d8994b6a0fca0fdf5 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 8 Apr 2021 00:43:25 +0700 Subject: [PATCH 101/121] Refactor code: saving bytes towards 15KB minified --- dist/ua-parser.min.js | 13 +- dist/ua-parser.pack.js | 13 +- package.json | 4 +- src/ua-parser.js | 676 ++++++++++++++++++++--------------------- 4 files changed, 339 insertions(+), 367 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 89a39e6..262021b 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,4 @@ -/*!@license - * UAParser.js v0.7.27 - * Lightweight JavaScript-based User-Agent string parser - * https://github.com/faisalman/ua-parser-js - * - * Copyright © 2012-2021 Faisal Salman - * Licensed under MIT License - */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.27",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file +/* UAParser.js v0.7.27 + Copyright © 2012-2021 Faisal Salman + MIT License */ +(function(window,undefined){"use strict";var LIBVERSION="0.7.27",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i in arr){enums[arr[i].toUpperCase()]=arr[i]}return enums},has=function(str1,str2){return typeof str1===STR_TYPE?lowerize(str2).indexOf(lowerize(str1))!==-1:false},lowerize=function(str){return str.toLowerCase()},majorize=function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,EMPTY).split(".")[0]:undefined},trim=function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,EMPTY);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)};var rgxMapper=function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);UAParser.CPU=enumerize([ARCHITECTURE]);UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]);UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define===FUNC_TYPE&&define.amd){define(function(){return UAParser})}else if(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(ua){parser.setUA(ua);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index 67612af..6b53d61 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,9 +1,4 @@ -/*!@license - * UAParser.js v0.7.27 - * Lightweight JavaScript-based User-Agent string parser - * https://github.com/faisalman/ua-parser-js - * - * Copyright © 2012-2021 Faisal Salman - * Licensed under MIT License - */ -!function(r,b){"use strict";var u="function",e="undefined",c="object",a="string",i="model",s="name",o="type",n="vendor",t="version",l="architecture",d="console",w="mobile",m="tablet",p="smarttv",f="wearable",h={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return typeof i==a&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i==a?i.replace(/[^\d\.]/g,"").split(".")[0]:b},trim:function(i,s){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof s==e?i:i.substring(0,255)}},g={rgx:function(i,s){for(var e,o,r,a,n,t=0;t + MIT License */ +!function(a,d){"use strict";function i(i){var e,s={};for(e in i)s[i[e].toUpperCase()]=i[e];return s}function r(i,e){return typeof i==w&&-1!==D(e).indexOf(D(i))}function n(i,e){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof e==b?i:i.substring(0,255)}function t(i,e){for(var s,o,a,r,n,t=0;t (http://faisalman.com)", - "description": "Lightweight JavaScript-based user-agent string parser", + "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ "user-agent", "parser", @@ -142,7 +142,7 @@ ], "main": "src/ua-parser.js", "scripts": { - "build": "uglifyjs src/ua-parser.js -o dist/ua-parser.min.js --comments && uglifyjs src/ua-parser.js -o dist/ua-parser.pack.js --comments --compress --mangle", + "build": "uglifyjs src/ua-parser.js -o dist/ua-parser.min.js --comments '/^ UA/' && uglifyjs src/ua-parser.js -o dist/ua-parser.pack.js --comments '/^ UA/' --compress --mangle", "test": "jshint src/ua-parser.js && mocha -R nyan test/test.js", "test-ci": "jshint src/ua-parser.js && mocha -R spec test/test.js", "verup": "node ./node_modules/verup", diff --git a/src/ua-parser.js b/src/ua-parser.js index 2dbdf7e..0a055f0 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,11 +1,12 @@ -/*!@license - * UAParser.js v0.7.27 - * Lightweight JavaScript-based User-Agent string parser - * https://github.com/faisalman/ua-parser-js - * - * Copyright © 2012-2021 Faisal Salman - * Licensed under MIT License - */ +///////////////////////////////////////////////////////////////////////////////// +/* UAParser.js v0.7.27 + Copyright © 2012-2021 Faisal Salman + MIT License *//* + Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. + Supports browser & node.js environment. + Demo : https://faisalman.github.io/ua-parser-js + Source : https://github.com/faisalman/ua-parser-js */ +///////////////////////////////////////////////////////////////////////////////// (function (window, undefined) { @@ -15,7 +16,6 @@ // Constants ///////////// - var LIBVERSION = '0.7.27', EMPTY = '', UNKNOWN = '?', @@ -23,7 +23,7 @@ UNDEF_TYPE = 'undefined', OBJ_TYPE = 'object', STR_TYPE = 'string', - MAJOR = 'major', // deprecated + MAJOR = 'major', MODEL = 'model', NAME = 'name', TYPE = 'type', @@ -38,14 +38,30 @@ EMBEDDED = 'embedded', UA_MAX_LENGTH = 255; + var AMAZON = 'Amazon', + APPLE = 'Apple', + ASUS = 'ASUS', + BLACKBERRY = 'BlackBerry', + BROWSER = 'Browser', + CHROME = 'Chrome', + EDGE = 'Edge', + FIREFOX = 'Firefox', + GOOGLE = 'Google', + HUAWEI = 'Huawei', + LG = 'LG', + MICROSOFT = 'Microsoft', + MOTOROLA = 'Motorola', + OPERA = 'Opera', + SAMSUNG = 'Samsung', + SONY = 'Sony', + XIAOMI = 'Xiaomi', + ZEBRA = 'Zebra'; /////////// // Helper ////////// - - var util = { - extend : function (regexes, extensions) { + var extend = function (regexes, extensions) { var mergedRegexes = {}; for (var i in regexes) { if (extensions[i] && extensions[i].length % 2 === 0) { @@ -56,30 +72,32 @@ } return mergedRegexes; }, - has : function (str1, str2) { - return typeof str1 === STR_TYPE ? str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1 : false; + enumerize = function (arr) { + var enums = {}; + for (var i in arr) { + enums[arr[i].toUpperCase()] = arr[i]; + } + return enums; }, - lowerize : function (str) { + has = function (str1, str2) { + return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false; + }, + lowerize = function (str) { return str.toLowerCase(); }, - major : function (version) { - return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g,'').split(".")[0] : undefined; + majorize = function (version) { + return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split('.')[0] : undefined; }, - trim : function (str, len) { - str = str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + trim = function (str, len) { + str = str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, EMPTY); return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); - } }; - /////////////// // Map helper ////////////// - - var mapper = { - - rgx : function (ua, arrays) { + var rgxMapper = function (ua, arrays) { var i = 0, j, k, p, q, matches, match; @@ -131,167 +149,145 @@ } }, - str : function (str, map) { + strMapper = function (str, map) { for (var i in map) { - // check if array + // check if current value is array if (typeof map[i] === OBJ_TYPE && map[i].length > 0) { for (var j = 0; j < map[i].length; j++) { - if (util.has(map[i][j], str)) { + if (has(map[i][j], str)) { return (i === UNKNOWN) ? undefined : i; } } - } else if (util.has(map[i], str)) { + } else if (has(map[i], str)) { return (i === UNKNOWN) ? undefined : i; } } return str; - } }; - /////////////// // String map ////////////// - - var maps = { - - browser : { - // Safari < 3.0 - oldSafari : { - version : { - '1.0' : '/8', - '1.2' : '/1', - '1.3' : '/3', - '2.0' : '/412', - '2.0.2' : '/416', - '2.0.3' : '/417', - '2.0.4' : '/419', - '?' : '/' - } - }, - oldEdge : { - version : { - '0.1' : '12.', - '21' : '13.', - '31' : '14.', - '39' : '15.', - '41' : '16.', - '42' : '17.', - '44' : '18.' - } - } + // Safari < 3.0 + var oldSafariMap = { + '1.0' : '/8', + '1.2' : '/1', + '1.3' : '/3', + '2.0' : '/412', + '2.0.2' : '/416', + '2.0.3' : '/417', + '2.0.4' : '/419', + '?' : '/' }, - - os : { - windows : { - version : { - 'ME' : '4.90', - 'NT 3.11' : 'NT3.51', - 'NT 4.0' : 'NT4.0', - '2000' : 'NT 5.0', - 'XP' : ['NT 5.1', 'NT 5.2'], - 'Vista' : 'NT 6.0', - '7' : 'NT 6.1', - '8' : 'NT 6.2', - '8.1' : 'NT 6.3', - '10' : ['NT 6.4', 'NT 10.0'], - 'RT' : 'ARM' - } - } - } + oldEdgeMap = { + '0.1' : '12.', + '21' : '13.', + '31' : '14.', + '39' : '15.', + '41' : '16.', + '42' : '17.', + '44' : '18.' + }, + windowsVersionMap = { + 'ME' : '4.90', + 'NT 3.11' : 'NT3.51', + 'NT 4.0' : 'NT4.0', + '2000' : 'NT 5.0', + 'XP' : ['NT 5.1', 'NT 5.2'], + 'Vista' : 'NT 6.0', + '7' : 'NT 6.1', + '8' : 'NT 6.2', + '8.1' : 'NT 6.3', + '10' : ['NT 6.4', 'NT 10.0'], + 'RT' : 'ARM' }; - ////////////// // Regex map ///////////// - var regexes = { browser : [[ /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS - ], [VERSION, [NAME, 'Chrome']], [ + ], [VERSION, [NAME, CHROME]], [ /(?:edgios|edga|edg)\/([\w\.]+)/i // Microsoft Edge - ], [VERSION, [NAME, 'Edge']], [ + ], [VERSION, [NAME, EDGE]], [ /edge\/([\w\.]+)/i // Old Edge (Trident) - ], [[VERSION, mapper.str, maps.browser.oldEdge.version], [NAME, 'Edge']], [ + ], [[VERSION, strMapper, oldEdgeMap], [NAME, EDGE]], [ // Presto based - /(opera\smini)\/([\w\.-]+)/i, // Opera Mini - /(opera\s[mobiletab]{3,6})\b.+version\/([\w\.-]+)/i, // Opera Mobi/Tablet + /(opera mini)\/([\w\.-]+)/i, // Opera Mini + /(opera [mobiletab]{3,6})\b.+version\/([\w\.-]+)/i, // Opera Mobi/Tablet /(opera)(?:.+version\/|[\/\s]+)([\w\.]+)/i, // Opera ], [NAME, VERSION], [ /opios[\/\s]+([\w\.]+)/i // Opera mini on iphone >= 8.0 - ], [VERSION, [NAME, 'Opera Mini']], [ - /\sopr\/([\w\.]+)/i // Opera Webkit - ], [VERSION, [NAME, 'Opera']], [ + ], [VERSION, [NAME, OPERA+' Mini']], [ + /\bopr\/([\w\.]+)/i // Opera Webkit + ], [VERSION, [NAME, OPERA]], [ // Mixed /(kindle)\/([\w\.]+)/i, // Kindle /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer // Trident based - /(avant\s|iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser + /(avant |iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser /(ba?idubrowser)[\/\s]?([\w\.]+)/i, // Baidu Browser - /(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer + /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer - // Webkit/KHTML based - /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon)\/([\w\.-]+)/i, - // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon - /(rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ + // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon + /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([\w\.-]+)/i, + // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ /(weibo)__([\d\.]+)/i // Weibo ], [NAME, VERSION], [ - /(?:[\s\/]uc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser - ], [VERSION, [NAME, 'UCBrowser']], [ - /(?:windowswechat)?\sqbcore\/([\w\.]+)\b.*(?:windowswechat)?/i // WeChat Desktop for Windows Built-in Browser + /(?:\buc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser + ], [VERSION, [NAME, 'UC'+BROWSER]], [ + /\bqbcore\/([\w\.]+)/i // WeChat Desktop for Windows Built-in Browser ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [ /micromessenger\/([\w\.]+)/i // WeChat ], [VERSION, [NAME, 'WeChat']], [ /konqueror\/([\w\.]+)/i // Konqueror ], [VERSION, [NAME, 'Konqueror']], [ - /trident.+rv[:\s]([\w\.]{1,9})\b.+like\sgecko/i // IE11 + /trident.+rv[:\s]([\w\.]{1,9})\b.+like gecko/i // IE11 ], [VERSION, [NAME, 'IE']], [ /yabrowser\/([\w\.]+)/i // Yandex ], [VERSION, [NAME, 'Yandex']], [ /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser - ], [[NAME, /(.+)/, '$1 Secure Browser'], VERSION], [ - /focus\/([\w\.]+)/i // Firefox Focus - ], [VERSION, [NAME, 'Firefox Focus']], [ - /opt\/([\w\.]+)/i // Opera Touch - ], [VERSION, [NAME, 'Opera Touch']], [ - /coc_coc_browser\/([\w\.]+)/i // Coc Coc Browser + ], [[NAME, /(.+)/, '$1 Secure '+BROWSER], VERSION], [ + /\bfocus\/([\w\.]+)/i // Firefox Focus + ], [VERSION, [NAME, FIREFOX+' Focus']], [ + /\bopt\/([\w\.]+)/i // Opera Touch + ], [VERSION, [NAME, OPERA+' Touch']], [ + /coc_coc\w+\/([\w\.]+)/i // Coc Coc Browser ], [VERSION, [NAME, 'Coc Coc']], [ /dolfin\/([\w\.]+)/i // Dolphin ], [VERSION, [NAME, 'Dolphin']], [ /coast\/([\w\.]+)/i // Opera Coast - ], [VERSION, [NAME, 'Opera Coast']], - [/xiaomi\/miuibrowser\/([\w\.]+)/i // MIUI Browser - ], [VERSION, [NAME, 'MIUI Browser']], [ + ], [VERSION, [NAME, OPERA+' Coast']], [ + /miuibrowser\/([\w\.]+)/i // MIUI Browser + ], [VERSION, [NAME, 'MIUI '+BROWSER]], [ /fxios\/([\w\.-]+)/i // Firefox for iOS - ], [VERSION, [NAME, 'Firefox']], [ - /(qihu|qhbrowser|qihoobrowser|360browser)/i // 360 - ], [[NAME, '360 Browser']], [ + ], [VERSION, [NAME, FIREFOX]], [ + /\bqihu|(qi?ho?o?|360)browser/i // 360 + ], [[NAME, '360 '+BROWSER]], [ /(oculus|samsung|sailfish)browser\/([\w\.]+)/i - ], [[NAME, /(.+)/, '$1 Browser'], VERSION], [ // Oculus/Samsung/Sailfish Browser + ], [[NAME, /(.+)/, '$1 '+BROWSER], VERSION], [ // Oculus/Samsung/Sailfish Browser /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ - /\s(electron)\/([\w\.]+)\ssafari/i, // Electron-based App - /(tesla)(?:\sqtcarbrowser|\/(20[12]\d\.[\w\.-]+))/i, // Tesla + /(electron)\/([\w\.]+) safari/i, // Electron-based App + /(tesla)(?:\sqtcarbrowser|\/(20\d\d\.[\w\.-]+))/i, // Tesla /m?(qqbrowser|baiduboxapp|2345Explorer)[\/\s]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser ], [NAME, VERSION], [ - /(MetaSr)[\/\s]?([\w\.]+)/i, // SouGouBrowser - /(LBBROWSER)/i // LieBao Browser + /(metasr)[\/\s]?([\w\.]+)/i, // SouGouBrowser + /(lbbrowser)/i // LieBao Browser ], [NAME], [ // WebView - /;fbav\/([\w\.]+);/i // Facebook App for iOS & Android with version - ], [VERSION, [NAME, 'Facebook']], [ - /FBAN\/FBIOS|FB_IAB\/FB4A/i // Facebook App for iOS & Android without version - ], [[NAME, 'Facebook']], [ - /safari\s(line)\/([\w\.]+)/i, // Line App for iOS + /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android + ], [[NAME, 'Facebook'], VERSION], [ + /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /(chromium|instagram)[\/\s]([\w\.-]+)/i // Chromium/Instagram ], [NAME, VERSION], [ @@ -299,13 +295,13 @@ ], [VERSION, [NAME, 'GSA']], [ /headlesschrome(?:\/([\w\.]+)|\s)/i // Chrome Headless - ], [VERSION, [NAME, 'Chrome Headless']], [ + ], [VERSION, [NAME, CHROME+' Headless']], [ /\swv\).+(chrome)\/([\w\.]+)/i // Chrome WebView - ], [[NAME, 'Chrome WebView'], VERSION], [ + ], [[NAME, CHROME+' WebView'], VERSION], [ - /droid.+\sversion\/([\w\.]+)\b.+(?:mobile\ssafari|safari)/i // Android Browser - ], [VERSION, [NAME, 'Android Browser']], [ + /droid.+\sversion\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser + ], [VERSION, [NAME, 'Android '+BROWSER]], [ /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [NAME, VERSION], [ @@ -315,7 +311,7 @@ /version\/([\w\.]+)\s.*(mobile\s?safari|safari)/i // Safari & Safari Mobile ], [VERSION, NAME], [ /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 - ], [NAME, [VERSION, mapper.str, maps.browser.oldSafari.version]], [ + ], [NAME, [VERSION, strMapper, oldSafariMap]], [ /(webkit|khtml)\/([\w\.]+)/i ], [NAME, VERSION], [ @@ -323,21 +319,21 @@ // Gecko based /(navigator|netscape)\/([\w\.-]+)/i // Netscape ], [[NAME, 'Netscape'], VERSION], [ - /ile\svr;\srv:([\w\.]+)\).+firefox/i // Firefox Reality - ], [VERSION, [NAME, 'Firefox Reality']], [ + /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality + ], [VERSION, [NAME, FIREFOX+' Reality']], [ /ekiohf.+(flow)\/([\w\.]+)/i, // Flow /(swiftfox)/i, // Swiftfox - /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, + /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror - /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i, + /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i, // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix - /(firefox)\/([\w\.]+)\s[\w\s\-]+\/[\w\.]+$/i, // Other Firefox-based + /(firefox)\/([\w\.]+)/i, // Other Firefox-based /(mozilla)\/([\w\.]+)\s.+rv\:.+gecko\/\d+/i, // Mozilla // Other /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i, // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir - /(links)\s\(([\w\.]+)/i, // Links + /(links) \(([\w\.]+)/i, // Links /(gobrowser)\/?([\w\.]*)/i, // GoBrowser /(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser /(mosaic)[\/\s]([\w\.]+)/i // Mosaic @@ -350,7 +346,7 @@ ], [[ARCHITECTURE, 'amd64']], [ /(ia32(?=;))/i // IA32 (quicktime) - ], [[ARCHITECTURE, util.lowerize]], [ + ], [[ARCHITECTURE, lowerize]], [ /((?:i[346]|x)86)[;\)]/i // IA32 (x86) ], [[ARCHITECTURE, 'ia32']], [ @@ -362,18 +358,18 @@ ], [[ARCHITECTURE, 'armhf']], [ // PocketPC mistakenly identified as PowerPC - /windows\s(ce|mobile);\sppc;/i + /windows\s(ce|mobile); ppc;/i ], [[ARCHITECTURE, 'arm']], [ - /((?:ppc|powerpc)(?:64)?)(?:\smac|;|\))/i // PowerPC - ], [[ARCHITECTURE, /ower/, '', util.lowerize]], [ + /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC + ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [ /(sun4\w)[;\)]/i // SPARC ], [[ARCHITECTURE, 'sparc']], [ - /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?:64|(?=v(?:[1-7]|[5-7]1)l?|;|eabi))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i + /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?:64|(?=v(?:[1-7]|[5-7]1)l?|;|eabi))|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC - ], [[ARCHITECTURE, util.lowerize]] + ], [[ARCHITECTURE, lowerize]] ], device : [[ @@ -384,135 +380,135 @@ ///////////////////////// // Samsung - /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus\s10)/i - ], [MODEL, [VENDOR, 'Samsung'], [TYPE, TABLET]], [ - /\b((?:s[cgp]h|gt|sm)-\w+|galaxy\snexus)/i, - /\ssamsung[\s-]([\w-]+)/i, + /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i + ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [ + /\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i, + /samsung[\s-]([\w-]+)/i, /sec-(sgh\w+)/i - ], [MODEL, [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [ // Apple /\((ip(?:hone|od)[\s\w]*);/i // iPod/iPhone - ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [ /\((ipad);[\w\s\),;-]+apple/i, // iPad - /applecoremedia\/[\w\.]+\s\((ipad)/i, + /applecoremedia\/[\w\.]+ \((ipad)/i, /\b(ipad)\d\d?,\d\d?[;\]].+ios/i - ], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [ + ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ // Huawei /\b((?:agr|ags[23]|bah2?|sht?)-a?[lw]\d{2})/i, - ], [MODEL, [VENDOR, 'Huawei'], [TYPE, TABLET]], [ - /d\/huawei([\w\s-]+)[;\)]/i, - /\b(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, + ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ + /huawei([\w\s-]+)[;\)]/i, + /\b(nexus 6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, /\b(\w{2,4}-[atu][ln][01259][019])[;\)\s]/i - ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi - /\b(poco[\s\w]+)(?:\sbuild|\))/i, // Xiaomi POCO - /\b;\s(\w+)\sbuild\/hm\1/i, // Xiaomi Hongmi 'numeric' models - /\b(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi - /\b(redmi[\s\-_]?(?:note|k)?[\w\s_]+)(?:\sbuild|\))/i, // Xiaomi Redmi - /\b(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i // Xiaomi Mi - ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ - /\b(mi[\s\-_]?(?:pad)(?:[\w\s_]+))(?:\sbuild|\))/i // Mi Pad tablets - ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [ + /\b(poco[\s\w]+)(?: bui|\))/i, // Xiaomi POCO + /\b;\s(\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models + /\b(hm[\s\-_]?note?[\s_]?(?:\d\w)?) bui/i, // Xiaomi Hongmi + /\b(redmi[\s\-_]?(?:note|k)?[\w\s_]+)(?: bui|\))/i, // Xiaomi Redmi + /\b(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?) bui/i // Xiaomi Mi + ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ + /\b(mi[\s\-_]?(?:pad)(?:[\w\s_]+))(?: bui|\))/i // Mi Pad tablets + ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ // OPPO - /;\s(\w+)\sbuild.+\soppo/i, - /\s(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007)\b/i + /; (\w+) bui.+ oppo/i, + /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007)\b/i ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ // Vivo - /\svivo\s(\w+)(?:\sbuild|\))/i, - /\s(v[12]\d{3}\w?[at])(?:\sbuild|;)/i + /vivo (\w+)(?: bui|\))/i, + /\b(v[12]\d{3}\w?[at])(?: bui|;)/i ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ // Realme - /\s(rmx[12]\d{3})(?:\sbuild|;)/i + /\b(rmx[12]\d{3})(?: bui|;)/i ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [ // Motorola - /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)\b[\w\s]+build\//i, - /\smot(?:orola)?[\s-](\w*)/i, - /((?:moto[\s\w\(\)]+|xt\d{3,4}|nexus\s6)(?=\sbuild|\)))/i - ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [ - /\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i - ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [ + /\b(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w\s]+build\//i, + /\bmot(?:orola)?[\s-](\w*)/i, + /((?:moto[\s\w\(\)]+|xt\d{3,4}|nexus\s6)(?= bui|\)))/i + ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [ + /\b(mz60\d|xoom[\s2]{0,2}) build\//i + ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [ // LG - /((?=lg)?[vl]k\-?\d{3})\sbuild|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4})/i - ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [ + /((?=lg)?[vl]k\-?\d{3})\sbui|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4})/i + ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ /(lm-?f100[nv]?|nexus\s[45])/i, - /lg[e;\s\/-]+((?!browser|netcast)\w+)/i, - /\blg(\-?[\d\w]+)\sbuild/i - ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [ + /\blg[e;\s\/-]+((?!browser|netcast)\w+)/i, + /\blg(\-?[\d\w]+)\sbui/i + ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ // Lenovo /(ideatab[\w\-\s]+)/i, - /lenovo\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+)|yt[\d\w-]{6}|tb[\d\w-]{6})/i // Lenovo tablets + /lenovo\s?(s[56]000[\w-]+|tab(?:[\s\w]+)|yt[\d\w-]{6}|tb[\d\w-]{6})/i ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ // Nokia - /(?:maemo|nokia).*(n900|lumia\s\d+)/i, + /(?:maemo|nokia).*(n900|lumia \d+)/i, /nokia[\s_-]?([\w\.-]*)/i ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ // Google - /droid.+;\s(pixel\sc)[\s)]/i // Google Pixel C - ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [ - /droid.+;\s(pixel[\s\daxl]{0,6})(?:\sbuild|\))/i // Google Pixel - ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [ + /(pixel c)\b/i // Google Pixel C + ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [ + /droid.+; (pixel[\s\daxl]{0,6})(?: bui|\))/i // Google Pixel + ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ // Sony - /droid.+\s([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?=\sbuild\/|\).+chrome\/(?![1-6]{0,1}\d\.))/i - ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [ - /sony\stablet\s[ps]\sbuild\//i, - /(?:sony)?sgp\w+(?:\sbuild\/|\))/i - ], [[MODEL, 'Xperia Tablet'], [VENDOR, 'Sony'], [TYPE, TABLET]], [ + /droid.+\s([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i + ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ + /sony tablet [ps]/i, + /\b(?:sony)?sgp\w+(?: bui|\))/i + ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [ // OnePlus /\s(kb2005|in20[12]5|be20[12][59])\b/i, - /\ba000(1)\sbuild/i, // OnePlus - /\boneplus\s(a\d{4})[\s)]/i + /\ba000(1) bui/i, + /oneplus (a\d{4})[\s)]/i ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ // Amazon /(alexa)webm/i, - /(kf[a-z]{2}wi)(\sbuild\/|\))/i, // Kindle Fire without Silk - /(kf[a-z]+)(\sbuild\/|\)).+silk\//i // Kindle Fire HD - ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ - /(sd|kf)[0349hijorstuw]+(\sbuild\/|\)).+silk\//i // Fire Phone - ], [[MODEL, 'Fire Phone'], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ + /(kf[a-z]{2}wi)( bui|\))/i, // Kindle Fire without Silk + /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD + ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [ + /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone + ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [ // BlackBerry - /\((playbook);[\w\s\),;-]+(rim)/i // BlackBerry PlayBook + /(playbook);[\w\s\),;-]+(rim)/i // BlackBerry PlayBook ], [MODEL, VENDOR, [TYPE, TABLET]], [ - /((?:bb[a-f]|st[hv])100-\d)/i, + /\b((?:bb[a-f]|st[hv])100-\d)/i, /\(bb10;\s(\w+)/i // BlackBerry 10 - ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [ // Asus - /(?:\b|asus_)(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus\s7|padfone|p00[cj])/i - ], [MODEL, [VENDOR, 'ASUS'], [TYPE, TABLET]], [ - /\s(z[es]6[027][01][km][ls]|zenfone\s\d\w?)\b/i - ], [MODEL, [VENDOR, 'ASUS'], [TYPE, MOBILE]], [ + /(?:\b|asus_)(transfo[prime\s]{4,10}\s\w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i + ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [ + /\s(z[es]6[027][01][km][ls]|zenfone \d\w?)\b/i + ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [ // HTC - /(nexus\s9)/i // HTC Nexus 9 + /(nexus 9)/i // HTC Nexus 9 ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ - /(htc)[;_\s-]{1,2}([\w\s]+(?=\)|\sbuild)|\w+)/i, // HTC + /(htc)[;_\s-]{1,2}([\w\s]+(?=\)| bui)|\w+)/i, // HTC // ZTE /(zte)-(\w*)/i, - /(alcatel|geeksphone|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony + /(alcatel|geeksphone|nexian|panasonic|sony)[_\s-]?([\w-]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ // Acer - /droid[x\d\.\s;]+\s([ab][1-7]\-?[0178a]\d\d?)/i + /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [ // Meizu - /droid.+;\s(m[1-5]\snote)\sbuild/i, + /droid.+; (m[1-5] note) bui/i, /\bmz-([\w-]{2,})/i ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ @@ -521,94 +517,94 @@ // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron /(hp)\s([\w\s]+\w)/i, // HP iPAQ /(asus)-?(\w+)/i, // Asus - /(microsoft);\s(lumia[\s\w]+)/i, // Microsoft Lumia + /(microsoft); (lumia[\s\w]+)/i, // Microsoft Lumia /(lenovo)[_\s-]?([\w-]+)/i, // Lenovo - /linux;.+(jolla);/i, // Jolla - /droid.+;\s(oppo)\s?([\w\s]+)\sbuild/i // OPPO + /(jolla)/i, // Jolla + /(oppo)\s?([\w\s]+)\sbui/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - /(archos)\s(gamepad2?)/i, // Archos + /(archos) (gamepad2?)/i, // Archos /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(kindle)\/([\w\.]+)/i, // Kindle - /\s(nook)[\w\s]+build\/(\w+)/i, // Nook - /(dell)\s(strea[kpr\s\d]*[\dko])/i, // Dell Streak - /[;\/]\s?(le[\s\-]+pan)[\s\-]+(\w{1,9})\sbuild/i, // Le Pan Tablets - /[;\/]\s?(trinity)[\-\s]*(t\d{3})\sbuild/i, // Trinity Tablets - /\b(gigaset)[\s\-]+(q\w{1,9})\sbuild/i, // Gigaset Tablets - /\b(vodafone)\s([\w\s]+)(?:\)|\sbuild)/i // Vodafone + /(nook)[\w\s]+build\/(\w+)/i, // Nook + /(dell) (strea[kpr\s\d]*[\dko])/i, // Dell Streak + /(le[\s\-]+pan)[\s\-]+(\w{1,9})\sbui/i, // Le Pan Tablets + /(trinity)[\-\s]*(t\d{3})\sbui/i, // Trinity Tablets + /(gigaset)[\s\-]+(q\w{1,9})\sbui/i, // Gigaset Tablets + /(vodafone)\s([\w\s]+)(?:\)|\sbui)/i // Vodafone ], [VENDOR, MODEL, [TYPE, TABLET]], [ - /\s(surface\sduo)\s/i // Surface Duo - ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, TABLET]], [ - /droid\s[\d\.]+;\s(fp\du?)\sbuild/i + /(surface duo)/i // Surface Duo + ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ + /droid\s[\d\.]+; (fp\du?) b/i // Fairphone ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ - /\s(u304aa)\sbuild/i // AT&T + /(u304aa)/i // AT&T ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ - /sie-(\w*)/i // Siemens + /\bsie-(\w*)/i // Siemens ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ - /[;\/]\s?(rct\w+)\sbuild/i // RCA Tablets + /\b(rct\w+) b/i // RCA Tablets ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [ - /[;\/\s](venue[\d\s]{2,7})\sbuild/i // Dell Venue Tablets + /\b(venue[\d\s]{2,7}) b/i // Dell Venue Tablets ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ - /[;\/]\s?(q(?:mv|ta)\w+)\sbuild/i // Verizon Tablet + /\b(q(?:mv|ta)\w+) b/i // Verizon Tablet ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ - /[;\/]\s(?:barnes[&\s]+noble\s|bn[rt])([\w\s\+]*)\sbuild/i // Barnes & Noble Tablet + /\b(?:barnes[&\s]+noble |bn[rt])([\w\s\+]*) b/i // Barnes & Noble Tablet ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [ - /[;\/]\s(tm\d{3}\w+)\sbuild/i + /\b(tm\d{3}\w+) b/i ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [ - /;\s(k88)\sbuild/i // ZTE K Series Tablet + /\b(k88) b/i // ZTE K Series Tablet ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [ - /;\s(nx\d{3}j)\sbuild/i // ZTE Nubia + /\b(nx\d{3}j) b/i // ZTE Nubia ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [ - /[;\/]\s?(gen\d{3})\sbuild.*49h/i // Swiss GEN Mobile + /\b(gen\d{3}) b.+49h/i // Swiss GEN Mobile ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [ - /[;\/]\s?(zur\d{3})\sbuild/i // Swiss ZUR Tablet + /\b(zur\d{3}) b/i // Swiss ZUR Tablet ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ - /[;\/]\s?((zeki)?tb.*\b)\sbuild/i // Zeki Tablets + /\b((zeki)?tb.*\b) b/i // Zeki Tablets ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ - /[;\/]\s([yr]\d{2})\sbuild/i, - /[;\/]\s(dragon[\-\s]+touch\s|dt)(\w{5})\sbuild/i // Dragon Touch Tablet + /\b([yr]\d{2}) b/i, + /\b(dragon[\-\s]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [ - /[;\/]\s?(ns-?\w{0,9})\sbuild/i // Insignia Tablets + /\b(ns-?\w{0,9}) b/i // Insignia Tablets ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [ - /[;\/]\s?((nxa|Next)-?\w{0,9})\sbuild/i // NextBook Tablets + /\b((nxa|next)-?\w{0,9}) b/i // NextBook Tablets ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [ - /[;\/]\s?(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05]))\sbuild/i - ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ // Voice Xtreme Phones - /[;\/]\s?(lvtel\-)?(v1[12])\sbuild/i // LvTel Phones + /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones + ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ + /\b(lvtel\-)?(v1[12]) b/i // LvTel Phones ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [ - /;\s(ph-1)\s/i - ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ // Essential PH-1 - /[;\/]\s?(v(100md|700na|7011|917g).*\b)\sbuild/i // Envizen Tablets + /\b(ph-1)\s/i // Essential PH-1 + ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ + /\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [ - /[;\/]\s?(trio[\s\w\-\.]+)\sbuild/i // MachSpeed Tablets + /\b(trio[\s\w\-\.]+) b/i // MachSpeed Tablets ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [ - /[;\/]\s?tu_(1491)\sbuild/i // Rotor Tablets + /\btu_(1491) b/i // Rotor Tablets ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [ - /(shield[\w\s]+)\sbuild/i // Nvidia Shield Tablets + /(shield[\w\s]+) b/i // Nvidia Shield Tablets ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [ - /(sprint)\s(\w+)/i // Sprint Phones + /(sprint) (\w+)/i // Sprint Phones ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kin\.[onetw]{3})/i // Microsoft Kin - ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ - /droid\s[\d\.]+;\s(cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra - ], [MODEL, [VENDOR, 'Zebra'], [TYPE, TABLET]], [ - /droid\s[\d\.]+;\s(ec30|ps20|tc[2-8]\d[kx])\)/i - ], [MODEL, [VENDOR, 'Zebra'], [TYPE, MOBILE]], [ + ], [[MODEL, /\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [ + /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra + ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [ + /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i + ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [ /////////////////// // CONSOLES /////////////////// - /\s(ouya)\s/i, // Ouya - /(nintendo)\s([wids3utch]+)/i // Nintendo + /(ouya)/i, // Ouya + /(nintendo) ([wids3utch]+)/i // Nintendo ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ - /droid.+;\s(shield)\sbuild/i // Nvidia + /droid.+; (shield) bui/i // Nvidia ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ - /(playstation\s[345portablevi]+)/i // Playstation - ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [ - /[\s\(;](xbox(?:\sone)?(?!;\sxbox))[\s\);]/i // Microsoft Xbox - ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [ + /(playstation [345portablevi]+)/i // Playstation + ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [ + /\b(xbox(?: one)?(?!; xbox))[\s\);]/i // Microsoft Xbox + ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [ /////////////////// // SMARTTVS @@ -617,52 +613,52 @@ /smart-tv.+(samsung)/i // Samsung ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i - ], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [ - /(?:linux;\snetcast.+smarttv|lg\snetcast\.tv-201\d)/i, // LG SmartTV - ], [[VENDOR, 'LG'], [TYPE, SMARTTV]], [ + ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ + /(?:nux; netcast.+smarttv|lg netcast\.tv-201\d)/i, // LG SmartTV + ], [[VENDOR, LG], [TYPE, SMARTTV]], [ /(apple)\s?tv/i // Apple TV - ], [VENDOR, [MODEL, 'Apple TV'], [TYPE, SMARTTV]], [ + ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ /crkey/i // Google Chromecast - ], [[MODEL, 'Chromecast'], [VENDOR, 'Google'], [TYPE, SMARTTV]], [ - /droid.+aft([\w])(\sbuild\/|\))/i // Fire TV - ], [MODEL, [VENDOR, 'Amazon'], [TYPE, SMARTTV]], [ + ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ + /droid.+aft(\w)( bui|\))/i // Fire TV + ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices - ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [ - /[\s\/\(](android\s|smart[-\s]?|opera\s)tv[;\)\s]/i // SmartTV from Unidentified Vendors + ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ + /[\s\/\(](android |smart[-\s]?|opera )tv[;\)\s]/i // SmartTV from Unidentified Vendors ], [[TYPE, SMARTTV]], [ /////////////////// // WEARABLES /////////////////// - /((pebble))app\/[\d\.]+\s/i // Pebble + /((pebble))app/i // Pebble ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ - /droid.+;\s(glass)\s\d/i // Google Glass - ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [ - /droid\s[\d\.]+;\s(wt63?0{2,3})\)/i - ], [MODEL, [VENDOR, 'Zebra'], [TYPE, WEARABLE]], [ + /droid.+; (glass) \d/i // Google Glass + ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [ + /droid.+; (wt63?0{2,3})\)/i + ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ /////////////////// // EMBEDDED /////////////////// - /(tesla)(?:\sqtcarbrowser|\/20[12]\d\.[\w\.-]+)/i // Tesla + /(tesla)(?: qtcarbrowser|\/[\w\.-]+)/i // Tesla ], [VENDOR, [TYPE, EMBEDDED]], [ //////////////////// // MIXED (GENERIC) /////////////////// - /droid .+?; ([^;]+?)(?: build|\) applewebkit).+? mobile safari/i // Android Phones from Unidentified Vendors + /droid .+?;\s([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors ], [MODEL, [TYPE, MOBILE]], [ - /droid .+?;\s([^;]+?)(?: build|\) applewebkit).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors + /droid .+?;\s([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors ], [MODEL, [TYPE, TABLET]], [ - /\s(tablet|tab)[;\/]/i, // Unidentifiable Tablet - /\s(mobile)(?:[;\/]|\ssafari)/i // Unidentifiable Mobile - ], [[TYPE, util.lowerize]], [ - /(android[\w\.\s\-]{0,9});.+build/i // Generic Android Device + /\b(tablet|tab)[;\/]/i, // Unidentifiable Tablet + /\b(mobile)(?:[;\/]| safari)/i // Unidentifiable Mobile + ], [[TYPE, lowerize]], [ + /(android[\w\.\s\-]{0,9});.+buil/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']], [ /(phone)/i ], [[TYPE, MOBILE]] @@ -670,8 +666,8 @@ engine : [[ - /windows.+\sedge\/([\w\.]+)/i // EdgeHTML - ], [VERSION, [NAME, 'EdgeHTML']], [ + /windows.+ edge\/([\w\.]+)/i // EdgeHTML + ], [VERSION, [NAME, EDGE+'HTML']], [ /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink ], [VERSION, [NAME, 'Blink']], [ @@ -690,60 +686,60 @@ os : [[ // Windows - /microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes) + /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ - /(windows)\snt\s6\.2;\s(arm)/i, // Windows RT - /(windows\sphone(?:\sos)*)[\s\/]?([\d\.\s\w]*)/i, // Windows Phone - /(windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)(?!.+xbox)/i - ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [ - /(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i - ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [ + /(windows) nt 6\.2; (arm)/i, // Windows RT + /(windows phone(?: os)*)[\s\/]?([\d\.\s\w]*)/i, // Windows Phone + /(windows mobile|windows)[\s\/]?([ntce\d\.\s]+\w)(?!.+xbox)/i + ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ + /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i + ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [ // iOS/macOS - /ip[honead]{2,4}\b(?:.*os\s([\w]+)\slike\smac|;\sopera)/i, // iOS + /ip[honead]{2,4}\b(?:.*os ([\w]+) like\smac|; opera)/i, // iOS /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ - /(mac\sos\sx)\s?([\w\s\.]*)/i, - /(macintosh|mac(?=_powerpc)\s)(?!.+haiku)/i // Mac OS + /(mac os x)\s?([\w\s\.]*)/i, + /(macintosh|mac(?=_powerpc) )(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ // Mobile OSes // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS - /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, + /(android|webos|palm os|qnx|bada|rim tablet os|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS /\((series40);/i // Series 40 ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 - ], [VERSION, [NAME, 'BlackBerry']], [ + ], [VERSION, [NAME, BLACKBERRY]], [ /(?:symbian\s?os|symbos|s60(?=;)|series60)[\/\s-]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS - ], [[NAME, 'Firefox OS']], [ + ], [[NAME, FIREFOX+' OS']], [ /web0s;.+rt(tv)/i, /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS ], [VERSION, [NAME, 'webOS']], [ // Google Chromecast /crkey\/([\d\.]+)/i // Google Chromecast - ], [VERSION, [NAME, 'Chromecast']], [ - /(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS + ], [VERSION, [NAME, CHROME+'cast']], [ + /(cros) [\w]+\s([\w\.]+\w)/i // Chromium OS ], [[NAME, 'Chromium OS'], VERSION],[ // Console - /(nintendo|playstation)\s([wids345portablevuch]+)/i, // Nintendo/Playstation - /(xbox);\s+xbox\s([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) + /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation + /(xbox);\s+xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) // GNU/Linux based /(mint)[\/\s\(\)]?(\w*)/i, // Mint /(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux - /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?=\slinux)|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus|raspbian)(?:\sgnu\/linux)?(?:\slinux)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, + /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus|raspbian)(?: gnu\/linux)?(?: linux)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus /(hurd|linux)\s?([\w\.]*)/i, // Hurd/Linux /(gnu)\s?([\w\.]*)/i, // GNU // BSD based - /\s([frentopc-]{0,4}bsd|dragonfly)\s?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly + /\b([frentopc-]{0,4}bsd|dragonfly)\s?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly /(haiku)\s(\w+)/i // Haiku ], [NAME, VERSION], [ @@ -751,20 +747,20 @@ /(sunos)\s?([\w\.\d]*)/i // Solaris ], [[NAME, 'Solaris'], VERSION], [ /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris - /(aix)\s((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX - /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms|fuchsia)/i, // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia + /(aix) ((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX + /(plan 9|minix|beos|os\/2|amigaos|morphos|risc os|openvms|fuchsia)/i, // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia /(unix)\s?([\w\.]*)/i // UNIX ], [NAME, VERSION] ] }; - ///////////////// // Constructor //////////////// + var UAParser = function (ua, extensions) { - if (typeof ua === 'object') { + if (typeof ua === OBJ_TYPE) { extensions = ua; ua = undefined; } @@ -773,33 +769,43 @@ return new UAParser(ua, extensions).getResult(); } - var _ua = ua || ((typeof window !== 'undefined' && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); - var _rgxmap = extensions ? util.extend(regexes, extensions) : regexes; + var _ua = ua || ((typeof window !== UNDEF_TYPE && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); + var _rgxmap = extensions ? extend(regexes, extensions) : regexes; this.getBrowser = function () { - var _browser = { name: undefined, version: undefined }; - mapper.rgx.call(_browser, _ua, _rgxmap.browser); - _browser.major = util.major(_browser.version); // deprecated + var _browser = {}; + _browser[NAME] = undefined; + _browser[VERSION] = undefined; + rgxMapper.call(_browser, _ua, _rgxmap.browser); + _browser.major = majorize(_browser.version); return _browser; }; this.getCPU = function () { - var _cpu = { architecture: undefined }; - mapper.rgx.call(_cpu, _ua, _rgxmap.cpu); + var _cpu = {}; + _cpu[ARCHITECTURE] = undefined; + rgxMapper.call(_cpu, _ua, _rgxmap.cpu); return _cpu; }; this.getDevice = function () { - var _device = { vendor: undefined, model: undefined, type: undefined }; - mapper.rgx.call(_device, _ua, _rgxmap.device); + var _device = {}; + _device[VENDOR] = undefined; + _device[MODEL] = undefined; + _device[TYPE] = undefined; + rgxMapper.call(_device, _ua, _rgxmap.device); return _device; }; this.getEngine = function () { - var _engine = { name: undefined, version: undefined }; - mapper.rgx.call(_engine, _ua, _rgxmap.engine); + var _engine = {}; + _engine[NAME] = undefined; + _engine[VERSION] = undefined; + rgxMapper.call(_engine, _ua, _rgxmap.engine); return _engine; }; this.getOS = function () { - var _os = { name: undefined, version: undefined }; - mapper.rgx.call(_os, _ua, _rgxmap.os); + var _os = {}; + _os[NAME] = undefined; + _os[VERSION] = undefined; + rgxMapper.call(_os, _ua, _rgxmap.os); return _os; }; this.getResult = function () { @@ -816,7 +822,7 @@ return _ua; }; this.setUA = function (ua) { - _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? util.trim(ua, UA_MAX_LENGTH) : ua; + _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua; return this; }; this.setUA(_ua); @@ -824,39 +830,15 @@ }; UAParser.VERSION = LIBVERSION; - UAParser.BROWSER = { - NAME : NAME, - MAJOR : MAJOR, // deprecated - VERSION : VERSION - }; - UAParser.CPU = { - ARCHITECTURE : ARCHITECTURE - }; - UAParser.DEVICE = { - MODEL : MODEL, - VENDOR : VENDOR, - TYPE : TYPE, - CONSOLE : CONSOLE, - MOBILE : MOBILE, - SMARTTV : SMARTTV, - TABLET : TABLET, - WEARABLE: WEARABLE, - EMBEDDED: EMBEDDED - }; - UAParser.ENGINE = { - NAME : NAME, - VERSION : VERSION - }; - UAParser.OS = { - NAME : NAME, - VERSION : VERSION - }; + UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]); + UAParser.CPU = enumerize([ARCHITECTURE]); + UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]); + UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]); /////////// // Export ////////// - // check js environment if (typeof(exports) !== UNDEF_TYPE) { // nodejs env @@ -866,11 +848,11 @@ exports.UAParser = UAParser; } else { // requirejs env (optional) - if (typeof(define) === 'function' && define.amd) { + if (typeof(define) === FUNC_TYPE && define.amd) { define(function () { return UAParser; }); - } else if (typeof window !== 'undefined') { + } else if (typeof window !== UNDEF_TYPE) { // browser env window.UAParser = UAParser; } @@ -881,15 +863,15 @@ // In AMD env the global scope should be kept clean, but jQuery is an exception. // jQuery always exports to global scope, unless jQuery.noConflict(true) is used, // and we should catch that. - var $ = typeof window !== 'undefined' && (window.jQuery || window.Zepto); + var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto); if ($ && !$.ua) { var parser = new UAParser(); $.ua = parser.getResult(); $.ua.get = function () { return parser.getUA(); }; - $.ua.set = function (uastring) { - parser.setUA(uastring); + $.ua.set = function (ua) { + parser.setUA(ua); var result = parser.getResult(); for (var prop in result) { $.ua[prop] = result[prop]; From 9200e53787a7c5ec5fe143780bf5c3bf3b32da7d Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 8 Apr 2021 21:06:52 +0700 Subject: [PATCH 102/121] Update readme: use https for demo link --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 30871eb..8afe2ce 100644 --- a/readme.md +++ b/readme.md @@ -15,7 +15,7 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data with relatively small footprint (~17KB minified, ~6KB gzipped) that can be used either in browser (client-side) or node.js (server-side). * Author : Faisal Salman <> -* Demo : http://faisalman.github.io/ua-parser-js +* Demo : https://faisalman.github.io/ua-parser-js * Source : https://github.com/faisalman/ua-parser-js # Documentation From c39590b673c87d82234139eb485f5345434d2030 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 8 Apr 2021 22:33:23 +0700 Subject: [PATCH 103/121] Test for Firefox UAs, add new browser: Klar, add new OS: Maemo Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox --- readme.md | 12 +++---- src/ua-parser.js | 27 ++++++++-------- test/browser-test.json | 40 +++++++++++++++++++++++ test/cpu-test.json | 16 ++++++++++ test/device-test.json | 72 ++++++++++++++++++++++++++++++++++++++++++ test/os-test.json | 65 +++++++++++++++++++++++++++++++++++++- 6 files changed, 211 insertions(+), 21 deletions(-) diff --git a/readme.md b/readme.md index 8afe2ce..08102cb 100644 --- a/readme.md +++ b/readme.md @@ -41,7 +41,7 @@ Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, Dolphin, Doris, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, Firebird, Firefox [Reality], Flock, Flow, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, -Kindle, Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, +Kindle, Klar, Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Oculus Browser, OmniWeb, Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, @@ -88,11 +88,11 @@ NetSurf, Presto, Tasman, Trident, w3m, WebKit # Possible 'os.name' AIX, Amiga OS, Android, Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, Contiki, Fedora, Firefox OS, FreeBSD, Debian, DragonFly, Fuchsia, Gentoo, GNU, -Haiku, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Mageia, Mandriva, MeeGo, -Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, -PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, RISC OS, -Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, Unix, -VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... +Haiku, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Maemo, Mageia, Mandriva, +MeeGo, Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, +PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, +RISC OS, Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, +Unix, VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... # 'os.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 0a055f0..2daa2a7 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -323,8 +323,8 @@ ], [VERSION, [NAME, FIREFOX+' Reality']], [ /ekiohf.+(flow)\/([\w\.]+)/i, // Flow /(swiftfox)/i, // Swiftfox - /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, - // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror + /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/\s]?([\w\.\+]+)/i, + // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i, // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix /(firefox)\/([\w\.]+)/i, // Other Firefox-based @@ -626,7 +626,7 @@ ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ - /[\s\/\(](android |smart[-\s]?|opera )tv[;\)\s]/i // SmartTV from Unidentified Vendors + /\b(android tv|smart[-\s]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors ], [[TYPE, SMARTTV]], [ /////////////////// @@ -655,13 +655,12 @@ ], [MODEL, [TYPE, MOBILE]], [ /droid .+?;\s([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors ], [MODEL, [TYPE, TABLET]], [ - /\b(tablet|tab)[;\/]/i, // Unidentifiable Tablet - /\b(mobile)(?:[;\/]| safari)/i // Unidentifiable Mobile - ], [[TYPE, lowerize]], [ + /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i, // Unidentifiable Tablet + ], [[TYPE, TABLET]], [ + /(phone|mobile(?:[;\/]| safari))/i // Unidentifiable Mobile + ], [[TYPE, MOBILE]], [ /(android[\w\.\s\-]{0,9});.+buil/i // Generic Android Device - ], [MODEL, [VENDOR, 'Generic']], [ - /(phone)/i - ], [[TYPE, MOBILE]] + ], [MODEL, [VENDOR, 'Generic']] ], engine : [[ @@ -690,7 +689,7 @@ ], [NAME, VERSION], [ /(windows) nt 6\.2; (arm)/i, // Windows RT /(windows phone(?: os)*)[\s\/]?([\d\.\s\w]*)/i, // Windows Phone - /(windows mobile|windows)[\s\/]?([ntce\d\.\s]+\w)(?!.+xbox)/i + /(windows mobile|windows)[\s\/]?([ntce\d\.\s]+[\w\.]+)(?!.+xbox)/i ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [ @@ -703,8 +702,8 @@ /(macintosh|mac(?=_powerpc) )(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ - // Mobile OSes // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS - /(android|webos|palm os|qnx|bada|rim tablet os|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, + // Mobile OSes // Android/WebOS/Palm/QNX/Bada/RIM/Maemo/MeeGo/Contiki/Sailfish OS + /(android|webos|palm os|qnx|bada|rim tablet os|maemo|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS /\((series40);/i // Series 40 @@ -713,8 +712,8 @@ ], [VERSION, [NAME, BLACKBERRY]], [ /(?:symbian\s?os|symbos|s60(?=;)|series60)[\/\s-]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ - /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS - ], [[NAME, FIREFOX+' OS']], [ + /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w\s]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS + ], [VERSION, [NAME, FIREFOX+' OS']], [ /web0s;.+rt(tv)/i, /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS ], [VERSION, [NAME, 'webOS']], [ diff --git a/test/browser-test.json b/test/browser-test.json index 1947fe0..7158045 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -159,6 +159,16 @@ "major" : "2" } }, + { + "desc" : "Camino on Mac", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Camino/2.2.1", + "expect" : + { + "name" : "Camino", + "version" : "2.2.1", + "major" : "2" + } + }, { "desc" : "Chimera", "ua" : "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; pl-PL; rv:1.0.1) Gecko/20021111 Chimera/0.6", @@ -429,6 +439,16 @@ "major" : "1" } }, + { + "desc" : "Firefox for Maemo (Nokia N900)", + "ua" : "Mozilla/5.0 (Maemo; Linux armv7l; rv:10.0.1) Gecko/20100101 Firefox/10.0.1 Fennec/10.0.1", + "expect" : + { + "name" : "Fennec", + "version" : "10.0.1", + "major" : "10" + } + }, { "desc": "Firefox Focus", "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/6.1.1 Chrome/68.0.3440.91 Mobile Safari/537.36", @@ -958,6 +978,16 @@ "major" : "2" } }, + { + "desc" : "SeaMonkey on Mac", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:10.0.1) Gecko/20100101 Firefox/10.0.1 SeaMonkey/2.7.1", + "expect" : + { + "name" : "SeaMonkey", + "version" : "2.7.1", + "major" : "2" + } + }, { "desc" : "Silk Browser", "ua" : "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-84)", @@ -1228,6 +1258,16 @@ "major" : "1" } }, + { + "desc" : "Firefox iOS using iPad", + "ua" : "Mozilla/5.0 (iPad; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4", + "expect" : + { + "name" : "Firefox", + "version" : "1.0", + "major" : "1" + } + }, { "desc" : "QQ on iOS", "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Mobile/14A456 QQ/6.5.3.410 V1_IPH_SQ_6.5.3_1_APP_A Pixel/1080 Core/UIWebView NetType/WIFI Mem/26", diff --git a/test/cpu-test.json b/test/cpu-test.json index 773c9f6..efa1c5b 100644 --- a/test/cpu-test.json +++ b/test/cpu-test.json @@ -79,6 +79,14 @@ "architecture" : "arm" } }, + { + "desc" : "Nokia N900 Linux mobile", + "ua" : "Mozilla/5.0 (Maemo; Linux armv7l; rv:10.0) Gecko/20100101 Firefox/10.0 Fennec/10.0", + "expect" : + { + "architecture" : "arm" + } + }, { "desc" : "ARMEABI", "ua" : "[FBAN/FB4A;FBAV/237.0.0.44.120;FBBV/170693408;FBDM/{density=1.75,width=720,height=1280};FBLC/en_US;FBRV/172067074;FBCR/ ;FBMF/samsung;FBBD/samsung;FBPN/com.facebook.katana;FBDV/SM-S367VL;FBSV/9;FBBK/1;FBOP/19;FBCA/armeabi-v7a:armeabi;]", @@ -135,6 +143,14 @@ "architecture" : "ppc" } }, + { + "desc" : "Mac OS X on PowerPC using Firefox", + "ua" : "Mozilla/5.0 (Macintosh; PPC Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "architecture" : "ppc" + } + }, { "desc" : "UltraSPARC", "ua" : "Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.9b5) Gecko/2008032620 Firefox/3.0b5", diff --git a/test/device-test.json b/test/device-test.json index fb4b914..41da99f 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -2442,5 +2442,77 @@ "model": "V1916A", "type": "mobile" } + }, + { + "desc": "Unknown Mobile using Firefox", + "ua": "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Firefox", + "ua": "Mozilla/5.0 (Android 4.4; Tablet; rv:41.0) Gecko/41.0 Firefox/41.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown Mobile using Focus for Android", + "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Focus for Android", + "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown Device using Focus for Android with GeckoView", + "ua": "Mozilla/5.0 (Android 7.0; Mobile; rv:62.0) Gecko/62.0 Firefox/62.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Mobile using Firefox OS", + "ua": "Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Firefox OS", + "ua": "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown TV using Firefox OS", + "ua": "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } } ] diff --git a/test/os-test.json b/test/os-test.json index 27c5427..3b80025 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -134,6 +134,24 @@ "version" : "8.0" } }, + { + "desc" : "Windows NT on x86 or aarch64 CPU using Firefox", + "ua" : "Mozilla/5.0 (Windows NT x.y; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "Windows", + "version" : "NT x.y" + } + }, + { + "desc" : "Windows NT on x64 CPU using Firefox", + "ua" : "Mozilla/5.0 (Windows NT x.y; Win64; x64; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "Windows", + "version" : "NT x.y" + } + }, { "desc" : "BlackBerry", "ua" : "BlackBerry9300/5.0.0.912 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/378", @@ -278,6 +296,15 @@ "version" : "2.1.0" } }, + { + "desc" : "Nokia N900 Linux mobile, on the Fennec browser", + "ua" : "Mozilla/5.0 (Maemo; Linux armv7l; rv:10.0) Gecko/20100101 Firefox/10.0 Fennec/10.0", + "expect" : + { + "name" : "Maemo", + "version" : "undefined" + } + }, { "desc" : "MeeGo", "ua" : "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", @@ -320,7 +347,25 @@ "expect" : { "name" : "Firefox OS", - "version" : "undefined" + "version" : "14.0" + } + }, + { + "desc" : "Firefox OS on Tablet", + "ua" : "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", + "expect" : + { + "name" : "Firefox OS", + "version" : "26.0" + } + }, + { + "desc" : "Firefox OS on TV", + "ua" : "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", + "expect" : + { + "name" : "Firefox OS", + "version" : "44.0" } }, { @@ -683,6 +728,24 @@ "version" : "undefined" } }, + { + "desc" : "Mac OS X on x86, x86_64, or aarch64 using Firefox", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "Mac OS", + "version" : "x.y" + } + }, + { + "desc" : "Mac OS X on PowerPC using Firefox", + "ua" : "Mozilla/5.0 (Macintosh; PPC Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "Mac OS", + "version" : "x.y" + } + }, { "desc" : "Mac OS", "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36", From 1d3c98a10c23915046a362c4e3b3b503fb40d611 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 10 Apr 2021 21:36:44 +0700 Subject: [PATCH 104/121] Revert breaking fix #279 and release as 0.7.28 --- bower.json | 2 +- dist/ua-parser.min.js | 4 ++-- dist/ua-parser.pack.js | 4 ++-- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 11 ++++++----- test/browser-test.json | 12 ++++++------ 7 files changed, 19 insertions(+), 18 deletions(-) diff --git a/bower.json b/bower.json index 54662ef..6539b1b 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.27", + "version": "0.7.28", "authors": [ "Faisal Salman " ], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 89a39e6..9affb6b 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,9 @@ /*!@license - * UAParser.js v0.7.27 + * UAParser.js v0.7.28 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.27",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file +(function(window,undefined){"use strict";var LIBVERSION="0.7.28",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index 67612af..08dd52b 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,9 +1,9 @@ /*!@license - * UAParser.js v0.7.27 + * UAParser.js v0.7.28 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * * Copyright © 2012-2021 Faisal Salman * Licensed under MIT License */ -!function(r,b){"use strict";var u="function",e="undefined",c="object",a="string",i="model",s="name",o="type",n="vendor",t="version",l="architecture",d="console",w="mobile",m="tablet",p="smarttv",f="wearable",h={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return typeof i==a&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i==a?i.replace(/[^\d\.]/g,"").split(".")[0]:b},trim:function(i,s){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof s==e?i:i.substring(0,255)}},g={rgx:function(i,s){for(var e,o,r,a,n,t=0;t (http://faisalman.com)", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": [ diff --git a/src/ua-parser.js b/src/ua-parser.js index 2dbdf7e..ac7112d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ /*!@license - * UAParser.js v0.7.27 + * UAParser.js v0.7.28 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * @@ -16,7 +16,7 @@ ///////////// - var LIBVERSION = '0.7.27', + var LIBVERSION = '0.7.28', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', @@ -215,10 +215,11 @@ /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS ], [VERSION, [NAME, 'Chrome']], [ - /(?:edgios|edga|edg)\/([\w\.]+)/i // Microsoft Edge + /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge ], [VERSION, [NAME, 'Edge']], [ - /edge\/([\w\.]+)/i // Old Edge (Trident) - ], [[VERSION, mapper.str, maps.browser.oldEdge.version], [NAME, 'Edge']], [ + // breaking change (reserved for next major release): + ///edge\/([\w\.]+)/i // Old Edge (Trident) + //], [[VERSION, mapper.str, maps.browser.oldEdge.version], [NAME, 'Edge']], [ // Presto based /(opera\smini)\/([\w\.-]+)/i, // Opera Mini diff --git a/test/browser-test.json b/test/browser-test.json index 1947fe0..c3b70d0 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1154,8 +1154,8 @@ "expect" : { "name" : "Edge", - "version" : "0.1", - "major" : "0" + "version" : "12.0", + "major" : "12" } }, { @@ -1164,8 +1164,8 @@ "expect" : { "name" : "Edge", - "version" : "42", - "major" : "42" + "version" : "17.17134", + "major" : "17" } }, { @@ -1174,8 +1174,8 @@ "expect" : { "name" : "Edge", - "version" : "44", - "major" : "44" + "version" : "18.17763", + "major" : "18" } }, { From 36b2275add551510b859b289af639cc02bf98437 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 12:19:01 +0700 Subject: [PATCH 105/121] Improve detection rule for Mac on PowerPC --- src/ua-parser.js | 2 +- test/os-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index fc3df6e..0885ab2 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -701,7 +701,7 @@ /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ /(mac os x)\s?([\w\s\.]*)/i, - /(macintosh|mac(?=_powerpc) )(?!.+haiku)/i // Mac OS + /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ // Mobile OSes // Android/WebOS/Palm/QNX/Bada/RIM/Maemo/MeeGo/Contiki/Sailfish OS diff --git a/test/os-test.json b/test/os-test.json index 3b80025..be59b19 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -728,6 +728,15 @@ "version" : "undefined" } }, + { + "desc" : "Mac OS on PowerPC", + "ua" : "Mozilla/4.0 (compatible; MSIE 5.0b1; Mac_PowerPC)", + "expect" : + { + "name" : "Mac OS", + "version" : "undefined" + } + }, { "desc" : "Mac OS X on x86, x86_64, or aarch64 using Firefox", "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", From f715023f476f3026ef2fabbb2250e1df1d6ac0e3 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 12:24:34 +0700 Subject: [PATCH 106/121] Improve device detection: categorize PDA as mobile --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 0885ab2..cfc0861 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -659,7 +659,7 @@ ], [MODEL, [TYPE, TABLET]], [ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i, // Unidentifiable Tablet ], [[TYPE, TABLET]], [ - /(phone|mobile(?:[;\/]| safari))/i // Unidentifiable Mobile + /(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ /(android[\w\.\s\-]{0,9});.+buil/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']] diff --git a/test/device-test.json b/test/device-test.json index 41da99f..eab9070 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -2514,5 +2514,14 @@ "model": "undefined", "type": "smarttv" } + }, + { + "desc": "PDA with Windows CE", + "ua": "Mozilla/4.0 (PDA; Windows CE/1.0.1) NetFront/3.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } } ] From 559ecaacb6aa471f2cb5b88c10cfc5f6d64203d6 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 12:28:24 +0700 Subject: [PATCH 107/121] Improve browser detection: Netscape with version --- src/ua-parser.js | 2 +- test/browser-test.json | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index cfc0861..94d34fe 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -319,7 +319,7 @@ ], [NAME, VERSION], [ // Gecko based - /(navigator|netscape)\/([\w\.-]+)/i // Netscape + /(navigator|netscape\d?)\/([\w\.-]+)/i // Netscape ], [[NAME, 'Netscape'], VERSION], [ /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality ], [VERSION, [NAME, FIREFOX+' Reality']], [ diff --git a/test/browser-test.json b/test/browser-test.json index 7c1c8ff..c77e316 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -748,6 +748,16 @@ "major" : "8" } }, + { + "desc" : "Netscape 6", + "ua" : "Mozilla/5.0 (Windows; U; Win95; de-DE; rv:0.9.2) Gecko/20010726 Netscape6/6.1", + "expect" : + { + "name" : "Netscape", + "version" : "6.1", + "major" : "6" + } + }, { "desc" : "Nokia Browser", "ua" : "Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaN8-00/025.007; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.37 Mobile Safari/533.4 3gpp-gba", From c53a2a1f72e3b632bcfaafb757f074d8c6056cac Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 12:55:37 +0700 Subject: [PATCH 108/121] Improve os detection: Windows Mobile without version --- src/ua-parser.js | 4 ++-- test/os-test.json | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 94d34fe..8ce831f 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -690,8 +690,8 @@ /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ /(windows) nt 6\.2; (arm)/i, // Windows RT - /(windows phone(?: os)*)[\s\/]?([\d\.\s\w]*)/i, // Windows Phone - /(windows mobile|windows)[\s\/]?([ntce\d\.\s]+[\w\.]+)(?!.+xbox)/i + /(windows (?:phone(?: os)?|mobile))[\s\/]?([\d\.\s\w]*)/i, // Windows Phone + /(windows)[\s\/]?([ntce\d\.\s]+\w)(?!.+xbox)/i ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [ diff --git a/test/os-test.json b/test/os-test.json index be59b19..14590f3 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -107,6 +107,15 @@ "version" : "6.1" } }, + { + "desc" : "Windows Mobile", + "ua" : "Opera/9.80 (Windows Mobile; WCE; Opera Mobi/WMD-50433; U; en) Presto/2.4.13 Version/10.00", + "expect" : + { + "name" : "Windows Mobile", + "version" : "undefined" + } + }, { "desc" : "Windows Phone", "ua" : "Opera/9.80 (Windows Phone; Opera Mini/7.6.8/35.7518; U; ru) Presto/2.8.119 Version/11.10", @@ -140,7 +149,7 @@ "expect" : { "name" : "Windows", - "version" : "NT x.y" + "version" : "NT x" } }, { @@ -149,7 +158,7 @@ "expect" : { "name" : "Windows", - "version" : "NT x.y" + "version" : "NT x" } }, { From c05e4e837fe67a9d820cc9e7d5895c0e2ae216d8 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 13:11:25 +0700 Subject: [PATCH 109/121] Add new OS: HP-UX --- readme.md | 6 +++--- src/ua-parser.js | 2 +- test/os-test.json | 9 +++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 08102cb..806cf74 100644 --- a/readme.md +++ b/readme.md @@ -88,9 +88,9 @@ NetSurf, Presto, Tasman, Trident, w3m, WebKit # Possible 'os.name' AIX, Amiga OS, Android, Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, Contiki, Fedora, Firefox OS, FreeBSD, Debian, DragonFly, Fuchsia, Gentoo, GNU, -Haiku, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Maemo, Mageia, Mandriva, -MeeGo, Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, -PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, +Haiku, HP-UX, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Maemo, Mageia, +Mandriva, MeeGo, Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, +Palm, PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, RISC OS, Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, Unix, VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... diff --git a/src/ua-parser.js b/src/ua-parser.js index 8ce831f..b7a6925 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -749,7 +749,7 @@ ], [[NAME, 'Solaris'], VERSION], [ /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris /(aix) ((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX - /(plan 9|minix|beos|os\/2|amigaos|morphos|risc os|openvms|fuchsia)/i, // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia + /(plan 9|minix|beos|os\/2|amigaos|morphos|risc os|openvms|fuchsia|hp-ux)/i, // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia/HP-UX /(unix)\s?([\w\.]*)/i // UNIX ], [NAME, VERSION] ] diff --git a/test/os-test.json b/test/os-test.json index 14590f3..8ba0095 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -997,5 +997,14 @@ "name" : "", "version" : "" } + }, + { + "desc" : "HP-UX", + "ua" : "Mozilla/5.0 (X11; U; HP-UX 9000/785; es-ES; rv:1.0.1) Gecko/20020827 Netscape/7.0", + "expect" : + { + "name" : "HP-UX", + "version" : "undefined" + } } ] From 3792900410e11d0525709148931b29f9053d9406 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 13:46:06 +0700 Subject: [PATCH 110/121] Add new browsers: Obigo, UP.Browser --- readme.md | 6 +++--- src/ua-parser.js | 9 +++------ test/browser-test.json | 30 ++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index 806cf74..b03e7b8 100644 --- a/readme.md +++ b/readme.md @@ -43,12 +43,12 @@ Firefox [Reality], Flock, Flow, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceAp IceCat, IceDragon, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, Kindle, Klar, Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, -Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Oculus Browser, +Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Obigo, Oculus Browser, OmniWeb, Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, Safari, Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim, -SlimBrowser, Swiftfox, Tesla, Tizen Browser, UCBrowser, Vivaldi, Waterfox, WeChat, -Weibo, Yandex, baidu, iCab, w3m, Whale Browser... +SlimBrowser, Swiftfox, Tesla, Tizen Browser, UCBrowser, UP.Browser, Vivaldi, +Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m, Whale Browser... # 'browser.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index b7a6925..92c177b 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -333,12 +333,9 @@ /(mozilla)\/([\w\.]+)\s.+rv\:.+gecko\/\d+/i, // Mozilla // Other - /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i, - // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir - /(links) \(([\w\.]+)/i, // Links - /(gobrowser)\/?([\w\.]*)/i, // GoBrowser - /(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser - /(mosaic)[\/\s]([\w\.]+)/i // Mosaic + /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\s\.]?browser)[\/\s-]?v?([\w\.]+)/i, + // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser + /(links) \(([\w\.]+)/i // Links ], [NAME, VERSION] ], diff --git a/test/browser-test.json b/test/browser-test.json index c77e316..2f4c2e0 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -768,6 +768,26 @@ "major" : "7" } }, + { + "desc" : "Obigo", + "ua" : "LG-GS290/V100 Obigo/WAP2.0 Profile/MIDP-2.1 Configuration/CLDC-1.1", + "expect" : + { + "name" : "Obigo", + "version" : "WAP2.0", + "major" : "2" + } + }, + { + "desc" : "Obigo", + "ua" : "LG/KU990i/v10a Browser/Obigo-Q05A/3.6 MMS/LG-MMS-V1.0/1.2 Java/ASVM/1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1", + "expect" : + { + "name" : "Obigo", + "version" : "Q05A", + "major" : "05" + } + }, { "desc" : "Oculus Browser", "ua" : "Mozilla/5.0 (Linux; Android 7.0; SM-G920I Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/3.4.9 SamsungBrowser/4.0 Chrome/57.0.2987.146 Mobile VR Safari/537.36", @@ -1128,6 +1148,16 @@ "major" : "7" } }, + { + "desc" : "UPBrowser", + "ua" : "BenQ-CF61/1.00/WAP2.0/MIDP2.0/CLDC1.0 UP.Browser/6.3.0.4.c.1.102 (GUI) MMP/2.0", + "expect" : + { + "name" : "UP.Browser", + "version" : "6.3.0.4.c.1.102", + "major" : "6" + } + }, { "desc": "WeChat on iOS", "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 8_4_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12H321 MicroMessenger/6.3.6 NetType/WIFI Language/zh_CN", From 9bed2b143705d467398075304b4c8904be017817 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 15:16:28 +0700 Subject: [PATCH 111/121] Add new device vendor: Roku Source: https://github.com/WhichBrowser/Parser-PHP/blob/master/tests/data/television/roku.yaml --- readme.md | 2 +- src/ua-parser.js | 7 +++++-- test/device-test.json | 27 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index b03e7b8..bcd4d3b 100644 --- a/readme.md +++ b/readme.md @@ -64,7 +64,7 @@ console, mobile, tablet, smarttv, wearable, embedded Acer, Alcatel, Amazon, Apple, Archos, ASUS, AT&T, BenQ, BlackBerry, Dell, Essential, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, OPPO, Ouya, -Palm, Panasonic, Pebble, Polytron, Realme, RIM, Samsung, Sharp, Siemens, +Palm, Panasonic, Pebble, Polytron, Realme, RIM, Roku, Samsung, Sharp, Siemens, Sony[Ericsson], Sprint, Tesla, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... # 'device.model' determined dynamically diff --git a/src/ua-parser.js b/src/ua-parser.js index 92c177b..72fdc1c 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -90,8 +90,10 @@ return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split('.')[0] : undefined; }, trim = function (str, len) { - str = str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, EMPTY); - return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); + if (typeof(str) === STR_TYPE) { + str = str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, EMPTY); + return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); + } }; /////////////// @@ -623,6 +625,7 @@ ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ + /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ /\b(android tv|smart[-\s]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors diff --git a/test/device-test.json b/test/device-test.json index eab9070..8d83c6d 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -846,6 +846,33 @@ "type": "smarttv" } }, + { + "desc": "Roku", + "ua": "Mozilla/5.0 (Roku) AppleWebKit/537.36 (KHTML, like Gecko) Web/1.1 Safari/537.36", + "expect": { + "vendor": "Roku", + "model": "", + "type": "smarttv" + } + }, + { + "desc": "Roku", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 Roku/DVP-8.10 (468.10E04145A)", + "expect": { + "vendor": "Roku", + "model": "DVP-8.10", + "type": "smarttv" + } + }, + { + "desc": "Roku", + "ua": "Roku4640X/DVP-7.70 (297.70E04154A)", + "expect": { + "vendor": "Roku", + "model": "DVP-7.70", + "type": "smarttv" + } + }, { "desc": "Kindle Fire HD", "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true", From ca83d4c9c3bdb3b9c44db8cadf1844e8b3d59bda Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 16 Apr 2021 07:11:23 +0700 Subject: [PATCH 112/121] Refine some OS detection Source: - https://www.zytrax.com/tech/web/browser_ids.htm - https://developers.whatismybrowser.com/useragents/explore/operating_system_name/ --- src/ua-parser.js | 18 ++---- test/os-test.json | 162 ++++++++++++++++++++++++++++++---------------- 2 files changed, 115 insertions(+), 65 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 72fdc1c..53a5cf5 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -704,8 +704,8 @@ /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ - // Mobile OSes // Android/WebOS/Palm/QNX/Bada/RIM/Maemo/MeeGo/Contiki/Sailfish OS - /(android|webos|palm os|qnx|bada|rim tablet os|maemo|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, + // Mobile OSes // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS + /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[\/\s-]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS /\((series40);/i // Series 40 @@ -730,26 +730,22 @@ /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation /(xbox);\s+xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) - // GNU/Linux based + // Other + /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm /(mint)[\/\s\(\)]?(\w*)/i, // Mint /(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux - /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus|raspbian)(?: gnu\/linux)?(?: linux)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, - // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware - // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus + /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki)(?: gnu\/linux)?(?: enterprise)?(?:[\s-]linux)?(?:-gnu)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, + // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki /(hurd|linux)\s?([\w\.]*)/i, // Hurd/Linux /(gnu)\s?([\w\.]*)/i, // GNU - - // BSD based /\b([frentopc-]{0,4}bsd|dragonfly)\s?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly /(haiku)\s(\w+)/i // Haiku ], [NAME, VERSION], [ - - // Other /(sunos)\s?([\w\.\d]*)/i // Solaris ], [[NAME, 'Solaris'], VERSION], [ /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris /(aix) ((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX - /(plan 9|minix|beos|os\/2|amigaos|morphos|risc os|openvms|fuchsia|hp-ux)/i, // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia/HP-UX + /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX /(unix)\s?([\w\.]*)/i // UNIX ], [NAME, VERSION] ] diff --git a/test/os-test.json b/test/os-test.json index 8ba0095..d614487 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -667,11 +667,11 @@ }, { "desc" : "Solaris", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.7) Gecko/20070606", "expect" : { - "name" : "", - "version" : "" + "name" : "Solaris", + "version" : "sun4u" } }, { @@ -703,11 +703,11 @@ }, { "desc" : "DragonFly", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; DragonFly i386; de; rv:1.9.1) Gecko/20090720 Firefox/3.5.1", "expect" : { - "name" : "", - "version" : "" + "name" : "DragonFly", + "version" : "undefined" } }, { @@ -847,137 +847,173 @@ }, { "desc" : "AIX", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; AIX 000138384C00; en-US; rv:1.0.1) Gecko/20030213 Netscape/7.0", "expect" : { - "name" : "", - "version" : "" + "name" : "AIX", + "version" : "undefined" } }, { "desc" : "Plan9", - "ua" : "", + "ua" : "NCSA_Mosaic/5.0 (X11;Plan 9 4.0)", "expect" : { - "name" : "", - "version" : "" + "name" : "Plan 9", + "version" : "4.0" } }, { "desc" : "Minix", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; Original ; Minix 3.3 ; rv:3.0)", "expect" : { - "name" : "", - "version" : "" + "name" : "Minix", + "version" : "3.3" } }, { "desc" : "BeOS", - "ua" : "", + "ua" : "Mozilla/5.0 (BeOS; U; BeOS BePC; en-US; rv:1.8.1.8pre) Gecko/20070926 SeaMonkey/1.1.5pre", "expect" : { - "name" : "", - "version" : "" + "name" : "BeOS", + "version" : "undefined" } }, { "desc" : "OS/2", - "ua" : "", + "ua" : "Links (2.1pre14; OS/2 1 i386; 80x33)", "expect" : { - "name" : "", - "version" : "" + "name" : "OS/2", + "version" : "undefined" } }, { "desc" : "AmigaOS", - "ua" : "", + "ua" : "Mozilla/4.0 (compatible; AWEB 3.4 SE; AmigaOS)", "expect" : { - "name" : "", - "version" : "" + "name" : "AmigaOS", + "version" : "undefined" } }, { "desc" : "MorphOS", - "ua" : "", + "ua" : "AmigaVoyager/3.4.4 (MorphOS/PPC native)", "expect" : { - "name" : "", - "version" : "" + "name" : "MorphOS", + "version" : "undefined" } }, { "desc" : "UNIX", - "ua" : "", + "ua" : "Surf/0.4.1 (X11; U; Unix; en-US) AppleWebKit/531.2+ Compatible (Safari)", "expect" : { - "name" : "", - "version" : "" + "name" : "Unix", + "version" : "undefined" } }, { "desc" : "Joli", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; Jolicloud Linux i686) AppleWebKit/537.6 (KHTML, like Gecko) Joli OS/1.2 Chromium/23.0.1240.0 Chrome/23.0.1240.0 Safari/537.6", "expect" : { - "name" : "", - "version" : "" + "name" : "Joli", + "version" : "1.2" } }, { "desc" : "CentOS", - "ua" : "", + "ua" : "Konqueror/15.13 (CentOS Linux 7.4; cs-CZ;)", "expect" : { - "name" : "", - "version" : "" + "name" : "CentOS", + "version" : "7.4" } }, { "desc" : "PCLinuxOS", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101209 PCLinuxOS/1.9.2.13-1pclos2010 (2010) Firefox/3.6.13", "expect" : { - "name" : "", - "version" : "" + "name" : "PCLinuxOS", + "version" : "1.9.2.13-1pclos2010" } }, { "desc" : "RedHat", - "ua" : "", + "ua" : "Mozilla/5.0 (compatible; Konqueror/4.3; Linux) KHTML/4.3.4 (like Gecko) Red Hat Enterprise Linux/4.3.4-11.el6_1.4", "expect" : { - "name" : "", - "version" : "" + "name" : "Red Hat", + "version" : "4.3.4-11.el6_1.4" + } + }, + { + "desc" : "RedHat", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.13pre) Gecko/20070717 Red Hat/1.0.9-4.el4 SeaMonkey/1.0.9", + "expect" : + { + "name" : "Red Hat", + "version" : "1.0.9-4.el4" + } + }, + { + "desc" : "RedHat", + "ua" : "iTunes/4.7.1 (Linux; N; Red Hat; x86_64-linux; EN; utf8) SqueezeCenter, Squeezebox Server, Logitech Media Server/7.9.1/1522157629", + "expect" : + { + "name" : "Red Hat", + "version" : "undefined" + } + }, + { + "desc" : "RedHat", + "ua" : "curl/7.20.0 (x86_64-redhat-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5", + "expect" : + { + "name" : "redhat", + "version" : "undefined" + } + }, + { + "desc" : "RISC OS", + "ua" : "Mozilla/1.10 [en] (Compatible; RISC OS 3.70; Oregano 1.10)", + "expect" : + { + "name" : "RISC OS", + "version" : "3.70" } }, { "desc" : "Zenwalk", - "ua" : "", + "ua" : "Flock/2.16 (Zenwalk 7.3; es_PR;)", "expect" : { - "name" : "", - "version" : "" + "name" : "Zenwalk", + "version" : "7.3" } }, { "desc" : "Hurd", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; Hurd 0.9 i386; en-US) libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/3.7.0 Safari/696.96", "expect" : { - "name" : "", - "version" : "" + "name" : "Hurd", + "version" : "0.9" } }, { "desc" : "Linux", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36", "expect" : { - "name" : "", - "version" : "" + "name" : "Linux", + "version" : "x86_64" } }, { @@ -991,11 +1027,11 @@ }, { "desc" : "Palm OS", - "ua" : "", + "ua" : "Mozilla/4.76 [en] (PalmOS; U; WebPro3.0; Palm-Arz1)", "expect" : { - "name" : "", - "version" : "" + "name" : "Palm", + "version" : "undefined" } }, { @@ -1006,5 +1042,23 @@ "name" : "HP-UX", "version" : "undefined" } + }, + { + "desc" : "Contiki", + "ua" : "Contiki/1.0 (Commodore 64; http://dunkels.com/adam/contiki/)", + "expect" : + { + "name" : "Contiki", + "version" : "1.0" + } + }, + { + "desc" : "Linpus", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9b5pre) Gecko/2008032619 Linpus/3.0-0.49", + "expect" : + { + "name" : "Linpus", + "version" : "3.0-0.49" + } } ] From ca644313d629896aa857a1c412753d06e28cb718 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 16 Apr 2021 07:15:50 +0700 Subject: [PATCH 113/121] Remove oldEdge map --- src/ua-parser.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 53a5cf5..8b8986b 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -184,15 +184,6 @@ '2.0.4' : '/419', '?' : '/' }, - oldEdgeMap = { - '0.1' : '12.', - '21' : '13.', - '31' : '14.', - '39' : '15.', - '41' : '16.', - '42' : '17.', - '44' : '18.' - }, windowsVersionMap = { 'ME' : '4.90', 'NT 3.11' : 'NT3.51', @@ -219,9 +210,6 @@ ], [VERSION, [NAME, 'Chrome']], [ /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge ], [VERSION, [NAME, 'Edge']], [ - // breaking change (reserved for next major release): - ///edge\/([\w\.]+)/i // Old Edge (Trident) - //], [[VERSION, mapper.str, maps.browser.oldEdge.version], [NAME, 'Edge']], [ // Presto based /(opera mini)\/([\w\.-]+)/i, // Opera Mini From 8e55e001779e136271cdf8b4ed977868e32e84ec Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 16 Apr 2021 23:02:11 +0700 Subject: [PATCH 114/121] Replace `\s` with space, saving ~0,3KB --- dist/ua-parser.min.js | 13 +-- dist/ua-parser.pack.js | 13 +-- src/ua-parser.js | 230 ++++++++++++++++++++--------------------- 3 files changed, 123 insertions(+), 133 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index f5421eb..14b5e8c 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,4 @@ -/*!@license - * UAParser.js v0.7.28 - * Lightweight JavaScript-based User-Agent string parser - * https://github.com/faisalman/ua-parser-js - * - * Copyright © 2012-2021 Faisal Salman - * Licensed under MIT License - */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.28",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); +/* UAParser.js v0.7.28 + Copyright © 2012-2021 Faisal Salman + MIT License */ +(function(window,undefined){"use strict";var LIBVERSION="0.7.28",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i in arr){enums[arr[i].toUpperCase()]=arr[i]}return enums},has=function(str1,str2){return typeof str1===STR_TYPE?lowerize(str2).indexOf(lowerize(str1))!==-1:false},lowerize=function(str){return str.toLowerCase()},majorize=function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,EMPTY).split(".")[0]:undefined},trim=function(str,len){if(typeof str===STR_TYPE){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,EMPTY);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);UAParser.CPU=enumerize([ARCHITECTURE]);UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]);UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define===FUNC_TYPE&&define.amd){define(function(){return UAParser})}else if(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(ua){parser.setUA(ua);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index c12e548..34c92c5 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,9 +1,4 @@ -/*!@license - * UAParser.js v0.7.28 - * Lightweight JavaScript-based User-Agent string parser - * https://github.com/faisalman/ua-parser-js - * - * Copyright © 2012-2021 Faisal Salman - * Licensed under MIT License - */ -!function(r,b){"use strict";var u="function",e="undefined",c="object",a="string",i="model",s="name",o="type",n="vendor",t="version",l="architecture",w="console",d="mobile",m="tablet",p="smarttv",f="wearable",h="embedded",g={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return typeof i==a&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i==a?i.replace(/[^\d\.]/g,"").split(".")[0]:b},trim:function(i,s){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof s==e?i:i.substring(0,255)}},v={rgx:function(i,s){for(var e,o,r,a,n,t=0;t + MIT License */ +!function(r,d){"use strict";function i(i){var e,o={};for(e in i)o[i[e].toUpperCase()]=i[e];return o}function t(i,e){return typeof i==w&&-1!==B(e).indexOf(B(i))}function n(i,e){if(typeof i==w)return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof e==b?i:i.substring(0,255)}function s(i,e){for(var o,a,r,t,n,s=0;s= 8.0 + /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0 ], [VERSION, [NAME, OPERA+' Mini']], [ /\bopr\/([\w\.]+)/i // Opera Webkit ], [VERSION, [NAME, OPERA]], [ // Mixed /(kindle)\/([\w\.]+)/i, // Kindle - /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer + /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer // Trident based - /(avant |iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser - /(ba?idubrowser)[\/\s]?([\w\.]+)/i, // Baidu Browser + /(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser + /(ba?idubrowser)[\/ ]?([\w\.]+)/i, // Baidu Browser /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon - /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([\w\.-]+)/i, + /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ /(weibo)__([\d\.]+)/i // Weibo ], [NAME, VERSION], [ - /(?:\buc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser + /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser ], [VERSION, [NAME, 'UC'+BROWSER]], [ /\bqbcore\/([\w\.]+)/i // WeChat Desktop for Windows Built-in Browser ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [ @@ -242,7 +242,7 @@ ], [VERSION, [NAME, 'WeChat']], [ /konqueror\/([\w\.]+)/i // Konqueror ], [VERSION, [NAME, 'Konqueror']], [ - /trident.+rv[:\s]([\w\.]{1,9})\b.+like gecko/i // IE11 + /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11 ], [VERSION, [NAME, 'IE']], [ /yabrowser\/([\w\.]+)/i // Yandex ], [VERSION, [NAME, 'Yandex']], [ @@ -260,7 +260,7 @@ ], [VERSION, [NAME, OPERA+' Coast']], [ /miuibrowser\/([\w\.]+)/i // MIUI Browser ], [VERSION, [NAME, 'MIUI '+BROWSER]], [ - /fxios\/([\w\.-]+)/i // Firefox for iOS + /fxios\/([-\w\.]+)/i // Firefox for iOS ], [VERSION, [NAME, FIREFOX]], [ /\bqihu|(qi?ho?o?|360)browser/i // 360 ], [[NAME, '360 '+BROWSER]], [ @@ -269,10 +269,10 @@ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ /(electron)\/([\w\.]+) safari/i, // Electron-based App - /(tesla)(?:\sqtcarbrowser|\/(20\d\d\.[\w\.-]+))/i, // Tesla - /m?(qqbrowser|baiduboxapp|2345Explorer)[\/\s]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser + /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla + /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser ], [NAME, VERSION], [ - /(metasr)[\/\s]?([\w\.]+)/i, // SouGouBrowser + /(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser /(lbbrowser)/i // LieBao Browser ], [NAME], [ @@ -281,49 +281,49 @@ ], [[NAME, 'Facebook'], VERSION], [ /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android - /(chromium|instagram)[\/\s]([\w\.-]+)/i // Chromium/Instagram + /(chromium|instagram)[\/ ]([-\w\.]+)/i // Chromium/Instagram ], [NAME, VERSION], [ - /\bgsa\/([\w\.]+)\s.*safari\//i // Google Search Appliance on iOS + /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, 'GSA']], [ - /headlesschrome(?:\/([\w\.]+)|\s)/i // Chrome Headless + /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless ], [VERSION, [NAME, CHROME+' Headless']], [ - /\swv\).+(chrome)\/([\w\.]+)/i // Chrome WebView + / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView ], [[NAME, CHROME+' WebView'], VERSION], [ - /droid.+\sversion\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser + /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser ], [VERSION, [NAME, 'Android '+BROWSER]], [ - /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia + /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [NAME, VERSION], [ - /version\/([\w\.]+)\s.*mobile\/\w+\s(safari)/i // Mobile Safari + /version\/([\w\.]+) .*mobile\/\w+ (safari)/i // Mobile Safari ], [VERSION, [NAME, 'Mobile Safari']], [ - /version\/([\w\.]+)\s.*(mobile\s?safari|safari)/i // Safari & Safari Mobile + /version\/([\w\.]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile ], [VERSION, NAME], [ - /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 + /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 ], [NAME, [VERSION, strMapper, oldSafariMap]], [ /(webkit|khtml)\/([\w\.]+)/i ], [NAME, VERSION], [ // Gecko based - /(navigator|netscape\d?)\/([\w\.-]+)/i // Netscape + /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape ], [[NAME, 'Netscape'], VERSION], [ /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality ], [VERSION, [NAME, FIREFOX+' Reality']], [ /ekiohf.+(flow)\/([\w\.]+)/i, // Flow /(swiftfox)/i, // Swiftfox - /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/\s]?([\w\.\+]+)/i, + /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i, // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar - /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i, + /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i, // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix /(firefox)\/([\w\.]+)/i, // Other Firefox-based - /(mozilla)\/([\w\.]+)\s.+rv\:.+gecko\/\d+/i, // Mozilla + /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla // Other - /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\s\.]?browser)[\/\s-]?v?([\w\.]+)/i, + /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser /(links) \(([\w\.]+)/i // Links ], [NAME, VERSION] @@ -331,7 +331,7 @@ cpu : [[ - /(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\)]/i // AMD64 (x64) + /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i // AMD64 (x64) ], [[ARCHITECTURE, 'amd64']], [ /(ia32(?=;))/i // IA32 (quicktime) @@ -347,10 +347,10 @@ ], [[ARCHITECTURE, 'armhf']], [ // PocketPC mistakenly identified as PowerPC - /windows\s(ce|mobile); ppc;/i + /windows (ce|mobile); ppc;/i ], [[ARCHITECTURE, 'arm']], [ - /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC + /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [ /(sun4\w)[;\)]/i // SPARC @@ -372,14 +372,14 @@ /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [ /\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i, - /samsung[\s-]([\w-]+)/i, + /samsung[- ]([-\w]+)/i, /sec-(sgh\w+)/i ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [ // Apple - /\((ip(?:hone|od)[\s\w]*);/i // iPod/iPhone + /\((ip(?:hone|od)[\w ]*);/i // iPod/iPhone ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [ - /\((ipad);[\w\s\),;-]+apple/i, // iPad + /\((ipad);[-\w\),; ]+apple/i, // iPad /applecoremedia\/[\w\.]+ \((ipad)/i, /\b(ipad)\d\d?,\d\d?[;\]].+ios/i ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ @@ -387,19 +387,19 @@ // Huawei /\b((?:agr|ags[23]|bah2?|sht?)-a?[lw]\d{2})/i, ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ - /huawei([\w\s-]+)[;\)]/i, + /huawei([-\w ]+)[;\)]/i, /\b(nexus 6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, - /\b(\w{2,4}-[atu][ln][01259][019])[;\)\s]/i + /\b(\w{2,4}-[atu][ln][01259][019])[;\) ]/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi - /\b(poco[\s\w]+)(?: bui|\))/i, // Xiaomi POCO - /\b;\s(\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models - /\b(hm[\s\-_]?note?[\s_]?(?:\d\w)?) bui/i, // Xiaomi Hongmi - /\b(redmi[\s\-_]?(?:note|k)?[\w\s_]+)(?: bui|\))/i, // Xiaomi Redmi - /\b(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?) bui/i // Xiaomi Mi + /\b(poco[\w ]+)(?: bui|\))/i, // Xiaomi POCO + /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models + /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi + /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi + /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte)?[_ ]?(?:\d?\w?)[_ ]?(?:plus)?) bui/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ - /\b(mi[\s\-_]?(?:pad)(?:[\w\s_]+))(?: bui|\))/i // Mi Pad tablets + /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ // OPPO @@ -417,48 +417,48 @@ ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [ // Motorola - /\b(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w\s]+build\//i, - /\bmot(?:orola)?[\s-](\w*)/i, - /((?:moto[\s\w\(\)]+|xt\d{3,4}|nexus\s6)(?= bui|\)))/i + /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i, + /\bmot(?:orola)?[- ](\w*)/i, + /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [ - /\b(mz60\d|xoom[\s2]{0,2}) build\//i + /\b(mz60\d|xoom[2 ]{0,2}) build\//i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [ // LG - /((?=lg)?[vl]k\-?\d{3})\sbui|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4})/i + /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ - /(lm-?f100[nv]?|nexus\s[45])/i, - /\blg[e;\s\/-]+((?!browser|netcast)\w+)/i, - /\blg(\-?[\d\w]+)\sbui/i + /(lm-?f100[nv]?|nexus [45])/i, + /\blg[-e;\/ ]+((?!browser|netcast)\w+)/i, + /\blg(\-?[\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ // Lenovo - /(ideatab[\w\-\s]+)/i, - /lenovo\s?(s[56]000[\w-]+|tab(?:[\s\w]+)|yt[\d\w-]{6}|tb[\d\w-]{6})/i + /(ideatab[-\w ]+)/i, + /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ // Nokia /(?:maemo|nokia).*(n900|lumia \d+)/i, - /nokia[\s_-]?([\w\.-]*)/i + /nokia[-_ ]?([-\w\.]*)/i ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ // Google /(pixel c)\b/i // Google Pixel C ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [ - /droid.+; (pixel[\s\daxl]{0,6})(?: bui|\))/i // Google Pixel + /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ // Sony - /droid.+\s([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i + /droid.+ ([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ /sony tablet [ps]/i, /\b(?:sony)?sgp\w+(?: bui|\))/i ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [ // OnePlus - /\s(kb2005|in20[12]5|be20[12][59])\b/i, + / (kb2005|in20[12]5|be20[12][59])\b/i, /\ba000(1) bui/i, - /oneplus (a\d{4})[\s)]/i + /oneplus (a\d{4})[) ]/i ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ // Amazon @@ -470,26 +470,26 @@ ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [ // BlackBerry - /(playbook);[\w\s\),;-]+(rim)/i // BlackBerry PlayBook + /(playbook);[-\w\),; ]+(rim)/i // BlackBerry PlayBook ], [MODEL, VENDOR, [TYPE, TABLET]], [ /\b((?:bb[a-f]|st[hv])100-\d)/i, - /\(bb10;\s(\w+)/i // BlackBerry 10 + /\(bb10; (\w+)/i // BlackBerry 10 ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [ // Asus - /(?:\b|asus_)(transfo[prime\s]{4,10}\s\w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i + /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [ - /\s(z[es]6[027][01][km][ls]|zenfone \d\w?)\b/i + / (z[es]6[027][01][km][ls]|zenfone \d\w?)\b/i ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [ // HTC /(nexus 9)/i // HTC Nexus 9 ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ - /(htc)[;_\s-]{1,2}([\w\s]+(?=\)| bui)|\w+)/i, // HTC + /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, // HTC // ZTE /(zte)-(\w*)/i, - /(alcatel|geeksphone|nexian|panasonic|sony)[_\s-]?([\w-]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony + /(alcatel|geeksphone|nexian|panasonic|sony)[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ // Acer @@ -498,34 +498,34 @@ // Meizu /droid.+; (m[1-5] note) bui/i, - /\bmz-([\w-]{2,})/i + /\bmz-([-\w]{2,})/i ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ // MIXED - /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[\s_-]?([\w-]*)/i, + /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron - /(hp)\s([\w\s]+\w)/i, // HP iPAQ + /(hp) ([\w ]+\w)/i, // HP iPAQ /(asus)-?(\w+)/i, // Asus - /(microsoft); (lumia[\s\w]+)/i, // Microsoft Lumia - /(lenovo)[_\s-]?([\w-]+)/i, // Lenovo + /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia + /(lenovo)[-_ ]?([-\w]+)/i, // Lenovo /(jolla)/i, // Jolla - /(oppo)\s?([\w\s]+)\sbui/i // OPPO + /(oppo) ?([\w ]+) bui/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(archos) (gamepad2?)/i, // Archos /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(kindle)\/([\w\.]+)/i, // Kindle - /(nook)[\w\s]+build\/(\w+)/i, // Nook - /(dell) (strea[kpr\s\d]*[\dko])/i, // Dell Streak - /(le[\s\-]+pan)[\s\-]+(\w{1,9})\sbui/i, // Le Pan Tablets - /(trinity)[\-\s]*(t\d{3})\sbui/i, // Trinity Tablets - /(gigaset)[\s\-]+(q\w{1,9})\sbui/i, // Gigaset Tablets - /(vodafone)\s([\w\s]+)(?:\)|\sbui)/i // Vodafone + /(nook)[\w ]+build\/(\w+)/i, // Nook + /(dell) (strea[kpr\d ]*[\dko])/i, // Dell Streak + /(le[- ]+pan)[- ]+(\w{1,9}) bui/i, // Le Pan Tablets + /(trinity)[- ]*(t\d{3}) bui/i, // Trinity Tablets + /(gigaset)[- ]+(q\w{1,9}) bui/i, // Gigaset Tablets + /(vodafone) ([\w ]+)(?:\)| bui)/i // Vodafone ], [VENDOR, MODEL, [TYPE, TABLET]], [ /(surface duo)/i // Surface Duo ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ - /droid\s[\d\.]+; (fp\du?) b/i // Fairphone + /droid [\d\.]+; (fp\du?) b/i // Fairphone ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ /(u304aa)/i // AT&T ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ @@ -533,11 +533,11 @@ ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ /\b(rct\w+) b/i // RCA Tablets ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [ - /\b(venue[\d\s]{2,7}) b/i // Dell Venue Tablets + /\b(venue[\d ]{2,7}) b/i // Dell Venue Tablets ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ /\b(q(?:mv|ta)\w+) b/i // Verizon Tablet ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ - /\b(?:barnes[&\s]+noble |bn[rt])([\w\s\+]*) b/i // Barnes & Noble Tablet + /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i // Barnes & Noble Tablet ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [ /\b(tm\d{3}\w+) b/i ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [ @@ -552,7 +552,7 @@ /\b((zeki)?tb.*\b) b/i // Zeki Tablets ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ /\b([yr]\d{2}) b/i, - /\b(dragon[\-\s]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet + /\b(dragon[- ]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [ /\b(ns-?\w{0,9}) b/i // Insignia Tablets ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [ @@ -562,15 +562,15 @@ ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ /\b(lvtel\-)?(v1[12]) b/i // LvTel Phones ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [ - /\b(ph-1)\s/i // Essential PH-1 + /\b(ph-1) /i // Essential PH-1 ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ /\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [ - /\b(trio[\s\w\-\.]+) b/i // MachSpeed Tablets + /\b(trio[-\w\. ]+) b/i // MachSpeed Tablets ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [ /\btu_(1491) b/i // Rotor Tablets ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [ - /(shield[\w\s]+) b/i // Nvidia Shield Tablets + /(shield[\w ]+) b/i // Nvidia Shield Tablets ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [ /(sprint) (\w+)/i // Sprint Phones ], [VENDOR, MODEL, [TYPE, MOBILE]], [ @@ -592,7 +592,7 @@ ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ /(playstation [345portablevi]+)/i // Playstation ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [ - /\b(xbox(?: one)?(?!; xbox))[\s\);]/i // Microsoft Xbox + /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [ /////////////////// @@ -605,7 +605,7 @@ ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ /(?:nux; netcast.+smarttv|lg netcast\.tv-201\d)/i, // LG SmartTV ], [[VENDOR, LG], [TYPE, SMARTTV]], [ - /(apple)\s?tv/i // Apple TV + /(apple) ?tv/i // Apple TV ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ /crkey/i // Google Chromecast ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ @@ -614,9 +614,9 @@ /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku - /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices + /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ - /\b(android tv|smart[-\s]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors + /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors ], [[TYPE, SMARTTV]], [ /////////////////// @@ -634,22 +634,22 @@ // EMBEDDED /////////////////// - /(tesla)(?: qtcarbrowser|\/[\w\.-]+)/i // Tesla + /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla ], [VENDOR, [TYPE, EMBEDDED]], [ //////////////////// // MIXED (GENERIC) /////////////////// - /droid .+?;\s([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors + /droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors ], [MODEL, [TYPE, MOBILE]], [ - /droid .+?;\s([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors + /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors ], [MODEL, [TYPE, TABLET]], [ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i, // Unidentifiable Tablet ], [[TYPE, TABLET]], [ /(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ - /(android[\w\.\s\-]{0,9});.+buil/i // Generic Android Device + /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']] ], @@ -664,8 +664,8 @@ /(presto)\/([\w\.]+)/i, // Presto /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna /ekioh(flow)\/([\w\.]+)/i, // Flow - /(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i, // KHTML/Tasman/Links - /(icab)[\/\s]([23]\.[\d\.]+)/i // iCab + /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links + /(icab)[\/ ]([23]\.[\d\.]+)/i // iCab ], [NAME, VERSION], [ /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko @@ -678,31 +678,31 @@ /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ /(windows) nt 6\.2; (arm)/i, // Windows RT - /(windows (?:phone(?: os)?|mobile))[\s\/]?([\d\.\s\w]*)/i, // Windows Phone - /(windows)[\s\/]?([ntce\d\.\s]+\w)(?!.+xbox)/i + /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, // Windows Phone + /(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [ // iOS/macOS - /ip[honead]{2,4}\b(?:.*os ([\w]+) like\smac|; opera)/i, // iOS + /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ - /(mac os x)\s?([\w\s\.]*)/i, - /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS + /(mac os x) ?([\w\. ]*)/i, + /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ // Mobile OSes // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS - /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[\/\s-]?([\w\.]*)/i, + /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry - /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS + /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS /\((series40);/i // Series 40 ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 ], [VERSION, [NAME, BLACKBERRY]], [ - /(?:symbian\s?os|symbos|s60(?=;)|series60)[\/\s-]?([\w\.]*)/i // Symbian + /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ - /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w\s]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS + /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS ], [VERSION, [NAME, FIREFOX+' OS']], [ /web0s;.+rt(tv)/i, /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS @@ -711,30 +711,30 @@ // Google Chromecast /crkey\/([\d\.]+)/i // Google Chromecast ], [VERSION, [NAME, CHROME+'cast']], [ - /(cros) [\w]+\s([\w\.]+\w)/i // Chromium OS + /(cros) [\w]+ ([\w\.]+\w)/i // Chromium OS ], [[NAME, 'Chromium OS'], VERSION],[ // Console /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation - /(xbox);\s+xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) + /(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) // Other /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm - /(mint)[\/\s\(\)]?(\w*)/i, // Mint - /(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux - /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki)(?: gnu\/linux)?(?: enterprise)?(?:[\s-]linux)?(?:-gnu)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, + /(mint)[\/\(\) ]?(\w*)/i, // Mint + /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux + /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i, // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki - /(hurd|linux)\s?([\w\.]*)/i, // Hurd/Linux - /(gnu)\s?([\w\.]*)/i, // GNU - /\b([frentopc-]{0,4}bsd|dragonfly)\s?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly - /(haiku)\s(\w+)/i // Haiku + /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux + /(gnu) ?([\w\.]*)/i, // GNU + /\b([-frentopc]{0,4}bsd|dragonfly) ?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly + /(haiku) (\w+)/i // Haiku ], [NAME, VERSION], [ - /(sunos)\s?([\w\.\d]*)/i // Solaris + /(sunos) ?([\w\.\d]*)/i // Solaris ], [[NAME, 'Solaris'], VERSION], [ - /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris - /(aix) ((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX + /((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris + /(aix) ((\d)(?=\.|\)| )[\w\.])*/i, // AIX /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX - /(unix)\s?([\w\.]*)/i // UNIX + /(unix) ?([\w\.]*)/i // UNIX ], [NAME, VERSION] ] }; From 7b3aa9fc15ad70ac33295c797971cbe5046222a6 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 18 Apr 2021 14:00:18 +0700 Subject: [PATCH 115/121] ES3 compat-fix: remove trailing comma --- .jshintrc | 3 +++ src/ua-parser.js | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 .jshintrc diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..5798043 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,3 @@ +{ + "esversion": 3 +} \ No newline at end of file diff --git a/src/ua-parser.js b/src/ua-parser.js index 5b3b5dd..8c7186b 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -214,7 +214,7 @@ // Presto based /(opera mini)\/([-\w\.]+)/i, // Opera Mini /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, // Opera Mobi/Tablet - /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i, // Opera + /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i // Opera ], [NAME, VERSION], [ /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0 ], [VERSION, [NAME, OPERA+' Mini']], [ @@ -385,7 +385,7 @@ ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ // Huawei - /\b((?:agr|ags[23]|bah2?|sht?)-a?[lw]\d{2})/i, + /\b((?:agr|ags[23]|bah2?|sht?)-a?[lw]\d{2})/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /huawei([-\w ]+)[;\)]/i, /\b(nexus 6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, @@ -603,7 +603,7 @@ ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ - /(?:nux; netcast.+smarttv|lg netcast\.tv-201\d)/i, // LG SmartTV + /(?:nux; netcast.+smarttv|lg netcast\.tv-201\d)/i // LG SmartTV ], [[VENDOR, LG], [TYPE, SMARTTV]], [ /(apple) ?tv/i // Apple TV ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ @@ -645,7 +645,7 @@ ], [MODEL, [TYPE, MOBILE]], [ /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors ], [MODEL, [TYPE, TABLET]], [ - /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i, // Unidentifiable Tablet + /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet ], [[TYPE, TABLET]], [ /(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ From 837042a3e8c65628349ed40ec74e4ec6c2a9ae5b Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 22 Apr 2021 07:00:28 +0700 Subject: [PATCH 116/121] Improve device detection: Huawei, Xiaomi, Realme, LG, OnePlus, ASUS, ZTE, Fairphone --- src/ua-parser.js | 28 +- test/device-test.json | 1152 +++++++++++++++++++++++++---------------- 2 files changed, 733 insertions(+), 447 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 8c7186b..5a5c28f 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -385,21 +385,20 @@ ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ // Huawei - /\b((?:agr|ags[23]|bah2?|sht?)-a?[lw]\d{2})/i + /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ - /huawei([-\w ]+)[;\)]/i, - /\b(nexus 6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, - /\b(\w{2,4}-[atu][ln][01259][019])[;\) ]/i + /(?:huawei|honor)([-\w ]+)[;\)]/i, + /\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi /\b(poco[\w ]+)(?: bui|\))/i, // Xiaomi POCO /\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(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte)?[_ ]?(?:\d?\w?)[_ ]?(?:plus)?) bui/i // Xiaomi Mi + /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ - /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets + /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ // OPPO @@ -413,7 +412,7 @@ ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ // Realme - /\b(rmx[12]\d{3})(?: bui|;)/i + /\b(rmx[12]\d{3})(?: bui|;|\))/i ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [ // Motorola @@ -427,9 +426,9 @@ // LG /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ - /(lm-?f100[nv]?|nexus [45])/i, + /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, /\blg[-e;\/ ]+((?!browser|netcast)\w+)/i, - /\blg(\-?[\d\w]+) bui/i + /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ // Lenovo @@ -457,8 +456,7 @@ // OnePlus / (kb2005|in20[12]5|be20[12][59])\b/i, - /\ba000(1) bui/i, - /oneplus (a\d{4})[) ]/i + /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ // Amazon @@ -479,7 +477,7 @@ // Asus /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [ - / (z[es]6[027][01][km][ls]|zenfone \d\w?)\b/i + / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [ // HTC @@ -488,7 +486,7 @@ /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, // HTC // ZTE - /(zte)-(\w*)/i, + /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i, /(alcatel|geeksphone|nexian|panasonic|sony)[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ @@ -525,7 +523,7 @@ /(surface duo)/i // Surface Duo ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ - /droid [\d\.]+; (fp\du?) b/i // Fairphone + /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ /(u304aa)/i // AT&T ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ diff --git a/test/device-test.json b/test/device-test.json index 8d83c6d..c8bd7c4 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -97,6 +97,15 @@ "type": "mobile" } }, + { + "desc": "ASUS Zenfone Max Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; ZB602KL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZB602KL", + "type": "mobile" + } + }, { "desc": "ASUS Zenfone Max Pro (M1)", "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X00TD Build/OPM1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", @@ -205,6 +214,24 @@ "type": "mobile" } }, + { + "desc": "Fairphone 2", + "ua": "Mozilla/5.0 (Linux; Android 7.1.2; FP2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Fairphone", + "model": "FP2", + "type": "mobile" + } + }, + { + "desc": "Fairphone 3", + "ua": "Mozilla/5.0 (Linux; Android 9; FP3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", + "expect": { + "vendor": "Fairphone", + "model": "FP3", + "type": "mobile" + } + }, { "desc": "HTC Desire 820", "ua": "Mozilla/5.0 (Linux; Android 6.0.1; HTC Desire 820 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", @@ -268,6 +295,330 @@ "type": "mobile" } }, + { + "desc": "HUAWEI MediaPad M3 Lite 10", + "ua": "Mozilla/5.0 (Linux; Android 7.0; BAH-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; BAH2-W19 Build/HUAWEIBAH2-W19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH2-W19", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5", + "ua": "Mozilla/5.0 (Linux; Android 9; SHT-AL09 Build/HUAWEISHT-AL09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SHT-AL09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T5", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; AGS2-L09 Build/HUAWEIAGS2-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/84.0.4147.125 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS2-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10", + "ua": "Mozilla/5.0 (Linux; Android 10; AGR-W09 Build/HUAWEIAGR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGR-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10s", + "ua": "Mozilla/5.0 (Linux; Android 10; AGS3-W09 Build/HUAWEIAGS3-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS3-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad T 10", + "ua": "Mozilla/5.0 (Linux; Android 10; AGR-L09; HMSCore 5.0.4.301) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 HuaweiBrowser/11.0.3.304 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGR-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei M3", + "ua": "Mozilla/5.0 (Linux; Android 7.0; BTV-W09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTV-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei Mate 10 Pro", + "ua": "Mozilla/5.0 (Linux; Android 8.0; BLA-L29 Build/HUAWEIBLA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3236.6 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BLA-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate X", + "ua": "Mozilla/5.0 (Linux; Android 9; TAH-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "TAH-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate X2", + "ua": "Mozilla/5.0 (Linux; Android 10; TET-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "TET-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 X", + "ua": "Mozilla/5.0 (Linux; Android 9; EVR-L29 Build/HUAWEIEVR-L29; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "EVR-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L09", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-AL00", + "type": "mobile" + } + }, + { + "desc": "Huawei P20 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; ANE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "ANE-LX1", + "type": "mobile" + } + }, + { + "desc": "Huawei P20", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; EML-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "EML-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; CLT-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "CLT-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P30", + "ua": "Mozilla/5.0 (Linux; Android 9; ELE-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "ELE-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P30 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; VOG-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "VOG-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P40", + "ua": "Mozilla/5.0 (Linux; Android 10; ANA-AN00 Build/HUAWEIANA-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/11.26 SP-engine/2.22.0 baiduboxapp/11.26.0.10 (Baidu; P1 10) NABar/1.0", + "expect": { + "vendor": "Huawei", + "model": "ANA-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei P40 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; ELS-AN00 Build/HUAWEIELS-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/6.0.0", + "expect": { + "vendor": "Huawei", + "model": "ELS-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei 30 Pro+", + "ua": "Mozilla/5.0 (Linux; Android 10; EBG-AN10 Build/HUAWEIEBG-AN10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.86 Mobile Safari/537.36 EdgA/42.0.0.2741", + "expect": { + "vendor": "Huawei", + "model": "EBG-AN10", + "type": "mobile" + } + }, + { + "desc": "Huawei 30S", + "ua": "Mozilla/5.0 (Linux; Android 10; CDY-AN90 Build/HUAWEICDY-AN90; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/5.8.0", + "expect": { + "vendor": "Huawei", + "model": "CDY-AN90", + "type": "mobile" + } + }, + { + "desc": "Huawei Enjoy10e", + "ua": "Dalvik/2.1.0 (Linux; U; Android 10; MED-AL00 Build/HUAWEIMED-AL00)", + "expect": { + "vendor": "Huawei", + "model": "MED-AL00", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 6A", + "ua": "Mozilla/5.0 (Linux; Android 7.0; DLI-L22 Build/HONORDLI-L22; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/252.0.0.22.355;]", + "expect": { + "vendor": "Huawei", + "model": "DLI-L22", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 7", + "ua": "Mozilla/5.0 (Linux; Android 6.0; PLK-L01 Build/HONORPLK-L01; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "PLK-L01", + "type": "mobile" + } + }, + { + "desc": "Huawei 10 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; HRY-LX1 Build/HONORHRY-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "HRY-LX1", + "type": "mobile" + } + }, + { + "desc": "Huawei Y7 2018", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; LDN-L01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.62 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LDN-L01", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 8X", + "ua": "Mozilla/5.0 (Linux; Android 9; JSN-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "JSN-L21", + "type": "mobile" + } + }, + { + "desc": "Huawei Y6 2019", + "ua": "Mozilla/5.0 (Linux; Android 9; MRD-LX1N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "MRD-LX1N", + "type": "mobile" + } + }, + { + "desc": "Huawei Y9 2019", + "ua": "Mozilla/5.0 (Linux; Android 9; JKM-LX2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "JKM-LX2", + "type": "mobile" + } + }, + { + "desc": "Huawei Y5", + "ua": "Mozilla/5.0 (Linux; Android 9; AMN-LX3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AMN-LX3", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; SNE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.116 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SNE-LX1", + "type": "mobile" + } + }, + { + "desc": "Huawei P10 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; WAS-LX1A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "WAS-LX1A", + "type": "mobile" + } + }, + { + "desc": "Huawei Y5 Lite 2018", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; DRA-LX5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "DRA-LX5", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 8C", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BKK-LX2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BKK-LX2", + "type": "mobile" + } + }, { "desc": "iPad using UCBrowser", "ua": "Mozilla/5.0 (iPad; U; CPU OS 11_2 like Mac OS X; zh-CN; iPad5,3) AppleWebKit/534.46 (KHTML, like Gecko) UCBrowser/3.0.1.776 U3/ Mobile/10A403 Safari/7543.48.3", @@ -367,6 +718,51 @@ "type": "tablet" } }, + { + "desc": "LG V40 ThinQ", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-V405) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-V405", + "type": "mobile" + } + }, + { + "desc": "LG K30", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; LM-X410.F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-X410.F", + "type": "mobile" + } + }, + { + "desc": "LG K30", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-X410.FGN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-X410.FGN", + "type": "mobile" + } + }, + { + "desc": "LG Stylo 5", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-Q720) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-Q720", + "type": "mobile" + } + }, + { + "desc": "LG G7 ThinQ", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-G710VM Build/PKQ1.181105.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-G710VM", + "type": "mobile" + } + }, { "desc": "LG K500", "ua": "Mozilla/5.0 (Linux; Android 6.0.1; LG-K500 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", @@ -644,7 +1040,7 @@ "ua": "Mozilla/5.0 (Linux; Android 4.4.4; A0001 Build/KTU84Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.59 Mobile Safari/537.36", "expect": { "vendor": "OnePlus", - "model": "1", + "model": "A0001", "type": "mobile" } }, @@ -653,7 +1049,16 @@ "ua": "Mozilla/5.0 (Linux; Android 4.4.2; OnePlus One A0001 Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Mobile Safari/537.36", "expect": { "vendor": "OnePlus", - "model": "1", + "model": "A0001", + "type": "mobile" + } + }, + { + "desc": "OnePlus 2", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; ONE A2003) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A2003", "type": "mobile" } }, @@ -828,6 +1233,15 @@ "type": "mobile" } }, + { + "desc": "Realme C2", + "ua": "Mozilla/5.0 (Linux; Android 9; RMX1941) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX1941", + "type": "mobile" + } + }, { "desc": "Realme Narzo 20", "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; RMX2193 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", @@ -837,6 +1251,15 @@ "type": "mobile" } }, + { + "desc": "Realme 2 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; RMX1801) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX1801", + "type": "mobile" + } + }, { "desc": "Philips SmartTV", "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", @@ -1334,6 +1757,51 @@ "type": "mobile" } }, + { + "desc": "Xiaomi Mi Max 3", + "ua": "Mozilla/5.0 (Linux; Android 9; MI MAX 3 Build/PKQ1.181007.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI MAX 3", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi A1", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.101 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A1", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi A2 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi A2 Lite) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.62 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A2 Lite", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 9 SE", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi 9 SE) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi 9 SE", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi A2", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi A2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A2", + "type": "mobile" + } + }, { "desc": "Xiaomi MI PAD 2", "ua": "Mozilla/5.0 (Linux; Android 5.1; MI PAD 2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Safari/537.36 [FB_IAB/FB4A;FBAV/137.0.0.24.91;]", @@ -1887,6 +2355,33 @@ "type": "mobile" } }, + { + "desc": "ZTE Blade A5", + "ua": "Mozilla/5.0 (Linux; Android 9; ZTE Blade A5 2019) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "ZTE", + "model": "Blade A5 2019", + "type": "mobile" + } + }, + { + "desc": "ZTE BLADE V0730", + "ua": "Mozilla/5.0 (Linux; Android 6.0; ZTE BLADE V0730) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "ZTE", + "model": "BLADE V0730", + "type": "mobile" + } + }, + { + "desc": "ZTE B2017G", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ZTE B2017G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", + "expect": { + "vendor": "ZTE", + "model": "B2017G", + "type": "mobile" + } + }, { "desc": "Swizz GEN610", "ua": "Mozilla/5.0 (Linux; Android 4.4.2; GEN610 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Mobile Safari/537.36", @@ -2095,460 +2590,253 @@ } }, { - "desc": "HUAWEI MediaPad M3 Lite 10", - "ua": "Mozilla/5.0 (Linux; Android 7.0; BAH-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36", + "desc": "Amazon Fire 7", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; KFAUWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/80.5.3 like Chrome/80.0.3987.162 Safari/537.36", "expect": { - "vendor": "Huawei", - "model": "BAH-L09", + "vendor": "Amazon", + "model": "KFAUWI", "type": "tablet" } }, { - "desc": "HUAWEI MediaPad M5 Lite", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; BAH2-W19 Build/HUAWEIBAH2-W19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Safari/537.36", + "desc": "AT&T Radiant Core U304AA", + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; U304AA Build/P00610)", "expect": { - "vendor": "Huawei", - "model": "BAH2-W19", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M5", - "ua": "Mozilla/5.0 (Linux; Android 9; SHT-AL09 Build/HUAWEISHT-AL09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "SHT-AL09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T5", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; AGS2-L09 Build/HUAWEIAGS2-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/84.0.4147.125 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGS2-L09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T10", - "ua": "Mozilla/5.0 (Linux; Android 10; AGR-W09 Build/HUAWEIAGR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGR-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T10s", - "ua": "Mozilla/5.0 (Linux; Android 10; AGS3-W09 Build/HUAWEIAGS3-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGS3-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad T 10", - "ua": "Mozilla/5.0 (Linux; Android 10; AGR-L09; HMSCore 5.0.4.301) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 HuaweiBrowser/11.0.3.304 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGR-L09", - "type": "tablet" - } - }, - { - "desc": "Huawei Mate 10 Pro", - "ua": "Mozilla/5.0 (Linux; Android 8.0; BLA-L29 Build/HUAWEIBLA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3236.6 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BLA-L29", + "vendor": "AT&T", + "model": "U304AA", "type": "mobile" } }, { - "desc": "Huawei Mate X", - "ua": "Mozilla/5.0 (Linux; Android 9; TAH-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Safari/537.36", + "desc": "Vodafone Smart Tab 4G", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; Vodafone Smart Tab 4G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", + "expect": { + "vendor": "Vodafone", + "model": "Smart Tab 4G", + "type": "tablet" + } + }, + { + "desc": "Vodafone Smart ultra 6", + "ua": "Mozilla/5.0 (Linux; Android 5.0.2; Vodafone Smart ultra 6 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "Vodafone", + "model": "Smart ultra 6", + "type": "tablet" + } + }, + { + "desc": "4ife 4K Smart TV Box", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; 4ife 4K Smart TV Box Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36 Vinebre", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "FaceBook Mobile App", + "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", "expect": { - "vendor": "Huawei", - "model": "TAH-AN00", "type": "mobile" } }, { - "desc": "Huawei Mate X2", - "ua": "Mozilla/5.0 (Linux; Android 10; TET-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "desc": "Issue #454", + "ua": "Mosamzilla/5.0 (Windows; U; Win98; en-US; rv:1.7.5) Gecko/20050603 Netscape/8.0.2", "expect": { - "vendor": "Huawei", - "model": "TET-AN00", + "vendor": "undefined", + "model": "undefined", + "type": "undefined" + } + }, + { + "desc": "Alcatel", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ALCATEL A564C Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "ALCATEL", + "model": "A564C", "type": "mobile" } }, { - "desc": "Huawei Mate 20 X", - "ua": "Mozilla/5.0 (Linux; Android 9; EVR-L29 Build/HUAWEIEVR-L29; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "EVR-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-L09", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-AL00", - "type": "mobile" - } - }, - { - "desc": "Huawei P20 Lite", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; ANE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", + "desc": "Alcatel Go Flip", + "ua": "Mozilla/5.0 (Mobile; ALCATEL4044T; rv:37.0) Gecko/37.0 Firefox/37.0 KaiOS/1.0", "expect": { - "vendor": "Huawei", - "model": "ANE-LX1", + "vendor": "ALCATEL", + "model": "4044T", "type": "mobile" } }, { - "desc": "Huawei P20", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; EML-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "EML-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei P20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; CLT-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "CLT-L29", - "type": "mobile" + "desc": "Jolla", + "ua": "Mozilla/5.0 (Maemo; Linux; U; Jolla; Sailfish; Mobile; rv:31.0) Gecko/31.0 Firefox/31.0 SailfishBrowser/1.0", + "expect": { + "vendor": "Jolla", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Xbox One", + "ua": "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; Xbox; Xbox One)", + "expect": { + "vendor": "Microsoft", + "model": "Xbox One", + "type": "console" + } + }, + { + "desc": "Xbox", + "ua": "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Xbox)", + "expect": { + "vendor": "Microsoft", + "model": "Xbox", + "type": "console" + } + }, + { + "desc": "Nvidia Shield Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SHIELD Tablet Build/LVY48E; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.19 Safari/537.36", + "expect": { + "vendor": "Nvidia", + "model": "SHIELD Tablet", + "type": "tablet" + } + }, + { + "desc": "Ouya", + "ua": "Mozilla/5.0 (Linux; Android 4.1.2; OUYA Console Build/JZO54L-OUYA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.84 Safari/537.36", + "expect": { + "vendor": "OUYA", + "model": "undefined", + "type": "console" + } + }, + { + "desc": "Vivo Y52s", + "ua": "Mozilla/5.0 (Linux; Android 10; V2057A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.10 SP-engine/2.28.0 baiduboxapp/12.10.0.10 (Baidu; P1 10) NABar/1.0", + "expect": { + "vendor": "Vivo", + "model": "V2057A", + "type": "mobile" + } + }, + { + "desc": "Vivo X60", + "ua": "Mozilla/5.0 (Linux; Android 11; V2046A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/8.8.71.0", + "expect": { + "vendor": "Vivo", + "model": "V2046A", + "type": "mobile" + } + }, + { + "desc": "Vivo Y79A", + "ua": "Mozilla/5.0 (Linux; Android 7.1.2; vivo Y79A Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", + "expect": { + "vendor": "Vivo", + "model": "Y79A", + "type": "mobile" + } + }, + { + "desc": "Vivo Y97", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; V1813T Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", + "expect": { + "vendor": "Vivo", + "model": "V1813T", + "type": "mobile" + } + }, + { + "desc": "Vivo iQOO Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; V1916A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.1.10.6", + "expect": { + "vendor": "Vivo", + "model": "V1916A", + "type": "mobile" + } + }, + { + "desc": "Unknown Mobile using Firefox", + "ua": "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Firefox", + "ua": "Mozilla/5.0 (Android 4.4; Tablet; rv:41.0) Gecko/41.0 Firefox/41.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown Mobile using Focus for Android", + "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Focus for Android", + "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown Device using Focus for Android with GeckoView", + "ua": "Mozilla/5.0 (Android 7.0; Mobile; rv:62.0) Gecko/62.0 Firefox/62.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Mobile using Firefox OS", + "ua": "Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Firefox OS", + "ua": "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown TV using Firefox OS", + "ua": "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "PDA with Windows CE", + "ua": "Mozilla/4.0 (PDA; Windows CE/1.0.1) NetFront/3.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } } - }, - { - "desc": "Huawei P30", - "ua": "Mozilla/5.0 (Linux; Android 9; ELE-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "ELE-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei P30 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; VOG-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "VOG-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei P40", - "ua": "Mozilla/5.0 (Linux; Android 10; ANA-AN00 Build/HUAWEIANA-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/11.26 SP-engine/2.22.0 baiduboxapp/11.26.0.10 (Baidu; P1 10) NABar/1.0", - "expect": { - "vendor": "Huawei", - "model": "ANA-AN00", - "type": "mobile" - } - }, - { - "desc": "Huawei P40 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; ELS-AN00 Build/HUAWEIELS-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/6.0.0", - "expect": { - "vendor": "Huawei", - "model": "ELS-AN00", - "type": "mobile" - } - }, - { - "desc": "Huawei 30 Pro+", - "ua": "Mozilla/5.0 (Linux; Android 10; EBG-AN10 Build/HUAWEIEBG-AN10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.86 Mobile Safari/537.36 EdgA/42.0.0.2741", - "expect": { - "vendor": "Huawei", - "model": "EBG-AN10", - "type": "mobile" - } - }, - { - "desc": "Huawei 30S", - "ua": "Mozilla/5.0 (Linux; Android 10; CDY-AN90 Build/HUAWEICDY-AN90; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/5.8.0", - "expect": { - "vendor": "Huawei", - "model": "CDY-AN90", - "type": "mobile" - } - }, - { - "desc": "Huawei Enjoy10e", - "ua": "Dalvik/2.1.0 (Linux; U; Android 10; MED-AL00 Build/HUAWEIMED-AL00)", - "expect": { - "vendor": "Huawei", - "model": "MED-AL00", - "type": "mobile" - } - }, - { - "desc": "Amazon Fire 7", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; KFAUWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/80.5.3 like Chrome/80.0.3987.162 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "KFAUWI", - "type": "tablet" - } - }, - { - "desc": "AT&T Radiant Core U304AA", - "ua": "Dalvik/2.1.0 (Linux; U; Android 9; U304AA Build/P00610)", - "expect": { - "vendor": "AT&T", - "model": "U304AA", - "type": "mobile" - } - }, - { - "desc": "Vodafone Smart Tab 4G", - "ua": "Mozilla/5.0 (Linux; Android 4.4.4; Vodafone Smart Tab 4G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", - "expect": { - "vendor": "Vodafone", - "model": "Smart Tab 4G", - "type": "tablet" - } - }, - { - "desc": "Vodafone Smart ultra 6", - "ua": "Mozilla/5.0 (Linux; Android 5.0.2; Vodafone Smart ultra 6 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", - "expect": { - "vendor": "Vodafone", - "model": "Smart ultra 6", - "type": "tablet" - } - }, - { - "desc": "4ife 4K Smart TV Box", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; 4ife 4K Smart TV Box Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36 Vinebre", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "FaceBook Mobile App", - "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", - "expect": { - "type": "mobile" - } - }, - { - "desc": "Issue #454", - "ua": "Mosamzilla/5.0 (Windows; U; Win98; en-US; rv:1.7.5) Gecko/20050603 Netscape/8.0.2", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "undefined" - } - }, - { - "desc": "Alcatel", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ALCATEL A564C Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", - "expect": { - "vendor": "ALCATEL", - "model": "A564C", - "type": "mobile" - } - }, - { - "desc": "Alcatel Go Flip", - "ua": "Mozilla/5.0 (Mobile; ALCATEL4044T; rv:37.0) Gecko/37.0 Firefox/37.0 KaiOS/1.0", - "expect": { - "vendor": "ALCATEL", - "model": "4044T", - "type": "mobile" - } - }, - { - "desc": "Jolla", - "ua": "Mozilla/5.0 (Maemo; Linux; U; Jolla; Sailfish; Mobile; rv:31.0) Gecko/31.0 Firefox/31.0 SailfishBrowser/1.0", - "expect": { - "vendor": "Jolla", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Xbox One", - "ua": "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; Xbox; Xbox One)", - "expect": { - "vendor": "Microsoft", - "model": "Xbox One", - "type": "console" - } - }, - { - "desc": "Xbox", - "ua": "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Xbox)", - "expect": { - "vendor": "Microsoft", - "model": "Xbox", - "type": "console" - } - }, - { - "desc": "Nvidia Shield Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SHIELD Tablet Build/LVY48E; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.19 Safari/537.36", - "expect": { - "vendor": "Nvidia", - "model": "SHIELD Tablet", - "type": "tablet" - } - }, - { - "desc": "Ouya", - "ua": "Mozilla/5.0 (Linux; Android 4.1.2; OUYA Console Build/JZO54L-OUYA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.84 Safari/537.36", - "expect": { - "vendor": "OUYA", - "model": "undefined", - "type": "console" - } - }, - { - "desc": "Vivo Y52s", - "ua": "Mozilla/5.0 (Linux; Android 10; V2057A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.10 SP-engine/2.28.0 baiduboxapp/12.10.0.10 (Baidu; P1 10) NABar/1.0", - "expect": { - "vendor": "Vivo", - "model": "V2057A", - "type": "mobile" - } - }, - { - "desc": "Vivo X60", - "ua": "Mozilla/5.0 (Linux; Android 11; V2046A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/8.8.71.0", - "expect": { - "vendor": "Vivo", - "model": "V2046A", - "type": "mobile" - } - }, - { - "desc": "Vivo Y79A", - "ua": "Mozilla/5.0 (Linux; Android 7.1.2; vivo Y79A Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", - "expect": { - "vendor": "Vivo", - "model": "Y79A", - "type": "mobile" - } - }, - { - "desc": "Vivo Y97", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; V1813T Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", - "expect": { - "vendor": "Vivo", - "model": "V1813T", - "type": "mobile" - } - }, - { - "desc": "Vivo iQOO Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; V1916A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.1.10.6", - "expect": { - "vendor": "Vivo", - "model": "V1916A", - "type": "mobile" - } - }, - { - "desc": "Unknown Mobile using Firefox", - "ua": "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Tablet using Firefox", - "ua": "Mozilla/5.0 (Android 4.4; Tablet; rv:41.0) Gecko/41.0 Firefox/41.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "tablet" - } - }, - { - "desc": "Unknown Mobile using Focus for Android", - "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Mobile Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Tablet using Focus for Android", - "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "tablet" - } - }, - { - "desc": "Unknown Device using Focus for Android with GeckoView", - "ua": "Mozilla/5.0 (Android 7.0; Mobile; rv:62.0) Gecko/62.0 Firefox/62.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Mobile using Firefox OS", - "ua": "Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Tablet using Firefox OS", - "ua": "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "tablet" - } - }, - { - "desc": "Unknown TV using Firefox OS", - "ua": "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "PDA with Windows CE", - "ua": "Mozilla/4.0 (PDA; Windows CE/1.0.1) NetFront/3.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - } ] From e5e13adc812b2e485ecf5efbedce7077f7d312cd Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 24 Apr 2021 21:15:16 +0700 Subject: [PATCH 117/121] Improve CPU detection for ARM64 --- src/ua-parser.js | 4 ++-- test/cpu-test.json | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 5a5c28f..eac8838 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -340,7 +340,7 @@ /((?:i[346]|x)86)[;\)]/i // IA32 (x86) ], [[ARCHITECTURE, 'ia32']], [ - /\b(aarch64|armv?8e?l?)\b/i // ARM64 + /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64 ], [[ARCHITECTURE, 'arm64']], [ /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF @@ -356,7 +356,7 @@ /(sun4\w)[;\)]/i // SPARC ], [[ARCHITECTURE, 'sparc']], [ - /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?:64|(?=v(?:[1-7]|[5-7]1)l?|;|eabi))|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i + /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC ], [[ARCHITECTURE, lowerize]] ], diff --git a/test/cpu-test.json b/test/cpu-test.json index efa1c5b..cf314f9 100644 --- a/test/cpu-test.json +++ b/test/cpu-test.json @@ -111,6 +111,22 @@ "architecture" : "arm64" } }, + { + "desc" : "ARM64", + "ua" : "Mozilla/5.0 (Windows NT 10.0; ARM64; RM-1096) AppleWebKit/537.36 (KHTML like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393", + "expect" : + { + "architecture" : "arm64" + } + }, + { + "desc" : "ARM64", + "ua" : "Mozilla/5.0 (Linux; arm_64; Android 9; HRY-LX1T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 YaBrowser/19.12.1.121.00 Mobile Safari/537.36", + "expect" : + { + "architecture" : "arm64" + } + }, { "desc" : "Pocket PC", "ua" : "Opera/9.7 (Windows Mobile; PPC; Opera Mobi/35166; U; en) Presto/2.2.1", From 1e7b6d2e8bccdc5719243c81123b7709bca0d064 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 24 Apr 2021 21:50:18 +0700 Subject: [PATCH 118/121] Improve device detection: LG Android TV --- src/ua-parser.js | 4 ++-- test/device-test.json | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index eac8838..15677d3 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -427,7 +427,7 @@ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, - /\blg[-e;\/ ]+((?!browser|netcast)\w+)/i, + /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i, /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ @@ -601,7 +601,7 @@ ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ - /(?:nux; netcast.+smarttv|lg netcast\.tv-201\d)/i // LG SmartTV + /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV ], [[VENDOR, LG], [TYPE, SMARTTV]], [ /(apple) ?tv/i // Apple TV ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ diff --git a/test/device-test.json b/test/device-test.json index c8bd7c4..885db14 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -826,6 +826,15 @@ "type": "smarttv" } }, + { + "desc": "LG Android TV", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; LG Android TV Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect": { + "vendor": "LG", + "model": "undefined", + "type": "smarttv" + } + }, { "desc": "Meizu M5 Note", "ua": "Mozilla/5.0 (Linux; Android 6.0; M5 Note Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043024 Safari/537.36 MicroMessenger/6.5.7.1040 NetType/WIFI Language/zh_CN", From 03c915277aac43e68379a4500819bd7a8d5bb28e Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 24 Apr 2021 23:04:16 +0700 Subject: [PATCH 119/121] Add new OS: Android-x86, Deepin, elementary OS, GhostBSD, Linspire, Manjaro, Sabayon User-Agent source: whatismybrowser.com --- readme.md | 14 +++++----- src/ua-parser.js | 10 ++++--- test/os-test.json | 68 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/readme.md b/readme.md index bcd4d3b..456d110 100644 --- a/readme.md +++ b/readme.md @@ -86,13 +86,13 @@ NetSurf, Presto, Tasman, Trident, w3m, WebKit ```sh # Possible 'os.name' -AIX, Amiga OS, Android, Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, -Contiki, Fedora, Firefox OS, FreeBSD, Debian, DragonFly, Fuchsia, Gentoo, GNU, -Haiku, HP-UX, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Maemo, Mageia, -Mandriva, MeeGo, Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, -Palm, PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, -RISC OS, Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, -Unix, VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... +AIX, Amiga OS, Android[-x86], Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, +Contiki, Fedora, Firefox OS, FreeBSD, Debian, Deepin, DragonFly, elementary OS, +Fuchsia, Gentoo, GhostBSD, GNU, Haiku, HP-UX, Hurd, iOS, Joli, KaiOS, Linpus, Linspire, +Linux, Mac OS, Maemo, Mageia, Mandriva, Manjaro, MeeGo, Minix, Mint, Morph OS, NetBSD, +Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, +Raspbian, RedHat, RIM Tablet OS, RISC OS, Sabayon, Sailfish, Series40, Slackware, Solaris, +SUSE, Symbian, Tizen, Ubuntu, Unix, VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... # 'os.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 15677d3..ea9e506 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -690,7 +690,9 @@ /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ - // Mobile OSes // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS + // Mobile OSes + /droid ([\w\.]+)\b.+(android[- ]x86)/i // Android-x86 + ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS @@ -720,11 +722,11 @@ /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm /(mint)[\/\(\) ]?(\w*)/i, // Mint /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux - /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i, - // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki + /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i, + // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux /(gnu) ?([\w\.]*)/i, // GNU - /\b([-frentopc]{0,4}bsd|dragonfly) ?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly + /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly /(haiku) (\w+)/i // Haiku ], [NAME, VERSION], [ /(sunos) ?([\w\.\d]*)/i // Solaris diff --git a/test/os-test.json b/test/os-test.json index d614487..a0eb412 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -604,11 +604,11 @@ }, { "desc" : "Slackware", - "ua" : "", + "ua" : "Mozilla/5.0 Slackware/13.37 (X11; U; Linux x86_64; en-US) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41", "expect" : { - "name" : "", - "version" : "" + "name" : "Slackware", + "version" : "13.37" } }, { @@ -1017,12 +1017,12 @@ } }, { - "desc" : "GNU", - "ua" : "", + "desc" : "Deepin", + "ua" : "Mozilla/5.0 (X11; Linux x86_64; Deepin 15.5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36 NFSBrowser/5.0.0.1886", "expect" : { - "name" : "", - "version" : "" + "name" : "Deepin", + "version" : "15.5" } }, { @@ -1060,5 +1060,59 @@ "name" : "Linpus", "version" : "3.0-0.49" } + }, + { + "desc" : "Manjaro", + "ua" : "Mozilla/5.0 (X11; Manjaro 19.0.2; Arch; x64; rv:84.0) Gecko/20100101 Firefox/84.0", + "expect" : + { + "name" : "Manjaro", + "version" : "19.0.2" + } + }, + { + "desc" : "elementary OS", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/604.1 (KHTML, like Gecko) Version/11.0 Safari/604.1 elementary OS/0.4 (Loki) Epiphany/3.18.11", + "expect" : + { + "name" : "elementary OS", + "version" : "0.4" + } + }, + { + "desc" : "GhostBSD", + "ua" : "Mozilla/5.0 (X11; GhostBSD/10.3; x86_64; rv:50.0.1) Gecko/20100101 Firefox/50.0.1", + "expect" : + { + "name" : "GhostBSD", + "version" : "10.3" + } + }, + { + "desc" : "Android-x86", + "ua" : "Mozilla/5.0 (Linux; Android 7.1.2; Generic Android-x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 OPR/61.2.3076.56749", + "expect" : + { + "name" : "Android-x86", + "version" : "7.1.2" + } + }, + { + "desc" : "Sabayon", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Sabayon Chrome/19.0.1084.46 Safari/536.5", + "expect" : + { + "name" : "Sabayon", + "version" : "undefined" + } + }, + { + "desc" : "Linspire", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.4) Gecko/20060803 Firefox/1.5.0.4 Linspire/1.5.0.4", + "expect" : + { + "name" : "Linspire", + "version" : "1.5.0.4" + } } ] From 39e8d4af0314117c4733ad9a9397ad32a0e42732 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 15 Jun 2021 12:49:19 +0700 Subject: [PATCH 120/121] Fix #500 Sharp devices misjudged as Huawei devices --- src/ua-parser.js | 8 ++++++-- test/device-test.json | 30 +++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index ea9e506..2a62367 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -385,10 +385,10 @@ ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ // Huawei - /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b/i + /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei|honor)([-\w ]+)[;\)]/i, - /\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b/i + /\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi @@ -499,6 +499,10 @@ /\bmz-([-\w]{2,})/i ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ + // Sharp + /\b(sh-?[altvz]?\d\d[a-ekm]?)/i + ], [MODEL, [VENDOR, 'Sharp'], [TYPE, MOBILE]], [ + // MIXED /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron diff --git a/test/device-test.json b/test/device-test.json index 885db14..794500c 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1539,6 +1539,33 @@ "type": "smarttv" } }, + { + "desc": "Sharp Aquos B10", + "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-A01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SH-A01", + "type": "mobile" + } + }, + { + "desc": "Sharp Aquos L2", + "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-L02 Build/S4045) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SH-L02", + "type": "mobile" + } + }, + { + "desc": "Sharp Aquos R2", + "ua": "Mozilla/5.0 (Linux; Android 8.0; SHV42) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.92 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SHV42", + "type": "mobile" + } + }, { "desc": "Sony G8141 (Xperia XZ Premium)", "ua": "Mozilla/5.0 (Linux; Android 8.0.0; G8141) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36", @@ -2197,9 +2224,10 @@ } }, { - "desc": "Android Phone Unidentified Vendor (docomo SH-02M)", + "desc": "docomo SH-02M", "ua": "Mozilla/5.0 (Linux; Android 9; SH-02M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", "expect": { + "vendor": "Sharp", "model": "SH-02M", "type": "mobile" } From 299283c436ad29f67242e928f8185ed53c194876 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 22 Jul 2021 20:30:54 +0700 Subject: [PATCH 121/121] Fix #506 - add test for Huawei ART-L29 --- test/device-test.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/device-test.json b/test/device-test.json index 794500c..ae9392f 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -583,6 +583,15 @@ "type": "mobile" } }, + { + "desc": "Huawei Y7p", + "ua": "Mozilla/5.0 (Linux; Android 9; ART-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.92 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "ART-L29", + "type": "mobile" + } + }, { "desc": "Huawei Mate 20 Lite", "ua": "Mozilla/5.0 (Linux; Android 8.1.0; SNE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.116 Mobile Safari/537.36",