bowser 0.6.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,39 @@
1
+ Copyright 2015, Dustin Diaz (the "Original Author")
2
+ All rights reserved.
3
+
4
+ MIT License
5
+
6
+ Permission is hereby granted, free of charge, to any person
7
+ obtaining a copy of this software and associated documentation
8
+ files (the "Software"), to deal in the Software without
9
+ restriction, including without limitation the rights to use,
10
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the
12
+ Software is furnished to do so, subject to the following
13
+ conditions:
14
+
15
+ The above copyright notice and this permission notice shall be
16
+ included in all copies or substantial portions of the Software.
17
+
18
+ Distributions of all or part of the Software intended to be used
19
+ by the recipients as they would use the unmodified Software,
20
+ containing modifications that substantially alter, remove, or
21
+ disable functionality of the Software, outside of the documented
22
+ configuration mechanisms provided by the Software, shall be
23
+ modified such that the Original Author's bug reporting email
24
+ addresses and urls are either replaced with the contact information
25
+ of the parties responsible for the changes, or removed entirely.
26
+
27
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
29
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
31
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
32
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
34
+ OTHER DEALINGS IN THE SOFTWARE.
35
+
36
+
37
+ Except where noted, this license applies to any and all software
38
+ programs and associated documentation files created by the
39
+ Original Author, when distributed with the Software.
package/Makefile CHANGED
@@ -1,7 +1,7 @@
1
1
  boosh:
2
2
  node make/build.js
3
3
 
4
- REPORTER = dot
4
+ REPORTER = spec
5
5
 
6
6
  test:
7
7
  @NODE_ENV=test ./node_modules/.bin/mocha \
package/README.md CHANGED
@@ -1,5 +1,4 @@
1
- Bowser
2
- ------
1
+ ## Bowser
3
2
  A Browser detector. Because sometimes, there is no other way, and not even good modern browsers always provide good feature detection mechanisms.
4
3
 
