diff --git a/package.json b/package.json index 383dc28..558d60e 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "Leonardo ", "Michael Hess ", "Ross Noble ", - "Sandro Sonntag " + "Sandro Sonntag ", + "Max Maurer " ], "main": "src/ua-parser.js", "scripts": { diff --git a/src/ua-parser.js b/src/ua-parser.js index 0cccc7c..c2bdcf1 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -166,6 +166,11 @@ }, device : { + amazon : { + model : { + 'Fire Phone' : ['SD', 'KF'] + } + }, sprint : { model : { 'Evo Shift 4G' : '7373KT' @@ -411,7 +416,7 @@ /(ia64(?=;)|68k(?=\))|arm(?=v\d+;)|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i // IA64, 68K, ARM, IRIX, MIPS, SPARC, PA-RISC - ], [ARCHITECTURE, util.lowerize] + ], [[ARCHITECTURE, util.lowerize]] ], device : [[ @@ -433,6 +438,8 @@ /(kf[A-z]+)\sbuild\/[\w\.]+.*silk\//i // Kindle Fire HD ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ + /(sd|kf)[0349hijorstuw]+\sbuild\/[\w\.]+.*silk\//i // Fire Phone + ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ /\((ip[honed|\s\w*]+);.+(apple)/i // iPod/iPhone ], [MODEL, VENDOR, [TYPE, MOBILE]], [ @@ -440,8 +447,8 @@ ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [ /(blackberry)[\s-]?(\w+)/i, // BlackBerry - /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|huawei|meizu|motorola)[\s_-]?([\w-]+)*/i, - // BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Huawei/Meizu/Motorola + /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|huawei|meizu|motorola|polytron)[\s_-]?([\w-]+)*/i, + // BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Huawei/Meizu/Motorola/Polytron /(hp)\s([\w\s]+\w)/i, // HP iPAQ /(asus)-?(\w+)/i // Asus ], [VENDOR, MODEL, [TYPE, MOBILE]], [ @@ -503,11 +510,14 @@ /(lg)[e;\s\/-]+(\w+)*/i ], [[VENDOR, 'LG'], MODEL, [TYPE, MOBILE]], [ - /android.+((ideatab[a-z0-9\-\s]+))/i // Lenovo + /android.+((ideatab[a-z0-9\-\s]+))/i // Lenovo ], [[VENDOR, 'Lenovo'], MODEL, [TYPE, TABLET]], [ + + /linux;.+((jolla));/i // Jolla + ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(mobile|tablet);.+rv\:.+gecko\//i // Unidentifiable - ], [TYPE, VENDOR, MODEL] + ], [[TYPE, util.lowerize], VENDOR, MODEL] ], engine : [[ @@ -540,11 +550,14 @@ ], [[NAME, 'BlackBerry'], VERSION], [ /(blackberry)\w*\/?([\w\.]+)*/i, // Blackberry /(tizen)\/([\w\.]+)/i, // Tizen - /(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i + /(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i, // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo + /linux;.+(sailfish);/i // Sailfish OS ], [NAME, VERSION], [ /(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i // Symbian - ], [[NAME, 'Symbian'], VERSION],[ + ], [[NAME, 'Symbian'], VERSION], [ + /\((series40);/i // Series 40 + ], [NAME], [ /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS ], [[NAME, 'Firefox OS'], VERSION], [ @@ -587,19 +600,39 @@ ] }; + /** + * Extends the regex array with another regex array from a given input array + * @param {object} extensions extension objects that contains an array under the given paramName + * @param {string} paramName key of the extensions object that should be used if given. + */ + function extend(extensions, paramName) { + if (!extensions || !extensions[paramName] || extensions[paramName].length%2!==0) { + return; + } + regexes[paramName] = regexes[paramName].concat(extensions[paramName]); + } + ///////////////// // Constructor //////////////// - var UAParser = function (uastring) { + var UAParser = function (uastring, extensions) { var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); if (!(this instanceof UAParser)) { - return new UAParser(uastring).getResult(); + return new UAParser(uastring, extensions).getResult(); } + + // extend regexes + extend(extensions, 'browser'); + extend(extensions, 'cpu'); + extend(extensions, 'device'); + extend(extensions, 'engine'); + extend(extensions, 'os'); + this.getBrowser = function () { return mapper.rgx.apply(this, regexes.browser); }; @@ -635,6 +668,12 @@ this.setUA(ua); }; + UAParser.NAME = NAME; + UAParser.VERSION = VERSION; + UAParser.VENDOR = VENDOR; + UAParser.TYPE = TYPE; + UAParser.ARCHITECTURE = ARCHITECTURE; + UAParser.MAJOR = MAJOR; /////////// // Export diff --git a/src/ua-parser.min.js b/src/ua-parser.min.js index cea6483..caf1b4a 100644 --- a/src/ua-parser.min.js +++ b/src/ua-parser.min.js @@ -1 +1,7 @@ -(function(window,undefined){"use strict";var EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv";var util={has:function(str1,str2){if(typeof str1==="string"){return str2.toLowerCase().indexOf(str1.toLowerCase())!==-1}},lowerize:function(str){return str.toLowerCase()}};var mapper={rgx:function(){for(var result,i=0,j,k,p,q,matches,match,args=arguments;i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){result[q[0]]=q[1].call(this,match)}else{result[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){result[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{result[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){result[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{result[q]=match?match:undefined}}break}}if(!!matches)break}return result},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j +// Dual licensed under GPLv2 & MIT +(function(e,t){"use strict";function S(e,t){if(!e||!e[t]||e[t].length%2!==0)return;E[t]=E[t].concat(e[t])}var n="",r="?",i="function",s="undefined",o="object",u="major",a="model",f="name",l="type",c="vendor",h="version",p="architecture",d="console",v="mobile",m="tablet",g="smarttv",y={has:function(e,t){if(typeof e=="string")return t.toLowerCase().indexOf(e.toLowerCase())!==-1},lowerize:function(e){return e.toLowerCase()}},b={rgx:function(){for(var e,n=0,r,u,a,f,l,c,h=arguments;n0?f.length==2?typeof f[1]==i?e[f[0]]=f[1].call(this,c):e[f[0]]=f[1]:f.length==3?typeof f[1]===i&&(!f[1].exec||!f[1].test)?e[f[0]]=c?f[1].call(this,c,f[2]):t:e[f[0]]=c?c.replace(f[1],f[2]):t:f.length==4&&(e[f[0]]=c?f[3].call(this,c.replace(f[1],f[2])):t):e[f]=c?c:t;break}}if(!!l)break}return e},str:function(e,n){for(var i in n)if(typeof n[i]===o&&n[i].length>0){for(var s=0;s