From 4d950db14572c84aaceea7e7368abe9ccb8b2687 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 28 Jan 2024 22:34:46 +0700 Subject: [PATCH] Update version to 2.0.0-beta.2 --- CHANGELOG.md | 44 +++++++ dist/ua-parser.min.js | 4 +- dist/ua-parser.pack.js | 4 +- package-lock.json | 4 +- package.js | 2 +- package.json | 2 +- src/enums/ua-parser-enums.js | 2 +- src/enums/ua-parser-enums.mjs | 148 ++++++++++++++++++++--- src/extensions/ua-parser-extensions.d.ts | 2 +- src/extensions/ua-parser-extensions.js | 2 +- src/extensions/ua-parser-extensions.mjs | 2 +- src/helpers/ua-parser-helpers.d.ts | 2 +- src/helpers/ua-parser-helpers.js | 2 +- src/helpers/ua-parser-helpers.mjs | 26 ++++ src/main/ua-parser.d.ts | 2 +- src/main/ua-parser.js | 4 +- src/main/ua-parser.mjs | 97 +++++++++------ test/specs/browser-all.json | 10 ++ 18 files changed, 290 insertions(+), 69 deletions(-) create mode 100644 src/helpers/ua-parser-helpers.mjs diff --git a/CHANGELOG.md b/CHANGELOG.md index 84bcaf0..b3541fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,10 +16,54 @@ - Provided Extensions submodule `'ua-parser-js/extensions'` - Provided Helpers submodule `'ua-parser-js/helpers'` +## Version 2.0.0-beta.2 + +- Increase UA_MAX_LENGTH to 500 +- Add TypeScript declaration file in `ua-parser-js/extensions` submodule +- Improve TypeScript module resolution +- Add new methods in `ua-parser-js/helpers` submodule: `isAppleSilicon()` & `isChromiumBased()` +- Fix misidentified WebView token as device model +- Add new browser: Alipay, Klarna, Opera GX, Smart Lenovo Browser, Vivo Browser +- Rename browser: Avant, Baidu, Samsung Internet, Sogou Explorer, Sogou Mobile, WeChat +- Improve client-hints detection: Edge, Xbox + +## Version 2.0.0-beta.1 + +- Update Client Hints Form-Factor +- Provide in-package type definitions +- Add new device: Ulefone +- Improve device detection: Realme, Xiaomi Redmi + +## Version 2.0.0-alpha.3 + +- Add `withFeatureCheck()` method +- Add `isFrozenUA()` method in `ua-parser-js/helpers` submodule +- Add `MediaPlayers` & `Modules` in `ua-parser-js/extensions` submodule +- Fix issue with ESM import + +## Version 2.0.0-alpha.2 + +- Fix browser result always returning Chromium when using withClientHints() +- Fix infinite-loop when await-ing withClientHints() in non-client-hints browser + +## Version 2.0.0-alpha.1 + +- Initial work on new major version + + # Version 0.7 / 1.0 Version 1.0.x is basically the equivalent of version 0.7.x. See [#536](https://github.com/faisalman/ua-parser-js/issues/536) for the reason behind this confusion. +## Version 0.7.37 + +- Fix misidentified WebView token as device model +- Increase UA_MAX_LENGTH to 500 +- Add new browser: Alipay, Klarna, Smart Lenovo Browser, Vivo Browser +- Add new device: Ulefone +- Improve device detection: Realme, Xiaomi Redmi +- Rename browser: Avant, Baidu, Samsung Internet, Sogou Explorer, Sogou Mobile, WeChat + ## Version 0.7.36 / 1.0.36 - Add new browser: Snapchat - Add new devices: Infinix, Tecno diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 093a092..f23c2c4 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.0-beta.1 +/* UAParser.js v2.0.0-beta.2 Copyright © 2012-2023 Faisal Salman AGPLv3 License */ -(function(window,undefined){"use strict";var LIBVERSION="2.0.0-beta.1",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",USER_AGENT="user-agent",UA_MAX_LENGTH=350,BRANDS="brands",FORMFACTOR="formFactor",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTOR=CH_HEADER+"-form-factor",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTOR,BITNESS],UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",WINDOWS="Windows";var NAVIGATOR=typeof window!==UNDEF_TYPE&&window.navigator?window.navigator:undefined,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:undefined;var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){mergedRegexes[i]=extensions[i]&&extensions[i].length%2===0?extensions[i].concat(regexes[i]):regexes[i]}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;i0){for(var i in str1){if(lowerize(str1[i])==lowerize(str2))return true}return false}return typeof str1===STR_TYPE?lowerize(str2).indexOf(lowerize(str1))!==-1:false},isExtensions=function(obj){for(var prop in obj){return/^(browser|cpu|device|engine|os)$/.test(prop)}},itemListToArray=function(header){if(!header)return undefined;var arr=[];var tokens=strip(/\\?\"/g,header).split(",");for(var i=0;i-1){var token=trim(tokens[i]).split(";v=");arr[i]={brand:token[0],version:token[1]}}else{arr[i]=tokens[i]}}return arr},lowerize=function(str){return typeof str===STR_TYPE?str.toLowerCase():str},majorize=function(version){return typeof version===STR_TYPE?strip(/[^\d\.]/g,version).split(".")[0]:undefined},setProps=function(arr){for(var i in arr){var propName=arr[i];if(typeof propName==OBJ_TYPE&&propName.length==2){this[propName[0]]=propName[1]}else{this[propName]=undefined}}return this},strip=function(pattern,str){return str.replace(pattern,EMPTY)},stripQuotes=function(val){return typeof val===STR_TYPE?strip(/\\?\"/g,val):val},trim=function(str,len){if(typeof str===STR_TYPE){str=strip(/^\s\s*/,str);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){if(!ua||!arrays)return;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;j2){this.set(MODEL,"iPad").set(TYPE,TABLET)}break;case UA_OS:if(!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]){this.set(NAME,NAVIGATOR_UADATA[PLATFORM])}break;case UA_RESULT:var data=this.data;var detect=function(itemType){return data[itemType].getItem().detectFeature().get()};this.set(UA_BROWSER,detect(UA_BROWSER)).set(UA_CPU,detect(UA_CPU)).set(UA_DEVICE,detect(UA_DEVICE)).set(UA_ENGINE,detect(UA_ENGINE)).set(UA_OS,detect(UA_OS))}}return this};this.parseUA=function(){if(this.itemType!=UA_RESULT){rgxMapper.call(this.data,this.ua,this.rgxMap)}if(this.itemType==UA_BROWSER){this.set(MAJOR,majorize(this.get(VERSION)))}return this};this.parseCH=function(){var uaCH=this.uaCH,rgxMap=this.rgxMap;switch(this.itemType){case UA_BROWSER:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS];if(brands){for(var i in brands){var brandName=brands[i].brand,brandVersion=brands[i].version;if(!/not.a.brand/i.test(brandName)&&(i<1||/chromi/i.test(this.get(NAME)))){this.set(NAME,strip(GOOGLE+" ",brandName)).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion))}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL])}if(uaCH[FORMFACTOR]){var ff;if(typeof uaCH[FORMFACTOR]!=="string"){var idx=0;while(!ff&&idx=13?"11":"10";this.set(NAME,osName).set(VERSION,osVersion)}break;case UA_RESULT:var data=this.data;var parse=function(itemType){return data[itemType].getItem().setCH(uaCH).parseCH().get()};this.set(UA_BROWSER,parse(UA_BROWSER)).set(UA_CPU,parse(UA_CPU)).set(UA_DEVICE,parse(UA_DEVICE)).set(UA_ENGINE,parse(UA_ENGINE)).set(UA_OS,parse(UA_OS))}return this};setProps.call(this,[["itemType",itemType],["ua",ua],["uaCH",uaCH],["rgxMap",rgxMap],["data",createIData(this,itemType)]]);return this}function UAParser(ua,extensions,headers){if(typeof ua===OBJ_TYPE){if(isExtensions(ua)){if(typeof extensions===OBJ_TYPE){headers=extensions}extensions=ua}else{headers=ua;extensions=undefined}ua=undefined}else if(typeof ua===STR_TYPE&&!isExtensions(extensions)){headers=extensions;extensions=undefined}if(!(this instanceof UAParser)){return new UAParser(ua,extensions,headers).getResult()}var userAgent=typeof ua===STR_TYPE?ua:NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:headers&&headers[USER_AGENT]?headers[USER_AGENT]:EMPTY,httpUACH=new UACHData(headers,true),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){if(itemType==UA_RESULT){return function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(UA_BROWSER,this.getBrowser()).set(UA_CPU,this.getCPU()).set(UA_DEVICE,this.getDevice()).set(UA_ENGINE,this.getEngine()).set(UA_OS,this.getOS()).get()}}else{return function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}}};setProps.call(this,[["getBrowser",createItemFunc(UA_BROWSER)],["getCPU",createItemFunc(UA_CPU)],["getDevice",createItemFunc(UA_DEVICE)],["getEngine",createItemFunc(UA_ENGINE)],["getOS",createItemFunc(UA_OS)],["getResult",createItemFunc(UA_RESULT)],["getUA",function(){return userAgent}],["setUA",function(ua){if(typeof ua===STR_TYPE)userAgent=ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this}]]).setUA(userAgent);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 +(function(window,undefined){"use strict";var LIBVERSION="2.0.0-beta.2",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",USER_AGENT="user-agent",UA_MAX_LENGTH=500,BRANDS="brands",FORMFACTOR="formFactor",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTOR=CH_HEADER+"-form-factor",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTOR,BITNESS],UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",WINDOWS="Windows";var isWindow=typeof window!==UNDEF_TYPE,NAVIGATOR=isWindow&&window.navigator?window.navigator:undefined,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:undefined;var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){mergedRegexes[i]=extensions[i]&&extensions[i].length%2===0?extensions[i].concat(regexes[i]):regexes[i]}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;i0){for(var i in str1){if(lowerize(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1:false},isExtensions=function(obj){for(var prop in obj){return/^(browser|cpu|device|engine|os)$/.test(prop)}},isString=function(val){return typeof val===STR_TYPE},itemListToArray=function(header){if(!header)return undefined;var arr=[];var tokens=strip(/\\?\"/g,header).split(",");for(var i=0;i-1){var token=trim(tokens[i]).split(";v=");arr[i]={brand:token[0],version:token[1]}}else{arr[i]=trim(tokens[i])}}return arr},lowerize=function(str){return isString(str)?str.toLowerCase():str},majorize=function(version){return isString(version)?strip(/[^\d\.]/g,version).split(".")[0]:undefined},setProps=function(arr){for(var i in arr){var propName=arr[i];if(typeof propName==OBJ_TYPE&&propName.length==2){this[propName[0]]=propName[1]}else{this[propName]=undefined}}return this},strip=function(pattern,str){return isString(str)?str.replace(pattern,EMPTY):str},stripQuotes=function(str){return strip(/\\?\"/g,str)},trim=function(str,len){if(isString(str)){str=strip(/^\s\s*/,str);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){if(!ua||!arrays)return;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;j2){this.set(MODEL,"iPad").set(TYPE,TABLET)}break;case UA_OS:if(!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]){this.set(NAME,NAVIGATOR_UADATA[PLATFORM])}break;case UA_RESULT:var data=this.data;var detect=function(itemType){return data[itemType].getItem().detectFeature().get()};this.set(UA_BROWSER,detect(UA_BROWSER)).set(UA_CPU,detect(UA_CPU)).set(UA_DEVICE,detect(UA_DEVICE)).set(UA_ENGINE,detect(UA_ENGINE)).set(UA_OS,detect(UA_OS))}}return this};this.parseUA=function(){if(this.itemType!=UA_RESULT){rgxMapper.call(this.data,this.ua,this.rgxMap)}if(this.itemType==UA_BROWSER){this.set(MAJOR,majorize(this.get(VERSION)))}return this};this.parseCH=function(){var uaCH=this.uaCH,rgxMap=this.rgxMap;switch(this.itemType){case UA_BROWSER:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS],prevName;if(brands){for(var i in brands){var brandName=strip(/(Google|Microsoft) /,brands[i].brand||brands[i]),brandVersion=brands[i].version;if(!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&!/chromi/i.test(brandName))){this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL])}if(uaCH[MODEL]=="Xbox"){this.set(TYPE,CONSOLE).set(VENDOR,MICROSOFT)}if(uaCH[FORMFACTOR]){var ff;if(typeof uaCH[FORMFACTOR]!=="string"){var idx=0;while(!ff&&idx=13?"11":"10";this.set(NAME,osName).set(VERSION,osVersion)}if(this.get(NAME)==WINDOWS&&uaCH[MODEL]=="Xbox"){this.set(NAME,"Xbox").set(VERSION,undefined)}break;case UA_RESULT:var data=this.data;var parse=function(itemType){return data[itemType].getItem().setCH(uaCH).parseCH().get()};this.set(UA_BROWSER,parse(UA_BROWSER)).set(UA_CPU,parse(UA_CPU)).set(UA_DEVICE,parse(UA_DEVICE)).set(UA_ENGINE,parse(UA_ENGINE)).set(UA_OS,parse(UA_OS))}return this};setProps.call(this,[["itemType",itemType],["ua",ua],["uaCH",uaCH],["rgxMap",rgxMap],["data",createIData(this,itemType)]]);return this}function UAParser(ua,extensions,headers){if(typeof ua===OBJ_TYPE){if(isExtensions(ua)){if(typeof extensions===OBJ_TYPE){headers=extensions}extensions=ua}else{headers=ua;extensions=undefined}ua=undefined}else if(typeof ua===STR_TYPE&&!isExtensions(extensions)){headers=extensions;extensions=undefined}if(!(this instanceof UAParser)){return new UAParser(ua,extensions,headers).getResult()}var userAgent=typeof ua===STR_TYPE?ua:NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:headers&&headers[USER_AGENT]?headers[USER_AGENT]:EMPTY,httpUACH=new UACHData(headers,true),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){if(itemType==UA_RESULT){return function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(UA_BROWSER,this.getBrowser()).set(UA_CPU,this.getCPU()).set(UA_DEVICE,this.getDevice()).set(UA_ENGINE,this.getEngine()).set(UA_OS,this.getOS()).get()}}else{return function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}}};setProps.call(this,[["getBrowser",createItemFunc(UA_BROWSER)],["getCPU",createItemFunc(UA_CPU)],["getDevice",createItemFunc(UA_DEVICE)],["getEngine",createItemFunc(UA_ENGINE)],["getOS",createItemFunc(UA_OS)],["getResult",createItemFunc(UA_RESULT)],["getUA",function(){return userAgent}],["setUA",function(ua){if(isString(ua))userAgent=ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this}]]).setUA(userAgent);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(isWindow){window.UAParser=UAParser}}var $=isWindow&&(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 8013a06..320b571 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.0-beta.1 +/* UAParser.js v2.0.0-beta.2 Copyright © 2012-2023 Faisal Salman AGPLv3 License */ -!function(i,c){"use strict";function e(i){for(var e={},t=0;t_?yi(i,_):i),this}]]).setUA(o),this}Pi.VERSION="2.0.0-beta.1",Pi.BROWSER=e([f,g,p]),Pi.CPU=e([v]),Pi.DEVICE=e([h,t,m,o,x,a,r,l,k]),Pi.ENGINE=Pi.OS=e([f,g]),typeof exports!==b?(typeof module!==b&&module.exports&&(exports=module.exports=Pi),exports.UAParser=Pi):typeof define===u&&define.amd?define(function(){return Pi}):typeof i!==b&&(i.UAParser=Pi);var Ui,Hi=typeof i!==b&&(i.jQuery||i.Zepto);Hi&&!Hi.ua&&(Ui=new Pi,Hi.ua=Ui.getResult(),Hi.ua.get=function(){return Ui.getUA()},Hi.ua.set=function(i){Ui.setUA(i);var e,t=Ui.getResult();for(e in t)Hi.ua[e]=t[e]})}("object"==typeof window?window:this); \ No newline at end of file +!function(i,u){"use strict";function e(i){for(var e={},t=0;t_?Ti(i,_):i),this}]]).setUA(o),this}Hi.VERSION="2.0.0-beta.2",Hi.BROWSER=e([f,v,p]),Hi.CPU=e([x]),Hi.DEVICE=e([h,g,m,k,y,t,r,o,a]),Hi.ENGINE=Hi.OS=e([f,v]),typeof exports!==b?(typeof module!==b&&module.exports&&(exports=module.exports=Hi),exports.UAParser=Hi):typeof define===c&&define.amd?define(function(){return Hi}):di&&(i.UAParser=Hi);var Ei,Mi=di&&(i.jQuery||i.Zepto);Mi&&!Mi.ua&&(Ei=new Hi,Mi.ua=Ei.getResult(),Mi.ua.get=function(){return Ei.getUA()},Mi.ua.set=function(i){Ei.setUA(i);var e,t=Ei.getResult();for(e in t)Mi.ua[e]=t[e]})}("object"==typeof window?window:this); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 72b415e..818a3bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ua-parser-js", - "version": "2.0.0-beta.1", + "version": "2.0.0-beta.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ua-parser-js", - "version": "2.0.0-beta.1", + "version": "2.0.0-beta.2", "funding": [ { "type": "opencollective", diff --git a/package.js b/package.js index 9b44ab3..d58154c 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'faisalman:ua-parser-js', - version: '2.0.0-beta.1', + version: '2.0.0-beta.2', summary: 'Lightweight JavaScript-based user-agent string parser', git: 'https://github.com/faisalman/ua-parser-js.git', documentation: 'readme.md' diff --git a/package.json b/package.json index 7f8a20f..09bfd49 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "2.0.0-beta.1", + "version": "2.0.0-beta.2", "author": "Faisal Salman (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment", "keywords": [ diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 111e3f1..8930a27 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -1,5 +1,5 @@ /////////////////////////////////////////////// -/* Enums for UAParser.js v2.0.0-beta.1 +/* Enums for UAParser.js v2.0.0-beta.2 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/enums/ua-parser-enums.mjs b/src/enums/ua-parser-enums.mjs index 83a2114..7561942 100644 --- a/src/enums/ua-parser-enums.mjs +++ b/src/enums/ua-parser-enums.mjs @@ -3,7 +3,7 @@ // Source: /src/enums/ua-parser-enums.js /////////////////////////////////////////////// -/* Enums for UAParser.js v2.0.0-beta.1 +/* Enums for UAParser.js v2.0.0-beta.2 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ @@ -12,28 +12,137 @@ /*jshint esversion: 6 */ const Browser = Object.freeze({ + _2345_EXPLORER: '2345Explorer', + _360: '360 Browser', + ALIPAY: 'Alipay', + AMAYA: 'Amaya', ANDROID: 'Android Browser', + ARORA: 'Arora', + AVANT: 'Avant', + AVAST: 'Avast Secure Browser', + AVG: 'AVG Secure Browser', + BAIDU: 'Baidu Browser', + BASILISK: 'Basilisk', + BLAZER: 'Blazer', + BOLT: 'Bolt', + BOWSER: 'Bowser', BRAVE: 'Brave', + CAMINO: 'Camino', + CHIMERA: 'Chimera', CHROME: 'Chrome', + CHROME_HEADLESS: 'Chrome Headless', + CHROME_MOBILE: 'Mobile Chrome', + CHROME_WEBVIEW: 'Chrome WebView', CHROMIUM: 'Chromium', + COBALT: 'Cobalt', + COC_COC: 'Coc Coc', + COMODO_DRAGON: 'Comodo Dragon', + CONKEROR: 'Conkeror', + DILLO: 'Dillo', DOLPHIN: 'Dolphin', + DORIS: 'Doris', DUCKDUCKGO: 'DuckDuckGo', EDGE: 'Edge', + EPIPHANY: 'Epiphany', + FACEBOOK: 'Facebook', + FALKON: 'Falkon', + FIREBIRD: 'Firebird', FIREFOX: 'Firefox', - FOCUS: 'Focus', + FIREFOX_FOCUS: 'Firefox Focus', + FIREFOX_MOBILE: 'Mobile Firefox', + FIREFOX_REALITY: 'Firefox Reality', + FENNEC: 'Fennec', + FLOCK: 'Flock', + FLOW: 'Flow', + GO: 'Go Browser', + GOOGLE_SEARCH: 'GSA', + HEYTAP: 'HeyTap', + HUAWEI: 'Huawei Browser', + ICAB: 'iCab', + ICE: 'ICE Browser', + ICEAPE: 'IceApe', + ICECAT: 'IceCat', + ICEDRAGON: 'IceDragon', + ICEWEASEL: 'IceWeasel', IE: 'IE', + INSTAGRAM: 'Instagram', + IRIDIUM: 'Iridium', + IRON: 'Iron', + JASMINE: 'Jasmine', KONQUEROR: 'Konqueror', - MOBILE_CHROME: 'Mobile Chrome', - MOBILE_FIREFOX: 'Mobile Firefox', - MOBILE_SAFARI: 'Mobile Safari', + KAKAO: 'KakaoTalk', + KHTML: 'KHTML', + K_MELEON: 'K-Meleon', + KLAR: 'Klar', + KLARNA: 'Klarna', + KINDLE: 'Kindle', + LENOVO: 'Smart Lenovo Browser', + LIEBAO: 'LBBROWSER', + LINE: 'Line', + LINKEDIN: 'LinkedIn', + LINKS: 'Links', + LUNASCAPE: 'Lunascape', + LYNX: 'Lynx', + MAEMO: 'Maemo Browser', + MAXTHON: 'Maxthon', + MIDORI: 'Midori', + MINIMO: 'Minimo', + MIUI: 'MIUI Browser', + MOZILLA: 'Mozilla', + MOSAIC: 'Mosaic', + NAVER: 'Naver', + NETFRONT: 'NetFront', + NETSCAPE: 'Netscape', + NETSURF: 'Netsurf', + NOKIA: 'Nokia Browser', + OBIGO: 'Obigo', + OCULUS: 'Oculus Browser', + OMNIWEB: 'OmniWeb', OPERA: 'Opera', + OPERA_COAST: 'Opera Coast', + OPERA_MINI: 'Opera Mini', + OPERA_MOBI: 'Opera Mobi', + OPERA_TABLET: 'Opera Tablet', + OPERA_TOUCH: 'Opera Touch', + OVI: 'OviBrowser', PALEMOON: 'PaleMoon', + PHANTOMJS: 'PhantomJS', + PHOENIX: 'Phoenix', + POLARIS: 'Polaris', PUFFIN: 'Puffin', - QQ: 'QQ Browser', + QQ: 'QQBrowser', + QQ_LITE: 'QQBrowserLite', + QUARK: 'Quark', + QUPZILLA: 'QupZilla', + REKONQ: 'rekonq', + ROCKMELT: 'Rockmelt', SAFARI: 'Safari', + SAFARI_MOBILE: 'Mobile Safari', + SAILFISH: 'Sailfish Browser', SAMSUNG: 'Samsung Internet', - UC: 'UC Browser', + SEAMONKEY: 'SeaMonkey', + SILK: 'Silk', + SKYFIRE: 'Skyfire', + SLEIPNIR: 'Sleipnir', + SLIMBROWSER: 'SlimBrowser', + SNAPCHAT: 'Snapchat', + SOGOU_EXPLORER: 'Sogou Explorer', + SOGOU_MOBILE: 'Sogou Mobile', + SWIFTFOX: 'Swiftfox', + TESLA: 'Tesla', + TIKTOK: 'TikTok', + TIZEN: 'Tizen Browser', + UC: 'UCBrowser', + UP: 'UP.Browser', + VIERA: 'Viera', VIVALDI: 'Vivaldi', + VIVO: 'Vivo Browser', + W3M: 'w3m', + WATERFOX: 'Waterfox', + WEBKIT: 'WebKit', + WECHAT: 'WeChat', + WEIBO: 'Weibo', + WHALE: 'Whale', YANDEX: 'Yandex' // TODO : test! @@ -41,25 +150,27 @@ const Browser = Object.freeze({ const CPU = Object.freeze({ ARM : 'arm', - ARM64: 'arm64', - ARMHF: 'armhf', + ARM_64: 'arm64', + ARM_HF: 'armhf', AVR: 'avr', + AVR_32: 'avr32', IA64: 'ia64', IRIX: 'irix', - IRIX64: 'irix64', + IRIX_64: 'irix64', MIPS: 'mips', - MIPS64: 'mips64', - MOTO_68K: '68k', + MIPS_64: 'mips64', + M68K: '68k', + PA_RISC: 'pa-risc', PPC: 'ppc', SPARC: 'sparc', - SPARC64: 'sparc64', + SPARC_64: 'sparc64', X86: 'ia32', X86_64: 'amd64' }); const Device = Object.freeze({ CONSOLE: 'console', - DEKSTOP: 'desktop', + DESKTOP: 'desktop', EMBEDDED: 'embedded', MOBILE: 'mobile', SMARTTV: 'smarttv', @@ -114,6 +225,7 @@ const Vendor = Object.freeze({ SIEMENS: 'Siemens', SONY: 'Sony', SPRINT: 'Sprint', + TECHNISAT: 'TechniSAT', TECNO: 'Tecno', TESLA: 'Tesla', ULEFONE: 'Ulefone', @@ -159,14 +271,15 @@ const OS = Object.freeze({ BLACKBERRY: 'BlackBerry', CENTOS: 'CentOS', CHROME_OS: 'Chrome OS', + CHROMECAST: 'Chromecast', CONTIKI: 'Contiki', - FEDORA: 'Fedora', - FIREFOX_OS: 'Firefox OS', - FREEBSD: 'FreeBSD', DEBIAN: 'Debian', DEEPIN: 'Deepin', DRAGONFLY: 'DragonFly', ELEMENTARY_OS: 'elementary OS', + FEDORA: 'Fedora', + FIREFOX_OS: 'Firefox OS', + FREEBSD: 'FreeBSD', FUCHSIA: 'Fuchsia', GENTOO: 'Gentoo', GHOSTBSD: 'GhostBSD', @@ -225,6 +338,7 @@ const OS = Object.freeze({ WINDOWS: 'Windows', WINDOWS_MOBILE: 'Windows Mobile', WINDOWS_PHONE: 'Windows Phone', + XBOX: 'Xbox', ZENWALK: 'Zenwalk' // TODO : test! diff --git a/src/extensions/ua-parser-extensions.d.ts b/src/extensions/ua-parser-extensions.d.ts index 12750c8..5f3a5e3 100644 --- a/src/extensions/ua-parser-extensions.d.ts +++ b/src/extensions/ua-parser-extensions.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.1 +// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.2 // Project: https://github.com/faisalman/ua-parser-js // Definitions by: Faisal Salman diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 4b1d5cd..777d227 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -1,5 +1,5 @@ /////////////////////////////////////////////// -/* Extensions for UAParser.js v2.0.0-beta.1 +/* Extensions for UAParser.js v2.0.0-beta.2 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/extensions/ua-parser-extensions.mjs b/src/extensions/ua-parser-extensions.mjs index 0af69e3..e0f9c8a 100644 --- a/src/extensions/ua-parser-extensions.mjs +++ b/src/extensions/ua-parser-extensions.mjs @@ -3,7 +3,7 @@ // Source: /src/extensions/ua-parser-extensions.js /////////////////////////////////////////////// -/* Extensions for UAParser.js v2.0.0-beta.1 +/* Extensions for UAParser.js v2.0.0-beta.2 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/helpers/ua-parser-helpers.d.ts b/src/helpers/ua-parser-helpers.d.ts index c7e9b1e..8102361 100644 --- a/src/helpers/ua-parser-helpers.d.ts +++ b/src/helpers/ua-parser-helpers.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.1 +// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.2 // Project: https://github.com/faisalman/ua-parser-js // Definitions by: Faisal Salman diff --git a/src/helpers/ua-parser-helpers.js b/src/helpers/ua-parser-helpers.js index 350b029..17eea7a 100644 --- a/src/helpers/ua-parser-helpers.js +++ b/src/helpers/ua-parser-helpers.js @@ -1,5 +1,5 @@ /////////////////////////////////////////////// -/* Helpers for UAParser.js v2.0.0-beta.1 +/* Helpers for UAParser.js v2.0.0-beta.2 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/helpers/ua-parser-helpers.mjs b/src/helpers/ua-parser-helpers.mjs new file mode 100644 index 0000000..d710c28 --- /dev/null +++ b/src/helpers/ua-parser-helpers.mjs @@ -0,0 +1,26 @@ +// Generated ESM version of ua-parser-js/helpers +// DO NOT EDIT THIS FILE! +// Source: /src/helpers/ua-parser-helpers.js + +/////////////////////////////////////////////// +/* Helpers for UAParser.js v2.0.0-beta.2 + https://github.com/faisalman/ua-parser-js + Author: Faisal Salman + AGPLv3 License */ +////////////////////////////////////////////// + +/*jshint esversion: 6 */ + +import { CPU, OS, Engine } from '../enums/ua-parser-enums'; + +const isAppleSilicon = (res) => res.os.is(OS.MACOS) && res.cpu.is(CPU.ARM); + +const isChromiumBased = (res) => res.engine.is(Engine.BLINK); + +const isFrozenUA = (ua) => /^Mozilla\/5\.0 \((Windows NT 10\.0; Win64; x64|Macintosh; Intel Mac OS X 10_15_7|X11; Linux x86_64|X11; CrOS x86_64 14541\.0\.0|Fuchsia|Linux; Android 10; K)\) AppleWebKit\/537\.36 \(KHTML, like Gecko\) Chrome\/\d+\.0\.0\.0 (Mobile )?Safari\/537\.36/.test(ua); + +export { + isAppleSilicon, + isChromiumBased, + isFrozenUA +} \ No newline at end of file diff --git a/src/main/ua-parser.d.ts b/src/main/ua-parser.d.ts index 3fa5749..09308fe 100644 --- a/src/main/ua-parser.d.ts +++ b/src/main/ua-parser.d.ts @@ -1,4 +1,4 @@ -// Type definitions for UAParser.js v2.0.0-beta.1 +// Type definitions for UAParser.js v2.0.0-beta.2 // Project: https://github.com/faisalman/ua-parser-js // Definitions by: Faisal Salman diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index df3c2da..7de870b 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v2.0.0-beta.1 +/* UAParser.js v2.0.0-beta.2 Copyright © 2012-2023 Faisal Salman AGPLv3 License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. @@ -19,7 +19,7 @@ // Constants ///////////// - var LIBVERSION = '2.0.0-beta.1', + var LIBVERSION = '2.0.0-beta.2', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', diff --git a/src/main/ua-parser.mjs b/src/main/ua-parser.mjs index abb8d60..0f4c2a8 100644 --- a/src/main/ua-parser.mjs +++ b/src/main/ua-parser.mjs @@ -3,7 +3,7 @@ // Source: /src/main/ua-parser.js ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v2.0.0-beta.1 +/* UAParser.js v2.0.0-beta.2 Copyright © 2012-2023 Faisal Salman AGPLv3 License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. @@ -21,8 +21,7 @@ // Constants ///////////// - - var LIBVERSION = '2.0.0-beta.1', + var LIBVERSION = '2.0.0-beta.2', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', @@ -43,7 +42,7 @@ WEARABLE = 'wearable', EMBEDDED = 'embedded', USER_AGENT = 'user-agent', - UA_MAX_LENGTH = 350, + UA_MAX_LENGTH = 500, BRANDS = 'brands', FORMFACTOR = 'formFactor', FULLVERLIST = 'fullVersionList', @@ -72,6 +71,7 @@ BLACKBERRY = 'BlackBerry', GOOGLE = 'Google', HUAWEI = 'Huawei', + LENOVO = 'Lenovo', LG = 'LG', MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola', @@ -87,9 +87,11 @@ FIREFOX = 'Firefox', OPERA = 'Opera', FACEBOOK = 'Facebook', + SOGOU = 'Sogou', WINDOWS = 'Windows'; - var NAVIGATOR = (typeof window !== UNDEF_TYPE && window.navigator) ? + var isWindow = typeof window !== UNDEF_TYPE, + NAVIGATOR = (isWindow && window.navigator) ? window.navigator : undefined, NAVIGATOR_UADATA = (NAVIGATOR && NAVIGATOR.userAgentData) ? @@ -121,13 +123,16 @@ } return false; } - return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false; + return isString(str1) ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false; }, isExtensions = function (obj) { for (var prop in obj) { return /^(browser|cpu|device|engine|os)$/.test(prop); } }, + isString = function (val) { + return typeof val === STR_TYPE; + }, itemListToArray = function (header) { if (!header) return undefined; var arr = []; @@ -137,16 +142,16 @@ var token = trim(tokens[i]).split(';v='); arr[i] = { brand : token[0], version : token[1] }; } else { - arr[i] = tokens[i]; + arr[i] = trim(tokens[i]); } } return arr; }, lowerize = function (str) { - return typeof(str) === STR_TYPE ? str.toLowerCase() : str; + return isString(str) ? str.toLowerCase() : str; }, majorize = function (version) { - return typeof(version) === STR_TYPE ? strip(/[^\d\.]/g, version).split('.')[0] : undefined; + return isString(version) ? strip(/[^\d\.]/g, version).split('.')[0] : undefined; }, setProps = function (arr) { for (var i in arr) { @@ -160,15 +165,15 @@ return this; }, strip = function (pattern, str) { - return str.replace(pattern, EMPTY); + return isString(str) ? str.replace(pattern, EMPTY) : str; }, - stripQuotes = function (val) { - return typeof val === STR_TYPE ? strip(/\\?\"/g, val) : val; + stripQuotes = function (str) { + return strip(/\\?\"/g, str); }, trim = function (str, len) { - if (typeof(str) === STR_TYPE) { + if (isString(str)) { str = strip(/^\s\s*/, str); - return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); + return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); } }; @@ -297,15 +302,18 @@ ], [NAME, VERSION], [ /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0 ], [VERSION, [NAME, OPERA+' Mini']], [ + /\bop(?:rg)?x\/([\w\.]+)/i // Opera GX + ], [VERSION, [NAME, OPERA+' GX']], [ /\bopr\/([\w\.]+)/i // Opera Webkit ], [VERSION, [NAME, OPERA]], [ // Mixed + /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu + ], [VERSION, [NAME, 'Baidu']], [ /(kindle)\/([\w\.]+)/i, // Kindle /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer // Trident based - /(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser - /(ba?idubrowser)[\/ ]?([\w\.]+)/i, // Baidu Browser + /(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon @@ -317,8 +325,7 @@ /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser ], [VERSION, [NAME, 'UCBrowser']], [ /microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser - /\bqbcore\/([\w\.]+).+microm/i - ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [ + /\bqbcore\/([\w\.]+).+microm/i, /micromessenger\/([\w\.]+)/i // WeChat ], [VERSION, [NAME, 'WeChat']], [ /konqueror\/([\w\.]+)/i // Konqueror @@ -327,6 +334,8 @@ ], [VERSION, [NAME, 'IE']], [ /ya(?:search)?browser\/([\w\.]+)/i // Yandex ], [VERSION, [NAME, 'Yandex']], [ + /slbrowser\/([\w\.]+)/i // Smart Lenovo Browser + ], [VERSION, [NAME, 'Smart ' + LENOVO + SUFFIX_BROWSER]], [ /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser ], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [ /\bfocus\/([\w\.]+)/i // Firefox Focus @@ -345,15 +354,20 @@ ], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [ /\bqihu|(qi?ho?o?|360)browser/i // 360 ], [[NAME, '360' + SUFFIX_BROWSER]], [ - /(oculus|samsung|sailfish|huawei)browser\/([\w\.]+)/i - ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Samsung/Sailfish/Huawei Browser + /(oculus|sailfish|huawei|vivo)browser\/([\w\.]+)/i + ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser + /samsungbrowser\/([\w\.]+)/i // Samsung Internet + ], [VERSION, [NAME, SAMSUNG + ' Internet']], [ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ + /metasr[\/ ]?([\d\.]+)/i // Sogou Explorer + ], [VERSION, [NAME, SOGOU + ' Explorer']], [ + /(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile + ], [[NAME, SOGOU + ' Mobile'], VERSION], [ /(electron)\/([\w\.]+) safari/i, // Electron-based App /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla - /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser + /m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser ], [NAME, VERSION], [ - /(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser /(lbbrowser)/i, // LieBao Browser /\[(linkedin)app\]/i // LinkedIn App for iOS & Android ], [NAME], [ @@ -361,10 +375,12 @@ // WebView /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android ], [[NAME, FACEBOOK], VERSION], [ + /(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android + /(alipay)client\/([\w\.]+)/i, // Alipay /(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat ], [NAME, VERSION], [ /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS @@ -496,7 +512,7 @@ /\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 - /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|\))/i, // Xiaomi Redmi 'numeric' models + /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad @@ -536,7 +552,7 @@ // Lenovo /(ideatab[-\w ]+)/i, /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i - ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ + ], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [ // Nokia /(?:maemo|nokia).*(n900|lumia \d+)/i, @@ -710,7 +726,7 @@ // MIXED (GENERIC) /////////////////// - /droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors + /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors ], [MODEL, [TYPE, MOBILE]], [ /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors ], [MODEL, [TYPE, TABLET]], [ @@ -747,12 +763,12 @@ // Windows /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ - /(windows) nt 6\.2; (arm)/i, // Windows RT - /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, // Windows Phone - /(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i + /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i // Windows Phone ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ - /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i - ], [[NAME, WINDOWS], [VERSION, strMapper, windowsVersionMap]], [ + /windows nt 6\.2; (arm)/i, // Windows RT + /windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i, + /(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i + ], [[VERSION, strMapper, windowsVersionMap], [NAME, WINDOWS]], [ // iOS/macOS /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS @@ -1041,15 +1057,16 @@ switch (this.itemType) { case UA_BROWSER: - var brands = uaCH[FULLVERLIST] || uaCH[BRANDS]; + var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName; if (brands) { for (var i in brands) { - var brandName = brands[i].brand, + var brandName = strip(/(Google|Microsoft) /, brands[i].brand || brands[i]), brandVersion = brands[i].version; - if (!/not.a.brand/i.test(brandName) && (i < 1 || /chromi/i.test(this.get(NAME)))) { - this.set(NAME, strip(GOOGLE+' ', brandName)) + if (!/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && !/chromi/i.test(brandName)))) { + this.set(NAME, brandName) .set(VERSION, brandVersion) .set(MAJOR, majorize(brandVersion)); + prevName = brandName; } } } @@ -1068,6 +1085,11 @@ if (uaCH[MODEL]) { this.set(MODEL, uaCH[MODEL]); } + // Xbox-Specific Detection + if (uaCH[MODEL] == 'Xbox') { + this.set(TYPE, CONSOLE) + .set(VENDOR, MICROSOFT); + } if (uaCH[FORMFACTOR]) { var ff; if (typeof uaCH[FORMFACTOR] !== 'string') { @@ -1089,6 +1111,11 @@ this.set(NAME, osName) .set(VERSION, osVersion); } + // Xbox-Specific Detection + if (this.get(NAME) == WINDOWS && uaCH[MODEL] == 'Xbox') { + this.set(NAME, 'Xbox') + .set(VERSION, undefined); + } break; case UA_RESULT: var data = this.data; @@ -1182,7 +1209,7 @@ ['getResult', createItemFunc(UA_RESULT)], ['getUA', function () { return userAgent; }], ['setUA', function (ua) { - if (typeof ua === STR_TYPE) + if (isString(ua)) userAgent = ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua; return this; }] diff --git a/test/specs/browser-all.json b/test/specs/browser-all.json index bae2f99..471cdb3 100644 --- a/test/specs/browser-all.json +++ b/test/specs/browser-all.json @@ -1308,6 +1308,16 @@ "major" : "4" } }, + { + "desc" : "Samsung Internet in Redmi 8A", + "ua" : "Mozilla/5.0 (Linux; Android 10; Redmi 8A) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36", + "expect" : + { + "name" : "Samsung Internet", + "version" : "23.0", + "major" : "23" + } + }, { "desc" : "SeaMonkey", "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b4pre) Gecko/20090405 SeaMonkey/2.0b1pre",