5
4
  [![bowser ci](https://secure.travis-ci.org/ded/bowser.png)](https://travis-ci.org/ded/bowser/)
@@ -12,16 +11,16 @@ if (bowser.msie && bowser.version <= 6) {
12
11
  }
13
12
  ```
14
13
 
15
- Flags set for detected Browsers[Engines]
16
- -----
14
+ ## Flags set for detected Browsers[Engines]
17
15
 
18
16
  * `chrome`[`webkit`]
19
17
  * `firefox`[`gecko`]
20
18
  * `msie`
19
+ * `msedge`
21
20
  * Android native browser as `android`[`webkit`]
22
21
  * iOS native browser as `ios`[`webkit`]
23
22
  * `opera`[`webkit` if >12]
24
- * `phantomjs`[`webkit`]
23
+ * `phantom`[`webkit`]
25
24
  * `safari`[`webkit`]
26
25
  * `seamonkey`[`gecko`]
27
26
  * BlackBerry native browser as `blackberry`[`webkit`]
@@ -33,8 +32,7 @@ Flags set for detected Browsers[Engines]
33
32
 
34
33
  For all detected browsers the browser version is set in the `version` field.
35
34
 
36
- Flags set for detected mobile Operating Systems
37
- -----
35
+ ## Flags set for detected mobile Operating Systems
38
36
 
39
37
  * `android`
40
38
  * Windows Phone as `windowsphone`
@@ -50,8 +48,7 @@ Android, iOS, Windows Phone, WebOS, Bada, and Tizen will all report the OS versi
50
48
 
51
49
  All detected mobile OSes are additionally flagged `mobile`, **if they are not powering a tablet device**. If a tablet device is detected, the flag `tablet` is set instead.
52
50
 
53
- Notes
54
- ----
51
+ ### Notes
55
52
  Safari, Chrome and some other minor browsers will report that they have `webkit` engines, Firefox and Seamonkey will report that they have `gecko` engines.
56
53
 
57
54
  ``` js
@@ -60,27 +57,23 @@ if (bowser.webkit) {
60
57
  }
61
58
  ```
62
59
 
63
- Ender installation
64
- -----
65
- If you don't already have [Ender](http://ender.no.de) (an npm package) install it now (and don't look back)
60
+ ### Ender Support
66
61
 
67
- $ npm install ender
62
+ `package.json`
68
63
 
69
- then add bowser to your module collection
70
-
71
- $ ender add bowser
72
-
73
- use it like this:
64
+ ``` json
65
+ "dependencies": {
66
+ "bowser": "x.x.x"
67
+ }
68
+ ```
74
69
 
75
70
  ``` js
76
- if ($.browser.chrome) {
77
- alert('Hello Silicon Valley');
71
+ if (require('bowser').chrome) {
72
+ alert('Hello Silicon Valley')
78
73
  }
79
74
  ```
80
75
 
81
- Graded Browser Support
82
- ---------
83
- One useful feature of Bowser is that aside from checking one browser from another -- it will keep up to date with [Yahoo's Graded Browser Support](http://developer.yahoo.com/yui/articles/gbs/) chart, giving you access to each grade on the bowser object
76
+ ### Graded Browser Support
84
77
 
85
78
  ``` js
86
79
  if (bowser.a) {
@@ -94,20 +87,21 @@ else {
94
87
  }
95
88
  ```
96
89
 
97
- Building
98
- --------
99
-
100
- If you'd like to contribute a change to bowser, modify the files in src/, then run the following (you'll need node + npm installed):
90
+ ### Contributing
91
+ If you'd like to contribute a change to bowser, modify the files in `src/`, then run the following (you'll need node + npm installed):
101
92
 
102
- $ npm install
103
- $ make
93
+ ``` sh
94
+ $ npm install
95
+ $ make test
96
+ ```
104
97
 
98
+ Please do not check-in the built files `bowser.js` and `bowser.min.js` in pull requests.
105
99
 
106
- Testing
107
- -------
108
- We started a list `src/useragents.js` with example user agents and their expected bowser object.
100
+ ### Adding tests
101
+ See the list in `src/useragents.js` with example user agents and their expected bowser object.
109
102
 
110
103
  Whenever you add support for new browsers or notice a bug / mismatch, please update the list and
111
104
  check if all tests are still passing.
112
105
 
113
- To run the test call `$ make test`
106
+ ### License
107
+ Licensed as MIT. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.
package/bowser.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /*!
2
2
  * Bowser - a browser detector
3
3
  * https://github.com/ded/bowser
4
- * MIT License | (c) Dustin Diaz 2014
4
+ * MIT License | (c) Dustin Diaz 2015
5
5
  */
6
6
 
7
7
  !function (name, definition) {
8
- if (typeof module != 'undefined' && module.exports) module.exports['browser'] = definition()
9
- else if (typeof define == 'function') define(definition)
8
+ if (typeof module != 'undefined' && module.exports) module.exports = definition()
9
+ else if (typeof define == 'function' && define.amd) define(definition)
10
10
  else this[name] = definition()
11
11
  }('bowser', function () {
12
12
  /**
@@ -22,9 +22,16 @@
22
22
  return (match && match.length > 1 && match[1]) || '';
23
23
  }
24
24
 
25
+ function getSecondMatch(regex) {
26
+ var match = ua.match(regex);
27
+ return (match && match.length > 1 && match[2]) || '';
28
+ }
29
+
25
30
  var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase()
26
31
  , likeAndroid = /like android/i.test(ua)
27
32
  , android = !likeAndroid && /android/i.test(ua)
33
+ , chromeBook = /CrOS/.test(ua)
34
+ , edgeVersion = getFirstMatch(/edge\/(\d+(\.\d+)?)/i)
28
35
  , versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i)
29
36
  , tablet = /tablet/i.test(ua)
30
37
  , mobile = !tablet && /[^-]mobi/i.test(ua)
@@ -37,12 +44,25 @@
37
44
  , version: versionIdentifier || getFirstMatch(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i)
38
45
  }
39
46
  }
47
+ else if (/yabrowser/i.test(ua)) {
48
+ result = {
49
+ name: 'Yandex Browser'
50
+ , yandexbrowser: t
51
+ , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i)
52
+ }
53
+ }
40
54
  else if (/windows phone/i.test(ua)) {
41
55
  result = {
42
56
  name: 'Windows Phone'
43
57
  , windowsphone: t
44
- , msie: t
45
- , version: getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i)
58
+ }
59
+ if (edgeVersion) {
60
+ result.msedge = t
61
+ result.version = edgeVersion
62
+ }
63
+ else {
64
+ result.msie = t
65
+ result.version = getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i)
46
66
  }
47
67
  }
48
68
  else if (/msie|trident/i.test(ua)) {
@@ -51,6 +71,19 @@
51
71
  , msie: t
52
72
  , version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i)
53
73
  }
74
+ } else if (chromeBook) {
75
+ result = {
76
+ name: 'Chrome'
77
+ , chromeBook: t
78
+ , chrome: t
79
+ , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)
80
+ }
81
+ } else if (/chrome.+? edge/i.test(ua)) {
82
+ result = {
83
+ name: 'Microsoft Edge'
84
+ , msedge: t
85
+ , version: edgeVersion
86
+ }
54
87
  }
55
88
  else if (/chrome|crios|crmo/i.test(ua)) {
56
89
  result = {
@@ -118,7 +151,7 @@
118
151
  , blackberry: t
119
152
  , version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i)
120
153
  }
121
- }
154
+ }
122
155
  else if (/(web|hpw)os/i.test(ua)) {
123
156
  result = {
124
157
  name: 'WebOS'
@@ -148,10 +181,15 @@
148
181
  , version: versionIdentifier
149
182
  }
150
183
  }
151
- else result = {}
184
+ else {
185
+ result = {
186
+ name: getFirstMatch(/^(.*)\/(.*) /),
187
+ version: getSecondMatch(/^(.*)\/(.*) /)
188
+ };
189
+ }
152
190
 
153
191
  // set webkit or gecko flag for browsers based on these engines
154
- if (/(apple)?webkit/i.test(ua)) {
192
+ if (!result.msedge && /(apple)?webkit/i.test(ua)) {
155
193
  result.name = result.name || "Webkit"
156
194
  result.webkit = t
157
195
  if (!result.version && versionIdentifier) {
@@ -164,7 +202,7 @@
164
202
  }
165
203
 
166
204
  // set OS flags for platforms that have multiple browsers
167
- if (android || result.silk) {
205
+ if (!result.msedge && (android || result.silk)) {
168
206
  result.android = t
169
207
  } else if (iosdevice) {
170
208
  result[iosdevice] = t
@@ -173,13 +211,13 @@
173
211
 
174
212
  // OS version extraction
175
213
  var osVersion = '';
176
- if (iosdevice) {
214
+ if (result.windowsphone) {
215
+ osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i);
216
+ } else if (iosdevice) {
177
217
  osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i);
178
218
  osVersion = osVersion.replace(/[_\s]/g, '.');
179
219
  } else if (android) {
180
220
  osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i);
181
- } else if (result.windowsphone) {
182
- osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i);
183
221
  } else if (result.webos) {
184
222
  osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i);
185
223
  } else if (result.blackberry) {
@@ -203,19 +241,22 @@
203
241
 
204
242
  // Graded Browser Support
205
243
  // http://developer.yahoo.com/yui/articles/gbs
206
- if ((result.msie && result.version >= 9) ||
244
+ if (result.msedge ||
245
+ (result.msie && result.version >= 10) ||
246
+ (result.yandexbrowser && result.version >= 15) ||
207
247
  (result.chrome && result.version >= 20) ||
208
- (result.firefox && result.version >= 10.0) ||
209
- (result.safari && result.version >= 5) ||
248
+ (result.firefox && result.version >= 20.0) ||
249
+ (result.safari && result.version >= 6) ||
210
250
  (result.opera && result.version >= 10.0) ||
211
- (result.ios && result.osversion && result.osversion.split(".")[0] >= 6)
251
+ (result.ios && result.osversion && result.osversion.split(".")[0] >= 6) ||
252
+ (result.blackberry && result.version >= 10.1)
212
253
  ) {
213
254
  result.a = t;
214
255
  }
215
- else if ((result.msie && result.version < 9) ||
256
+ else if ((result.msie && result.version < 10) ||
216
257
  (result.chrome && result.version < 20) ||
217
- (result.firefox && result.version < 10.0) ||
218
- (result.safari && result.version < 5) ||
258
+ (result.firefox && result.version < 20.0) ||
259
+ (result.safari && result.version < 6) ||
219
260
  (result.opera && result.version < 10.0) ||
220
261
  (result.ios && result.osversion && result.osversion.split(".")[0] < 6)
221
262
  ) {
@@ -227,6 +268,17 @@
227
268
 
228
269
  var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : '')
229
270
 
271
+ bowser.test = function (browserList) {
272
+ for (var i = 0; i < browserList.length; ++i) {
273
+ var browserItem = browserList[i];
274
+ if (typeof browserItem=== 'string') {
275
+ if (browserItem in bowser) {
276
+ return true;
277
+ }
278
+ }
279
+ }
280
+ return false;
281
+ }
230
282
 
231
283
  /*
232
284
  * Set our detect method to the main bowser object so we can
package/bowser.min.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Bowser - a browser detector
3
3
  * https://github.com/ded/bowser
4
- * MIT License | (c) Dustin Diaz 2014
4
+ * MIT License | (c) Dustin Diaz 2015
5
5
  */
6
- !function(e,t){typeof module!="undefined"&&module.exports?module.exports.browser=t():typeof define=="function"?define(t):this[e]=t()}("bowser",function(){function t(t){function n(e){var n=t.match(e);return n&&n.length>1&&n[1]||""}var r=n(/(ipod|iphone|ipad)/i).toLowerCase(),i=/like android/i.test(t),s=!i&&/android/i.test(t),o=n(/version\/(\d+(\.\d+)?)/i),u=/tablet/i.test(t),a=!u&&/[^-]mobi/i.test(t),f;/opera|opr/i.test(t)?f={name:"Opera",opera:e,version:o||n(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i)}:/windows phone/i.test(t)?f={name:"Windows Phone",windowsphone:e,msie:e,version:n(/iemobile\/(\d+(\.\d+)?)/i)}:/msie|trident/i.test(t)?f={name:"Internet Explorer",msie:e,version:n(/(?:msie |rv:)(\d+(\.\d+)?)/i)}:/chrome|crios|crmo/i.test(t)?f={name:"Chrome",chrome:e,version:n(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)}:r?(f={name:r=="iphone"?"iPhone":r=="ipad"?"iPad":"iPod"},o&&(f.version=o)):/sailfish/i.test(t)?f={name:"Sailfish",sailfish:e,version:n(/sailfish\s?browser\/(\d+(\.\d+)?)/i)}:/seamonkey\//i.test(t)?f={name:"SeaMonkey",seamonkey:e,version:n(/seamonkey\/(\d+(\.\d+)?)/i)}:/firefox|iceweasel/i.test(t)?(f={name:"Firefox",firefox:e,version:n(/(?:firefox|iceweasel)[ \/](\d+(\.\d+)?)/i)},/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(t)&&(f.firefoxos=e)):/silk/i.test(t)?f={name:"Amazon Silk",silk:e,version:n(/silk\/(\d+(\.\d+)?)/i)}:s?f={name:"Android",version:o}:/phantom/i.test(t)?f={name:"PhantomJS",phantom:e,version:n(/phantomjs\/(\d+(\.\d+)?)/i)}:/blackberry|\bbb\d+/i.test(t)||/rim\stablet/i.test(t)?f={name:"BlackBerry",blackberry:e,version:o||n(/blackberry[\d]+\/(\d+(\.\d+)?)/i)}:/(web|hpw)os/i.test(t)?(f={name:"WebOS",webos:e,version:o||n(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i)},/touchpad\//i.test(t)&&(f.touchpad=e)):/bada/i.test(t)?f={name:"Bada",bada:e,version:n(/dolfin\/(\d+(\.\d+)?)/i)}:/tizen/i.test(t)?f={name:"Tizen",tizen:e,version:n(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i)||o}:/safari/i.test(t)?f={name:"Safari",safari:e,version:o}:f={},/(apple)?webkit/i.test(t)?(f.name=f.name||"Webkit",f.webkit=e,!f.version&&o&&(f.version=o)):!f.opera&&/gecko\//i.test(t)&&(f.name=f.name||"Gecko",f.gecko=e,f.version=f.version||n(/gecko\/(\d+(\.\d+)?)/i)),s||f.silk?f.android=e:r&&(f[r]=e,f.ios=e);var l="";r?(l=n(/os (\d+([_\s]\d+)*) like mac os x/i),l=l.replace(/[_\s]/g,".")):s?l=n(/android[ \/-](\d+(\.\d+)*)/i):f.windowsphone?l=n(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i):f.webos?l=n(/(?:web|hpw)os\/(\d+(\.\d+)*)/i):f.blackberry?l=n(/rim\stablet\sos\s(\d+(\.\d+)*)/i):f.bada?l=n(/bada\/(\d+(\.\d+)*)/i):f.tizen&&(l=n(/tizen[\/\s](\d+(\.\d+)*)/i)),l&&(f.osversion=l);var c=l.split(".")[0];if(u||r=="ipad"||s&&(c==3||c==4&&!a)||f.silk)f.tablet=e;else if(a||r=="iphone"||r=="ipod"||s||f.blackberry||f.webos||f.bada)f.mobile=e;return f.msie&&f.version>=9||f.chrome&&f.version>=20||f.firefox&&f.version>=10||f.safari&&f.version>=5||f.opera&&f.version>=10||f.ios&&f.osversion&&f.osversion.split(".")[0]>=6?f.a=e:f.msie&&f.version<9||f.chrome&&f.version<20||f.firefox&&f.version<10||f.safari&&f.version<5||f.opera&&f.version<10||f.ios&&f.osversion&&f.osversion.split(".")[0]<6?f.c=e:f.x=e,f}var e=!0,n=t(typeof navigator!="undefined"?navigator.userAgent:"");return n._detect=t,n})
6
+ !function(e,t){typeof module!="undefined"&&module.exports?module.exports=t():typeof define=="function"&&define.amd?define(t):this[e]=t()}("bowser",function(){function t(t){function n(e){var n=t.match(e);return n&&n.length>1&&n[1]||""}function r(e){var n=t.match(e);return n&&n.length>1&&n[2]||""}var i=n(/(ipod|iphone|ipad)/i).toLowerCase(),s=/like android/i.test(t),o=!s&&/android/i.test(t),u=/CrOS/.test(t),a=n(/edge\/(\d+(\.\d+)?)/i),f=n(/version\/(\d+(\.\d+)?)/i),l=/tablet/i.test(t),c=!l&&/[^-]mobi/i.test(t),h;/opera|opr/i.test(t)?h={name:"Opera",opera:e,version:f||n(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i)}:/yabrowser/i.test(t)?h={name:"Yandex Browser",yandexbrowser:e,version:f||n(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i)}:/windows phone/i.test(t)?(h={name:"Windows Phone",windowsphone:e},a?(h.msedge=e,h.version=a):(h.msie=e,h.version=n(/iemobile\/(\d+(\.\d+)?)/i))):/msie|trident/i.test(t)?h={name:"Internet Explorer",msie:e,version:n(/(?:msie |rv:)(\d+(\.\d+)?)/i)}:u?h={name:"Chrome",chromeBook:e,chrome:e,version:n(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)}:/chrome.+? edge/i.test(t)?h={name:"Microsoft Edge",msedge:e,version:a}:/chrome|crios|crmo/i.test(t)?h={name:"Chrome",chrome:e,version:n(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)}:i?(h={name:i=="iphone"?"iPhone":i=="ipad"?"iPad":"iPod"},f&&(h.version=f)):/sailfish/i.test(t)?h={name:"Sailfish",sailfish:e,version:n(/sailfish\s?browser\/(\d+(\.\d+)?)/i)}:/seamonkey\//i.test(t)?h={name:"SeaMonkey",seamonkey:e,version:n(/seamonkey\/(\d+(\.\d+)?)/i)}:/firefox|iceweasel/i.test(t)?(h={name:"Firefox",firefox:e,version:n(/(?:firefox|iceweasel)[ \/](\d+(\.\d+)?)/i)},/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(t)&&(h.firefoxos=e)):/silk/i.test(t)?h={name:"Amazon Silk",silk:e,version:n(/silk\/(\d+(\.\d+)?)/i)}:o?h={name:"Android",version:f}:/phantom/i.test(t)?h={name:"PhantomJS",phantom:e,version:n(/phantomjs\/(\d+(\.\d+)?)/i)}:/blackberry|\bbb\d+/i.test(t)||/rim\stablet/i.test(t)?h={name:"BlackBerry",blackberry:e,version:f||n(/blackberry[\d]+\/(\d+(\.\d+)?)/i)}:/(web|hpw)os/i.test(t)?(h={name:"WebOS",webos:e,version:f||n(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i)},/touchpad\//i.test(t)&&(h.touchpad=e)):/bada/i.test(t)?h={name:"Bada",bada:e,version:n(/dolfin\/(\d+(\.\d+)?)/i)}:/tizen/i.test(t)?h={name:"Tizen",tizen:e,version:n(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i)||f}:/safari/i.test(t)?h={name:"Safari",safari:e,version:f}:h={name:n(/^(.*)\/(.*) /),version:r(/^(.*)\/(.*) /)},!h.msedge&&/(apple)?webkit/i.test(t)?(h.name=h.name||"Webkit",h.webkit=e,!h.version&&f&&(h.version=f)):!h.opera&&/gecko\//i.test(t)&&(h.name=h.name||"Gecko",h.gecko=e,h.version=h.version||n(/gecko\/(\d+(\.\d+)?)/i)),!h.msedge&&(o||h.silk)?h.android=e:i&&(h[i]=e,h.ios=e);var p="";h.windowsphone?p=n(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i):i?(p=n(/os (\d+([_\s]\d+)*) like mac os x/i),p=p.replace(/[_\s]/g,".")):o?p=n(/android[ \/-](\d+(\.\d+)*)/i):h.webos?p=n(/(?:web|hpw)os\/(\d+(\.\d+)*)/i):h.blackberry?p=n(/rim\stablet\sos\s(\d+(\.\d+)*)/i):h.bada?p=n(/bada\/(\d+(\.\d+)*)/i):h.tizen&&(p=n(/tizen[\/\s](\d+(\.\d+)*)/i)),p&&(h.osversion=p);var d=p.split(".")[0];if(l||i=="ipad"||o&&(d==3||d==4&&!c)||h.silk)h.tablet=e;else if(c||i=="iphone"||i=="ipod"||o||h.blackberry||h.webos||h.bada)h.mobile=e;return h.msedge||h.msie&&h.version>=10||h.yandexbrowser&&h.version>=15||h.chrome&&h.version>=20||h.firefox&&h.version>=20||h.safari&&h.version>=6||h.opera&&h.version>=10||h.ios&&h.osversion&&h.osversion.split(".")[0]>=6||h.blackberry&&h.version>=10.1?h.a=e:h.msie&&h.version<10||h.chrome&&h.version<20||h.firefox&&h.version<20||h.safari&&h.version<6||h.opera&&h.version<10||h.ios&&h.osversion&&h.osversion.split(".")[0]<6?h.c=e:h.x=e,h}var e=!0,n=t(typeof navigator!="undefined"?navigator.userAgent:"");return n.test=function(e){for(var t=0;t<e.length;++t){var r=e[t];if(typeof r=="string"&&r in n)return!0}return!1},n._detect=t,n})
package/component.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "bowser",
3
+ "description": "a browser detector",
4
+ "keywords": [
5
+ "ender",
6
+ "browser",
7
+ "sniff",
8
+ "detection"
9
+ ],
10
+ "version": "0.7.2",
11
+ "homepage": "https://github.com/ded/bowser",
12
+ "author": "Dustin Diaz <dustin@dustindiaz.com> (http://dustindiaz.com)",
13
+ "main": "bowser.js",
14
+ "scripts": [
15
+ "bowser.js"
16
+ ]
17
+ }
package/package.json CHANGED
@@ -7,16 +7,26 @@
7
7
  "sniff",
8
8
  "detection"
9
9
  ],
10
- "version": "0.6.0",
10
+ "version": "1.0.0",
11
11
  "homepage": "https://github.com/ded/bowser",
12
12
  "author": "Dustin Diaz <dustin@dustindiaz.com> (http://dustindiaz.com)",
13
13
  "main": "./bowser.js",
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "https://github.com/ded/bowser.git"
16
+ "url": "git+https://github.com/ded/bowser.git"
17
17
  },
18
18
  "devDependencies": {
19
19
  "smoosh": "*",
20
20
  "mocha": "*"
21
- }
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/ded/bowser/issues"
24
+ },
25
+ "directories": {
26
+ "test": "test"
27
+ },
28
+ "scripts": {
29
+ "test": "make test"
30
+ },
31
+ "license": "MIT"
22
32
  }
package/src/bowser.js CHANGED
@@ -1,6 +1,6 @@
1
1
  !function (name, definition) {
2
- if (typeof module != 'undefined' && module.exports) module.exports['browser'] = definition()
3
- else if (typeof define == 'function') define(definition)
2
+ if (typeof module != 'undefined' && module.exports) module.exports = definition()
3
+ else if (typeof define == 'function' && define.amd) define(definition)
4
4
  else this[name] = definition()
5
5
  }('bowser', function () {
6
6
  /**
@@ -16,9 +16,16 @@
16
16
  return (match && match.length > 1 && match[1]) || '';
17
17
  }
18
18
 
19
+ function getSecondMatch(regex) {
20
+ var match = ua.match(regex);
21
+ return (match && match.length > 1 && match[2]) || '';
22
+ }
23
+
19
24
  var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase()
20
25
  , likeAndroid = /like android/i.test(ua)
21
26
  , android = !likeAndroid && /android/i.test(ua)
27
+ , chromeBook = /CrOS/.test(ua)
28
+ , edgeVersion = getFirstMatch(/edge\/(\d+(\.\d+)?)/i)
22
29
  , versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i)
23
30
  , tablet = /tablet/i.test(ua)
24
31
  , mobile = !tablet && /[^-]mobi/i.test(ua)
@@ -31,12 +38,25 @@
31
38
  , version: versionIdentifier || getFirstMatch(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i)
32
39
  }
33
40
  }
41
+ else if (/yabrowser/i.test(ua)) {
42
+ result = {
43
+ name: 'Yandex Browser'
44
+ , yandexbrowser: t
45
+ , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i)
46
+ }
47
+ }
34
48
  else if (/windows phone/i.test(ua)) {
35
49
  result = {
36
50
  name: 'Windows Phone'
37
51
  , windowsphone: t
38
- , msie: t
39
- , version: getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i)
52
+ }
53
+ if (edgeVersion) {
54
+ result.msedge = t
55
+ result.version = edgeVersion
56
+ }
57
+ else {
58
+ result.msie = t
59
+ result.version = getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i)
40
60
  }
41
61
  }
42
62
  else if (/msie|trident/i.test(ua)) {
@@ -45,6 +65,19 @@
45
65
  , msie: t
46
66
  , version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i)
47
67
  }
68
+ } else if (chromeBook) {
69
+ result = {
70
+ name: 'Chrome'
71
+ , chromeBook: t
72
+ , chrome: t
73
+ , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)
74
+ }
75
+ } else if (/chrome.+? edge/i.test(ua)) {
76
+ result = {
77
+ name: 'Microsoft Edge'
78
+ , msedge: t
79
+ , version: edgeVersion
80
+ }
48
81
  }
49
82
  else if (/chrome|crios|crmo/i.test(ua)) {
50
83
  result = {
@@ -112,7 +145,7 @@
112
145
  , blackberry: t
113
146
  , version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i)
114
147
  }
115
- }
148
+ }
116
149
  else if (/(web|hpw)os/i.test(ua)) {
117
150
  result = {
118
151
  name: 'WebOS'
@@ -142,10 +175,15 @@
142
175
  , version: versionIdentifier
143
176
  }
144
177
  }
145
- else result = {}
178
+ else {
179
+ result = {
180
+ name: getFirstMatch(/^(.*)\/(.*) /),
181
+ version: getSecondMatch(/^(.*)\/(.*) /)
182
+ };
183
+ }
146
184
 
147
185
  // set webkit or gecko flag for browsers based on these engines
148
- if (/(apple)?webkit/i.test(ua)) {
186
+ if (!result.msedge && /(apple)?webkit/i.test(ua)) {
149
187
  result.name = result.name || "Webkit"
150
188
  result.webkit = t
151
189
  if (!result.version && versionIdentifier) {
@@ -158,7 +196,7 @@
158
196
  }
159
197
 
160
198
  // set OS flags for platforms that have multiple browsers
161
- if (android || result.silk) {
199
+ if (!result.msedge && (android || result.silk)) {
162
200
  result.android = t
163
201
  } else if (iosdevice) {
164
202
  result[iosdevice] = t
@@ -167,13 +205,13 @@
167
205
 
168
206
  // OS version extraction
169
207
  var osVersion = '';
170
- if (iosdevice) {
208
+ if (result.windowsphone) {
209
+ osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i);
210
+ } else if (iosdevice) {
171
211
  osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i);
172
212
  osVersion = osVersion.replace(/[_\s]/g, '.');
173
213
  } else if (android) {
174
214
  osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i);
175
- } else if (result.windowsphone) {
176
- osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i);
177
215
  } else if (result.webos) {
178
216
  osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i);
179
217
  } else if (result.blackberry) {
@@ -197,19 +235,22 @@
197
235
 
198
236
  // Graded Browser Support
199
237
  // http://developer.yahoo.com/yui/articles/gbs
200
- if ((result.msie && result.version >= 9) ||
238
+ if (result.msedge ||
239
+ (result.msie && result.version >= 10) ||
240
+ (result.yandexbrowser && result.version >= 15) ||
201
241
  (result.chrome && result.version >= 20) ||
202
- (result.firefox && result.version >= 10.0) ||
203
- (result.safari && result.version >= 5) ||
242
+ (result.firefox && result.version >= 20.0) ||
243
+ (result.safari && result.version >= 6) ||
204
244
  (result.opera && result.version >= 10.0) ||
205
- (result.ios && result.osversion && result.osversion.split(".")[0] >= 6)
245
+ (result.ios && result.osversion && result.osversion.split(".")[0] >= 6) ||
246
+ (result.blackberry && result.version >= 10.1)
206
247
  ) {
207
248
  result.a = t;
208
249
  }
209
- else if ((result.msie && result.version < 9) ||
250
+ else if ((result.msie && result.version < 10) ||
210
251
  (result.chrome && result.version < 20) ||
211
- (result.firefox && result.version < 10.0) ||
212
- (result.safari && result.version < 5) ||
252
+ (result.firefox && result.version < 20.0) ||
253
+ (result.safari && result.version < 6) ||
213
254
  (result.opera && result.version < 10.0) ||
214
255
  (result.ios && result.osversion && result.osversion.split(".")[0] < 6)
215
256
  ) {
@@ -221,6 +262,17 @@
221
262
 
222
263
  var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : '')
223
264
 
265
+ bowser.test = function (browserList) {
266
+ for (var i = 0; i < browserList.length; ++i) {
267
+ var browserItem = browserList[i];
268
+ if (typeof browserItem=== 'string') {
269
+ if (browserItem in bowser) {
270
+ return true;
271
+ }
272
+ }
273
+ }
274
+ return false;
275
+ }
224
276
 
225
277
  /*
226
278
  * Set our detect method to the main bowser object so we can
package/src/copyright.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
2
  * Bowser - a browser detector
3
3
  * https://github.com/ded/bowser
4
- * MIT License | (c) Dustin Diaz 2014
4
+ * MIT License | (c) Dustin Diaz 2015
5
5
  */
package/src/useragents.js CHANGED
@@ -86,6 +86,7 @@ module.exports.useragents = {
86
86
  }
87
87
  , 'Mozilla/5.0 (X11; CrOS i686 4319.74.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36': {
88
88
  chrome: true
89
+ , chromeBook: true
89
90
  , version: '29.0'
90
91
  , webkit: true
91
92
  , a: true
@@ -252,30 +253,47 @@ module.exports.useragents = {
252
253
  , c: true
253
254
  }
254
255
  }
256
+ , 'Yandex Browser': {
257
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 YaBrowser/15.4.2272.3420 (beta) Yowser/2.0 Safari/537.36': {
258
+ yandexbrowser: true
259
+ , webkit: true
260
+ , version: '15.4'
261
+ , a: true
262
+ },
263
+ 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 YaBrowser/15.4.2272.3608.00 Mobile Safari/537.36': {
264
+ yandexbrowser: true
265
+ , android: true
266
+ , osversion: '5.1.1'
267
+ , mobile: true
268
+ , version: '15.4'
269
+ , webkit: true
270
+ , a: true
271
+ }
272
+ }
255
273
  , Safari: {
256
274
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2': {
257
275
  safari: true
258
276
  , version: '5.1'
259
277
  , webkit: true
260
- , a: true
278
+ , c: true
261
279
  }
262
280
  , 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1': {
263
281
  safari: true
264
282
  , version: '5.0'
265
283
  , webkit: true
266
- , a: true
284
+ , c: true
267
285
  }
268
286
  , 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5': {
269
287
  safari: true
270
288
  , version: '5.0'
271
289
  , webkit: true
272
- , a: true
290
+ , c: true
273
291
  }
274
292
  , 'Mozilla/5.0 (X11; U; Linux x86_64; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/531.2+': {
275
293
  safari: true
276
294
  , version: '5.0'
277
295
  , webkit: true
278
- , a: true
296
+ , c: true
279
297
  }
280
298
  , 'Mozilla/5.0 (Windows; U; Windows NT 5.0; en-en) AppleWebKit/533.16 (KHTML, like Gecko) Version/4.1 Safari/533.16': {
281
299
  safari: true
@@ -330,7 +348,7 @@ module.exports.useragents = {
330
348
  , 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)': {
331
349
  msie: true
332
350
  , version: '9.0'
333
- , a: true
351
+ , c: true
334
352
  }
335
353
  , 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)': {
336
354
  msie: true
@@ -358,6 +376,13 @@ module.exports.useragents = {
358
376
  , c: true
359
377
  }
360
378
  }
379
+ , 'Microsoft Edge': {
380
+ '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': {
381
+ msedge: true
382
+ , version: '12.0'
383
+ , a: true
384
+ }
385
+ }
361
386
  , Firefox: {
362
387
  'Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0': {
363
388
  gecko: true
@@ -381,7 +406,7 @@ module.exports.useragents = {
381
406
  , version: '18.1'
382
407
  , mobile: true
383
408
  , firefoxos: true
384
- , a: true
409
+ , c: true
385
410
  }
386
411
  , 'Mozilla/5.0 (Android; Mobile; rv:27.0) Gecko/27.0 Firefox/27.0': {
387
412
  gecko: true
@@ -421,25 +446,25 @@ module.exports.useragents = {
421
446
  gecko: true
422
447
  , firefox: true
423
448
  , version: '17.0'
424
- , a: true
449
+ , c: true
425
450
  }
426
451
  , 'Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120724 Debian Iceweasel/15.0': {
427
452
  gecko: true
428
453
  , firefox: true
429
454
  , version: '15.0'
430
- , a: true
455
+ , c: true
431
456
  }
432
457
  , 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:15.0) Gecko/20120910144328 Firefox/15.0.2': {
433
458
  gecko: true
434
459
  , firefox: true
435
460
  , version: '15.0'
436
- , a: true
461
+ , c: true
437
462
  }
438
463
  , 'Mozilla/5.0 (Windows; U; Windows NT 6.1; WOW64; en-US; rv:2.0.4) Gecko/20120718 AskTbAVR-IDW/3.12.5.17700 Firefox/14.0.1': {
439
464
  gecko: true
440
465
  , firefox: true
441
466
  , version: '14.0'
442
- , a: true
467
+ , c: true
443
468
  }
444
469
  , 'Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0 FirePHP/0.6': {
445
470
  gecko: true
@@ -637,14 +662,14 @@ module.exports.useragents = {
637
662
  , version: '10.1'
638
663
  , webkit: true
639
664
  , mobile: true
640
- , x: true
665
+ , a: true
641
666
  }
642
667
  , 'Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.1.0.1429 Mobile Safari/537.10+': {
643
668
  blackberry: true
644
669
  , version: '10.1'
645
670
  , webkit: true
646
671
  , mobile: true
647
- , x: true
672
+ , a: true
648
673
  }
649
674
  , 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+': {
650
675
  blackberry: true
@@ -725,7 +750,7 @@ module.exports.useragents = {
725
750
  , msie: true
726
751
  , version: '9.0'
727
752
  , mobile: true
728
- , a: true
753
+ , c: true
729
754
  }
730
755
  , 'Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; Nokia;N70)': {
731
756
  windowsphone: true
@@ -735,6 +760,14 @@ module.exports.useragents = {
735
760
  , mobile: true
736
761
  , c: true
737
762
  }
763
+ , 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; DEVICE INFO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Mobile Safari/537.36 Edge/12.0': {
764
+ windowsphone: true
765
+ , osversion: '10.0'
766
+ , msedge: true
767
+ , version: '12.0'
768
+ , mobile: true
769
+ , a: true
770
+ }
738
771
  }
739
772
  , WebOS: {
740
773
  'Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.5; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/234.83 Safari/534.6 TouchPad/1.0': {
@@ -931,4 +964,11 @@ module.exports.useragents = {
931
964
  , x: true
932
965
  }
933
966
  }
934
- };
967
+ , Generic: {
968
+ 'Generic/2.15 libww': {
969
+ name: 'Generic'
970
+ , version: '2.15'
971
+ , x: true
972
+ }
973
+ }
974
+ };
package/test/test.js CHANGED
@@ -9,7 +9,7 @@ var g
9
9
  , ua
10
10
  , p
11
11
  , assert = require('assert')
12
- , browser = require('../src/bowser').browser
12
+ , browser = require('../src/bowser')
13
13
  , allUserAgents = require('../src/useragents').useragents
14
14
 
15
15
  /**