Compare commits

..

60 Commits

Author SHA1 Message Date
Faisal Salman
0109c76858 Automatically create $.ua object if jQuery is present 2013-02-07 23:25:21 +07:00
Faisal Salman
d1120a4d5d Update contributors 2013-02-05 20:43:15 +07:00
Faisal Salman
204345a8bf Add Rekonq, Comodo Dragon, Conkeror, Amaya, w3m, Links, ICE Browser, NetSurf, RISC OS 2013-02-05 20:29:26 +07:00
Faisal Salman
a20d8f7052 Sprint default vendor to Sprint 2013-02-05 14:43:17 +07:00
Faisal Salman
9a90d932ce Add new OS: Firefox OS 2013-01-28 18:46:03 +07:00
Faisal Salman
cea29e5c1b Add new devices: Alcatel, GeeksPhone, Huawei, Lenovo, Nexian, Panasonic, Sony 2013-01-28 18:21:12 +07:00
Faisal Salman
e0b6ae65e5 Better fix for issue #8 2013-01-28 17:11:12 +07:00
Faisal Salman
59714adea3 Add a test for issue #8 2013-01-25 20:33:03 +07:00
Faisal Salman
249dcf0c80 Merge branch 'htc-evo' 2013-01-25 19:47:58 +07:00
Faisalman
b99546072d Workaround for issue #8 2013-01-25 19:46:09 +07:00
Faisal Salman
4e911cec88 Merge pull request #9 from leetreveil/google_closure_compiler
Fix google closure compiler JSC_TRAILING_COMMA errors
2013-01-15 08:21:55 -08:00
Lee Treveil
f1fa7f38a1 Fix google closure compiler JSC_TRAILING_COMMA errors 2013-01-15 15:17:51 +00:00
Faisal Salman
a6610646ca Fix issue #7 2012-12-23 06:45:59 +07:00
Faisal Salman
4703137b79 Minify filesize by variable-izing strings 2012-12-11 18:40:03 +07:00
Faisal Salman
541dfea86d Add some more test 2012-12-07 17:04:26 +07:00
Faisal Salman
35b410009f Insert dog 2012-12-06 20:37:39 +07:00
Faisal Salman
5e84ab7b82 Add test for engine parser 2012-12-06 20:29:37 +07:00
Faisal Salman
816b5d22b4 Add Opera Tablet & capture AppleWebKit as just WebKit 2012-12-06 20:28:33 +07:00
Faisal Salman
29bb0797a6 Merge branch 'test-cases' 2012-12-05 08:56:59 +07:00
Faisal Salman
52897acf24 Fix error build 2012-12-05 08:56:54 +07:00
Faisal Salman
9ccc32ce5a More test cases 2012-12-05 08:53:32 +07:00
Faisal Salman
4a65f1b3f8 Add minifier 2012-12-04 15:57:27 +07:00
Faisal Salman
be4d8a10d1 Turn off travis-ci notification if build success 2012-12-04 15:45:03 +07:00
Faisal Salman
6d183003b3 Fix error build 2012-12-04 15:25:47 +07:00
Faisal Salman
a2b4f6d5c5 Add .travis.yml 2012-12-04 15:08:05 +07:00
Faisal Salman
3f98036d50 Add browser test cases 2012-12-04 14:49:36 +07:00
Faisal Salman
d1d4e0a7a0 Fix Chrome for iOS not detected 2012-12-04 14:04:39 +07:00
Faisalman
3ecb3fbea2 Revise window object detection 2012-11-28 15:32:56 +07:00
Faisal Salman
5cc6bf78a5 Merge pull request #6 from tantalor/master
Fixes nodejs require.
2012-11-28 00:00:51 -08:00
John Tantalo
08c7a84407 added simple test case (mocha) 2012-11-27 20:44:37 -08:00
John Tantalo
ea9d093f0d in strict mode, this is undefined 2012-11-27 19:52:35 -08:00
Faisalman
1f4befe4c3 Fix issue #4 2012-11-26 10:34:37 +07:00
Faisalman
d35fb44066 Distinguish Windows RT from Windows 8 2012-11-15 16:44:31 +07:00
Faisalman
9a6479193a Add Polaris, Tasman, PS Vita, Hurd, AmigaOS, MorphOS 2012-11-12 16:36:11 +07:00
Faisalman
527ba70cf4 Add BB10 new UA pattern & Fix Mobile Safari being caught as just Safari 2012-11-07 18:20:59 +07:00
Faisalman
3fe07487cd Add OS/2, Plan 9, AIX, QNX 2012-11-07 17:03:23 +07:00
Faisalman
8030aa33f7 Add Mosaic, Chimera, Firebird, Phoenix 2012-11-07 16:32:33 +07:00
Faisalman
99251addfc Exclude the letter 'v' from Omniweb version 2012-11-07 15:25:20 +07:00
Faisalman
610cdb84ae Improve Mac OS detection 2012-11-07 15:22:29 +07:00
Faisalman
31b386c636 Add Baidu, Yandex, UCBrowser. Make Apple & RIM as vendor name 2012-11-06 15:53:17 +07:00
Faisalman
b15b48b1bf Rename Dolfin as Dolphin 2012-11-06 14:22:26 +07:00
Faisalman
58fe246468 Add S60 & OviBrowser 2012-11-06 14:18:28 +07:00
Faisalman
e1d3f25bf8 Get device type defined by Firefox 2012-11-06 12:24:12 +07:00
Faisal Salman
4efb13be3e Return unidentified version as undefined 2012-11-02 18:22:06 +07:00
Faisal Salman
bf9fb794d8 Fix issue #3 for old Safari < 3.0 2012-11-02 17:41:29 +07:00
Faisal Salman
df815d4109 Merge pull request #3 from cadecairos/safari-fix
Fix Safari version detection
2012-11-01 23:50:15 -07:00
Christopher De Cairos
6dcee61a0b Fix Safari version detection 2012-11-01 17:11:07 -04:00
Faisal Salman
0288766544 Check if userAgent property is defined 2012-10-23 17:35:24 +07:00
Faisal Salman
7ea79afc2f Fix issue #2 2012-10-22 16:04:23 +07:00
Faisal Salman
59270c8cf7 Some fixes 2012-09-22 00:06:50 +07:00
Faisal Salman
3f92a3cb10 Fix readme & version 2012-09-21 23:21:51 +07:00
Faisal Salman
b9843b4108 Change device properties naming into more appropriate names 2012-09-21 22:59:30 +07:00
Faisal Salman
bdeefcd1fb New identifier for device: type (Mobile, Tablet, Console) 2012-09-20 01:52:23 +07:00
Faisal Salman
bf9c8de5c4 Maps object should contains only data 2012-09-18 00:40:03 +07:00
Faisal Salman
41b3e247a4 Add some Android browsers and some others 2012-09-17 23:11:28 +07:00
Faisal Salman
e5be3083cf Use strict 2012-09-15 14:18:49 +07:00
Faisal Salman
68d124c59c Reorganize the structure of the code 2012-09-15 03:48:30 +07:00
Faisal Salman
33e6fe42d1 Move string checker to outside as strMapper 2012-09-15 02:27:54 +07:00
Faisal Salman
51822ad172 Make sure the result only get constructed once 2012-09-15 02:22:41 +07:00
Faisal Salman
ec40433c5c Fix node.js old example in readme 2012-09-15 01:55:02 +07:00
8 changed files with 1844 additions and 222 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
node_modules/
npm-debug.log

