Comparing version 1.9.4 to 2.0.0-alpha.1
# Bowser Changelog | ||
### 2.0.0-alpha.1 (July 9, 2018) | ||
- [ADD] `Bowser.getParser()` | ||
- [ADD] `Bowser.parse` | ||
- [ADD] `Parser` class which describes parsing process | ||
- [CHANGE] Change bowser's returning object | ||
- [REMOVE] Remove bower support | ||
### 1.9.4 (June 28, 2018) | ||
@@ -4,0 +11,0 @@ - [FIX] Fix NAVER Whale browser detection (#220) |
Template to report about browser detection issue | ||
`window.navigator.userAgent` of the browser is: ... | ||
And it's detected like a ... | ||
But real name of the browser is ... | ||
And it's detected like ... | ||
However, the real name of the browser is ... |
{ | ||
"name": "bowser", | ||
"version": "1.9.4", | ||
"version": "2.0.0-alpha.1", | ||
"description": "Lightweight browser detector", | ||
@@ -17,14 +17,46 @@ "keywords": [ | ||
"author": "Dustin Diaz <dustin@dustindiaz.com> (http://dustindiaz.com)", | ||
"main": "./src/bowser.js", | ||
"contributors": [ | ||
{ | ||
"name": "Denis Demchenko", | ||
"url": "http://twitter.com/lancedikson" | ||
} | ||
], | ||
"main": "./dist/bowser.compiled.js", | ||
"typings": "./typings.d.ts", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/ded/bowser.git" | ||
"url": "git+https://github.com/lancedikson/bowser.git" | ||
}, | ||
"devDependencies": { | ||
"smoosh": "*", | ||
"mocha": "*" | ||
"ava": "^0.25.0", | ||
"babel-cli": "^6.26.0", | ||
"babel-core": "^6.26.3", | ||
"babel-loader": "^7.1.5", | ||
"babel-plugin-add-module-exports": "^0.3.1", | ||
"babel-plugin-istanbul": "^4.1.6", | ||
"babel-polyfill": "^6.26.0", | ||
"babel-preset-env": "^1.7.0", | ||
"babel-register": "^6.26.0", | ||
"coveralls": "^3.0.2", | ||
"docdash": "^0.4.0", | ||
"eslint": "^4.19.1", | ||
"eslint-config-airbnb-base": "^12.1.0", | ||
"eslint-plugin-ava": "^4.5.1", | ||
"eslint-plugin-import": "^2.13.0", | ||
"jsdoc": "^3.5.5", | ||
"nyc": "^12.0.2", | ||
"sinon": "^2.4.1", | ||
"testem": "^1.18.5", | ||
"webpack": "^4.15.1", | ||
"webpack-cli": "^3.0.8", | ||
"yamljs": "^0.3.0" | ||
}, | ||
"ava": { | ||
"require": [ | ||
"babel-register" | ||
], | ||
"babel": "inherit" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/ded/bowser/issues" | ||
"url": "https://github.com/lancedikson/bowser/issues" | ||
}, | ||
@@ -35,6 +67,11 @@ "directories": { | ||
"scripts": { | ||
"test": "make test", | ||
"prepublish": "make boosh" | ||
"build": "webpack --config webpack.config.js", | ||
"prepublish": "npm run build", | ||
"lint": "eslint ./src --fix", | ||
"testem": "testem", | ||
"test": "eslint ./src & nyc --reporter=html --reporter=text ava", | ||
"coverage": "nyc report --reporter=text-lcov | coveralls", | ||
"docs": "jsdoc -c jsdoc.json" | ||
}, | ||
"license": "MIT" | ||
} |
244
README.md
## Bowser | ||
A Browser detector. Because sometimes, there is no other way, and not even good modern browsers always provide good feature detection mechanisms. | ||
[![Build Status](https://travis-ci.org/lancedikson/bowser.svg?branch=master)](https://travis-ci.org/lancedikson/bowser) | ||
[![Build Status](https://travis-ci.org/lancedikson/bowser.svg?branch=master)](https://travis-ci.org/lancedikson/bowser/) | ||
So... it works like this: | ||
# Contents | ||
- [Overview](#overview) | ||
- [Use cases](#use-cases) | ||
- [Advanced usage](#advanced-usage) | ||
- [How can I help?](#contributing) | ||
``` js | ||
if (bowser.msie && bowser.version <= 6) { | ||
alert('Hello China'); | ||
} | ||
``` | ||
# Overview | ||
## 1.1.0 breaking changes | ||
We don't save built script in the repo anymore. The main file (`src/bowser.js`) is available through NPM or Bower. | ||
Also you can download minified file from [the release page](https://github.com/ded/bowser/releases). | ||
The library is made to help to detect what browser your user has and gives you a convenient API to filter the users somehow depending on their browsers. | ||
## 1.0.0 breaking changes | ||
`browser = require('bowser').browser;` becomes `bowser = require('bowser');` | ||
_Please, note that this is an alpha version. Check out the [1.x](https://github.com/lancedikson/bowser/tree/v1.x) branch for a stable version._ | ||
--- | ||
**Changes of the 2.0** | ||
The upcoming 2.0 version has drastically changed API. All available methods can be found in the `docs` folder from now on and on a webpage soon. | ||
## API | ||
# Use cases | ||
### bowser`:Object` | ||
Use it to get object with detected flags of your current browser. | ||
First of all, require the library: | ||
### bowser._detect(ua `:String`)`:Object` | ||
Use it to get object with detected flags from User Agent string. | ||
``` | ||
const bowser = require('bowser'); | ||
``` | ||
### bowser.check(minVersions`:Object`, strictMode`:Boolean`, [ua]`:String`)`:Boolean` | ||
Use it to check if browser is supported. In default non-strict mode any browser family not present in `minVersions` will pass the check (like Chrome in the third call in the sample bellow). When strict mode is enabled then any not specified browser family in `minVersions` will cause `check` to return `false` (in the sample it is the fourth call, the last one). | ||
## Browser props detection | ||
``` js | ||
/** | ||
* in case of using IE10 | ||
*/ | ||
bowser.check({msie: "11"}); // true | ||
bowser.check({msie: "9.0"}); // false | ||
Often we need to pick users' browser properties such as the name, the version, the rendering engine and so on. Here is an example how to make it with Bowser: | ||
/** | ||
* specific user agent | ||
*/ | ||
bowser.check({chrome: "45"}, window.navigator.userAgent); // true | ||
``` | ||
const browser = bowser.getParser(window.navigator.userAgent); | ||
/** | ||
* but false in strict mode | ||
*/ | ||
bowser.check({chrome: "45"}, true, window.navigator.userAgent); // false | ||
console.log(`The current browser name is "${browser.getBrowserName()}"`); | ||
// The current browser name is "Internet Explorer" | ||
``` | ||
### bowser.compareVersions(versions`:Array<String>`)`:Number` | ||
Use it to compare two versions. | ||
or | ||
``` js | ||
bowser.compareVersions(['9.0', '10']); | ||
// -1 | ||
``` | ||
const impression = new Impression(); | ||
### bowser.isUnsupportedBrowser(minVersions`:Object`, [strictMode]`:Boolean`, [ua]`:string`)`:Boolean` | ||
Use it to check if browser is unsupported. | ||
``` js | ||
bowser.isUnsupportedBrowser({msie: "10"}, window.navigator.userAgent); | ||
// true / false | ||
const browser = bowser.getParser(window.navigator.userAgent); | ||
const browserInfo = browser.getBrowser(); | ||
impression.brName = browserInfo.name; | ||
impression.brVer = browserInfo.version; | ||
``` | ||
See more examples in [tests](test/test.js). | ||
or | ||
--- | ||
## Bowser Flags | ||
Your mileage may vary, but these flags should be set. See Contributing below. | ||
``` js | ||
alert('Hello ' + bowser.name + ' ' + bowser.version); | ||
``` | ||
### All detected browsers | ||
These flags are set for all detected browsers: | ||
* `name` - A human readable name for this browser. E.g. 'Chrome', '' | ||
* `version` - Version number for the browser. E.g. '32.0' | ||
For unknown browsers, Bowser makes a best guess from the UA string. So, these may not be set. | ||
### Rendering engine flags | ||
If detected, one of these flags may be set to true: | ||
* `webkit` - Chrome 0-27, Android <4.4, iOs, BB, etc. | ||
* `blink` - Chrome >=28, Android >=4.4, Opera, etc. | ||
* `gecko` - Firefox, etc. | ||
* `msie` - IE <= 11 | ||
* `msedge` - IE > 11 | ||
Safari, Chrome and some other minor browsers will report that they have `webkit` engines. | ||
Firefox and Seamonkey will report that they have `gecko` engines. | ||
``` js | ||
if (bowser.webkit) { | ||
// do stuff with safari & chrome & opera & android & blackberry & webos & silk | ||
const browser = bowser.getParser(window.navigator.userAgent); | ||
impression.userTechData = browser.parse(); | ||
console.log(impression.userTechData); | ||
// outputs | ||
{ | ||
browser: { | ||
name: "Internet Explorer" | ||
version: "11.0" | ||
}, | ||
os: { | ||
name: "Windows" | ||
version: "NT 6.3" | ||
versionName: "8.1" | ||
}, | ||
platform: { | ||
type: "desktop" | ||
}, | ||
engine: { | ||
name: "Trident" | ||
version: "7.0" | ||
} | ||
} | ||
``` | ||
### Device flags | ||
If detected, one of these flags may be set to true: | ||
* `mobile` - All detected mobile OSes are additionally flagged `mobile`, **unless it's a tablet** | ||
* `tablet` - If a tablet device is detected, the flag `tablet` is **set instead of `mobile`**. | ||
## Filtering browsers | ||
### Browser flags | ||
If detected, one of these flags may be set to true. The rendering engine flag is shown in []'s: | ||
You could want to filter some particular browsers to provide any special support for them or make any workarounds. | ||
It could look like this: | ||
* `chrome` - [`webkit`|`blink`] | ||
* `chromium` - [`webkit`|`blink`] | ||
* `firefox` - [`gecko`] | ||
* `msie` | ||
* `msedge` | ||
* `safari` - [`webkit`] | ||
* `android` - native browser - [`webkit`|`blink`] | ||
* `ios` - native browser - [`webkit`] | ||
* `opera` - [`blink` if >=15] | ||
* `samsungBrowser` - [`blink`] | ||
* `phantom` - [`webkit`] | ||
* `blackberry` - native browser - [`webkit`] | ||
* `webos` - native browser - [`webkit`] | ||
* `silk` - Amazon Kindle browser - [`webkit`] | ||
* `bada` - [`webkit`] | ||
* `tizen` - [`webkit`] | ||
* `seamonkey` - [`gecko`] | ||
* `sailfish` - [`gecko`] | ||
* `ucbrowser` — [`webkit`] | ||
* `qupzilla` — [`webkit`] | ||
* `vivaldi` — [`blink`] | ||
* `sleipnir` — [`blink`] | ||
* `kMeleon` — [`gecko`] | ||
* `whale` — [`blink`] | ||
``` | ||
const browser = bowser.getParsers(window.navigator.userAgent); | ||
const isValidBrowser = browser.satisfies({ | ||
// declare browsers per OS | ||
windows: { | ||
"internet explorer": ">10", | ||
}, | ||
macos: { | ||
safari: ">10.1" | ||
}, | ||
For all detected browsers the browser version is set in the `version` field. | ||
// per platform (mobile, desktop or tablet) | ||
mobile: { | ||
safari: '>9', | ||
'android browser': '>3.10' | ||
}, | ||
### OS Flags | ||
If detected, one of these flags may be set to true: | ||
// or in general | ||
chrome: ">20.1.1432", | ||
firefox: ">31", | ||
opera: ">22" | ||
}); | ||
``` | ||
* `mac` | ||
* `windows` - other than Windows Phone | ||
* `windowsphone` | ||
* `linux` - other than `android`, `chromeos`, `webos`, `tizen`, and `sailfish` | ||
* `chromeos` | ||
* `android` | ||
* `ios` - also sets one of `iphone`/`ipad`/`ipod` | ||
* `blackberry` | ||
* `firefoxos` | ||
* `webos` - may also set `touchpad` | ||
* `bada` | ||
* `tizen` | ||
* `sailfish` | ||
Settings for any particular OS or platform has more priority and redefines settings of standalone browsers. | ||
Thus, you can define OS or platform specific rules and they will have more priority in the end. | ||
`osname` and `osversion` may also be set: | ||
More of API and possibilities you will find in the `docs` folder. | ||
* `osname` - for the OS flags detected above: macOS, Windows, Windows Phone, Linux, Chrome OS, Android, iOS, Blackberry OS, Firefox OS, WebOS, Bada, Tizen, Sailfish OS, and Xbox | ||
* `osversion` - for Android, iOS, MacOS, Windows, Windows Phone, WebOS, Bada, and Tizen. If included in UA string. | ||
# Advanced Usage | ||
By default, `require('bowser')` requires the pre-compiled file, which can | ||
include useless for you polyfills. In case you don't need that, you can choose | ||
using source file requiring bowser like that: `require('bowser/src/bowser`); | ||
Then you get ES2015 file, which is not precompiled and can be easier to debug. | ||
iOS is always reported as `ios` and additionally as `iphone`/`ipad`/`ipod`, whichever one matches best. | ||
If WebOS device is an HP TouchPad the flag `touchpad` is additionally set. | ||
### Browser capability grading | ||
One of these flags may be set: | ||
* `a` - This browser has full capabilities | ||
* `c` - This browser has degraded capabilities. Serve simpler version | ||
* `x` - This browser has minimal capabilities and is probably not well detected. | ||
There is no `b`. For unknown browsers, none of these flags may be set. | ||
### Ender Support | ||
`package.json` | ||
``` json | ||
"dependencies": { | ||
"bowser": "x.x.x" | ||
} | ||
``` | ||
``` js | ||
if (require('bowser').chrome) { | ||
alert('Hello Silicon Valley') | ||
} | ||
``` | ||
### Contributing | ||
# Contributing | ||
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): | ||
@@ -196,9 +124,7 @@ | ||
$ npm install | ||
$ make test | ||
$ npm test | ||
``` | ||
Please do not check-in the built files `bowser.js` and `bowser.min.js` in pull requests. | ||
### Adding tests | ||
See the list in `src/useragents.js` with example user agents and their expected bowser object. | ||
See the list in `test/acceptance/useragentstrings.yml` with example user agents and their expected bowser object. | ||
@@ -205,0 +131,0 @@ Whenever you add support for new browsers or notice a bug / mismatch, please update the list and |
/*! | ||
* Bowser - a browser detector | ||
* https://github.com/ded/bowser | ||
* MIT License | (c) Dustin Diaz 2015 | ||
* https://github.com/lancedikson/bowser | ||
* MIT License | (c) Dustin Diaz 2012-2015 | ||
* MIT License | (c) Denis Demchenko 2015-2017 | ||
*/ | ||
import Parser from './parser'; | ||
!function (root, name, definition) { | ||
if (typeof module != 'undefined' && module.exports) module.exports = definition() | ||
else if (typeof define == 'function' && define.amd) define(name, definition) | ||
else root[name] = definition() | ||
}(this, 'bowser', function () { | ||
/** | ||
* Bowser class. | ||
* Keep it simple as much as it can be. | ||
* It's supposed to work with collections of {@link Parser} instances | ||
* rather then solve one-instance problems. | ||
* All the one-instance stuff is located in Parser class. | ||
*/ | ||
class Bowser { | ||
/** | ||
* See useragents.js for examples of navigator.userAgent | ||
*/ | ||
var t = true | ||
function detect(ua) { | ||
function getFirstMatch(regex) { | ||
var match = ua.match(regex); | ||
return (match && match.length > 1 && match[1]) || ''; | ||
} | ||
function getSecondMatch(regex) { | ||
var match = ua.match(regex); | ||
return (match && match.length > 1 && match[2]) || ''; | ||
} | ||
var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase() | ||
, likeAndroid = /like android/i.test(ua) | ||
, android = !likeAndroid && /android/i.test(ua) | ||
, nexusMobile = /nexus\s*[0-6]\s*/i.test(ua) | ||
, nexusTablet = !nexusMobile && /nexus\s*[0-9]+/i.test(ua) | ||
, chromeos = /CrOS/.test(ua) | ||
, silk = /silk/i.test(ua) | ||
, sailfish = /sailfish/i.test(ua) | ||
, tizen = /tizen/i.test(ua) | ||
, webos = /(web|hpw)(o|0)s/i.test(ua) | ||
, windowsphone = /windows phone/i.test(ua) | ||
, samsungBrowser = /SamsungBrowser/i.test(ua) | ||
, windows = !windowsphone && /windows/i.test(ua) | ||
, mac = !iosdevice && !silk && /macintosh/i.test(ua) | ||
, linux = !android && !sailfish && !tizen && !webos && /linux/i.test(ua) | ||
, edgeVersion = getSecondMatch(/edg([ea]|ios)\/(\d+(\.\d+)?)/i) | ||
, versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i) | ||
, tablet = /tablet/i.test(ua) && !/tablet pc/i.test(ua) | ||
, mobile = !tablet && /[^-]mobi/i.test(ua) | ||
, xbox = /xbox/i.test(ua) | ||
, result | ||
if (/opera/i.test(ua)) { | ||
// an old Opera | ||
result = { | ||
name: 'Opera' | ||
, opera: t | ||
, version: versionIdentifier || getFirstMatch(/(?:opera|opr|opios)[\s\/](\d+(\.\d+)?)/i) | ||
} | ||
} else if (/opr\/|opios/i.test(ua)) { | ||
// a new Opera | ||
result = { | ||
name: 'Opera' | ||
, opera: t | ||
, version: getFirstMatch(/(?:opr|opios)[\s\/](\d+(\.\d+)?)/i) || versionIdentifier | ||
} | ||
} | ||
else if (/SamsungBrowser/i.test(ua)) { | ||
result = { | ||
name: 'Samsung Internet for Android' | ||
, samsungBrowser: t | ||
, version: versionIdentifier || getFirstMatch(/(?:SamsungBrowser)[\s\/](\d+(\.\d+)?)/i) | ||
} | ||
} | ||
else if (/Whale/i.test(ua)) { | ||
result = { | ||
name: 'NAVER Whale browser' | ||
, whale: t | ||
, version: getFirstMatch(/(?:whale)[\s\/](\d+(?:\.\d+)+)/i) | ||
} | ||
} | ||
else if (/MZBrowser/i.test(ua)) { | ||
result = { | ||
name: 'MZ Browser' | ||
, mzbrowser: t | ||
, version: getFirstMatch(/(?:MZBrowser)[\s\/](\d+(?:\.\d+)+)/i) | ||
} | ||
} | ||
else if (/coast/i.test(ua)) { | ||
result = { | ||
name: 'Opera Coast' | ||
, coast: t | ||
, version: versionIdentifier || getFirstMatch(/(?:coast)[\s\/](\d+(\.\d+)?)/i) | ||
} | ||
} | ||
else if (/focus/i.test(ua)) { | ||
result = { | ||
name: 'Focus' | ||
, focus: t | ||
, version: getFirstMatch(/(?:focus)[\s\/](\d+(?:\.\d+)+)/i) | ||
} | ||
} | ||
else if (/yabrowser/i.test(ua)) { | ||
result = { | ||
name: 'Yandex Browser' | ||
, yandexbrowser: t | ||
, version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i) | ||
} | ||
} | ||
else if (/ucbrowser/i.test(ua)) { | ||
result = { | ||
name: 'UC Browser' | ||
, ucbrowser: t | ||
, version: getFirstMatch(/(?:ucbrowser)[\s\/](\d+(?:\.\d+)+)/i) | ||
} | ||
} | ||
else if (/mxios/i.test(ua)) { | ||
result = { | ||
name: 'Maxthon' | ||
, maxthon: t | ||
, version: getFirstMatch(/(?:mxios)[\s\/](\d+(?:\.\d+)+)/i) | ||
} | ||
} | ||
else if (/epiphany/i.test(ua)) { | ||
result = { | ||
name: 'Epiphany' | ||
, epiphany: t | ||
, version: getFirstMatch(/(?:epiphany)[\s\/](\d+(?:\.\d+)+)/i) | ||
} | ||
} | ||
else if (/puffin/i.test(ua)) { | ||
result = { | ||
name: 'Puffin' | ||
, puffin: t | ||
, version: getFirstMatch(/(?:puffin)[\s\/](\d+(?:\.\d+)?)/i) | ||
} | ||
} | ||
else if (/sleipnir/i.test(ua)) { | ||
result = { | ||
name: 'Sleipnir' | ||
, sleipnir: t | ||
, version: getFirstMatch(/(?:sleipnir)[\s\/](\d+(?:\.\d+)+)/i) | ||
} | ||
} | ||
else if (/k-meleon/i.test(ua)) { | ||
result = { | ||
name: 'K-Meleon' | ||
, kMeleon: t | ||
, version: getFirstMatch(/(?:k-meleon)[\s\/](\d+(?:\.\d+)+)/i) | ||
} | ||
} | ||
else if (windowsphone) { | ||
result = { | ||
name: 'Windows Phone' | ||
, osname: 'Windows Phone' | ||
, windowsphone: t | ||
} | ||
if (edgeVersion) { | ||
result.msedge = t | ||
result.version = edgeVersion | ||
} | ||
else { | ||
result.msie = t | ||
result.version = getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i) | ||
} | ||
} | ||
else if (/msie|trident/i.test(ua)) { | ||
result = { | ||
name: 'Internet Explorer' | ||
, msie: t | ||
, version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i) | ||
} | ||
} else if (chromeos) { | ||
result = { | ||
name: 'Chrome' | ||
, osname: 'Chrome OS' | ||
, chromeos: t | ||
, chromeBook: t | ||
, chrome: t | ||
, version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) | ||
} | ||
} else if (/edg([ea]|ios)/i.test(ua)) { | ||
result = { | ||
name: 'Microsoft Edge' | ||
, msedge: t | ||
, version: edgeVersion | ||
} | ||
} | ||
else if (/vivaldi/i.test(ua)) { | ||
result = { | ||
name: 'Vivaldi' | ||
, vivaldi: t | ||
, version: getFirstMatch(/vivaldi\/(\d+(\.\d+)?)/i) || versionIdentifier | ||
} | ||
} | ||
else if (sailfish) { | ||
result = { | ||
name: 'Sailfish' | ||
, osname: 'Sailfish OS' | ||
, sailfish: t | ||
, version: getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i) | ||
} | ||
} | ||
else if (/seamonkey\//i.test(ua)) { | ||
result = { | ||
name: 'SeaMonkey' | ||
, seamonkey: t | ||
, version: getFirstMatch(/seamonkey\/(\d+(\.\d+)?)/i) | ||
} | ||
} | ||
else if (/firefox|iceweasel|fxios/i.test(ua)) { | ||
result = { | ||
name: 'Firefox' | ||
, firefox: t | ||
, version: getFirstMatch(/(?:firefox|iceweasel|fxios)[ \/](\d+(\.\d+)?)/i) | ||
} | ||
if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) { | ||
result.firefoxos = t | ||
result.osname = 'Firefox OS' | ||
} | ||
} | ||
else if (silk) { | ||
result = { | ||
name: 'Amazon Silk' | ||
, silk: t | ||
, version : getFirstMatch(/silk\/(\d+(\.\d+)?)/i) | ||
} | ||
} | ||
else if (/phantom/i.test(ua)) { | ||
result = { | ||
name: 'PhantomJS' | ||
, phantom: t | ||
, version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i) | ||
} | ||
} | ||
else if (/slimerjs/i.test(ua)) { | ||
result = { | ||
name: 'SlimerJS' | ||
, slimer: t | ||
, version: getFirstMatch(/slimerjs\/(\d+(\.\d+)?)/i) | ||
} | ||
} | ||
else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) { | ||
result = { | ||
name: 'BlackBerry' | ||
, osname: 'BlackBerry OS' | ||
, blackberry: t | ||
, version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i) | ||
} | ||
} | ||
else if (webos) { | ||
result = { | ||
name: 'WebOS' | ||
, osname: 'WebOS' | ||
, webos: t | ||
, version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i) | ||
}; | ||
/touchpad\//i.test(ua) && (result.touchpad = t) | ||
} | ||
else if (/bada/i.test(ua)) { | ||
result = { | ||
name: 'Bada' | ||
, osname: 'Bada' | ||
, bada: t | ||
, version: getFirstMatch(/dolfin\/(\d+(\.\d+)?)/i) | ||
}; | ||
} | ||
else if (tizen) { | ||
result = { | ||
name: 'Tizen' | ||
, osname: 'Tizen' | ||
, tizen: t | ||
, version: getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || versionIdentifier | ||
}; | ||
} | ||
else if (/qupzilla/i.test(ua)) { | ||
result = { | ||
name: 'QupZilla' | ||
, qupzilla: t | ||
, version: getFirstMatch(/(?:qupzilla)[\s\/](\d+(?:\.\d+)+)/i) || versionIdentifier | ||
} | ||
} | ||
else if (/chromium/i.test(ua)) { | ||
result = { | ||
name: 'Chromium' | ||
, chromium: t | ||
, version: getFirstMatch(/(?:chromium)[\s\/](\d+(?:\.\d+)?)/i) || versionIdentifier | ||
} | ||
} | ||
else if (/chrome|crios|crmo/i.test(ua)) { | ||
result = { | ||
name: 'Chrome' | ||
, chrome: t | ||
, version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) | ||
} | ||
} | ||
else if (android) { | ||
result = { | ||
name: 'Android' | ||
, version: versionIdentifier | ||
} | ||
} | ||
else if (/safari|applewebkit/i.test(ua)) { | ||
result = { | ||
name: 'Safari' | ||
, safari: t | ||
} | ||
if (versionIdentifier) { | ||
result.version = versionIdentifier | ||
} | ||
} | ||
else if (iosdevice) { | ||
result = { | ||
name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod' | ||
} | ||
// WTF: version is not part of user agent in web apps | ||
if (versionIdentifier) { | ||
result.version = versionIdentifier | ||
} | ||
} | ||
else if(/googlebot/i.test(ua)) { | ||
result = { | ||
name: 'Googlebot' | ||
, googlebot: t | ||
, version: getFirstMatch(/googlebot\/(\d+(\.\d+))/i) || versionIdentifier | ||
} | ||
} | ||
else { | ||
result = { | ||
name: getFirstMatch(/^(.*)\/(.*) /), | ||
version: getSecondMatch(/^(.*)\/(.*) /) | ||
}; | ||
} | ||
// set webkit or gecko flag for browsers based on these engines | ||
if (!result.msedge && /(apple)?webkit/i.test(ua)) { | ||
if (/(apple)?webkit\/537\.36/i.test(ua)) { | ||
result.name = result.name || "Blink" | ||
result.blink = t | ||
} else { | ||
result.name = result.name || "Webkit" | ||
result.webkit = t | ||
} | ||
if (!result.version && versionIdentifier) { | ||
result.version = versionIdentifier | ||
} | ||
} else if (!result.opera && /gecko\//i.test(ua)) { | ||
result.name = result.name || "Gecko" | ||
result.gecko = t | ||
result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i) | ||
} | ||
// set OS flags for platforms that have multiple browsers | ||
if (!result.windowsphone && (android || result.silk)) { | ||
result.android = t | ||
result.osname = 'Android' | ||
} else if (!result.windowsphone && iosdevice) { | ||
result[iosdevice] = t | ||
result.ios = t | ||
result.osname = 'iOS' | ||
} else if (mac) { | ||
result.mac = t | ||
result.osname = 'macOS' | ||
} else if (xbox) { | ||
result.xbox = t | ||
result.osname = 'Xbox' | ||
} else if (windows) { | ||
result.windows = t | ||
result.osname = 'Windows' | ||
} else if (linux) { | ||
result.linux = t | ||
result.osname = 'Linux' | ||
} | ||
function getWindowsVersion (s) { | ||
switch (s) { | ||
case 'NT': return 'NT' | ||
case 'XP': return 'XP' | ||
case 'NT 5.0': return '2000' | ||
case 'NT 5.1': return 'XP' | ||
case 'NT 5.2': return '2003' | ||
case 'NT 6.0': return 'Vista' | ||
case 'NT 6.1': return '7' | ||
case 'NT 6.2': return '8' | ||
case 'NT 6.3': return '8.1' | ||
case 'NT 10.0': return '10' | ||
default: return undefined | ||
} | ||
} | ||
// OS version extraction | ||
var osVersion = ''; | ||
if (result.windows) { | ||
osVersion = getWindowsVersion(getFirstMatch(/Windows ((NT|XP)( \d\d?.\d)?)/i)) | ||
} else if (result.windowsphone) { | ||
osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i); | ||
} else if (result.mac) { | ||
osVersion = getFirstMatch(/Mac OS X (\d+([_\.\s]\d+)*)/i); | ||
osVersion = osVersion.replace(/[_\s]/g, '.'); | ||
} else if (iosdevice) { | ||
osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i); | ||
osVersion = osVersion.replace(/[_\s]/g, '.'); | ||
} else if (android) { | ||
osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i); | ||
} else if (result.webos) { | ||
osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i); | ||
} else if (result.blackberry) { | ||
osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i); | ||
} else if (result.bada) { | ||
osVersion = getFirstMatch(/bada\/(\d+(\.\d+)*)/i); | ||
} else if (result.tizen) { | ||
osVersion = getFirstMatch(/tizen[\/\s](\d+(\.\d+)*)/i); | ||
} | ||
if (osVersion) { | ||
result.osversion = osVersion; | ||
} | ||
// device type extraction | ||
var osMajorVersion = !result.windows && osVersion.split('.')[0]; | ||
if ( | ||
tablet | ||
|| nexusTablet | ||
|| iosdevice == 'ipad' | ||
|| (android && (osMajorVersion == 3 || (osMajorVersion >= 4 && !mobile))) | ||
|| result.silk | ||
) { | ||
result.tablet = t | ||
} else if ( | ||
mobile | ||
|| iosdevice == 'iphone' | ||
|| iosdevice == 'ipod' | ||
|| android | ||
|| nexusMobile | ||
|| result.blackberry | ||
|| result.webos | ||
|| result.bada | ||
) { | ||
result.mobile = t | ||
} | ||
// Graded Browser Support | ||
// http://developer.yahoo.com/yui/articles/gbs | ||
if (result.msedge || | ||
(result.msie && result.version >= 10) || | ||
(result.yandexbrowser && result.version >= 15) || | ||
(result.vivaldi && result.version >= 1.0) || | ||
(result.chrome && result.version >= 20) || | ||
(result.samsungBrowser && result.version >= 4) || | ||
(result.whale && compareVersions([result.version, '1.0']) === 1) || | ||
(result.mzbrowser && compareVersions([result.version, '6.0']) === 1) || | ||
(result.focus && compareVersions([result.version, '1.0']) === 1) || | ||
(result.firefox && result.version >= 20.0) || | ||
(result.safari && result.version >= 6) || | ||
(result.opera && result.version >= 10.0) || | ||
(result.ios && result.osversion && result.osversion.split(".")[0] >= 6) || | ||
(result.blackberry && result.version >= 10.1) | ||
|| (result.chromium && result.version >= 20) | ||
) { | ||
result.a = t; | ||
} | ||
else if ((result.msie && result.version < 10) || | ||
(result.chrome && result.version < 20) || | ||
(result.firefox && result.version < 20.0) || | ||
(result.safari && result.version < 6) || | ||
(result.opera && result.version < 10.0) || | ||
(result.ios && result.osversion && result.osversion.split(".")[0] < 6) | ||
|| (result.chromium && result.version < 20) | ||
) { | ||
result.c = t | ||
} else result.x = t | ||
return result | ||
} | ||
var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent || '' : '') | ||
bowser.test = function (browserList) { | ||
for (var i = 0; i < browserList.length; ++i) { | ||
var browserItem = browserList[i]; | ||
if (typeof browserItem=== 'string') { | ||
if (browserItem in bowser) { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
/** | ||
* Get version precisions count | ||
* Creates a {@link module:parser:Parser} instance | ||
* | ||
* @example | ||
* getVersionPrecision("1.10.3") // 3 | ||
* @param {String} UA UserAgent string | ||
* @param {Boolean} [skipParsing=false] same as skipParsing for {@link Parser} | ||
* @returns {Parser} | ||
* @throws {Error} when UA is not a String | ||
* | ||
* @param {string} version | ||
* @return {number} | ||
*/ | ||
function getVersionPrecision(version) { | ||
return version.split(".").length; | ||
} | ||
/** | ||
* Array::map polyfill | ||
* | ||
* @param {Array} arr | ||
* @param {Function} iterator | ||
* @return {Array} | ||
*/ | ||
function map(arr, iterator) { | ||
var result = [], i; | ||
if (Array.prototype.map) { | ||
return Array.prototype.map.call(arr, iterator); | ||
} | ||
for (i = 0; i < arr.length; i++) { | ||
result.push(iterator(arr[i])); | ||
} | ||
return result; | ||
} | ||
/** | ||
* Calculate browser version weight | ||
* | ||
* @example | ||
* compareVersions(['1.10.2.1', '1.8.2.1.90']) // 1 | ||
* compareVersions(['1.010.2.1', '1.09.2.1.90']); // 1 | ||
* compareVersions(['1.10.2.1', '1.10.2.1']); // 0 | ||
* compareVersions(['1.10.2.1', '1.0800.2']); // -1 | ||
* | ||
* @param {Array<String>} versions versions to compare | ||
* @return {Number} comparison result | ||
* const bowser = new Bowser(window.navigator.userAgent); | ||
* bowser.getResult() | ||
*/ | ||
function compareVersions(versions) { | ||
// 1) get common precision for both versions, for example for "10.0" and "9" it should be 2 | ||
var precision = Math.max(getVersionPrecision(versions[0]), getVersionPrecision(versions[1])); | ||
var chunks = map(versions, function (version) { | ||
var delta = precision - getVersionPrecision(version); | ||
// 2) "9" -> "9.0" (for precision = 2) | ||
version = version + new Array(delta + 1).join(".0"); | ||
// 3) "9.0" -> ["000000000"", "000000009"] | ||
return map(version.split("."), function (chunk) { | ||
return new Array(20 - chunk.length).join("0") + chunk; | ||
}).reverse(); | ||
}); | ||
// iterate in reverse order by reversed chunks array | ||
while (--precision >= 0) { | ||
// 4) compare: "000000009" > "000000010" = false (but "9" > "10" = true) | ||
if (chunks[0][precision] > chunks[1][precision]) { | ||
return 1; | ||
} | ||
else if (chunks[0][precision] === chunks[1][precision]) { | ||
if (precision === 0) { | ||
// all version chunks are same | ||
return 0; | ||
} | ||
} | ||
else { | ||
return -1; | ||
} | ||
static getParser(UA, skipParsing=false) { | ||
if (typeof UA !== 'string') { | ||
throw new Error('UserAgent should be a string'); | ||
} | ||
return new Parser(UA, skipParsing); | ||
} | ||
/** | ||
* Check if browser is unsupported | ||
* Creates a {@link Parser} instance and runs {@link Parser.getResult} immediately | ||
* | ||
* @example | ||
* bowser.isUnsupportedBrowser({ | ||
* msie: "10", | ||
* firefox: "23", | ||
* chrome: "29", | ||
* safari: "5.1", | ||
* opera: "16", | ||
* phantom: "534" | ||
* }); | ||
* | ||
* @param {Object} minVersions map of minimal version to browser | ||
* @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map | ||
* @param {String} [ua] user agent string | ||
* @return {Boolean} | ||
* @param UA | ||
* @return {ParsedResult} | ||
*/ | ||
function isUnsupportedBrowser(minVersions, strictMode, ua) { | ||
var _bowser = bowser; | ||
// make strictMode param optional with ua param usage | ||
if (typeof strictMode === 'string') { | ||
ua = strictMode; | ||
strictMode = void(0); | ||
} | ||
if (strictMode === void(0)) { | ||
strictMode = false; | ||
} | ||
if (ua) { | ||
_bowser = detect(ua); | ||
} | ||
var version = "" + _bowser.version; | ||
for (var browser in minVersions) { | ||
if (minVersions.hasOwnProperty(browser)) { | ||
if (_bowser[browser]) { | ||
if (typeof minVersions[browser] !== 'string') { | ||
throw new Error('Browser version in the minVersion map should be a string: ' + browser + ': ' + String(minVersions)); | ||
} | ||
// browser version and min supported version. | ||
return compareVersions([version, minVersions[browser]]) < 0; | ||
} | ||
} | ||
} | ||
return strictMode; // not found | ||
static parse(UA) { | ||
return (new Parser(UA)).getResult(); | ||
} | ||
} | ||
/** | ||
* Check if browser is supported | ||
* | ||
* @param {Object} minVersions map of minimal version to browser | ||
* @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map | ||
* @param {String} [ua] user agent string | ||
* @return {Boolean} | ||
*/ | ||
function check(minVersions, strictMode, ua) { | ||
return !isUnsupportedBrowser(minVersions, strictMode, ua); | ||
} | ||
bowser.isUnsupportedBrowser = isUnsupportedBrowser; | ||
bowser.compareVersions = compareVersions; | ||
bowser.check = check; | ||
/* | ||
* Set our detect method to the main bowser object so we can | ||
* reuse it to test other user agents. | ||
* This is needed to implement future tests. | ||
*/ | ||
bowser._detect = detect; | ||
/* | ||
* Set our detect public method to the main bowser object | ||
* This is needed to implement bowser in server side | ||
*/ | ||
bowser.detect = detect; | ||
return bowser | ||
}); | ||
export default Bowser; |
116
typings.d.ts
@@ -1,115 +0,1 @@ | ||
// Type definitions for Bowser 1.x | ||
// Project: https://github.com/lancedikson/bowser | ||
// Definitions by: Paulo Cesar <https://github.com/pocesar> | ||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped | ||
declare const bowser: bowser.IBowser; | ||
export = bowser; | ||
export as namespace bowser; | ||
declare namespace bowser { | ||
export interface IBowserPlatform { | ||
ipad: boolean; | ||
ipod: boolean; | ||
iphone: boolean; | ||
/** If a tablet device is detected, the flag tablet is set instead of mobile. */ | ||
tablet: boolean; | ||
/** All detected mobile OSes are additionally flagged mobile, unless it's a tablet */ | ||
mobile: boolean; | ||
} | ||
export interface IBowserOS { | ||
mac: boolean; | ||
/**other than Windows Phone */ | ||
windows: boolean; | ||
windowsphone: boolean; | ||
/**other than android, chromeos, webos, tizen, and sailfish */ | ||
linux: boolean; | ||
chromeos: boolean; | ||
android: boolean; | ||
/** also sets one of iphone/ipad/ipod */ | ||
ios: boolean; | ||
blackberry: boolean; | ||
firefoxos: boolean; | ||
/** may also set touchpad */ | ||
webos: boolean; | ||
bada: boolean; | ||
tizen: boolean; | ||
sailfish: boolean; | ||
} | ||
export interface IBowserVersions { | ||
chrome: boolean; | ||
chromium: boolean; | ||
firefox: boolean; | ||
msie: boolean; | ||
msedge: boolean; | ||
safari: boolean; | ||
android: boolean; | ||
ios: boolean; | ||
opera: boolean; | ||
samsungBrowser: boolean; | ||
phantom: boolean; | ||
blackberry: boolean; | ||
webos: boolean; | ||
silk: boolean; | ||
bada: boolean; | ||
tizen: boolean; | ||
seamonkey: boolean; | ||
sailfish: boolean; | ||
ucbrowser: boolean; | ||
qupzilla: boolean; | ||
vivaldi: boolean; | ||
sleipnir: boolean; | ||
kMeleon: boolean; | ||
whale: boolean; | ||
} | ||
export interface IBowserEngines { | ||
/** IE <= 11 */ | ||
msie: boolean; | ||
/**Chrome 0-27, Android <4.4, iOs, BB, etc. */ | ||
webkit: boolean; | ||
/**Chrome >=28, Android >=4.4, Opera, etc. */ | ||
blink: boolean; | ||
/**Firefox, etc. */ | ||
gecko: boolean; | ||
/** IE > 11 */ | ||
msedge: boolean; | ||
} | ||
export interface IBowserGrade { | ||
/** Grade A browser */ | ||
a: boolean; | ||
/** Grade C browser */ | ||
c: boolean; | ||
/** Grade X browser */ | ||
x: boolean; | ||
/** A human readable name for this browser. E.g. 'Chrome', '' */ | ||
name: string; | ||
/** Version number for the browser. E.g. '32.0' */ | ||
version: string|number; | ||
/** Name for this operating system. E.g. 'macOS' */ | ||
osname: string; | ||
/** Version number for this operating system. E.g. '10.12.6' */ | ||
osversion: string|number; | ||
} | ||
export interface IBowserDetection extends IBowserGrade, IBowserEngines, IBowserOS, IBowserVersions, IBowserPlatform { } | ||
export interface IBowserMinVersions { | ||
// { msie: "11", "firefox": "4" } | ||
[index: string]: string; | ||
} | ||
export interface IBowser extends IBowserDetection { | ||
(): IBowserDetection; | ||
test(browserList: string[]): boolean; | ||
_detect(ua: string): IBowser; | ||
detect(ua: string): IBowser; | ||
compareVersions(versions: string[]): number; | ||
check(minVersions: IBowserMinVersions, strictMode?: boolean|string, ua?: string): Boolean; | ||
isUnsupportedBrowser(minVersions: IBowserMinVersions, strictMode?: boolean|string, ua?: string): boolean; | ||
} | ||
} | ||
// to be defined in stable version |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
663747
55
2347
22
1
138
1