Merge branch 'release/2.1.0' into production

pull/291/head 2.1.0
Denis Demchenko 5 years ago
commit 943adfb581

@ -1,5 +1,10 @@
# Bowser Changelog # Bowser Changelog
### 2.1.0 (January 24, 2019)
- [ADD] Add new `Parser.getEngineName()` method (#288)
- [ADD] Add detection of ChromeOS (#287)
- [FIX] Fix README
### 2.0.0 (January 19, 2019) ### 2.0.0 (January 19, 2019)
- [ADD] Support a non strict equality in `Parser.satisfies()` (#275) - [ADD] Support a non strict equality in `Parser.satisfies()` (#275)
- [ADD] Add Android versions names (#276) - [ADD] Add Android versions names (#276)

@ -1,7 +1,31 @@
# Contributing # Contributing
The project runs Git-flow, where the `master` branch is the development one and `production` is the production one. We're always open to pull requests or code reviews. Everyone can become a permanent contributor. Just ping @lancedikson in the issues or on Twitter ❤️
In a nutshell, if you're about to propose a new feature with adding some totally new functionality to `bowser`, it's better to branch from `master` and make a PR pointing back to `master` as well. ## Branches
If it's a small hotfix, fix a typo in the docs or you've added support for a new browser/OS/platform/etc, then it's better to branch from `production` and make a PR pointing back to `production`.
Following these simple rules will help to maintain the repo a lot! Thanks ❤️ The project runs Git-flow, where the `master` branch is for development and `production` is for production.
In a nutshell, if you are proposing a new feature that adds totally new functionality to `bowser`, it's better to branch from `master` and make a PR pointing back to `master` as well.
If it's a small hot-fix, an improvement to the docs, or added support for a new browser/OS/platform/etc, then it's better to branch from `production` and make a PR pointing back to `production`.
Following these simple rules will really help maintain the repo! Thanks ❤️
## Adding Tests
See the list in `test/acceptance/useragentstrings.yml` with example user agents and their expected `bowser` object.
Whenever you add support for new browsers or notice a bug / mismatch, please update the list and
check if all tests are still passing.
## Testing
If you'd like to contribute a change to `bowser`, modify the files in `src/`, and run the following (you'll need `node` + `npm` installed):
``` sh
$ npm install
$ npm run build #build
$ npm test #run tests
$ npm run lint #check lint rules
```

@ -13,19 +13,23 @@ A browser detector. Because sometimes, there is no other way, and not even good
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. 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.
_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 version 2.0** **Changes of version 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.
The version 2.0 has drastically changed API. All available methods can be found in the `docs` folder from now on and on a webpage soon.
_For legacy code, check out the [1.x](https://github.com/lancedikson/bowser/tree/v1.x) branch and install it through `npm install bowser@1.9.4`._
# Use cases # Use cases
First of all, require the library. This is a UMD Module, so it will work for AMD, Typescript and CommonJS module systems. First of all, require the library. This is a UMD Module, so it will work for AMD, TypeScript, ES6, and CommonJS module systems.
```javascript ```javascript
const Bowser = require("bowser"); // CommonJS const Bowser = require("bowser"); // CommonJS
import * as Bowser from "bowser" // Typescript import * as Bowser from "bowser"; // TypeScript
import Bowser from "bowser"; // ES6 (and TypeScript with --esModuleInterop enabled)
``` ```
By default, the exported version is the *ES5 transpiled version*, which **do not** include any polyfills. By default, the exported version is the *ES5 transpiled version*, which **do not** include any polyfills.
@ -41,7 +45,7 @@ You may need to use the source files, so they will be available in the package a
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 do it with Bowser: 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 do it with Bowser:
```javascript ```javascript
const browser = bowser.getParser(window.navigator.userAgent); const browser = Bowser.getParser(window.navigator.userAgent);
console.log(`The current browser name is "${browser.getBrowserName()}"`); console.log(`The current browser name is "${browser.getBrowserName()}"`);
// The current browser name is "Internet Explorer" // The current browser name is "Internet Explorer"
@ -52,7 +56,7 @@ or
```javascript ```javascript
const impression = new Impression(); const impression = new Impression();
const browser = bowser.getParser(window.navigator.userAgent); const browser = Bowser.getParser(window.navigator.userAgent);
const browserInfo = browser.getBrowser(); const browserInfo = browser.getBrowser();
impression.brName = browserInfo.name; impression.brName = browserInfo.name;
impression.brVer = browserInfo.version; impression.brVer = browserInfo.version;
@ -61,7 +65,7 @@ impression.brVer = browserInfo.version;
or or
```javascript ```javascript
const browser = bowser.getParser(window.navigator.userAgent); const browser = Bowser.getParser(window.navigator.userAgent);
impression.userTechData = browser.parse(); impression.userTechData = browser.parse();
console.log(impression.userTechData); console.log(impression.userTechData);
@ -93,7 +97,7 @@ You could want to filter some particular browsers to provide any special support
It could look like this: It could look like this:
```javascript ```javascript
const browser = bowser.getParser(window.navigator.userAgent); const browser = Bowser.getParser(window.navigator.userAgent);
const isValidBrowser = browser.satisfies({ const isValidBrowser = browser.satisfies({
// declare browsers per OS // declare browsers per OS
windows: { windows: {
@ -128,25 +132,6 @@ Thus, you can define OS or platform specific rules and they will have more prior
More of API and possibilities you will find in the `docs` folder. More of API and possibilities you will find in the `docs` folder.
# Contributing
We're always open to pull requests or code reviews. Everyone can become a permanent contributor. Just ping @lancedikson in the issues or on Twitter ❤️
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):
``` sh
$ npm install
$ npm run build #build
$ npm test #run tests
$ npm run lint #check lint rules
```
### Adding tests
See the list in `test/acceptance/useragentstrings.yml` with example user agents and their expected bowser object.
Whenever you add support for new browsers or notice a bug / mismatch, please update the list and
check if all tests are still passing.
### Similar Projects ### Similar Projects
* [Kong](https://github.com/BigBadBleuCheese/Kong) - A C# port of Bowser. * [Kong](https://github.com/BigBadBleuCheese/Kong) - A C# port of Bowser.

54
index.d.ts vendored

@ -13,7 +13,7 @@ declare namespace Bowser {
* @param {boolean} skipParsing * @param {boolean} skipParsing
*/ */
function getParser(UA: string, skipParsing?: boolean): Parser.Parser; function getParser(UA: string, skipParsing?: boolean): Parser.Parser;
/** /**
* Creates a Parser instance and runs Parser.getResult immediately * Creates a Parser instance and runs Parser.getResult immediately
@ -26,28 +26,28 @@ declare namespace Bowser {
declare namespace Parser { declare namespace Parser {
class Parser { class Parser {
constructor(UA: string, skipParsing?: boolean); constructor(UA: string, skipParsing?: boolean);
/** /**
* Get parsed browser object * Get parsed browser object
* @return {BrowserDetails} Browser's details * @return {BrowserDetails} Browser's details
*/ */
getBrowser(): BrowserDetails; getBrowser(): BrowserDetails;
/** /**
* Get browser's name * Get browser's name
* @return {String} Browser's name or an empty string * @return {String} Browser's name or an empty string
*/ */
getBrowserName(): string; getBrowserName(): string;
/** /**
* Get browser's version * Get browser's version
* @return {String} version of browser * @return {String} version of browser
*/ */
getBrowserVersion(): string; getBrowserVersion(): string;
/** /**
* Get OS * Get OS
@ -60,7 +60,7 @@ declare namespace Parser {
* // } * // }
*/ */
getOS(): OSDetails; getOS(): OSDetails;
/** /**
* Get OS name * Get OS name
@ -68,49 +68,49 @@ declare namespace Parser {
* @return {String} name of the OS macOS, Windows, Linux, etc. * @return {String} name of the OS macOS, Windows, Linux, etc.
*/ */
getOSName(toLowerCase?: boolean): string; getOSName(toLowerCase?: boolean): string;
/** /**
* Get OS version * Get OS version
* @return {String} full version with dots ('10.11.12', '5.6', etc) * @return {String} full version with dots ('10.11.12', '5.6', etc)
*/ */
getOSVersion(): string; getOSVersion(): string;
/** /**
* Get parsed platform * Get parsed platform
* @returns {PlatformDetails} * @returns {PlatformDetails}
*/ */
getPlatform(): PlatformDetails; getPlatform(): PlatformDetails;
/** /**
* Get platform name * Get platform name
* @param {boolean} toLowerCase * @param {boolean} toLowerCase
*/ */
getPlatformType(toLowerCase?: boolean): string; getPlatformType(toLowerCase?: boolean): string;
/** /**
* Get parsed engine * Get parsed engine
* @returns {EngineDetails} * @returns {EngineDetails}
*/ */
getEngine(): EngineDetails; getEngine(): EngineDetails;
/** /**
* Get parsed result * Get parsed result
* @return {ParsedResult} * @return {ParsedResult}
*/ */
getResult(): ParsedResult; getResult(): ParsedResult;
/** /**
* Get UserAgent string of current Parser instance * Get UserAgent string of current Parser instance
* @return {String} User-Agent String of the current <Parser> object * @return {String} User-Agent String of the current <Parser> object
*/ */
getUA(): string; getUA(): string;
/** /**
* Is anything? Check if the browser is called "anything", * Is anything? Check if the browser is called "anything",
@ -119,41 +119,41 @@ declare namespace Parser {
* @returns {Boolean} * @returns {Boolean}
*/ */
is(anything: any): boolean; is(anything: any): boolean;
/** /**
* Parse full information about the browser * Parse full information about the browser
*/ */
parse(): void; parse(): void;
/** /**
* Get parsed browser object * Get parsed browser object
* @returns {BrowserDetails} * @returns {BrowserDetails}
*/ */
parseBrowser(): BrowserDetails; parseBrowser(): BrowserDetails;
/** /**
* Get parsed engine * Get parsed engine
* @returns {EngineDetails} * @returns {EngineDetails}
*/ */
parseEngine(): EngineDetails; parseEngine(): EngineDetails;
/** /**
* Parse OS and save it to this.parsedResult.os * Parse OS and save it to this.parsedResult.os
* @returns {OSDetails} * @returns {OSDetails}
*/ */
parseOS(): OSDetails; parseOS(): OSDetails;
/** /**
* Get parsed platform * Get parsed platform
* @returns {PlatformDetails} * @returns {PlatformDetails}
*/ */
parsePlatform(): PlatformDetails; parsePlatform(): PlatformDetails;
/** /**
* Check if parsed browser matches certain conditions * Check if parsed browser matches certain conditions
@ -174,7 +174,7 @@ declare namespace Parser {
* if (browser.check({desktop: { chrome: '>118.01.1322' } })) * if (browser.check({desktop: { chrome: '>118.01.1322' } }))
*/ */
satisfies(checkTree: checkTree): boolean | undefined; satisfies(checkTree: checkTree): boolean | undefined;
/** /**
* Check if any of the given values satifies `.is(anything)` * Check if any of the given values satifies `.is(anything)`
@ -182,7 +182,7 @@ declare namespace Parser {
* @returns {boolean} true if at least one condition is satisfied, false otherwise. * @returns {boolean} true if at least one condition is satisfied, false otherwise.
*/ */
some(anythings: string[]): boolean | undefined; some(anythings: string[]): boolean | undefined;
/** /**
* Test a UA string for a regexp * Test a UA string for a regexp
@ -191,34 +191,34 @@ declare namespace Parser {
*/ */
test(regex: RegExp): boolean; test(regex: RegExp): boolean;
} }
interface ParsedResult { interface ParsedResult {
browser: BrowserDetails; browser: BrowserDetails;
os: OSDetails; os: OSDetails;
platform: PlatformDetails; platform: PlatformDetails;
engine: EngineDetails; engine: EngineDetails;
} }
interface Details { interface Details {
name?: string; name?: string;
version?: string; version?: string;
} }
interface OSDetails extends Details { interface OSDetails extends Details {
versionName?: string; versionName?: string;
} }
interface PlatformDetails { interface PlatformDetails {
type?: string; type?: string;
vendor?: string; vendor?: string;
model?: string; model?: string;
} }
type BrowserDetails = Details; type BrowserDetails = Details;
type EngineDetails = Details; type EngineDetails = Details;
interface checkTree { interface checkTree {
[key: string]: any; [key: string]: any;
} }
} }

2
package-lock.json generated

@ -1,6 +1,6 @@
{ {
"name": "bowser", "name": "bowser",
"version": "2.0.0", "version": "2.1.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

@ -1,6 +1,6 @@
{ {
"name": "bowser", "name": "bowser",
"version": "2.0.0", "version": "2.1.0",
"description": "Lightweight browser detector", "description": "Lightweight browser detector",
"keywords": [ "keywords": [
"browser", "browser",

@ -144,4 +144,14 @@ export default [
}; };
}, },
}, },
/* Chrome OS */
{
test: [/CrOS/],
describe() {
return {
name: 'Chrome OS',
};
},
},
]; ];

@ -272,6 +272,19 @@ class Parser {
return this.parseEngine(); return this.parseEngine();
} }
/**
* Get engines's name
* @return {String} Engines's name or an empty string
*
* @public
*/
getEngineName(toLowerCase) {
if (toLowerCase) {
return String(this.getEngine().name).toLowerCase() || '';
}
return this.getEngine().name || '';
}
/** /**
* Get parsed platform * Get parsed platform
* @return {{}} * @return {{}}
@ -437,6 +450,10 @@ class Parser {
return this.getPlatformType(true) === String(platformType).toLowerCase(); return this.getPlatformType(true) === String(platformType).toLowerCase();
} }
isEngine(engineName) {
return this.getEngineName(true) === String(engineName).toLowerCase();
}
/** /**
* Is anything? Check if the browser is called "anything", * Is anything? Check if the browser is called "anything",
* the OS called "anything" or the platform called "anything" * the OS called "anything" or the platform called "anything"

@ -174,7 +174,8 @@
browser: browser:
name: "Chrome" name: "Chrome"
version: "29.0.1547.57" version: "29.0.1547.57"
os: {} os:
name: "Chrome OS"
platform: {} platform: {}
engine: engine:
name: "Blink" name: "Blink"

@ -53,6 +53,21 @@ test('Parser.getOSVersion returns a correct result', (t) => {
t.is(parser.getOSVersion(), '10.12.4'); t.is(parser.getOSVersion(), '10.12.4');
}); });
test('Parser.parseEngine is being called when getEngine() called', (t) => {
const spy = sinon.spy(parser, 'parseEngine');
parser.getEngine();
t.truthy(spy.called);
parser.parseEngine.restore();
});
test('Parser.getEngineName gives a name of the engine', (t) => {
t.is(parser.getEngineName(), 'Blink');
});
test('Parser.getEngineName gives a lower-cased name of the engine', (t) => {
t.is(parser.getEngineName(true), 'blink');
});
test('Skip parsing shouldn\'t parse', (t) => { test('Skip parsing shouldn\'t parse', (t) => {
t.deepEqual((new Parser(UA, true)).getResult(), {}); t.deepEqual((new Parser(UA, true)).getResult(), {});
}); });

Loading…
Cancel
Save