diff --git a/bower.json b/bower.json index c83d0a9..d7496a9 100644 --- a/bower.json +++ b/bower.json @@ -1,8 +1,8 @@ { "name": "ua-parser-js", - "version": "0.7.19", + "version": "0.7.20", "authors": [ - "Faisal Salman " + "Faisal Salman " ], "private": false, "main": "src/ua-parser.js", diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index c12f2ef..6e8acb3 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,9 @@ /*! - * UAParser.js v0.7.19 + * UAParser.js v0.7.20 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * - * Copyright © 2012-2016 Faisal Salman - * Dual licensed under GPLv2 or MIT + * Copyright © 2012-2019 Faisal Salman + * Licensed under MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.19",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){var margedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){margedRegexes[i]=extensions[i].concat(regexes[i])}else{margedRegexes[i]=regexes[i]}}return margedRegexes},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.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str){return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}};var mapper={rgx:function(ua,arrays){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}},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){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}},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 or MIT + * Copyright © 2012-2019 Faisal Salman + * Licensed under MIT License */ -!function(i,s){"use strict";var e="0.7.19",o="",r="?",n="function",a="undefined",d="object",t="string",l="major",w="model",u="name",c="type",m="vendor",b="version",p="architecture",g="console",f="mobile",h="tablet",v="smarttv",x="wearable",k="embedded",y={extend:function(i,s){var e={};for(var o in i)s[o]&&s[o].length%2===0?e[o]=s[o].concat(i[o]):e[o]=i[o];return e},has:function(i,s){return"string"==typeof i&&s.toLowerCase().indexOf(i.toLowerCase())!==-1},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i===t?i.replace(/[^\d\.]/g,"").split(".")[0]:s},trim:function(i){return i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}},T={rgx:function(i,e){for(var o,r,a,t,l,w,u=0;u0?2==t.length?typeof t[1]==n?this[t[0]]=t[1].call(this,w):this[t[0]]=t[1]:3==t.length?typeof t[1]!==n||t[1].exec&&t[1].test?this[t[0]]=w?w.replace(t[1],t[2]):s:this[t[0]]=w?t[1].call(this,w,t[2]):s:4==t.length&&(this[t[0]]=w?t[3].call(this,w.replace(t[1],t[2])):s):this[t]=w?w:s;u+=2}},str:function(i,e){for(var o in e)if(typeof e[o]===d&&e[o].length>0){for(var n=0;n> +Copyright (c) 2012-2019 Faisal Salman <> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/package.js b/package.js index adff37c..e41d5e7 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'faisalman:ua-parser-js', - version: '0.7.19', + version: '0.7.20', 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 9686761..8b6c554 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "0.7.19", + "version": "0.7.20", "author": "Faisal Salman (http://faisalman.com)", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": [ @@ -125,7 +125,7 @@ "type": "git", "url": "https://github.com/faisalman/ua-parser-js.git" }, - "license": "(GPL-2.0 OR MIT)", + "license": "MIT", "engines": { "node": "*" }, diff --git a/readme.md b/readme.md index 6044576..b8ff86a 100644 --- a/readme.md +++ b/readme.md @@ -259,18 +259,6 @@ $ npm install --save @types/ua-parser-js # https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/ua-parser-js ``` -## Using CLI - -```sh -$ node ua-parser.min.js "Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)" -# multiple args -$ node ua-parser.min.js "Opera/1.2" "Opera/3.4" -# piped args -$ echo "Opera/1.2" | node ua-parser.min.js -# log file -$ cat ua.log | node ua-parser.min.js -``` - ## Using jQuery/Zepto ($.ua) Although written in vanilla js (which means it doesn't depends on jQuery), this library will automatically detect if jQuery/Zepto is present and create `$.ua` object based on browser's user-agent (although in case you need, `window.UAParser` constructor is still present). To get/set user-agent you can use: `$.ua.get()` / `$.ua.set(uastring)`. @@ -343,18 +331,18 @@ Do you use & like UAParser.js but you don’t find a way to show some love? If y # License -Dual licensed under GPLv2 or MIT +MIT License -Copyright © 2012-2018 Faisal Salman <> +Copyright (c) 2012-2019 Faisal Salman <> -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR diff --git a/src/ua-parser.js b/src/ua-parser.js index 8cc6630..1cb82f7 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,10 +1,10 @@ /*! - * UAParser.js v0.7.19 + * UAParser.js v0.7.20 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * - * Copyright © 2012-2016 Faisal Salman - * Dual licensed under GPLv2 or MIT + * Copyright © 2012-2019 Faisal Salman + * Licensed under MIT License */ (function (window, undefined) { @@ -16,7 +16,7 @@ ///////////// - var LIBVERSION = '0.7.19', + var LIBVERSION = '0.7.20', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', @@ -45,15 +45,15 @@ var util = { extend : function (regexes, extensions) { - var margedRegexes = {}; + var mergedRegexes = {}; for (var i in regexes) { if (extensions[i] && extensions[i].length % 2 === 0) { - margedRegexes[i] = extensions[i].concat(regexes[i]); + mergedRegexes[i] = extensions[i].concat(regexes[i]); } else { - margedRegexes[i] = regexes[i]; + mergedRegexes[i] = regexes[i]; } } - return margedRegexes; + return mergedRegexes; }, has : function (str1, str2) { if (typeof str1 === "string") { @@ -83,14 +83,7 @@ rgx : function (ua, arrays) { - //var result = {}, - var i = 0, j, k, p, q, matches, match;//, args = arguments; - - /*// construct object barebones - for (p = 0; p < args[1].length; p++) { - q = args[1][p]; - result[typeof q === OBJ_TYPE ? q[0] : q] = undefined; - }*/ + var i = 0, j, k, p, q, matches, match; // loop through all regexes maps while (i < arrays.length && !matches) { @@ -138,8 +131,6 @@ } i += 2; } - // console.log(this); - //return this; }, str : function (str, map) { @@ -264,7 +255,7 @@ /(trident).+rv[:\s]([\w\.]+).+like\sgecko/i // IE11 ], [[NAME, 'IE'], VERSION], [ - /(edge|edgios|edga)\/((\d+)?[\w\.]+)/i // Microsoft Edge + /(edge|edgios|edga|edg)\/((\d+)?[\w\.]+)/i // Microsoft Edge ], [[NAME, 'Edge'], VERSION], [ /(yabrowser)\/([\w\.]+)/i // Yandex @@ -285,6 +276,9 @@ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ + /(windowswechat qbcore)\/([\w\.]+)/i // WeChat Desktop for Windows Built-in Browser + ], [[NAME, 'WeChat(Win) Desktop'], VERSION], [ + /(micromessenger)\/([\w\.]+)/i // WeChat ], [[NAME, 'WeChat'], VERSION], [ @@ -334,6 +328,9 @@ /android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)*/i // Android Browser ], [VERSION, [NAME, 'Android Browser']], [ + /(sailfishbrowser)\/([\w\.]+)/i // Sailfish Browser + ], [[NAME, 'Sailfish Browser'], VERSION], [ + /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [NAME, VERSION], [ @@ -384,117 +381,6 @@ /(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser /(mosaic)[\/\s]([\w\.]+)/i // Mosaic ], [NAME, VERSION] - - /* ///////////////////// - // Media players BEGIN - //////////////////////// - - , [ - - /(apple(?:coremedia|))\/((\d+)[\w\._]+)/i, // Generic Apple CoreMedia - /(coremedia) v((\d+)[\w\._]+)/i - ], [NAME, VERSION], [ - - /(aqualung|lyssna|bsplayer)\/((\d+)?[\w\.-]+)/i // Aqualung/Lyssna/BSPlayer - ], [NAME, VERSION], [ - - /(ares|ossproxy)\s((\d+)[\w\.-]+)/i // Ares/OSSProxy - ], [NAME, VERSION], [ - - /(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/((\d+)[\w\.-]+)/i, - // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC - // NSPlayer/PSP-InternetRadioPlayer/Videos - /(clementine|music player daemon)\s((\d+)[\w\.-]+)/i, // Clementine/MPD - /(lg player|nexplayer)\s((\d+)[\d\.]+)/i, - /player\/(nexplayer|lg player)\s((\d+)[\w\.-]+)/i // NexPlayer/LG Player - ], [NAME, VERSION], [ - /(nexplayer)\s((\d+)[\w\.-]+)/i // Nexplayer - ], [NAME, VERSION], [ - - /(flrp)\/((\d+)[\w\.-]+)/i // Flip Player - ], [[NAME, 'Flip Player'], VERSION], [ - - /(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i - // FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit - ], [NAME], [ - - /(gstreamer) souphttpsrc (?:\([^\)]+\)){0,1} libsoup\/((\d+)[\w\.-]+)/i - // Gstreamer - ], [NAME, VERSION], [ - - /(htc streaming player)\s[\w_]+\s\/\s((\d+)[\d\.]+)/i, // HTC Streaming Player - /(java|python-urllib|python-requests|wget|libcurl)\/((\d+)[\w\.-_]+)/i, - // Java/urllib/requests/wget/cURL - /(lavf)((\d+)[\d\.]+)/i // Lavf (FFMPEG) - ], [NAME, VERSION], [ - - /(htc_one_s)\/((\d+)[\d\.]+)/i // HTC One S - ], [[NAME, /_/g, ' '], VERSION], [ - - /(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+){0,1})/i - // MPlayer SVN - ], [NAME, VERSION], [ - - /(mplayer)(?:\s|\/|[unkow-]+)((\d+)[\w\.-]+)/i // MPlayer - ], [NAME, VERSION], [ - - /(mplayer)/i, // MPlayer (no other info) - /(yourmuze)/i, // YourMuze - /(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime - ], [NAME], [ - - /(nero (?:home|scout))\/((\d+)[\w\.-]+)/i // Nero Home/Nero Scout - ], [NAME, VERSION], [ - - /(nokia\d+)\/((\d+)[\w\.-]+)/i // Nokia - ], [NAME, VERSION], [ - - /\s(songbird)\/((\d+)[\w\.-]+)/i // Songbird/Philips-Songbird - ], [NAME, VERSION], [ - - /(winamp)3 version ((\d+)[\w\.-]+)/i, // Winamp - /(winamp)\s((\d+)[\w\.-]+)/i, - /(winamp)mpeg\/((\d+)[\w\.-]+)/i - ], [NAME, VERSION], [ - - /(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info) - // inlight radio - ], [NAME], [ - - /(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/((\d+)[\w\.-]+)/i - // QuickTime/RealMedia/RadioApp/RadioClientApplication/ - // SoundTap/Totem/Stagefright/Streamium - ], [NAME, VERSION], [ - - /(smp)((\d+)[\d\.]+)/i // SMP - ], [NAME, VERSION], [ - - /(vlc) media player - version ((\d+)[\w\.]+)/i, // VLC Videolan - /(vlc)\/((\d+)[\w\.-]+)/i, - /(xbmc|gvfs|xine|xmms|irapp)\/((\d+)[\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp - /(foobar2000)\/((\d+)[\d\.]+)/i, // Foobar2000 - /(itunes)\/((\d+)[\d\.]+)/i // iTunes - ], [NAME, VERSION], [ - - /(wmplayer)\/((\d+)[\w\.-]+)/i, // Windows Media Player - /(windows-media-player)\/((\d+)[\w\.-]+)/i - ], [[NAME, /-/g, ' '], VERSION], [ - - /windows\/((\d+)[\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i - // Windows Media Server - ], [VERSION, [NAME, 'Windows']], [ - - /(com\.riseupradioalarm)\/((\d+)[\d\.]*)/i // RiseUP Radio Alarm - ], [NAME, VERSION], [ - - /(rad.io)\s((\d+)[\d\.]+)/i, // Rad.io - /(radio.(?:de|at|fr))\s((\d+)[\d\.]+)/i - ], [[NAME, 'rad.io'], VERSION] - - ////////////////////// - // Media players END - ////////////////////*/ - ], cpu : [[ @@ -585,13 +471,10 @@ /(sprint\s(\w+))/i // Sprint Phones ], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [ - /(lenovo)\s?(S(?:5000|6000)+(?:[-][\w+]))/i // Lenovo tablets - ], [VENDOR, MODEL, [TYPE, TABLET]], [ - /(htc)[;_\s-]+([\w\s]+(?=\)|\sbuild)|\w+)/i, // HTC /(zte)-(\w*)/i, // ZTE - /(alcatel|geeksphone|lenovo|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]*)/i - // Alcatel/GeeksPhone/Lenovo/Nexian/Panasonic/Sony + /(alcatel|geeksphone|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]*)/i + // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ /(nexus\s9)/i // HTC Nexus 9 @@ -658,8 +541,12 @@ /android.+lg(\-?[\d\w]+)\s+build/i ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [ + /(lenovo)\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+))/i // Lenovo tablets + ], [VENDOR, MODEL, [TYPE, TABLET]], [ /android.+(ideatab[a-z0-9\-\s]+)/i // Lenovo ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ + /(lenovo)[_\s-]?([\w-]+)/i + ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /linux;.+((jolla));/i // Jolla ], [VENDOR, MODEL, [TYPE, MOBILE]], [ @@ -679,19 +566,20 @@ /android.+;\s(pixel c)[\s)]/i // Google Pixel C ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [ - /android.+;\s(pixel( [23])?( xl)?)\s/i // Google Pixel + /android.+;\s(pixel( [23])?( xl)?)[\s)]/i // Google Pixel ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [ /android.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i, // Xiaomi Hongmi - /android.+(mi[\s\-_]*(?:one|one[\s_]plus|note lte)?[\s_]*(?:\d?\w?)[\s_]*(?:plus)?)\s+build/i, // Xiaomi Mi + /android.+(mi[\s\-_]*(?:a\d|one|one[\s_]plus|note lte)?[\s_]*(?:\d?\w?)[\s_]*(?:plus)?)\s+build/i, + // Xiaomi Mi /android.+(redmi[\s\-_]*(?:note)?(?:[\s_]*[\w\s]+))\s+build/i // Redmi Phones ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ /android.+(mi[\s\-_]*(?:pad)(?:[\s_]*[\w\s]+))\s+build/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [ - /android.+;\s(m[1-5]\snote)\sbuild/i // Meizu Tablet - ], [MODEL, [VENDOR, 'Meizu'], [TYPE, TABLET]], [ - /(mz)-([\w-]{2,})/i // Meizu Phone + /android.+;\s(m[1-5]\snote)\sbuild/i // Meizu + ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ + /(mz)-([\w-]{2,})/i ], [[VENDOR, 'Meizu'], MODEL, [TYPE, MOBILE]], [ /android.+a000(1)\s+build/i, // OnePlus @@ -774,58 +662,6 @@ /(android[\w\.\s\-]{0,9});.+build/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']] - - - /*////////////////////////// - // TODO: move to string map - //////////////////////////// - - /(C6603)/i // Sony Xperia Z C6603 - ], [[MODEL, 'Xperia Z C6603'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [ - /(C6903)/i // Sony Xperia Z 1 - ], [[MODEL, 'Xperia Z 1'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [ - - /(SM-G900[F|H])/i // Samsung Galaxy S5 - ], [[MODEL, 'Galaxy S5'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ - /(SM-G7102)/i // Samsung Galaxy Grand 2 - ], [[MODEL, 'Galaxy Grand 2'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ - /(SM-G530H)/i // Samsung Galaxy Grand Prime - ], [[MODEL, 'Galaxy Grand Prime'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ - /(SM-G313HZ)/i // Samsung Galaxy V - ], [[MODEL, 'Galaxy V'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ - /(SM-T805)/i // Samsung Galaxy Tab S 10.5 - ], [[MODEL, 'Galaxy Tab S 10.5'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [ - /(SM-G800F)/i // Samsung Galaxy S5 Mini - ], [[MODEL, 'Galaxy S5 Mini'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ - /(SM-T311)/i // Samsung Galaxy Tab 3 8.0 - ], [[MODEL, 'Galaxy Tab 3 8.0'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [ - - /(T3C)/i // Advan Vandroid T3C - ], [MODEL, [VENDOR, 'Advan'], [TYPE, TABLET]], [ - /(ADVAN T1J\+)/i // Advan Vandroid T1J+ - ], [[MODEL, 'Vandroid T1J+'], [VENDOR, 'Advan'], [TYPE, TABLET]], [ - /(ADVAN S4A)/i // Advan Vandroid S4A - ], [[MODEL, 'Vandroid S4A'], [VENDOR, 'Advan'], [TYPE, MOBILE]], [ - - /(V972M)/i // ZTE V972M - ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [ - - /(i-mobile)\s(IQ\s[\d\.]+)/i // i-mobile IQ - ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - /(IQ6.3)/i // i-mobile IQ IQ 6.3 - ], [[MODEL, 'IQ 6.3'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [ - /(i-mobile)\s(i-style\s[\d\.]+)/i // i-mobile i-STYLE - ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - /(i-STYLE2.1)/i // i-mobile i-STYLE 2.1 - ], [[MODEL, 'i-STYLE 2.1'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [ - - /(mobiistar touch LAI 512)/i // mobiistar touch LAI 512 - ], [[MODEL, 'Touch LAI 512'], [VENDOR, 'mobiistar'], [TYPE, MOBILE]], [ - - ///////////// - // END TODO - ///////////*/ - ], engine : [[ @@ -878,9 +714,8 @@ ], [[NAME, 'BlackBerry'], VERSION], [ /(blackberry)\w*\/?([\w\.]*)/i, // Blackberry /(tizen)[\/\s]([\w\.]+)/i, // Tizen - /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|contiki)[\/\s-]?([\w\.]*)/i, - // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki - /linux;.+(sailfish);/i // Sailfish OS + /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i + // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS ], [NAME, VERSION], [ /(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]*)/i // Symbian ], [[NAME, 'Symbian'], VERSION], [ @@ -938,22 +773,6 @@ ///////////////// // Constructor //////////////// - /* - var Browser = function (name, version) { - this[NAME] = name; - this[VERSION] = version; - }; - var CPU = function (arch) { - this[ARCHITECTURE] = arch; - }; - var Device = function (vendor, model, type) { - this[VENDOR] = vendor; - this[MODEL] = model; - this[TYPE] = type; - }; - var Engine = Browser; - var OS = Browser; - */ var UAParser = function (uastring, extensions) { if (typeof uastring === 'object') { @@ -967,11 +786,6 @@ var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); var rgxmap = extensions ? util.extend(regexes, extensions) : regexes; - //var browser = new Browser(); - //var cpu = new CPU(); - //var device = new Device(); - //var engine = new Engine(); - //var os = new OS(); var renderer; // browser only @@ -1034,11 +848,6 @@ }; this.setUA = function (uastring) { ua = uastring; - //browser = new Browser(); - //cpu = new CPU(); - //device = new Device(); - //engine = new Engine(); - //os = new OS(); return this; }; return this; @@ -1076,7 +885,6 @@ NAME : NAME, VERSION : VERSION }; - //UAParser.Utils = util; /////////// // Export @@ -1089,39 +897,10 @@ if (typeof module !== UNDEF_TYPE && module.exports) { exports = module.exports = UAParser; } - // TODO: test!!!!!!!! - /* - if (require && require.main === module && process) { - // cli - var jsonize = function (arr) { - var res = []; - for (var i in arr) { - res.push(new UAParser(arr[i]).getResult()); - } - process.stdout.write(JSON.stringify(res, null, 2) + '\n'); - }; - if (process.stdin.isTTY) { - // via args - jsonize(process.argv.slice(2)); - } else { - // via pipe - var str = ''; - process.stdin.on('readable', function() { - var read = process.stdin.read(); - if (read !== null) { - str += read; - } - }); - process.stdin.on('end', function () { - jsonize(str.replace(/\n$/, '').split('\n')); - }); - } - } - */ exports.UAParser = UAParser; } else { // requirejs env (optional) - if (typeof(define) === FUNC_TYPE && define.amd) { + if (typeof(define) === 'function' && define.amd) { define(function () { return UAParser; }); diff --git a/test/browser-test.json b/test/browser-test.json index b98db59..58ef6cc 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -59,6 +59,16 @@ "major" : "3" } }, + { + "desc" : "Sailfish Browser", + "ua" : "Mozilla/5.0 (Linux; U; Sailfish 3.0; Mobile; rv:45.0) Gecko/45.0 Firefox/45.0 SailfishBrowser/1.0", + "expect" : + { + "name" : "Sailfish Browser", + "version" : "1.0", + "major" : "1" + } + }, { "desc" : "Arora", "ua" : "Mozilla/5.0 (Windows; U; Windows NT 5.1; de-CH) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.2", @@ -1048,6 +1058,16 @@ "major" : "42" } }, + { + "desc" : "Microsoft Edge Chromium", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.48 Safari/537.36 Edg/74.1.96.24", + "expect" : + { + "name" : "Edge", + "version" : "74.1.96.24", + "major" : "74" + } + }, { "desc" : "Iridium", "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Iridium/43.8 Safari/537.36 Chrome/43.0.2357.132", @@ -1088,6 +1108,16 @@ "major" : "6" } }, + { + "desc" : "WeChat Desktop for Windows Built-in Browser", + "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.901.400 QQBrowser/9.0.2524.400", + "expect" : + { + "name" : "WeChat(Win) Desktop", + "version" : "3.43.901.400", + "major" : "3" + } + }, { "desc" : "GSA on iOS", "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) GSA/30.1.161623614 Mobile/14F89 Safari/602.1", diff --git a/test/device-test.json b/test/device-test.json index a283f76..6074665 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -133,6 +133,15 @@ "type": "mobile" } }, + { + "desc": "Lenovo Tab 2", + "ua": "Mozilla/5.0 (Linux; Android 5.0.1; Lenovo TAB 2 A7-30HC Build/LRX21M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.157 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TAB 2 A7", + "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", @@ -157,7 +166,7 @@ "expect": { "vendor": "Meizu", "model": "M5 Note", - "type": "tablet" + "type": "mobile" } }, { @@ -522,6 +531,15 @@ "type": "mobile" } }, + { + "desc": "Xiaomi Mi A1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; Mi A1 Build/OPR1.170623.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A1", + "type": "mobile" + } + }, { "desc": "Xiaomi Mi Note", "ua": "Mozilla/5.0 (Linux; Android 4.4.4; MI NOTE LTE Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", @@ -558,6 +576,15 @@ "type": "mobile" } }, + { + "desc": "Samsung Galaxy C9 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0; SAMSUNG SM-C900F Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.2 Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-C900F", + "type": "mobile" + } + }, { "desc": "Samsung Galaxy S5", "ua": "Mozilla/5.0 (Linux; Android 5.0; SM-G900F Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.78 Mobile Safari/537.36", @@ -647,6 +674,15 @@ "type": "mobile" } }, + { + "desc": "Google Pixel XL", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel XL", + "type": "mobile" + } + }, { "desc": "Google Pixel 2", "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Pixel 2 Build/OPM1.171019.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Safari/537.36", @@ -665,6 +701,15 @@ "type": "mobile" } }, + { + "desc": "Google Pixel 2 XL", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 2 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 2 XL", + "type": "mobile" + } + }, { "desc": "Google Pixel 3", "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PD1A.180720.030) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", @@ -683,6 +728,15 @@ "type": "mobile" } }, + { + "desc": "Google Pixel 3 XL", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3 XL", + "type": "mobile" + } + }, { "desc": "Generic Android Device", "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", diff --git a/test/os-test.json b/test/os-test.json index 5dc4c1d..a2a2411 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -170,6 +170,15 @@ "version" : "2.2.2" } }, + { + "desc" : "Sailfish", + "ua" : "Mozilla/5.0 (Linux; U; Sailfish 3.0; Mobile; rv:45.0) Gecko/45.0 Firefox/45.0 SailfishBrowser/1.0", + "expect" : + { + "name" : "Sailfish", + "version" : "3.0" + } + }, { "desc" : "WebOS", "ua" : "",