diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts index b41dfc4..44fefbf 100644 --- a/src/enums/ua-parser-enums.d.ts +++ b/src/enums/ua-parser-enums.d.ts @@ -38,6 +38,8 @@ export const Browser: Readonly<{ DUCKDUCKGO: "DuckDuckGo"; ECOSIA: "Ecosia"; EDGE: "Edge"; + EDGE_WEBVIEW: "Edge WebView"; + EDGE_WEBVIEW2: "Edge WebView2"; EPIPHANY: "Epiphany"; FACEBOOK: "Facebook"; FALKON: "Falkon"; diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 2ae437c..3420acb 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -43,6 +43,8 @@ const Browser = Object.freeze({ DUCKDUCKGO: 'DuckDuckGo', ECOSIA: 'Ecosia', EDGE: 'Edge', + EDGE_WEBVIEW: 'Edge WebView', + EDGE_WEBVIEW2: 'Edge WebView2', EPIPHANY: 'Epiphany', FACEBOOK: 'Facebook', FALKON: 'Falkon', diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index ae91dbd..1e6210c 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -152,11 +152,11 @@ has = function (str1, str2) { if (typeof str1 === OBJ_TYPE && str1.length > 0) { for (var i in str1) { - if (lowerize(str1[i]) == lowerize(str2)) return true; + if (lowerize(str2) == lowerize(str1[i])) return true; } return false; } - return isString(str1) ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false; + return isString(str1) ? lowerize(str2) == lowerize(str1) : false; }, isExtensions = function (obj, deep) { for (var prop in obj) { @@ -326,7 +326,9 @@ // Most common regardless engine /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS ], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [ - /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge + /webview.+edge\/([\w\.]+)/i // Microsoft Edge + ], [VERSION, [NAME, EDGE+' WebView']], [ + /edg(?:e|ios|a)?\/([\w\.]+)/i ], [VERSION, [NAME, 'Edge']], [ // Presto based @@ -441,6 +443,9 @@ /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless ], [VERSION, [NAME, CHROME+' Headless']], [ + /wv\).+chrome\/([\w\.]+).+edgw\//i // Edge WebView2 + ], [VERSION, [NAME, EDGE+' WebView2']], [ + / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView ], [[NAME, CHROME+' WebView'], VERSION], [ @@ -1232,10 +1237,16 @@ for (var i in brands) { var brandName = brands[i].brand || brands[i], brandVersion = brands[i].version; - if (this.itemType == UA_BROWSER && !/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && brandName != CHROMIUM))) { + if (this.itemType == UA_BROWSER && + !/not.a.brand/i.test(brandName) && + (!prevName || + (/Chrom/.test(prevName) && brandName != CHROMIUM) || + (prevName == EDGE && /WebView2/.test(brandName)) + )) { brandName = strMapper(brandName, { 'Chrome' : 'Google Chrome', 'Edge' : 'Microsoft Edge', + 'Edge WebView2' : 'Microsoft Edge WebView2', 'Chrome WebView' : 'Android WebView', 'Chrome Headless' : 'HeadlessChrome', 'Huawei Browser' : 'HuaweiBrowser', diff --git a/test/data/ua/browser/browser-all.json b/test/data/ua/browser/browser-all.json index 3fc0e5e..9f39de9 100644 --- a/test/data/ua/browser/browser-all.json +++ b/test/data/ua/browser/browser-all.json @@ -2229,6 +2229,26 @@ "major" : "74" } }, + { + "desc" : "Microsoft Edge WebView", + "ua" : "Mozilla/5.0 (Windows IoT 10.0; Android 6.0.1; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Mobile Safari/537.36 Edge/18.17763", + "expect" : + { + "name" : "Edge WebView", + "version" : "18.17763", + "major" : "18" + } + }, + { + "desc" : "Microsoft Edge WebView2", + "ua" : "Mozilla/5.0 (Linux; Android 11; SM-G991B Build/RP1A.200720.012; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.120 Mobile Safari/537.36 EdgW/1.0", + "expect" : + { + "name" : "Edge WebView2", + "version" : "91.0.4472.120", + "major" : "91" + } + }, { "desc" : "Iridium", "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Iridium/43.8 Safari/537.36 Chrome/43.0.2357.132", diff --git a/test/unit/ua-ch.js b/test/unit/ua-ch.js index 18dd09a..7d12d50 100644 --- a/test/unit/ua-ch.js +++ b/test/unit/ua-ch.js @@ -313,6 +313,19 @@ describe('UA-CH Headers tests', () => { } } }, + { + headers : { + 'sec-ch-ua': '" Not;A Brand";v="99", "Microsoft Edge";v="103", "Chromium";v="103", "Microsoft Edge WebView2";v="104"' + }, + expect: { + browser : { + name : 'Edge WebView2', + version : '104', + major : '104', + type : undefined + } + } + }, { headers : { 'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "HuaweiBrowser";v="114"'