8
.travis.yml Normal file
View File

@@ -0,0 +1,8 @@
language: node_js
node_js:
- 0.8
- 0.6
notifications:
email:
on_success: never
on_failure: always

View File

@@ -1,11 +1,11 @@
{ {
"title": "UA-Parser.JS", "title": "UA-Parser.JS",
"name": "ua-parser-js", "name": "ua-parser-js",
"version": "0.3.4", "version": "0.5.11",
"author": "Faisal Salman <fyzlman@gmail.com> (http://faisalman.com)", "author": "Faisal Salman <fyzlman@gmail.com> (http://faisalman.com)",
"description": "Lightweight JavaScript-based user-agent string parser", "description": "Lightweight JavaScript-based user-agent string parser",
"keywords": [ "keywords": [
"user agent", "user-agent",
"parser", "parser",
"browser", "browser",
"engine", "engine",
@@ -14,9 +14,20 @@
], ],
"homepage": "http://github.com/faisalman/ua-parser-js", "homepage": "http://github.com/faisalman/ua-parser-js",
"contributors": [ "contributors": [
"Faisal Salman <fyzlman@gmail.com>" "Faisal Salman <fyzlman@gmail.com>",
"Christopher De Cairos <chris.decairos@gmail.com>",
"John Tantalo <john.tantalo@gmail.com>",
"Lee Treveil <leetreveil@gmail.com>"
], ],
"main": "ua-parser", "main": "ua-parser",
"scripts": {
"test": "./node_modules/mocha/bin/mocha -R spec",
"pretest": "./node_modules/uglify-js/bin/uglifyjs ua-parser.js > ua-parser.min.js"
},
"devDependencies": {
"mocha": ">= 1.7.1",
"uglify-js": ">= 1.3.4"
},
"repositories": [ "repositories": [
{ {
"type": "git", "type": "git",

View File

@@ -2,6 +2,8 @@
Lightweight JavaScript-based User-Agent string parser Lightweight JavaScript-based User-Agent string parser
[![Build Status](https://travis-ci.org/faisalman/ua-parser-js.png)](https://travis-ci.org/faisalman/ua-parser-js)
* Author : Faisalman <<fyzlman@gmail.com>> * Author : Faisalman <<fyzlman@gmail.com>>
* Home : http://faisalman.github.com/ua-parser-js * Home : http://faisalman.github.com/ua-parser-js
* Source : https://github.com/faisalman/ua-parser-js * Source : https://github.com/faisalman/ua-parser-js
@@ -9,7 +11,9 @@ Lightweight JavaScript-based User-Agent string parser
## Features ## Features
Extract detailed type of web browser, layout engine, operating system, and device purely from user-agent string. Extract detailed type of web browser, layout engine, operating system, and device purely from user-agent string with relatively lightweight footprint (~7KB minified / ~3KB gzipped).
![It's over 9000](https://pbs.twimg.com/media/A9LpEG6CIAA5VrT.jpg)
## Methods ## Methods
@@ -48,8 +52,9 @@ Extract detailed type of web browser, layout engine, operating system, and devic
version: "" version: ""
}, },
device: { device: {
name: "", model: "",
version: "" type: "",
vendor: ""
} }
} }
*/ */
@@ -59,32 +64,58 @@ Extract detailed type of web browser, layout engine, operating system, and devic
parser.setUA(uastr); parser.setUA(uastr);
console.log(parser.getResult().browser); // {name: "Chromium", major: "15", version: "15.0.874.106"} console.log(parser.getResult().browser); // {name: "Chromium", major: "15", version: "15.0.874.106"}
console.log(parser.getResult().engine); // {name: "AppleWebKit", version: "535.2"} console.log(parser.getResult().device); // {model: undefined, type: undefined, vendor: undefined}
console.log(parser.getResult().engine); // {name: "WebKit", version: "535.2"}
console.log(parser.getResult().os); // {name: "Ubuntu", version: "11.10"} console.log(parser.getResult().os); // {name: "Ubuntu", version: "11.10"}
// let's take another test please // let's take another test please
console.log(parser.setUA("Mozilla/5.0 (compatible; Konqueror/4.1; OpenBSD) KHTML/4.1.4 (like Gecko)").getOS().name); // "OpenBSD" console.log(parser.setUA("Mozilla/5.0 (compatible; Konqueror/4.1; OpenBSD) KHTML/4.1.4 (like Gecko)").getBrowser().name); // "Konqueror"
console.log(parser.getOS()); // {name: "OpenBSD", version: undefined}
console.log(parser.getEngine()); // {name: "KHTML", version: "4.1.4"}
</script> </script>
``` ```
## Using node.js ## Using node.js
```js ```sh
var UAParser = require('ua-parser'); $ npm install ua-parser-js
var parser = new UAParser(); ```
var ua1 = 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 1.0.0; en-US) AppleWebKit/534.11 (KHTML, like Gecko) Version/7.1.0.7 Safari/534.11';
var ua2 = 'Midori/0.2 (X11; Linux; U; cs-cz) WebKit/531.2+';
console.log(parser.setUA(ua1).getDevice().name); // "PlayBook" ```js
console.log(parser.getOS()) // {name: "RIM Tablet OS", version: "1.0.0"} var UAParser = require('ua-parser');
console.log(parser.getOS(ua2)) // {name: "Linux", version: undefined} var parser = new UAParser();
console.log(parser.getOS()) // {name: "RIM Tablet OS", version: "1.0.0"} var uaString = 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 1.0.0; en-US) AppleWebKit/534.11 (KHTML, like Gecko) Version/7.1.0.7 Safari/534.11';
console.log(parser.getEngine().name); // "AppleWebKit"
console.log(parser.setUA(uaString).getDevice().model); // "PlayBook"
console.log(parser.getOS()) // {name: "RIM Tablet OS", version: "1.0.0"}
console.log(parser.getEngine().name); // "WebKit"
```
## Using jQuery
If you're using jQuery, `$.ua` object will be created automatically based on container's user-agent. To change different user-agent use `$.setUA(uastring)`. In case you need, `UAParser` is still present in global though.
```js
// In browser with default user-agent: 'Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0':
// Do some tests
console.log($.ua.device); // {vendor: "HTC", model: "Evo Shift 4G", type: "mobile"}
console.log($.ua.os); // {name: "Android", version: "2.3.4"}
console.log($.ua.os.name); // "Android"
// reset to custom user-agent
$.setUA('Mozilla/5.0 (Linux; U; Android 3.0.1; en-us; Xoom Build/HWI69) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13');
// Test again
console.log($.ua.device); // {vendor: "Motorola", model: "Xoom", type: "tablet"}
console.log($.ua.engine.name); // "Webkit"
console.log($.ua.browser.version); // "4.0"
console.log(parseInt($.ua.browser.version.split('.')[0], 10)); // 4
``` ```
## License ## License
Copyright © 2012 Faisalman <<fyzlman@gmail.com>> Copyright © 2012-2013 Faisalman <<fyzlman@gmail.com>>
Permission is hereby granted, free of charge, to any person obtaining a copy of 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 this software and associated documentation files (the "Software"), to deal in

1362
test.js Normal file

File diff suppressed because it is too large Load Diff

31
ua-parser-js.jquery.json Normal file
View File

@@ -0,0 +1,31 @@
{
"title": "UA-Parser.JS",
"name": "ua-parser-js",
"version": "0.5.11",
"description": "Lightweight JavaScript-based user-agent string parser",
"keywords": [
"user-agent",
"parser",
"browser",
"engine",
"os",
"device"
],
"homepage": "https://faisalman.github.com/ua-parser-js",
"author": {
"name": "Faisal Salman",
"email": "fyzlman@gmail.com"
},
"dependencies": {
"jquery": ">=1.5"
},
"licenses": [
{
"type": "MIT",
"url": "http://www.opensource.org/licenses/mit-license.php"
}
],
"bugs": "https://github.com/faisalman/ua-parser-js/issues",
"docs": "https://github.com/faisalman/ua-parser-js",
"download": "https://raw.github.com/faisalman/ua-parser-js/master/ua-parser.min.js"
}

View File

@@ -1,235 +1,392 @@
// UA-Parser.JS v0.3.4 // UA-Parser.JS v0.5.11
// Lightweight JavaScript-based User-Agent string parser // Lightweight JavaScript-based User-Agent string parser
// https://github.com/faisalman/ua-parser-js // https://github.com/faisalman/ua-parser-js
// //
// Copyright © 2012 Faisalman // Copyright © 2012-2013 Faisalman
// Dual licensed under GPLv2 & MIT // Dual licensed under GPLv2 & MIT
(function (undefined) { (function (global, undefined) {
var regexMapper = function (ua, args) { 'use strict';
var result = {}, i, j, k, l, m; var EMPTY = '',
FUNC = 'function',
// loop through all regexes maps UNDEF = 'undefined',
for (i = 1; i < arguments.length; i += 2) { OBJ = 'object',
MAJOR = 'major',
var regex = arguments[i], // even sequence (1,3,5,..) MODEL = 'model',
props = arguments[i + 1]; // odd sequence (2,4,6,..) NAME = 'name',
TYPE = 'type',
// build object barebones VENDOR = 'vendor',
for (k = 0; k < props.length; k++) { VERSION = 'version',
if (typeof props[k] == 'object') { CONSOLE = 'console',
result[props[k][0]] = undefined; MOBILE = 'mobile',
} else { TABLET = 'tablet';
result[props[k]] = undefined;
} var mapper = {
}
regex : function () {
// try matching uastring with regexes
for (j = 0; j < regex.length; j++) { var result, i, j, k, l, m, args = arguments;
l = regex[j].exec(ua);
if (!!l) { // loop through all regexes maps
for (i = 0; i < args.length; i += 2) {
var regex = args[i], // odd sequence (0,2,4,..)
props = args[i + 1]; // even sequence (1,3,5,..)
// construct object barebones
if (typeof result === UNDEF) {
result = {};
for (k = 0; k < props.length; k++) { for (k = 0; k < props.length; k++) {
m = l[k + 1]; if (typeof props[k] === OBJ) {
if (typeof props[k] === 'object' && props[k].length === 2) { result[props[k][0]] = undefined;
result[props[k][0]] = props[k][1];
} else if (typeof props[k] === 'object' && props[k].length === 3) {
result[props[k][0]] = m ? m.replace(props[k][1], props[k][2]) : undefined;
} else { } else {
result[props[k]] = m ? m : undefined; result[props[k]] = undefined;
} }
} }
break; if (this.getUA().toString() === EMPTY) {
return result;
}
} }
}
if(!!l) break; // break the loop immediately if match found
}
return result;
};
var maps = { // try matching uastring with regexes
for (j = 0; j < regex.length; j++) {
check : function(str, map){ l = regex[j].exec(this.getUA());
for (var i in map){ if (!!l) {
if (map.hasOwnProperty(i)) { for (k = 0; k < props.length; k++) {
if (typeof map[i] === 'object' && map[i].length > 0) { m = l[k + 1];
for (var j = 0; j < map[i].length; j++) { if (typeof props[k] === OBJ && props[k].length === 2) {
if (str.toLowerCase().indexOf(map[i][j]) !== -1) { result[props[k][0]] = props[k][1];
return i; } else if (typeof props[k] === OBJ && props[k].length === 3) {
if (typeof props[k][1] === FUNC && !(props[k][1].exec && props[k][1].test)) {
result[props[k][0]] = m ? props[k][1].call(this, m, props[k][2]) : undefined;
} else {
result[props[k][0]] = m ? m.replace(props[k][1], props[k][2]) : undefined;
}
} else {
result[props[k]] = m ? m : undefined;
} }
} }
} else if (str.toLowerCase().indexOf(map[i]) !== -1) { break;
return i; }
}
if(!!l) break; // break the loop immediately if match found
}
return result;
},
string : function (str, map) {
for (var i in map) {
if (map.hasOwnProperty(i)) {
if (typeof map[i] === OBJ && map[i].length > 0) {
for (var j = 0; j < map[i].length; j++) {
if (str.toLowerCase().indexOf(map[i][j].toLowerCase()) !== -1) {
return (i.toString() === UNDEF) ? undefined : i;
}
}
} else if (str.toLowerCase().indexOf(map[i].toLowerCase()) !== -1) {
return (i.toString() === UNDEF) ? undefined : i;
} }
} }
} }
return str; return str;
}
};
var maps = {
browser : {
oldsafari : {
major : {
'1' : ['/85', '/125', '/312'],
'2' : ['/412', '/416', '/417', '/419'],
'undefined' : '/'
},
version : {
'1.0' : '/85',
'1.2' : '/125',
'1.3' : '/312',
'2.0' : '/412',
'2.0.2' : '/416',
'2.0.3' : '/417',
'2.0.4' : '/419',
'undefined' : '/'
}
}
}, },
device : {
sprint : {
model : {
'Evo Shift 4G' : '7373KT'
},
vendor : {
'HTC' : 'APA',
'Sprint' : 'Sprint'
}
}
},
os : { os : {
win : function (match, str1) { windows : {
return maps.check(str1, { version : {
'ME' : '4.90', 'ME' : '4.90',
'NT 3.11' : 'nt3.51', 'NT 3.11' : 'NT3.51',
'NT 4.0' : 'nt4.0', 'NT 4.0' : 'NT4.0',
'2000' : 'nt 5.0', '2000' : 'NT 5.0',
'XP' : ['nt 5.1', 'nt 5.2'], 'XP' : ['NT 5.1', 'NT 5.2'],
'Vista' : 'nt 6.0', 'Vista' : 'NT 6.0',
'7' : 'nt 6.1', '7' : 'NT 6.1',
'8' : 'nt 6.2' '8' : 'NT 6.2',
}); 'RT' : 'ARM'
}
} }
} }
}; };
var regexes = {
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
// Mixed
/(kindle)\/((\d+)?[\w\.]+)/i, // Kindle
/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?((\d+)?[\w\.]+)*/i,
// Lunascape/Maxthon/Netfront/Jasmine/Blazer
// Trident based
/(avant\sbrowser|iemobile|slimbrowser|baidubrowser)[\/\s]?((\d+)?[\w\.]*)/i,
// Avant/IEMobile/SlimBrowser/Baidu
/ms(ie)\s((\d+)?[\w\.]+)/i, // Internet Explorer
// Webkit/KHTML based
/(rekonq)((?:\/)[\w\.]+)*/i, // Rekonq
/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt)\/((\d+)?[\w\.-]+)/i
// Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt
], [NAME, VERSION, MAJOR], [
/(yabrowser)\/((\d+)?[\w\.]+)/i // Yandex
], [[NAME, 'Yandex'], VERSION, MAJOR], [
/(comodo_dragon)\/((\d+)?[\w\.]+)/i // Comodo Dragon
], [[NAME, /_/g, ' '], VERSION, MAJOR], [
/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?((\d+)?[\w\.]+)/i
// Chrome/OmniWeb/Arora/Tizen/Nokia
], [NAME, VERSION, MAJOR], [
/(dolfin)\/((\d+)?[\w\.]+)/i // Dolphin
], [[NAME, 'Dolphin'], VERSION, MAJOR], [
/((?:android.+)crmo|crios)\/((\d+)?[\w\.]+)/i // Chrome for Android/iOS
], [[NAME, 'Chrome'], VERSION, MAJOR], [
/version\/((\d+)?[\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari
], [VERSION, MAJOR, [NAME, 'Mobile Safari']], [
/version\/((\d+)?[\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile
], [VERSION, MAJOR, NAME], [
/applewebkit.+?(mobile\s?safari|safari)((\/[\w\.]+))/i // Safari < 3.0
], [NAME, [MAJOR, mapper.string, maps.browser.oldsafari.major], [VERSION, mapper.string, maps.browser.oldsafari.version]], [
/(konqueror)\/((\d+)?[\w\.]+)/i, // Konqueror
/(applewebkit|khtml)\/((\d+)?[\w\.]+)/i
], [NAME, VERSION, MAJOR], [
// Gecko based
/(navigator|netscape)\/((\d+)?[\w\.-]+)/i // Netscape
], [[NAME, 'Netscape'], VERSION, MAJOR], [
/(swiftfox)/i, // Swiftfox
/(iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?((\d+)?[\w\.\+]+)/i,
// 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
/(mozilla)\/((\d+)?[\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla
// Other
/(uc\s?browser|polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf)[\/\s]?((\d+)?[\w\.]+)/i,
// UCBrowser/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]
],
device : [[
/\((ipad|playbook);[\w\s\);-]+(rim|apple)/i // iPad/PlayBook
], [MODEL, VENDOR, [TYPE, TABLET]], [
/(hp).+(touchpad)/i, // HP TouchPad
/(kindle)\/([\w\.]+)/i, // Kindle
/\s(nook)[\w\s]+build\/(\w+)/i, // Nook
/(dell)\s(strea[kpr\s\d]*[\dko])/i // Dell Streak
], [VENDOR, MODEL, [TYPE, TABLET]], [
/\((ip[honed]+);.+(apple)/i // iPod/iPhone
], [MODEL, VENDOR, [TYPE, MOBILE]], [
/(blackberry)[\s-]?(\w+)/i, // BlackBerry
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|huawei|meizu|motorola)[\s_-]?([\w-]+)*/i,
// BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Huawei/Meizu/Motorola
/(hp)\s([\w\s]+\w)/i, // HP iPAQ
/(asus)-?(\w+)/i // Asus
], [VENDOR, MODEL, [TYPE, MOBILE]], [
/\((bb10);\s(\w+)/i // BlackBerry 10
], [[VENDOR, 'BlackBerry'], MODEL, [TYPE, MOBILE]], [
/android.+((transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+))/i // Asus Tablets
], [[VENDOR, 'Asus'], MODEL, [TYPE, TABLET]], [
/(sony)\s(tablet\s[ps])/i // Sony Tablets
], [VENDOR, MODEL, [TYPE, TABLET]], [
/(nintendo|playstation)\s([wids3portablev]+)/i // Nintendo/Playstation
], [VENDOR, MODEL, [TYPE, CONSOLE]], [
/(sprint\s(\w+))/i // Sprint Phones
], [[VENDOR, mapper.string, maps.device.sprint.vendor], [MODEL, mapper.string, maps.device.sprint.model], [TYPE, MOBILE]], [
/(htc)[;_\s-]+([\w\s]+(?=\))|\w+)*/i, // HTC
/(zte)-(\w+)*/i, // ZTE
/(alcatel|geeksphone|huawei|lenovo|nexian|panasonic|;\ssony)[_\s-]?([\w-]+)*/i
// Alcatel/GeeksPhone/Huawei/Lenovo/Nexian/Panasonic/Sony
], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
/\s((milestone|droid[2x]?))[globa\s]*\sbuild\//i, // Motorola
/(mot)[\s-]?(\w+)*/i
], [[VENDOR, 'Motorola'], MODEL, [TYPE, MOBILE]], [
/android.+\s((mz60\d|xoom[\s2]{0,2}))\sbuild\//i
], [[VENDOR, 'Motorola'], MODEL, [TYPE, TABLET]], [
/android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n8000|sgh-t8[56]9))/i
], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung
/((s[cgp]h-\w+|gt-\w+|galaxy\snexus))/i,
/(sam[sung]*)[\s-]*(\w+-?[\w-]*)*/i,
/sec-((sgh\w+))/i
], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [
/(sie)-(\w+)*/i // Siemens
], [[VENDOR, 'Siemens'], MODEL, [TYPE, MOBILE]], [
/(maemo|nokia).*(n900|lumia\s\d+)/i, // Nokia
/(nokia)[\s_-]?([\w-]+)*/i
], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [
/android\s3\.[\s\w-;]{10}((a\d{3}))/i // Acer
], [[VENDOR, 'Acer'], MODEL, [TYPE, TABLET]], [
/android\s3\.[\s\w-;]{10}(lg?)-([06cv9]{3,4})/i // LG
], [[VENDOR, 'LG'], MODEL, [TYPE, TABLET]], [
/(lg)[e;\s-\/]+(\w+)*/i
], [[VENDOR, 'LG'], MODEL, [TYPE, MOBILE]], [
/(mobile|tablet);.+rv\:.+gecko\//i // Unidentifiable
], [TYPE, VENDOR, MODEL]
],
engine : [[
/(presto)\/([\w\.]+)/i, // Presto
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m
/(khtml)\/([\w\.]+)/i, // KHTML
/(tasman)\s([\w\.]+)/i, // Tasman
/(links)\s\(([\w\.]+)/i, // Links
/(icab)[\/\s]([2-3]\.[\d\.]+)/i // iCab
], [NAME, VERSION], [
/rv\:([\w\.]+).*(gecko)/i // Gecko
], [VERSION, NAME]
],
os : [[
// Windows based
/(windows)\snt\s6\.2;\s(arm)/i, // Windows RT
/(windows\sphone\sos|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i
], [NAME, [VERSION, mapper.string, maps.os.windows.version]], [
/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i
], [[NAME, 'Windows'], [VERSION, mapper.string, maps.os.windows.version]], [
// Mobile/Embedded OS
/\((bb)(10);/i // BlackBerry 10
], [[NAME, 'BlackBerry'], VERSION], [
/(blackberry)\w*\/?([\w\.]+)*/i, // Blackberry
/(tizen)\/([\w\.]+)/i, // Tizen
/(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i
// Android/WebOS/Palm/QNX/Bada/RIM/MeeGo
], [NAME, VERSION], [
/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i // Symbian
], [[NAME, 'Symbian'], VERSION],[
/mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS
], [[NAME, 'Firefox OS'], VERSION], [
// Console
/(nintendo|playstation)\s([wids3portablev]+)/i, // Nintendo/Playstation
// GNU/Linux based
/(mint)[\/\s\(]?(\w+)*/i, // Mint
/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk)[\/\s-]?([\w\.-]+)*/i,
// Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware
// Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk
/(hurd|linux)\s?([\w\.]+)*/i, // Hurd/Linux
/(gnu)\s?([\w\.]+)*/i // GNU
], [NAME, VERSION], [
/(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS
], [[NAME, 'Chromium OS'], VERSION],[
// Solaris
/(sunos)\s?([\w\.]+\d)*/i // Solaris
], [[NAME, 'Solaris'], VERSION], [
// BSD based
/\s(\w*bsd|dragonfly)\s?([\w\.]+)*/i // FreeBSD/NetBSD/OpenBSD/DragonFly
], [NAME, VERSION],[
/(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i // iOS
], [[NAME, 'iOS'], [VERSION, /_/g, '.']], [
/(mac\sos\sx)\s?([\w\s\.]+\w)*/i // Mac OS
], [NAME, [VERSION, /_/g, '.']], [
// Other
/(haiku)\s(\w+)/i, // Haiku
/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i, // AIX
/(macintosh|mac(?=_powerpc)|plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos)/i,
// Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS
/(unix)\s?([\w\.]+)*/i // UNIX
], [NAME, VERSION]
]
};
var UAParser = function UAParser (uastring) { var UAParser = function UAParser (uastring) {
var ua = uastring || (typeof window !== 'undefined' ? window.navigator.userAgent : ""); var ua = uastring || ((global && global.navigator && global.navigator.userAgent) ? global.navigator.userAgent : EMPTY);
this.getBrowser = function () { this.getBrowser = function () {
return mapper.regex.apply(this, regexes.browser);
};
return regexMapper(ua, [ this.getDevice = function () {
return mapper.regex.apply(this, regexes.device);
// Mixed
/(kindle)\/((\d+)?[\w\.]+)/i, // Kindle
/(lunascape|maxthon|netfront|jasmine)[\/\s]?((\d+)?[\w\.]+)/i, // Lunascape/Maxthon/Netfront/Jasmine
// Presto based
/(opera\smini)\/((\d+)?[\w\.-]+)/i, // Opera Mini
/(opera\smobi)\/((\d+)?[\w\.-]+)/i, // Opera Mobile
/(opera).+version\/((\d+)?[\w\.]+)/i, // Opera
/(opera)[\/\s]+((\d+)?[\w\.]+)/i,
// Trident based
/(avant\sbrowser|iemobile|slimbrowser)[\/\s]?((\d+)?[\w\.]*)/i, // Avant/IEMobile/SlimBrowser
/ms(ie)\s((\d+)?[\w\.]+)/i, // Internet Explorer
// Webkit/KHTML based
/(chromium|flock|rockmelt|midori|epiphany|silk)\/((\d+)?[\w\.]+)/i, // Chromium/Flock/RockMelt/Midori/Epiphany
/(chrome|omniweb|arora|dolfin|[tizenaok]{5}\s?browser)\/((\d+)?[\w\.]+)/i,
// Chrome/OmniWeb/Arora/Dolphin/Tizen/Nokia
], ['name', 'version', 'major'], [
/(?:android.+(crmo|crios))\/((\d+)?[\w\.]+)/i, // Chrome for Android/iOS
], [['name', 'Chrome'], 'version', 'major'], [
/(mobile\ssafari|safari|konqueror)\/((\d+)?[\w\.]+)/i, // Safari/Konqueror
/(applewebkit|khtml)\/((\d+)?[\w\.]+)/i,
// Gecko based
/(iceweasel|camino|fennec|maemo\sbrowser|minimo)[\/\s]?((\d+)?[\w\.\+]+)/i,
// Iceweasel/Camino/Fennec/Maemo/Minimo
/(firefox|seamonkey|netscape|navigator|k-meleon|icecat|iceape)\/((\d+)?[\w\.]+)/i,
// Firefox/SeaMonkey/Netscape/K-Meleon/IceCat/IceApe
/(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla
// Other
/(lynx|dillo|icab)[\/\s]?((\d+)?[\w\.]+)/i, // Lynx/Dillo/iCab
], ['name', 'version', 'major']);
}; };
this.getEngine = function () { this.getEngine = function () {
return mapper.regex.apply(this, regexes.engine);
return regexMapper(ua, [
/(presto)\/([\w\.]+)/i, // Presto
/([aple]*webkit|trident)\/([\w\.]+)/i, // Webkit/Trident
/(khtml)\/([\w\.]+)/i // KHTML
], ['name', 'version'], [
/rv\:([\w\.]+).*(gecko)/i // Gecko
], ['version', 'name']);
}; };
this.getOS = function () { this.getOS = function () {
return mapper.regex.apply(this, regexes.os);
return regexMapper(ua, [
// Windows based
/(windows\sphone\sos|windows)\s?([nt\d\.\s]+\d)/i // Windows
], ['name', ['version', /(.+)/gi, maps.os.win]], [
/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i
], [['name', 'Windows'], ['version', /(.+)/gi, maps.os.win]], [
// Mobile/Embedded OS
/(blackberry).+version\/([\w\.]+)/i, // Blackberry
/(tizen)\/([\w\.]+)/i, // Tizen
/(android|symbianos|symbos|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i,
// Android/Symbian/WebOS/Palm/QNX/Bada/RIM/MeeGo
/(nintendo|playstation)\s([wids3portable]+)/i, // Nintendo/Playstation
// GNU/Linux based
/(mint)[\/\s\(]?(\w+)*/i, // Mint
/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk)[\/\s-]?([\w\.-]+)*/i,
// Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware
// Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk
/(gnu|linux)\s?([\w\.]+)*/i // Other GNU/Linux
], ['name', 'version'], [
/(cros)\s([\w\.\s]+\d)/i // Chromium OS
], [['name', 'Chromium OS'], 'version'],[
// Solaris
/(sunos)\s?([\w\.\s]+\d)*/i // Solaris
], [['name', 'Solaris'], 'version'], [
// BSD based
/\s(\w*bsd|dragonfly)\s?([\w\.]+)*/i, // FreeBSD/NetBSD/OpenBSD/DragonFly
], ['name', 'version'],[
/(ip[honead]+).*os\s*([\w]+)*\slike\smac/i // iOS
], [['name', /.+/g, 'iOS'], ['version', /_/g, '.']], [
/(mac\sos\sx)\s([\w\s\.]+\w)/i, // Mac OS
], ['name', ['version', /_/g, '.']], [
// Other
/(haiku)\s(\w+)/i, // Haiku
/(macintosh|unix|minix|beos)[\/\s]?()*/i // UNIX/Minix/BeOS
], ['name', 'version']);
};
this.getDevice = function () {
return regexMapper(ua, [
/\((ip[honead]+|playbook);/i, // iPod/iPhone/iPad/PlayBook
/(blackberry)[\s-]?(\w+)/i, // BlackBerry
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|nexus|zte)[\s_-]?([\w-]+)*/i,
// BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Nexus/ZTE
/(hp)\s([\w\s]+\w)/i, // HP iPAQ
/(hp).+(touchpad)/i, // HP TouchPad
/(kindle)\/([\w\.]+)/i, // Kindle
/(lg)[e;\s-]+(\w+)*/i, // LG
/(nintendo|playstation)\s([wids3portable]+)/i // Nintendo/Playstation
], ['name', 'version'], [
/(htc)[;_\s-]+([\w\s]+(?=\))|[\w]+)*/i, // HTC
/(zte)-([\w]+)*/i
], ['name', ['version', /_/g, ' ']], [
/\s((milestone|mz601|droid[2x]?|xoom))[globa\s]*\sbuild\//i, // Motorola
/(mot)[\s-]?(\w+)*/i
], [['name', 'Motorola'], 'version'], [
/((s[cgp]h-\w+|gt-\w+|galaxy\snexus))/i, // Samsung
/(sam[sung]*)[\s-]*(\w+-?[\w-]*)*/i,
/sec-((sgh\w+))/i
], [['name', 'Samsung'], 'version'], [
/((transfo[prime\s]{4,10}\s\w+|(?:android.*)eeepc))/i // Asus
], [['name', 'Asus'], 'version'], [
/(sie)-(\w+)*/i // Siemens
], [['name', 'Siemens'], 'version'], [
/(maemo|nokia).*(n900|lumia\s\d+)/i, // Nokia
/(nokia)[\s_-]?([\w-]+)*/i
], [['name', 'Nokia'], 'version']);
};
this.getUA = function() {
return ua;
}; };
this.getResult = function() { this.getResult = function() {
@@ -241,6 +398,10 @@
}; };
}; };
this.getUA = function() {
return ua;
};
this.setUA = function (uastring) { this.setUA = function (uastring) {
ua = uastring; ua = uastring;
return this; return this;
@@ -248,14 +409,23 @@
this.setUA(ua); this.setUA(ua);
}; };
// check whether script is running inside node.js export as module // check js environment
if (typeof exports !== 'undefined' && this.toString() !== '[object DOMWindow]') { if (typeof exports !== UNDEF && !/\[object\s[DOM]*Window\]/.test(global.toString())) {
if (typeof module !== 'undefined' && module.exports) { // nodejs env
if (typeof module !== UNDEF && module.exports) {
exports = module.exports = UAParser; exports = module.exports = UAParser;
} }
exports.UAParser = UAParser; exports.UAParser = UAParser;
} else { } else {
this['UAParser'] = UAParser; // browser env
global.UAParser = UAParser;
// jQuery specific
if (typeof global.jQuery !== UNDEF) {
global.jQuery.ua = new UAParser().getResult();
global.jQuery.setUA = function (uastring) {
global.jQuery.ua = new UAParser(uastring).getResult();
}
}
} }
})(); })(this);

7
ua-parser.min.js vendored Normal file

File diff suppressed because one or more lines are too long