From 801c2409b3e0fb83f67e95ebeca2723adb4976c9 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 9 Apr 2023 15:54:46 +0700 Subject: [PATCH] Update readme & IData explanations --- dist/ua-parser.min.js | 2 +- dist/ua-parser.pack.js | 2 +- readme.md | 127 +++++++++++++++++++++++++-------------- src/module/ua-parser.mjs | 62 ++++++++++++------- src/ua-parser.js | 42 ++++++------- 5 files changed, 144 insertions(+), 91 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index d5b153c..e18ba06 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ /* UAParser.js v2.0.0-alpha.2 Copyright © 2012-2023 Faisal Salman MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="2.0.0-alpha.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=350,BRANDS="brands",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_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","fullVersionList",MOBILE,MODEL,"platform","platformVersion",ARCHITECTURE,"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;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])}}}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 ua=this.ua,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])}break;case UA_OS:var osName=uaCH[PLATFORM];if(osName){var osVersion=uaCH[PLATFORMVER];if(osName==WINDOWS)osVersion=parseInt(majorize(osVersion),10)>=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",ua).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",createUAParserData(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=ua||(NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:headers&&headers[USER_AGENT]?headers[USER_AGENT]:EMPTY),HTTP_UACH=new UAParserDataCH(headers,true),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){if(itemType==UA_RESULT){return function(){return new UAParserItem(itemType,userAgent,regexMap,HTTP_UACH).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 UAParserItem(itemType,userAgent,regexMap[itemType],HTTP_UACH).parseUA().detectFeature().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){userAgent=typeof ua===STR_TYPE&&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-alpha.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=350,BRANDS="brands",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_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","fullVersionList",MOBILE,MODEL,"platform","platformVersion",ARCHITECTURE,"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;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 ua=this.ua,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])}break;case UA_OS:var osName=uaCH[PLATFORM];if(osName){var osVersion=uaCH[PLATFORMVER];if(osName==WINDOWS)osVersion=parseInt(majorize(osVersion),10)>=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=ua||(NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:headers&&headers[USER_AGENT]?headers[USER_AGENT]:EMPTY),HTTP_UACH=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,HTTP_UACH).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],HTTP_UACH).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){userAgent=typeof ua===STR_TYPE&&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 diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index 141057c..59ce392 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ /* UAParser.js v2.0.0-alpha.2 Copyright © 2012-2023 Faisal Salman MIT License */ -!function(i,u){"use strict";function e(i){for(var e={},t=0;tS?ki(i,S):i,this}]]).setUA(o),this}Ni.VERSION="2.0.0-alpha.2",Ni.BROWSER=e([h,m,l]),Ni.CPU=e([g]),Ni.DEVICE=e([p,o,f,r,v,x,a,k,y]),Ni.ENGINE=Ni.OS=e([h,m]),typeof exports!==b?(typeof module!==b&&module.exports&&(exports=module.exports=Ni),exports.UAParser=Ni):typeof define===c&&define.amd?define(function(){return Ni}):typeof i!==b&&(i.UAParser=Ni);var Oi,zi=typeof i!==b&&(i.jQuery||i.Zepto);zi&&!zi.ua&&(Oi=new Ni,zi.ua=Oi.getResult(),zi.ua.get=function(){return Oi.getUA()},zi.ua.set=function(i){Oi.setUA(i);var e,t=Oi.getResult();for(e in t)zi.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;tS?ki(i,S):i,this}]]).setUA(o),this}Ni.VERSION="2.0.0-alpha.2",Ni.BROWSER=e([h,m,l]),Ni.CPU=e([g]),Ni.DEVICE=e([p,o,f,r,v,x,a,k,y]),Ni.ENGINE=Ni.OS=e([h,m]),typeof exports!==b?(typeof module!==b&&module.exports&&(exports=module.exports=Ni),exports.UAParser=Ni):typeof define===c&&define.amd?define(function(){return Ni}):typeof i!==b&&(i.UAParser=Ni);var Oi,zi=typeof i!==b&&(i.jQuery||i.Zepto);zi&&!zi.ua&&(Oi=new Ni,zi.ua=Oi.getResult(),zi.ua.get=function(){return Oi.getUA()},zi.ua.set=function(i){Oi.setUA(i);var e,t=Oi.getResult();for(e in t)zi.ua[e]=t[e]})}("object"==typeof window?window:this); \ No newline at end of file diff --git a/readme.md b/readme.md index b73df8d..ed4c749 100644 --- a/readme.md +++ b/readme.md @@ -3,11 +3,13 @@

