From 70d629ca71e514bcd1920516c784ebd42ce129d1 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 10 Nov 2014 18:42:33 +0700 Subject: [PATCH 01/25] Extract major from version instead of directly using regex --- src/ua-parser.js | 147 ++++++++++++++++++++++++----------------------- 1 file changed, 74 insertions(+), 73 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index fe36687..41dd8ff 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -22,6 +22,7 @@ FUNC_TYPE = 'function', UNDEF_TYPE = 'undefined', OBJ_TYPE = 'object', + STR_TYPE = 'string', MAJOR = 'major', MODEL = 'model', NAME = 'name', @@ -58,6 +59,9 @@ }, lowerize : function (str) { return str.toLowerCase(); + }, + major : function (version) { + return typeof(version) === STR_TYPE ? version.split(".")[0] : undefined; } }; @@ -161,11 +165,6 @@ browser : { oldsafari : { - major : { - '1' : ['/8', '/1', '/3'], - '2' : '/4', - '?' : '/' - }, version : { '1.0' : '/8', '1.2' : '/1', @@ -226,84 +225,84 @@ browser : [[ // Presto based - /(opera\smini)\/((\d+)?[\w\.-]+)/i, // Opera Mini - /(opera\s[mobiletab]+).+version\/((\d+)?[\w\.-]+)/i, // Opera Mobi/Tablet - /(opera).+version\/((\d+)?[\w\.]+)/i, // Opera > 9.80 - /(opera)[\/\s]+((\d+)?[\w\.]+)/i // Opera < 9.80 + /(opera\smini)\/([\w\.-]+)/i, // Opera Mini + /(opera\s[mobiletab]+).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet + /(opera).+version\/([\w\.]+)/i, // Opera > 9.80 + /(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80 - ], [NAME, VERSION, MAJOR], [ + ], [NAME, VERSION], [ - /\s(opr)\/((\d+)?[\w\.]+)/i // Opera Webkit - ], [[NAME, 'Opera'], VERSION, MAJOR], [ + /\s(opr)\/([\w\.]+)/i // Opera Webkit + ], [[NAME, 'Opera'], VERSION], [ // Mixed - /(kindle)\/((\d+)?[\w\.]+)/i, // Kindle - /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?((\d+)?[\w\.]+)*/i, + /(kindle)\/([\w\.]+)/i, // Kindle + /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]+)*/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer // Trident based - /(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?((\d+)?[\w\.]*)/i, + /(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser/Baidu - /(?:ms|\()(ie)\s((\d+)?[\w\.]+)/i, // Internet Explorer + /(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer // Webkit/KHTML based - /(rekonq)((?:\/)[\w\.]+)*/i, // Rekonq - /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron)\/((\d+)?[\w\.-]+)/i + /(rekonq)\/([\w\.]+)*/i, // Rekonq + /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron)\/([\w\.-]+)/i // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron - ], [NAME, VERSION, MAJOR], [ + ], [NAME, VERSION], [ - /(trident).+rv[:\s]((\d+)?[\w\.]+).+like\sgecko/i // IE11 - ], [[NAME, 'IE'], VERSION, MAJOR], [ + /(trident).+rv[:\s]([\w\.]+).+like\sgecko/i // IE11 + ], [[NAME, 'IE'], VERSION], [ - /(yabrowser)\/((\d+)?[\w\.]+)/i // Yandex - ], [[NAME, 'Yandex'], VERSION, MAJOR], [ + /(yabrowser)\/([\w\.]+)/i // Yandex + ], [[NAME, 'Yandex'], VERSION], [ - /(comodo_dragon)\/((\d+)?[\w\.]+)/i // Comodo Dragon - ], [[NAME, /_/g, ' '], VERSION, MAJOR], [ + /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon + ], [[NAME, /_/g, ' '], VERSION], [ - /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?((\d+)?[\w\.]+)/i, + /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i, // Chrome/OmniWeb/Arora/Tizen/Nokia - /(uc\s?browser|qqbrowser)[\/\s]?((\d+)?[\w\.]+)/i + /(uc\s?browser|qqbrowser)[\/\s]?([\w\.]+)/i //UCBrowser/QQBrowser - ], [NAME, VERSION, MAJOR], [ + ], [NAME, VERSION], [ - /(dolfin)\/((\d+)?[\w\.]+)/i // Dolphin - ], [[NAME, 'Dolphin'], VERSION, MAJOR], [ + /(dolfin)\/([\w\.]+)/i // Dolphin + ], [[NAME, 'Dolphin'], VERSION], [ - /((?:android.+)crmo|crios)\/((\d+)?[\w\.]+)/i // Chrome for Android/iOS - ], [[NAME, 'Chrome'], VERSION, MAJOR], [ + /((?:android.+)crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS + ], [[NAME, 'Chrome'], VERSION], [ - /version\/((\d+)?[\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari - ], [VERSION, MAJOR, [NAME, 'Mobile Safari']], [ + /version\/([\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari + ], [VERSION, [NAME, 'Mobile Safari']], [ - /version\/((\d+)?[\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile - ], [VERSION, MAJOR, NAME], [ + /version\/([\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile + ], [VERSION, NAME], [ - /webkit.+?(mobile\s?safari|safari)((\/[\w\.]+))/i // Safari < 3.0 - ], [NAME, [MAJOR, mapper.str, maps.browser.oldsafari.major], [VERSION, mapper.str, maps.browser.oldsafari.version]], [ + /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 + ], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [ - /(konqueror)\/((\d+)?[\w\.]+)/i, // Konqueror - /(webkit|khtml)\/((\d+)?[\w\.]+)/i - ], [NAME, VERSION, MAJOR], [ + /(konqueror)\/([\w\.]+)/i, // Konqueror + /(webkit|khtml)\/([\w\.]+)/i + ], [NAME, VERSION], [ // Gecko based - /(navigator|netscape)\/((\d+)?[\w\.-]+)/i // Netscape - ], [[NAME, 'Netscape'], VERSION, MAJOR], [ + /(navigator|netscape)\/([\w\.-]+)/i // Netscape + ], [[NAME, 'Netscape'], VERSION], [ /(swiftfox)/i, // Swiftfox - /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?((\d+)?[\w\.\+]+)/i, + /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror - /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/((\d+)?[\w\.-]+)/i, + /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/([\w\.-]+)/i, // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix - /(mozilla)\/((\d+)?[\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla + /(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla // Other - /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf)[\/\s]?((\d+)?[\w\.]+)/i, + /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf)[\/\s]?([\w\.]+)/i, // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf - /(links)\s\(((\d+)?[\w\.]+)/i, // Links - /(gobrowser)\/?((\d+)?[\w\.]+)*/i, // GoBrowser - /(ice\s?browser)\/v?((\d+)?[\w\._]+)/i, // ICE Browser - /(mosaic)[\/\s]((\d+)?[\w\.]+)/i // Mosaic - ], [NAME, VERSION, MAJOR] + /(links)\s\(([\w\.]+)/i, // Links + /(gobrowser)\/?([\w\.]+)*/i, // GoBrowser + /(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser + /(mosaic)[\/\s]([\w\.]+)/i // Mosaic + ], [NAME, VERSION] /* ///////////////////// // Media players BEGIN @@ -313,13 +312,13 @@ /(apple(?:coremedia|))\/((\d+)[\w\._]+)/i, // Generic Apple CoreMedia /(coremedia) v((\d+)[\w\._]+)/i - ], [NAME, VERSION, MAJOR], [ + ], [NAME, VERSION], [ /(aqualung|lyssna|bsplayer)\/((\d+)?[\w\.-]+)/i // Aqualung/Lyssna/BSPlayer ], [NAME, VERSION], [ /(ares|ossproxy)\s((\d+)[\w\.-]+)/i // Ares/OSSProxy - ], [NAME, VERSION, MAJOR], [ + ], [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 @@ -327,12 +326,12 @@ /(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, MAJOR], [ + ], [NAME, VERSION], [ /(nexplayer)\s((\d+)[\w\.-]+)/i // Nexplayer - ], [NAME, VERSION, MAJOR], [ + ], [NAME, VERSION], [ /(flrp)\/((\d+)[\w\.-]+)/i // Flip Player - ], [[NAME, 'Flip Player'], VERSION, MAJOR], [ + ], [[NAME, 'Flip Player'], VERSION], [ /(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i // FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit @@ -340,23 +339,23 @@ /(gstreamer) souphttpsrc (?:\([^\)]+\)){0,1} libsoup\/((\d+)[\w\.-]+)/i // Gstreamer - ], [NAME, VERSION, MAJOR], [ + ], [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, MAJOR], [ + ], [NAME, VERSION], [ /(htc_one_s)\/((\d+)[\d\.]+)/i // HTC One S - ], [[NAME, /_/g, ' '], VERSION, MAJOR], [ + ], [[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, MAJOR], [ + ], [NAME, VERSION], [ /(mplayer)/i, // MPlayer (no other info) /(yourmuze)/i, // YourMuze @@ -364,18 +363,18 @@ ], [NAME], [ /(nero (?:home|scout))\/((\d+)[\w\.-]+)/i // Nero Home/Nero Scout - ], [NAME, VERSION, MAJOR], [ + ], [NAME, VERSION], [ /(nokia\d+)\/((\d+)[\w\.-]+)/i // Nokia - ], [NAME, VERSION, MAJOR], [ + ], [NAME, VERSION], [ /\s(songbird)\/((\d+)[\w\.-]+)/i // Songbird/Philips-Songbird - ], [NAME, VERSION, MAJOR], [ + ], [NAME, VERSION], [ /(winamp)3 version ((\d+)[\w\.-]+)/i, // Winamp /(winamp)\s((\d+)[\w\.-]+)/i, /(winamp)mpeg\/((\d+)[\w\.-]+)/i - ], [NAME, VERSION, MAJOR], [ + ], [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 @@ -384,32 +383,32 @@ /(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/((\d+)[\w\.-]+)/i // QuickTime/RealMedia/RadioApp/RadioClientApplication/ // SoundTap/Totem/Stagefright/Streamium - ], [NAME, VERSION, MAJOR], [ + ], [NAME, VERSION], [ /(smp)((\d+)[\d\.]+)/i // SMP - ], [NAME, VERSION, MAJOR], [ + ], [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, MAJOR], [ + ], [NAME, VERSION], [ /(wmplayer)\/((\d+)[\w\.-]+)/i, // Windows Media Player /(windows-media-player)\/((\d+)[\w\.-]+)/i - ], [[NAME, /-/g, ' '], VERSION, MAJOR], [ + ], [[NAME, /-/g, ' '], VERSION], [ /windows\/((\d+)[\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i // Windows Media Server - ], [VERSION, MAJOR, [NAME, 'Windows']], [ + ], [VERSION, [NAME, 'Windows']], [ /(com\.riseupradioalarm)\/((\d+)[\d\.]*)/i // RiseUP Radio Alarm - ], [NAME, VERSION, MAJOR], [ + ], [NAME, VERSION], [ /(rad.io)\s((\d+)[\d\.]+)/i, // Rad.io /(radio.(?:de|at|fr))\s((\d+)[\d\.]+)/i - ], [[NAME, 'rad.io'], VERSION, MAJOR] + ], [[NAME, 'rad.io'], VERSION] ////////////////////// // Media players END @@ -662,7 +661,9 @@ var rgxmap = extensions ? util.extend(regexes, extensions) : regexes; this.getBrowser = function () { - return mapper.rgx.apply(this, rgxmap.browser); + var browser = mapper.rgx.apply(this, rgxmap.browser); + browser.major = util.major(browser.version); + return browser; }; this.getCPU = function () { return mapper.rgx.apply(this, rgxmap.cpu); From 9256ed418676fb2be1b96db896e2a3141a031f97 Mon Sep 17 00:00:00 2001 From: Vadim Kurachevsky Date: Wed, 19 Nov 2014 10:38:48 +0200 Subject: [PATCH 02/25] Moto X, G, Razr Mobile detection Moto RAZR: Mozilla/5.0 (Linux; Android 4.0.4; XT910 Build/6.7.2-180_SPU-19-TA-11.6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Mobile Safari/537.36 Moto X: Mozilla/5.0 (Linux; U; Android 4.2; xx-xx; XT1058 Build/13.9.0Q2.X-70-GHOST-ATT_LE-2) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 Moto G: Mozilla/5.0 (Linux; Android 4.4.2; XT1033 Build/KXB20.25-1.31) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.136 Mobile Safari/537.36 --- src/ua-parser.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 41dd8ff..1e776e3 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -514,7 +514,8 @@ // Motorola /\s((milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?(:?\s4g)?))[\w\s]+build\//i, - /(mot)[\s-]?(\w+)*/i + /(mot)[\s-]?(\w+)*/i, + /XT\d{3,4} build\//i ], [[VENDOR, 'Motorola'], MODEL, [TYPE, MOBILE]], [ /android.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [ From e725633328ac2ccce819a986e4a3795d1c3fca9a Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 20 Nov 2014 07:15:18 +0700 Subject: [PATCH 03/25] Fix #24 #80 --- src/ua-parser.js | 11 +++++++---- test/device-test.json | 10 ++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 1e776e3..8dbf650 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -55,6 +55,8 @@ has : function (str1, str2) { if (typeof str1 === "string") { return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1; + } else { + return false; } }, lowerize : function (str) { @@ -513,10 +515,10 @@ ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ // Motorola - /\s((milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?(:?\s4g)?))[\w\s]+build\//i, - /(mot)[\s-]?(\w+)*/i, - /XT\d{3,4} build\//i - ], [[VENDOR, 'Motorola'], MODEL, [TYPE, MOBILE]], [ + /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?(:?\s4g)?)[\w\s]+build\//i, + /mot[\s-]?(\w+)*/i, + /(XT\d{3,4}) build\//i + ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [ /android.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [ @@ -696,6 +698,7 @@ return this; }; this.setUA(ua); + return this; }; UAParser.VERSION = LIBVERSION; diff --git a/test/device-test.json b/test/device-test.json index 67b2c7c..e32d587 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -59,6 +59,16 @@ "type" : "mobile" } }, + { + "desc" : "Moto X", + "ua" : "Mozilla/5.0 (Linux; U; Android 4.2; xx-xx; XT1058 Build/13.9.0Q2.X-70-GHOST-ATT_LE-2) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect" : + { + "vendor" : "Motorola", + "model" : "XT1058", + "type" : "mobile" + } + }, { "desc" : "Nokia3xx", "ua" : "Nokia303/14.87 CLDC-1.1", From 5002ea08468ce07d3eb96b558afc5672e8f014e2 Mon Sep 17 00:00:00 2001 From: Sylvain Gizard Date: Thu, 18 Dec 2014 16:04:08 +0100 Subject: [PATCH 04/25] Rough detection of Sony Xperia phones and tablets --- src/ua-parser.js | 10 ++++-- test/device-test.json | 80 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 8dbf650..4add349 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -484,8 +484,14 @@ /android.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7)/i ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [ - /(sony)\s(tablet\s[ps])/i // Sony Tablets - ], [VENDOR, MODEL, [TYPE, TABLET]], [ + /(sony)\s(tablet\s[ps])\sbuild\//i // Sony Tablets + ], [VENDOR, [MODEL, 'Xperia Tablet'], [TYPE, TABLET]], [ + + /(sony)?(?:sgp.+)\sbuild\//i // Sony Tablets + ], [[VENDOR, 'Sony'], [MODEL, 'Xperia Tablet'], [TYPE, TABLET]], [ + + /(?:sony)?(?:(?:(?:c|d)\d{4})|(?:so[-l].+))\sbuild\//i // Sony Phones + ], [[VENDOR, 'Sony'], [MODEL, 'Xperia Phone'], [TYPE, MOBILE]], [ /\s(ouya)\s/i, // Ouya /(nintendo)\s([wids3u]+)/i // Nintendo diff --git a/test/device-test.json b/test/device-test.json index e32d587..5618960 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -118,5 +118,85 @@ "model" : "SM-T520", "type" : "tablet" } + }, + { + "desc" : "Sony C5303 (Xperia SP)", + "ua" : "Mozilla/5.0 (Linux; Android 4.3; C5303 Build/12.1.A.1.205) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.93 Mobile Safari/537.36", + "expect" : + { + "vendor" : "Sony", + "model" : "Xperia Phone", + "type" : "mobile" + } + }, + { + "desc": " Sony SO-02F (Xperia Z1 F)", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; SO-02F Build/14.1.H.2.119) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36", + "expect" : + { + "vendor" : "Sony", + "model" : "Xperia Phone", + "type" : "mobile" + } + }, + { + "desc": "Sony D6653 (Xperia Z3)", + "ua": "Mozilla/5.0 (Linux; Android 4.4; D6653 Build/23.0.A.0.376) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Mobile Safari/537.36", + "expect" : + { + "vendor" : "Sony", + "model" : "Xperia Phone", + "type" : "mobile" + } + }, + { + "desc": "Sony Xperia SOL25 (ZL2)", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4; SOL25 Build/17.1.1.C.1.64) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect" : + { + "vendor" : "Sony", + "model" : "Xperia Phone", + "type" : "mobile" + } + }, + { + "desc": "Sony SO-02F (Xperia Z1)", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4; SonySO-02F Build/14.3.B.0.288) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect" : + { + "vendor" : "Sony", + "model" : "Xperia Phone", + "type" : "mobile" + } + }, + { + "desc": " Sony SGP521 (Xperia Z2 Tablet)", + "ua": "Mozilla/5.0 (Linux; Android 4.4; SGP521 Build/17.1.A.0.432) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", + "expect" : + { + "vendor" : "Sony", + "model" : "Xperia Tablet", + "type" : "tablet" + } + }, + { + "desc": "Sony Tablet S", + "ua": "Mozilla/5.0 (Linux; U; Android 3.1; Sony Tablet S Build/THMAS10000) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13", + "expect" : + { + "vendor" : "Sony", + "model" : "Xperia Tablet", + "type" : "tablet" + } + }, + { + "desc": "Sony Tablet Z LTE", + "ua": "Mozilla/5.0 (Linux; U; Android 4.1; SonySGP321 Build/10.2.C.0.143) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect" : + { + "vendor" : "Sony", + "model" : "Xperia Tablet", + "type" : "tablet" + } } ] From 50c4e3e551295088824192f08b4deea52fa7e7c9 Mon Sep 17 00:00:00 2001 From: Sylvain Gizard Date: Thu, 18 Dec 2014 16:04:24 +0100 Subject: [PATCH 05/25] Trailing whitespace --- src/ua-parser.js | 18 +++++++++--------- test/device-test.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 4add349..c876392 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -2,7 +2,7 @@ * UAParser.js v0.7.3 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js - * + * * Copyright © 2012-2014 Faisal Salman * Dual licensed under GPLv2 & MIT */ @@ -260,7 +260,7 @@ ], [[NAME, 'Yandex'], VERSION], [ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon - ], [[NAME, /_/g, ' '], VERSION], [ + ], [[NAME, /_/g, ' '], VERSION], [ /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i, // Chrome/OmniWeb/Arora/Tizen/Nokia @@ -556,16 +556,16 @@ /(nexus\s[45])/i, // LG /lg[e;\s\/-]+(\w+)*/i ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [ - + /android.+(ideatab[a-z0-9\-\s]+)/i // Lenovo ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ - + /linux;.+((jolla));/i // Jolla ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - + /((pebble))app\/[\d\.]+\s/i // Pebble ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ - + /android.+;\s(glass)\s\d/i // Google Glass ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [ @@ -639,7 +639,7 @@ /(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i // iOS ], [[NAME, 'iOS'], [VERSION, /_/g, '.']], [ - /(mac\sos\sx)\s?([\w\s\.]+\w)*/i, + /(mac\sos\sx)\s?([\w\s\.]+\w)*/i, /(macintosh|mac(?=_powerpc)\s)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ @@ -711,7 +711,7 @@ UAParser.BROWSER = { NAME : NAME, MAJOR : MAJOR, - VERSION : VERSION + VERSION : VERSION }; UAParser.CPU = { ARCHITECTURE : ARCHITECTURE @@ -733,7 +733,7 @@ }; UAParser.OS = { NAME : NAME, - VERSION : VERSION + VERSION : VERSION }; diff --git a/test/device-test.json b/test/device-test.json index 5618960..49262a1 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -72,7 +72,7 @@ { "desc" : "Nokia3xx", "ua" : "Nokia303/14.87 CLDC-1.1", - "expect" : + "expect" : { "vendor" : "Nokia", "model" : "303", From d47e1a5e8e44e0514488fac4b355c402f7af5588 Mon Sep 17 00:00:00 2001 From: Sylvain Gizard Date: Thu, 18 Dec 2014 16:04:31 +0100 Subject: [PATCH 06/25] Update build --- dist/ua-parser.min.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index c61588d..f6da89e 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -2,8 +2,8 @@ * UAParser.js v0.7.3 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js - * + * * Copyright © 2012-2014 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.3",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",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}},lowerize:function(str){return str.toLowerCase()}};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 Date: Thu, 18 Dec 2014 16:09:43 +0100 Subject: [PATCH 07/25] Remove duplicated test --- test/device-test.json | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test/device-test.json b/test/device-test.json index 49262a1..1a2d1d9 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -159,16 +159,6 @@ "type" : "mobile" } }, - { - "desc": "Sony SO-02F (Xperia Z1)", - "ua": "Mozilla/5.0 (Linux; U; Android 4.4; SonySO-02F Build/14.3.B.0.288) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect" : - { - "vendor" : "Sony", - "model" : "Xperia Phone", - "type" : "mobile" - } - }, { "desc": " Sony SGP521 (Xperia Z2 Tablet)", "ua": "Mozilla/5.0 (Linux; Android 4.4; SGP521 Build/17.1.A.0.432) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", From 7d5e50f0089d1d6e5a61c97c9e279bd2dad1ecb8 Mon Sep 17 00:00:00 2001 From: Sylvain Gizard Date: Thu, 18 Dec 2014 16:26:38 +0100 Subject: [PATCH 08/25] Remove duplication --- dist/ua-parser.min.js | 2 +- src/ua-parser.js | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index f6da89e..a8a0579 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2014 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.3",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 Date: Sun, 25 Jan 2015 15:53:44 +0300 Subject: [PATCH 09/25] Add Android Browser and Xiaomi MIUI Browser --- dist/ua-parser.min.js | 2 +- src/ua-parser.js | 8 +++++++- test/browser-test.json | 30 ++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index a8a0579..06d07dd 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2014 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.3",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 Date: Sun, 25 Jan 2015 17:54:39 +0300 Subject: [PATCH 10/25] Add Xiaomi devices --- dist/ua-parser.min.js | 2 +- src/ua-parser.js | 3 +++ test/device-test.json | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 06d07dd..6bfe486 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2014 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.3",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 Date: Sun, 25 Jan 2015 18:26:43 +0300 Subject: [PATCH 11/25] Add Android and MIUI Browser to description --- readme.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index a7d04d1..a866e7b 100644 --- a/readme.md +++ b/readme.md @@ -21,13 +21,13 @@ Extract detailed type of web browser, layout engine, operating system, cpu archi ``` # Possible 'browser.name': -Amaya, Arora, Avant, Baidu, Blazer, Bolt, Camino, Chimera, Chrome, Chromium, -Comodo Dragon, Conkeror, Dillo, Dolphin, Doris, Epiphany, Fennec, Firebird, +Amaya, Android Browser, Arora, Avant, Baidu, Blazer, Bolt, Camino, Chimera, Chrome, +Chromium, Comodo Dragon, Conkeror, Dillo, Dolphin, Doris, Epiphany, Fennec, Firebird, Firefox, Flock, GoBrowser, iCab, ICE Browser, IceApe, IceCat, IceDragon, Iceweasel, IE [Mobile], Iron, Jasmine, K-Meleon, Konqueror, Kindle, Links, -Lunascape, Lynx, Maemo, Maxthon, Midori, Minimo, [Mobile] Safari, Mosaic, Mozilla, -Netfront, Netscape, NetSurf, Nokia, OmniWeb, Opera [Mini/Mobi/Tablet], Phoenix, -Polaris, QQBrowser, RockMelt, Silk, Skyfire, SeaMonkey, SlimBrowser, Swiftfox, +Lunascape, Lynx, Maemo, Maxthon, Midori, Minimo, MIUI Browser, [Mobile] Safari, +Mosaic, Mozilla, Netfront, Netscape, NetSurf, Nokia, OmniWeb, Opera [Mini/Mobi/Tablet], +Phoenix, Polaris, QQBrowser, RockMelt, Silk, Skyfire, SeaMonkey, SlimBrowser, Swiftfox, Tizen, UCBrowser, w3m, Yandex # 'browser.version' & 'browser.major' determined dynamically From 7cae802f3c627563132f73df66036d2f553c008e Mon Sep 17 00:00:00 2001 From: Austin Pray Date: Wed, 28 Jan 2015 13:01:03 -0600 Subject: [PATCH 12/25] fixes typeof --- src/ua-parser.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 47aa574..d9ba3cf 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -80,11 +80,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; @@ -101,9 +101,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 { @@ -112,7 +112,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 { @@ -137,7 +137,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; @@ -735,15 +735,15 @@ // check js environment - if (typeof(exports) !== UNDEF_TYPE) { + if (typeof exports !== UNDEF_TYPE) { // nodejs env - if (typeof(module) !== UNDEF_TYPE && module.exports) { + if (typeof module !== UNDEF_TYPE && module.exports) { exports = module.exports = UAParser; } exports.UAParser = UAParser; } else { // requirejs env - if (typeof(define) === FUNC_TYPE && define.amd) { + if (typeof define === FUNC_TYPE && define.amd) { define(function () { return UAParser; }); @@ -760,7 +760,7 @@ // 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) { + if (typeof $ !== UNDEF_TYPE) { var parser = new UAParser(); $.ua = parser.getResult(); $.ua.get = function() { From f6b22d6654bf7a9fd6584a195011ebab592de1dc Mon Sep 17 00:00:00 2001 From: Dmitry Tyschenko Date: Fri, 30 Jan 2015 11:17:01 +0200 Subject: [PATCH 13/25] Added Xperia Z, Galaxy, Oppo, Advan, i-mobile --- dist/ua-parser.min.js | 2 +- src/ua-parser.js | 55 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 6bfe486..ac61463 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2014 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.3",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 Date: Mon, 2 Feb 2015 19:53:29 +0300 Subject: [PATCH 14/25] Add Vivaldi browser --- dist/ua-parser.min.js | 2 +- readme.md | 2 +- src/ua-parser.js | 2 +- test/browser-test.json | 10 ++++++++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 6bfe486..2e7cb22 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2014 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.3",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 Date: Mon, 2 Feb 2015 19:54:46 +0300 Subject: [PATCH 15/25] Refactor Xiaomi regexps --- dist/ua-parser.min.js | 2 +- src/ua-parser.js | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 2e7cb22..8a7598f 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2014 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.3",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 Date: Thu, 5 Feb 2015 12:31:47 +0200 Subject: [PATCH 16/25] Added Facebook application browser --- dist/ua-parser.min.js | 2 +- src/ua-parser.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index ac61463..427e08d 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2014 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.3",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 Date: Thu, 26 Feb 2015 15:19:09 +0200 Subject: [PATCH 17/25] Get rid of duplicate Xiaomi detection --- dist/ua-parser.min.js | 10 +--------- src/ua-parser.js | 3 --- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 427e08d..56625c2 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1 @@ -/** - * UAParser.js v0.7.3 - * Lightweight JavaScript-based User-Agent string parser - * https://github.com/faisalman/ua-parser-js - * - * Copyright © 2012-2014 Faisal Salman - * Dual licensed under GPLv2 & MIT - */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.3",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 Date: Fri, 27 Feb 2015 17:42:20 +0000 Subject: [PATCH 18/25] Character class may not be used inside character range Additional information and examples at http://stackoverflow.com/questions/15321938/regex-character-class-inside-character-range-failing-intellijs-jslint-inspectio --- src/ua-parser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index d9ba3cf..4601555 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -541,10 +541,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]], [ From 89a3a21ce3b24d1ea8bb9bbf31a506679a27b508 Mon Sep 17 00:00:00 2001 From: Demis Palma Date: Fri, 27 Feb 2015 17:57:27 +0000 Subject: [PATCH 19/25] Unneeded comma Removed last comma in array literal --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index d9ba3cf..068f13c 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -508,7 +508,7 @@ // Alcatel/GeeksPhone/Huawei/Lenovo/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ - /(nexus\s9)/i, // HTC Nexus 9 + /(nexus\s9)/i // HTC Nexus 9 ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ /[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox From a5cb2d88211eb51473e6be8fa20896d12fe845fa Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 29 Mar 2015 09:57:34 +0700 Subject: [PATCH 20/25] Fix #100: Detect NT 10.0 as Windows 10 --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index d31d018..e453a72 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -209,7 +209,7 @@ '7' : 'NT 6.1', '8' : 'NT 6.2', '8.1' : 'NT 6.3', - '10' : 'NT 6.4', + '10' : ['NT 6.4', 'NT 10.0'], 'RT' : 'ARM' } } From 866bdc27af4342b89e56f016bf1ceeca1fdd4c75 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 29 Mar 2015 10:02:39 +0700 Subject: [PATCH 21/25] Windows 10 test --- test/os-test.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/os-test.json b/test/os-test.json index 79e77bd..4ef53bf 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -71,6 +71,15 @@ "version" : "8" } }, + { + "desc" : "Windows 10", + "ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0", + "expect" : + { + "name" : "Windows", + "version" : "10" + } + }, { "desc" : "Windows RT", "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0)", From ad2613d8e9c1225500789e32aa35fbb148a1da62 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 7 Apr 2015 01:19:14 +0700 Subject: [PATCH 22/25] Create package.js for meteor package --- package.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 package.js diff --git a/package.js b/package.js new file mode 100644 index 0000000..bec6fe2 --- /dev/null +++ b/package.js @@ -0,0 +1,12 @@ +Package.describe({ + name: 'faisalman:ua-parser-js', + version: '0.7.3', + summary: 'Lightweight JavaScript-based user-agent string parser', + git: 'https://github.com/faisalman/ua-parser-js.git', + documentation: 'readme.md' +}); + +Package.on_use(function (api) { + api.export("UAParser"); + api.addFiles("src/ua-parser.js"); +}); From 6a284e26705f69f4f9f3d03d8fea558e8f7e46e1 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 7 Apr 2015 01:37:14 +0700 Subject: [PATCH 23/25] Temporarily comment device models to be moved soon --- dist/ua-parser.min.js | 2 +- src/ua-parser.js | 52 ++++++++++++++++++++++--------------- test/device-test.json | 60 +++++++++++++++++++++---------------------- 3 files changed, 62 insertions(+), 52 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 5d8ad53..db51b51 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -6,4 +6,4 @@ * Copyright © 2012-2014 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.3",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 Date: Tue, 7 Apr 2015 01:41:46 +0700 Subject: [PATCH 24/25] Increment patch version to 0.7.4 --- bower.json | 2 +- component.json | 2 +- dist/ua-parser.min.js | 4 ++-- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 4 ++-- ua-parser-js.jquery.json | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index c0d9396..b048c0a 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.3", + "version": "0.7.4", "authors": [ "Faisal Salman " ], diff --git a/component.json b/component.json index ccbbe19..68dc881 100644 --- a/component.json +++ b/component.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.3", + "version": "0.7.4", "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 db51b51..ecedd63 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,9 @@ /** - * UAParser.js v0.7.3 + * UAParser.js v0.7.4 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * * Copyright © 2012-2014 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.3",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 a2d5dbe..803fb8e 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ /** - * UAParser.js v0.7.3 + * UAParser.js v0.7.4 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * @@ -16,7 +16,7 @@ ///////////// - var LIBVERSION = '0.7.3', + var LIBVERSION = '0.7.4', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', diff --git a/ua-parser-js.jquery.json b/ua-parser-js.jquery.json index 907f18d..9ae9a68 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.3", + "version": "0.7.4", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": [ "user-agent", From cce9dc14744f05dd71dbf7b01e2d34c1807f80d0 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 7 Apr 2015 02:40:50 +0700 Subject: [PATCH 25/25] Add meteor support --- .gitignore | 1 + bower.json | 2 +- component.json | 2 +- dist/ua-parser.min.js | 6 +++--- package.js | 2 +- package.json | 2 +- readme.md | 10 ++++++++-- src/ua-parser.js | 29 +++++++++++++++++------------ ua-parser-js.jquery.json | 2 +- 9 files changed, 34 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index ab50210..154d1f0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ npm-debug.log Session.vim .netrwhist *~ +.versions ### OSX ### .DS_Store diff --git a/bower.json b/bower.json index b048c0a..7a6368f 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.4", + "version": "0.7.5", "authors": [ "Faisal Salman " ], diff --git a/component.json b/component.json index 68dc881..7d133b5 100644 --- a/component.json +++ b/component.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.4", + "version": "0.7.5", "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 ecedd63..eda2adf 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,9 @@ /** - * UAParser.js v0.7.4 + * UAParser.js v0.7.5 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * - * Copyright © 2012-2014 Faisal Salman + * Copyright © 2012-2015 Faisal Salman * Dual licensed under GPLv2 & MIT */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.4",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/readme.md b/readme.md index 3100847..8be4d91 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # UAParser.js -Lightweight JavaScript-based User-Agent string parser. Supports browser & node.js environment. Also available as jQuery/Zepto plugin, Component package, Bower package, & AMD module +Lightweight JavaScript-based User-Agent string parser. Supports browser & node.js environment. Also available as jQuery/Zepto plugin, Component package, Bower package, Meteor package, & AMD module [![Build Status](https://travis-ci.org/faisalman/ua-parser-js.svg?branch=master)](https://travis-ci.org/faisalman/ua-parser-js) @@ -221,6 +221,12 @@ console.log(parser.getResult()); $ bower install ua-parser-js ``` +### Using meteor + +```sh +$ meteor add faisalman:ua-parser-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)`. @@ -259,7 +265,7 @@ Then submit a pull request to https://github.com/faisalman/ua-parser-js under `d Dual licensed under GPLv2 & MIT -Copyright © 2012-2014 Faisal Salman <> +Copyright © 2012-2015 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 diff --git a/src/ua-parser.js b/src/ua-parser.js index 803fb8e..c97136a 100644 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,9 +1,9 @@ /** - * UAParser.js v0.7.4 + * UAParser.js v0.7.5 * Lightweight JavaScript-based User-Agent string parser * https://github.com/faisalman/ua-parser-js * - * Copyright © 2012-2014 Faisal Salman + * Copyright © 2012-2015 Faisal Salman * Dual licensed under GPLv2 & MIT */ @@ -16,7 +16,7 @@ ///////////// - var LIBVERSION = '0.7.4', + var LIBVERSION = '0.7.5', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', @@ -734,10 +734,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 +781,16 @@ return this; }; - UAParser.VERSION = LIBVERSION; - UAParser.BROWSER = { + _UAParser.VERSION = LIBVERSION; + _UAParser.BROWSER = { NAME : NAME, MAJOR : MAJOR, VERSION : VERSION }; - UAParser.CPU = { + _UAParser.CPU = { ARCHITECTURE : ARCHITECTURE }; - UAParser.DEVICE = { + _UAParser.DEVICE = { MODEL : MODEL, VENDOR : VENDOR, TYPE : TYPE, @@ -801,11 +801,11 @@ WEARABLE: WEARABLE, EMBEDDED: EMBEDDED }; - UAParser.ENGINE = { + _UAParser.ENGINE = { NAME : NAME, VERSION : VERSION }; - UAParser.OS = { + _UAParser.OS = { NAME : NAME, VERSION : VERSION }; @@ -818,12 +818,17 @@ // check js environment if (typeof(exports) !== UNDEF_TYPE) { + var UAParser = _UAParser; // nodejs env 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) diff --git a/ua-parser-js.jquery.json b/ua-parser-js.jquery.json index 9ae9a68..46f1b34 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.4", + "version": "0.7.5", "description": "Lightweight JavaScript-based user-agent string parser", "keywords": [ "user-agent",