diff --git a/bower.json b/bower.json index 7a6368f..4d9e500 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.5", + "version": "0.7.6", "authors": [ "Faisal Salman " ], diff --git a/component.json b/component.json index 7d133b5..4d0db35 100644 --- a/component.json +++ b/component.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.5", + "version": "0.7.6", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": ["user-agent", "parser", "browser", "engine", "os", "device", "cpu"], "scripts": ["src/ua-parser.js"], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index eda2adf..7407f53 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,9 @@ /** - * UAParser.js v0.7.5 + * UAParser.js v0.7.6 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * * Copyright © 2012-2015 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.5",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){for(var i in extensions){if("browser cpu device engine os".indexOf(i)!==-1&&extensions[i].length%2===0){regexes[i]=extensions[i].concat(regexes[i])}}return regexes},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.split(".")[0]:undefined}};var mapper={rgx:function(){var result,i=0,j,k,p,q,matches,match,args=arguments;while(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}}}}i+=2}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;j0){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}}}}i+=2}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 (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 c97136a..32bbddc 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ /** - * UAParser.js v0.7.5 + * UAParser.js v0.7.6 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * @@ -16,14 +16,14 @@ ///////////// - var LIBVERSION = '0.7.5', + var LIBVERSION = '0.7.6', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', UNDEF_TYPE = 'undefined', OBJ_TYPE = 'object', STR_TYPE = 'string', - MAJOR = 'major', + MAJOR = 'major', // deprecated MODEL = 'model', NAME = 'name', TYPE = 'type', @@ -86,11 +86,11 @@ props = args[i + 1]; // odd sequence (1,3,5,..) // construct object barebones - if (typeof(result) === UNDEF_TYPE) { + if (typeof result === UNDEF_TYPE) { result = {}; for (p in props) { q = props[p]; - if (typeof(q) === OBJ_TYPE) { + if (typeof q === OBJ_TYPE) { result[q[0]] = undefined; } else { result[q] = undefined; @@ -107,9 +107,9 @@ match = matches[++k]; q = props[p]; // check if given property is actually array - if (typeof(q) === OBJ_TYPE && q.length > 0) { + if (typeof q === OBJ_TYPE && q.length > 0) { if (q.length == 2) { - if (typeof(q[1]) == FUNC_TYPE) { + if (typeof q[1] == FUNC_TYPE) { // assign modified match result[q[0]] = q[1].call(this, match); } else { @@ -118,7 +118,7 @@ } } else if (q.length == 3) { // check whether function or regex - if (typeof(q[1]) === FUNC_TYPE && !(q[1].exec && q[1].test)) { + if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) { // call function (usually string mapper) result[q[0]] = match ? q[1].call(this, match, q[2]) : undefined; } else { @@ -143,7 +143,7 @@ for (var i in map) { // check if array - if (typeof(map[i]) === OBJ_TYPE && map[i].length > 0) { + 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)) { return (i === UNKNOWN) ? undefined : i; @@ -280,8 +280,8 @@ /android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)/i // Android Browser ], [VERSION, [NAME, 'Android Browser']], [ - /FBAV\/((\d+)?[\w\.]+);/i // Facebook App for iOS - ], [VERSION, MAJOR, [NAME, 'Facebook']], [ + /FBAV\/([\w\.]+);/i // Facebook App for iOS + ], [VERSION, [NAME, 'Facebook']], [ /version\/([\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari ], [VERSION, [NAME, 'Mobile Safari']], [ @@ -520,6 +520,9 @@ /(alcatel|geeksphone|huawei|lenovo|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]+)*/i // Alcatel/GeeksPhone/Huawei/Lenovo/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ + + /(nexus\s9)/i // HTC Nexus 9 + ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ /[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [ @@ -553,10 +556,10 @@ /(nokia)[\s_-]?([\w-]+)*/i ], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [ - /android\s3\.[\s\w-;]{10}(a\d{3})/i // Acer + /android\s3\.[\s\w;-]{10}(a\d{3})/i // Acer ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [ - /android\s3\.[\s\w-;]{10}(lg?)-([06cv9]{3,4})/i // LG 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]], [ @@ -734,10 +737,10 @@ //////////////// - var _UAParser = function (uastring, extensions) { + var UAParser = function (uastring, extensions) { - if (!(this instanceof _UAParser)) { - return new _UAParser(uastring, extensions).getResult(); + if (!(this instanceof UAParser)) { + return new UAParser(uastring, extensions).getResult(); } var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); @@ -781,16 +784,16 @@ return this; }; - _UAParser.VERSION = LIBVERSION; - _UAParser.BROWSER = { + UAParser.VERSION = LIBVERSION; + UAParser.BROWSER = { NAME : NAME, - MAJOR : MAJOR, + MAJOR : MAJOR, // deprecated VERSION : VERSION }; - _UAParser.CPU = { + UAParser.CPU = { ARCHITECTURE : ARCHITECTURE }; - _UAParser.DEVICE = { + UAParser.DEVICE = { MODEL : MODEL, VENDOR : VENDOR, TYPE : TYPE, @@ -801,11 +804,11 @@ WEARABLE: WEARABLE, EMBEDDED: EMBEDDED }; - _UAParser.ENGINE = { + UAParser.ENGINE = { NAME : NAME, VERSION : VERSION }; - _UAParser.OS = { + UAParser.OS = { NAME : NAME, VERSION : VERSION }; @@ -818,41 +821,42 @@ // check js environment if (typeof(exports) !== UNDEF_TYPE) { - var UAParser = _UAParser; // nodejs env - if (typeof(module) !== UNDEF_TYPE && module.exports) { + if (typeof module !== UNDEF_TYPE && module.exports) { exports = module.exports = UAParser; } exports.UAParser = UAParser; - } else if (typeof(Package) !== UNDEF_TYPE) { - // meteor - UAParser = _UAParser; } else { - var UAParser = _UAParser; - // browser env - window.UAParser = UAParser; // requirejs env (optional) if (typeof(define) === FUNC_TYPE && define.amd) { define(function () { return UAParser; }); - } - // jQuery/Zepto specific (optional) - var $ = window.jQuery || window.Zepto; - if (typeof($) !== UNDEF_TYPE) { - 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]; - } - }; + } else { + // browser env + window.UAParser = UAParser; } } + // jQuery/Zepto specific (optional) + // Note: + // 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.jQuery || window.Zepto; + if (typeof $ !== UNDEF_TYPE) { + 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]; + } + }; + } + })(this); diff --git a/test/device-test.json b/test/device-test.json index 43746a0..8317dd7 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -9,6 +9,16 @@ "type" : "mobile" } }, + { + "desc" : "HTC Nexus 9", + "ua" : "Mozilla/5.0 (Linux; Android 5.0; Nexus 9 Build/LRX21R) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Mobile Crosswalk/7.36.154.13 Safari/537.36", + "expect" : + { + "vendor" : "HTC", + "model" : "Nexus 9", + "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", diff --git a/ua-parser-js.jquery.json b/ua-parser-js.jquery.json index 46f1b34..b96ad54 100644 --- a/ua-parser-js.jquery.json +++ b/ua-parser-js.jquery.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "0.7.5", + "version": "0.7.6", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": [ "user-agent",