- - - - - + + + + + + +

# UAParser.js @@ -47,39 +49,47 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro What's new & breaking, please read [CHANGELOG](changelog.md) before upgrading. # Documentation -### UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)]) - -In the browser environment you dont need to pass the user-agent string to the function, you can just call the funtion and it should automatically get the string from the `window.navigator.userAgent`, but that is not the case in nodejs. The user-agent string must be passed in' nodejs for the function to work. Usually you can find the user agent in: `request.headers["user-agent"]`. +### `UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)]):IData` +In browser environment you don't need to pass the user-agent string to the function, as it should automatically get the string from the `window.navigator.userAgent`. Whereas in nodejs environment, the user-agent string must be passed in order for the function to work (usually you can find the user-agent in: `request.headers["user-agent"]`). ## Constructor + +#### * `new UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)]):UAParser` + When you call `UAParser` with the `new` keyword, `UAParser` will return a new instance with an empty result object, you have to call one of the available methods to get the information from the user-agent string. Like so: -* `new UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)])` + ```js let parser = new UAParser("your user-agent here"); // you need to pass the user-agent for nodejs console.log(parser); // {} let parserResults = parser.getResult(); console.log(parserResults); -/** { - "ua" : "", - "browser" : {}, - "engine" : {}, - "os" : {}, - "device" : {}, - "cpu" : {} -} */ +/* + { + ua : "", + browser : {}, + engine : {}, + os : {}, + device : {}, + cpu : {} + } +*/ ``` -When you call UAParser without the `new` keyword, it will automatically call `getResult()` function and return the parsed results. -* `UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)])` - * returns result object `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }` +#### * `UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)]):IData` -## Methods +When you call `UAParser` without the `new` keyword, it will automatically call `getResult()` function and return the parsed results. + +```sh +returns result object `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }` +``` + +## `UAParser`: #### Methods table The methods are self explanatory, here's a small overview on all the available methods: -* `getResult()` - returns all function object calls, user-agent string, browser info, cpu, device, engine, os: + * `getResult()` - returns all function object calls, user-agent string, browser info, cpu, device, engine, os: `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }`. * `getBrowser()` - returns the browser name and version. @@ -88,17 +98,21 @@ The methods are self explanatory, here's a small overview on all the available m * `getOS()` - returns the running operating system name and version. * `getCPU()` - returns CPU architectural design name. * `getUA()` - returns the user-agent string. - * `setUA(user-agent)` - set a custom user-agent to be parsed. + * `setUA(ua)` - set a custom user-agent to be parsed. --- -* `getResult()` - * returns `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }` - -* `getBrowser()` - * returns `{ name: '', version: '' }` +#### * `getResult():IData` ```sh +returns `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }` +``` + +#### * `getBrowser():IData` + +```sh +returns `{ name: '', version: '' }` + # Possible 'browser.name': 2345Explorer, 360 Browser, Amaya, Android Browser, Arora, Avant, Avast, AVG, BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, @@ -119,10 +133,11 @@ Vivaldi, Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m, Whale Browser, ... # 'browser.version' determined dynamically ``` -* `getDevice()` - * returns `{ model: '', type: '', vendor: '' }` +#### * `getDevice():IData` ```sh +returns `{ model: '', type: '', vendor: '' }` + # Possible 'device.type': console, mobile, tablet, smarttv, wearable, embedded @@ -143,10 +158,11 @@ Siemens, Sony[Ericsson], Sprint, Tesla, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE # 'device.model' determined dynamically ``` -* `getEngine()` - * returns `{ name: '', version: '' }` +#### * `getEngine():IData` ```sh +returns `{ name: '', version: '' }` + # Possible 'engine.name' Amaya, Blink, EdgeHTML, Flow, Gecko, Goanna, iCab, KHTML, LibWeb, Links, Lynx, NetFront, NetSurf, Presto, Tasman, Trident, w3m, WebKit @@ -154,10 +170,11 @@ NetFront, NetSurf, Presto, Tasman, Trident, w3m, WebKit # 'engine.version' determined dynamically ``` -* `getOS()` - * returns `{ name: '', version: '' }` +#### * `getOS():IData` ```sh +returns `{ name: '', version: '' }` + # Possible 'os.name' AIX, Amiga OS, Android[-x86], Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, Contiki, Fedora, Firefox OS, FreeBSD, Debian, Deepin, DragonFly, elementary OS, @@ -172,22 +189,42 @@ Zenwalk, ... # 'os.version' determined dynamically ``` -* `getCPU()` - * returns `{ architecture: '' }` +#### * `getCPU():IData` ```sh +returns `{ architecture: '' }` + # Possible 'cpu.architecture' 68k, amd64, arm[64/hf], avr, ia[32/64], irix[64], mips[64], pa-risc, ppc, sparc[64] ``` -* `getUA()` - * returns UA string of current instance +#### * `getUA():string` -* `setUA(uastring)` - * set UA string to be parsed - * returns current instance +```sh +returns user-agent string of current instance +``` -#### * `is():boolean` utility `since@2.0` +#### * `setUA(ua:string):UAParser` + +```sh +set user-agent string to be parsed +returns current instance +``` + +--- + +## `IData`: `since@2.0` + +#### Methods table +The methods are self explanatory, here's a small overview on all the available methods: + * `is(value)` - returns `true` if the passed value matches a value of current object, `false` otherwise + * `toString()` - returns the full-name values of current object as a string + * `withClientHints()` - returns an object with re-updated data from client hints + * `withFeatureCheck()` - returns an object with re-updated data from feature detection + +--- + +#### * `is(value:string):boolean` ```js // Is just a shorthand comparison to check whether the value of specified item equals one of its properties (in a case-insensitive way) @@ -246,7 +283,7 @@ let engine = uap.getEngine(); engine.is("Blink"); // true ``` -#### * `toString():string` utility `since@2.0` +#### * `toString():string` ```js // Retrieve full-name values as a string @@ -287,7 +324,7 @@ engine.version; // "28.0.1500.95" engine.toString(); // "Blink 28.0.1500.95" ``` -#### * `withClientHints():Promise|Thenable|object` `since@2.0` +#### * `withClientHints():Promise|Thenable|IData` Recently, Chrome limits the information exposed through user-agent and introduces a new experimental set of data called "client-hints". In browser-environment, obtaining the client-hints data via JavaScript must be done in an asynchronous way. In `UAParser` you can chain the result object from `get*` method with `withClientHints()` to also read the client-hints data from the browser and return the updated data as a `Promise`. @@ -346,7 +383,7 @@ new UAParser(request.headers) }); ``` -#### * `withFeatureCheck():object` `since@2.0` +#### * `withFeatureCheck():IData` This method allows us to examine other features beyond `navigator.userAgent` to further improve detection of the following: - browser : Brave (check for `navigator.isBrave`) diff --git a/src/module/ua-parser.mjs b/src/module/ua-parser.mjs index ba554e3..250eea7 100644 --- a/src/module/ua-parser.mjs +++ b/src/module/ua-parser.mjs @@ -829,22 +829,22 @@ return props; })(); - var createUAParserData = function (item, itemType) { + var createIData = function (item, itemType) { var init_props = defaultProps.init[itemType], is_ignoreProps = defaultProps.isIgnore[itemType] || 0, is_ignoreRgx = defaultProps.isIgnoreRgx[itemType] || 0, toString_props = defaultProps.toString[itemType] || 0; - function UAParserData () { + function IData () { setProps.call(this, init_props); } - UAParserData.prototype.getItem = function () { + IData.prototype.getItem = function () { return item; }; - UAParserData.prototype.withClientHints = function () { + IData.prototype.withClientHints = function () { // nodejs / non-client-hints browsers if (!NAVIGATOR_UADATA) { @@ -858,14 +858,18 @@ .getHighEntropyValues(CH_ALL_VALUES) .then(function (res) { return item - .setCH(new UAParserDataCH(res, false)) + .setCH(new UACHData(res, false)) .parseCH() .get(); }); }; + IData.prototype.withFeatureCheck = function () { + return item.detectFeature().get(); + }; + if (itemType != UA_RESULT) { - UAParserData.prototype.is = function (strToCheck) { + IData.prototype.is = function (strToCheck) { var is = false; for (var i in this) { if (this.hasOwnProperty(i) && !has(is_ignoreProps, i) && lowerize(is_ignoreRgx ? strip(is_ignoreRgx, this[i]) : this[i]) == lowerize(is_ignoreRgx ? strip(is_ignoreRgx, strToCheck) : strToCheck)) { @@ -878,7 +882,7 @@ } return is; }; - UAParserData.prototype.toString = function () { + IData.prototype.toString = function () { var str = EMPTY; for (var i in toString_props) { if (typeof(this[toString_props[i]]) !== UNDEF_TYPE) { @@ -890,33 +894,33 @@ } if (!NAVIGATOR_UADATA) { - UAParserData.prototype.then = function (cb) { + IData.prototype.then = function (cb) { var that = this; - var UAParserDataResolve = function () { + var IDataResolve = function () { for (var prop in that) { if (that.hasOwnProperty(prop)) { this[prop] = that[prop]; } } }; - UAParserDataResolve.prototype = { - is : UAParserData.prototype.is, - toString : UAParserData.prototype.toString + IDataResolve.prototype = { + is : IData.prototype.is, + toString : IData.prototype.toString }; - var resolveData = new UAParserDataResolve(); + var resolveData = new IDataResolve(); cb(resolveData); return resolveData; }; } - return new UAParserData(); + return new IData(); }; ///////////////// // Constructor //////////////// - function UAParserDataCH (uach, isHTTP_UACH) { + function UACHData (uach, isHTTP_UACH) { uach = uach || {}; setProps.call(this, CH_ALL_VALUES); if (isHTTP_UACH) { @@ -938,7 +942,7 @@ } } - function UAParserItem (itemType, ua, rgxMap, uaCH) { + function UAItem (itemType, ua, rgxMap, uaCH) { this.get = function (prop) { if (!prop) return this.data; @@ -980,6 +984,20 @@ 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; @@ -1048,8 +1066,7 @@ .parseCH() .get(); }; - this.set('ua', ua) - .set(UA_BROWSER, parse(UA_BROWSER)) + 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)) @@ -1063,7 +1080,7 @@ ['ua', ua], ['uaCH', uaCH], ['rgxMap', rgxMap], - ['data', createUAParserData(this, itemType)] + ['data', createIData(this, itemType)] ]); return this; @@ -1098,7 +1115,7 @@ headers[USER_AGENT] : EMPTY)), - HTTP_UACH = new UAParserDataCH(headers, true), + HTTP_UACH = new UACHData(headers, true), regexMap = extensions ? extend(defaultRegexes, extensions) : @@ -1107,7 +1124,7 @@ createItemFunc = function (itemType) { if (itemType == UA_RESULT) { return function () { - return new UAParserItem(itemType, userAgent, regexMap, HTTP_UACH) + return new UAItem(itemType, userAgent, regexMap, HTTP_UACH) .set('ua', userAgent) .set(UA_BROWSER, this.getBrowser()) .set(UA_CPU, this.getCPU()) @@ -1118,9 +1135,8 @@ }; } else { return function () { - return new UAParserItem(itemType, userAgent, regexMap[itemType], HTTP_UACH) + return new UAItem(itemType, userAgent, regexMap[itemType], HTTP_UACH) .parseUA() - .detectFeature() .get(); }; } diff --git a/src/ua-parser.js b/src/ua-parser.js index 68ac98d..d72fda7 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -827,22 +827,22 @@ return props; })(); - var createUAParserData = function (item, itemType) { + var createIData = function (item, itemType) { var init_props = defaultProps.init[itemType], is_ignoreProps = defaultProps.isIgnore[itemType] || 0, is_ignoreRgx = defaultProps.isIgnoreRgx[itemType] || 0, toString_props = defaultProps.toString[itemType] || 0; - function UAParserData () { + function IData () { setProps.call(this, init_props); } - UAParserData.prototype.getItem = function () { + IData.prototype.getItem = function () { return item; }; - UAParserData.prototype.withClientHints = function () { + IData.prototype.withClientHints = function () { // nodejs / non-client-hints browsers if (!NAVIGATOR_UADATA) { @@ -856,18 +856,18 @@ .getHighEntropyValues(CH_ALL_VALUES) .then(function (res) { return item - .setCH(new UAParserDataCH(res, false)) + .setCH(new UACHData(res, false)) .parseCH() .get(); }); }; - UAParserData.prototype.withFeatureCheck = function () { + IData.prototype.withFeatureCheck = function () { return item.detectFeature().get(); }; if (itemType != UA_RESULT) { - UAParserData.prototype.is = function (strToCheck) { + IData.prototype.is = function (strToCheck) { var is = false; for (var i in this) { if (this.hasOwnProperty(i) && !has(is_ignoreProps, i) && lowerize(is_ignoreRgx ? strip(is_ignoreRgx, this[i]) : this[i]) == lowerize(is_ignoreRgx ? strip(is_ignoreRgx, strToCheck) : strToCheck)) { @@ -880,7 +880,7 @@ } return is; }; - UAParserData.prototype.toString = function () { + IData.prototype.toString = function () { var str = EMPTY; for (var i in toString_props) { if (typeof(this[toString_props[i]]) !== UNDEF_TYPE) { @@ -892,33 +892,33 @@ } if (!NAVIGATOR_UADATA) { - UAParserData.prototype.then = function (cb) { + IData.prototype.then = function (cb) { var that = this; - var UAParserDataResolve = function () { + var IDataResolve = function () { for (var prop in that) { if (that.hasOwnProperty(prop)) { this[prop] = that[prop]; } } }; - UAParserDataResolve.prototype = { - is : UAParserData.prototype.is, - toString : UAParserData.prototype.toString + IDataResolve.prototype = { + is : IData.prototype.is, + toString : IData.prototype.toString }; - var resolveData = new UAParserDataResolve(); + var resolveData = new IDataResolve(); cb(resolveData); return resolveData; }; } - return new UAParserData(); + return new IData(); }; ///////////////// // Constructor //////////////// - function UAParserDataCH (uach, isHTTP_UACH) { + function UACHData (uach, isHTTP_UACH) { uach = uach || {}; setProps.call(this, CH_ALL_VALUES); if (isHTTP_UACH) { @@ -940,7 +940,7 @@ } } - function UAParserItem (itemType, ua, rgxMap, uaCH) { + function UAItem (itemType, ua, rgxMap, uaCH) { this.get = function (prop) { if (!prop) return this.data; @@ -1078,7 +1078,7 @@ ['ua', ua], ['uaCH', uaCH], ['rgxMap', rgxMap], - ['data', createUAParserData(this, itemType)] + ['data', createIData(this, itemType)] ]); return this; @@ -1113,7 +1113,7 @@ headers[USER_AGENT] : EMPTY)), - HTTP_UACH = new UAParserDataCH(headers, true), + HTTP_UACH = new UACHData(headers, true), regexMap = extensions ? extend(defaultRegexes, extensions) : @@ -1122,7 +1122,7 @@ createItemFunc = function (itemType) { if (itemType == UA_RESULT) { return function () { - return new UAParserItem(itemType, userAgent, regexMap, HTTP_UACH) + return new UAItem(itemType, userAgent, regexMap, HTTP_UACH) .set('ua', userAgent) .set(UA_BROWSER, this.getBrowser()) .set(UA_CPU, this.getCPU()) @@ -1133,7 +1133,7 @@ }; } else { return function () { - return new UAParserItem(itemType, userAgent, regexMap[itemType], HTTP_UACH) + return new UAItem(itemType, userAgent, regexMap[itemType], HTTP_UACH) .parseUA() .get(); };