mirror of
https://github.com/lancedikson/bowser
synced 2024-10-27 20:34:22 +00:00
Merge branch 'release/2.0.0-beta.1'
This commit is contained in:
commit
505f19f207
@ -1,5 +1,10 @@
|
||||
# Bowser Changelog
|
||||
|
||||
### 2.0.0-beta.1 (August 18, 2018)
|
||||
- [ADD] Add loose version comparison to `Parser.compareVersion()` and `Parser.satisfies()`
|
||||
- [CHORE] Add CONTRIBUTING.md
|
||||
- [DOCS] Regenerate docs
|
||||
|
||||
### 2.0.0-alpha.4 (August 2, 2018)
|
||||
- [DOCS] Fix usage docs (#238)
|
||||
- [CHANGE] Make `./es5.js` the main file of the package (#239)
|
||||
|
7
CONTRIBUTING.md
Normal file
7
CONTRIBUTING.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Contributing
|
||||
|
||||
The project runs Git-flow, where the `master` branch is the production one and the `develop` is the developing one.
|
||||
|
||||
In a nutshell, if you're about to propose a new feature with adding new functionality to bowser, it's better to branch from `develop` and make a PR pointing to `develop` as well.
|
||||
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 `master` and make a PR pointing to `master` as well.
|
||||
Following these simple rules will help to maintain the repo a lot! Thanks ❤️
|
@ -111,6 +111,13 @@ const isValidBrowser = browser.satisfies({
|
||||
chrome: ">20.1.1432",
|
||||
firefox: ">31",
|
||||
opera: ">22"
|
||||
|
||||
// also supports equality operator
|
||||
chrome: "=20.1.1432", // will match particular build only
|
||||
|
||||
// and loose-equality operator
|
||||
chrome: "~20" // will match any 20.* sub-version
|
||||
chrome: "~20.1" // will match any 20.1.* sub-version (20.1.19 as well as 20.1.12.42-alpha.1)
|
||||
});
|
||||
```
|
||||
|
||||
|
@ -559,7 +559,7 @@ bowser.getResult()</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jul 22 2018 19:42:18 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sat Aug 18 2018 14:14:47 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
</footer>
|
||||
|
||||
<script>prettyPrint();</script>
|
||||
|
@ -1558,7 +1558,7 @@ like <a href="Parser.html#parseBrowser">Parser#parseBrowser</a> or <a href="Pars
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="parser.js.html">parser.js</a>, <a href="parser.js.html#line427">line 427</a>
|
||||
<a href="parser.js.html">parser.js</a>, <a href="parser.js.html#line432">line 432</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2376,7 +2376,7 @@ Returns <code>undefined</code> when the browser is no described in the checkTree
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="parser.js.html">parser.js</a>, <a href="parser.js.html#line436">line 436</a>
|
||||
<a href="parser.js.html">parser.js</a>, <a href="parser.js.html#line441">line 441</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2679,7 +2679,7 @@ Returns <code>undefined</code> when the browser is no described in the checkTree
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jul 22 2018 19:42:18 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sat Aug 18 2018 14:14:47 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
</footer>
|
||||
|
||||
<script>prettyPrint();</script>
|
||||
|
@ -96,7 +96,7 @@ export default Bowser;
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jul 22 2018 19:42:18 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sat Aug 18 2018 14:14:47 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
</footer>
|
||||
|
||||
<script>prettyPrint();</script>
|
||||
|
@ -758,7 +758,7 @@ like <code>"iPhone"</code> or <code>"Kindle Fire HD 7"</code
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jul 22 2018 19:42:18 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sat Aug 18 2018 14:14:47 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
</footer>
|
||||
|
||||
<script>prettyPrint();</script>
|
||||
|
@ -59,13 +59,12 @@
|
||||
<p><strong>Changes of the 2.0</strong>
|
||||
The upcoming 2.0 version has drastically changed API. All available methods can be found in the <code>docs</code> folder from now on and on a webpage soon.</p>
|
||||
<h1>Use cases</h1><p>First of all, require the library:</p>
|
||||
<pre class="prettyprint source lang-javascript"><code>const bowser = require('bowser');</code></pre><p>By default, <code>require('bowser')</code> requires the <em>ES6 version of files</em>, which
|
||||
<pre class="prettyprint source lang-javascript"><code>const bowser = require('bowser');</code></pre><p>By default, <code>require('bowser')</code> requires the <em>ES5 version of files</em>, which
|
||||
<strong>do not</strong> include any polyfills.</p>
|
||||
<p>In case if you don't use your own <code>babel-polyfill</code> you may need to have pre-built bundle with all needed polyfills.
|
||||
So, for you it's suitable to require bowser like this: <code>require('bowser/bundled')</code>.
|
||||
As the result, you get a ES5 version of bowser with <code>babel-polyfill</code> bundled together.</p>
|
||||
<p>If you use bowser for Node.js, you'd better use <code>require('bowser/es5')</code>,
|
||||
since source files have <code>import</code> statements, which are not compatible with Node.js yet.</p>
|
||||
<p>You may need to use the source files, so they will be available in the package as well.</p>
|
||||
<h2>Browser props detection</h2><p>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:</p>
|
||||
<pre class="prettyprint source lang-javascript"><code>const browser = bowser.getParser(window.navigator.userAgent);
|
||||
|
||||
@ -100,7 +99,7 @@ console.log(impression.userTechData);
|
||||
}
|
||||
}</code></pre><h2>Filtering browsers</h2><p>You could want to filter some particular browsers to provide any special support for them or make any workarounds.
|
||||
It could look like this:</p>
|
||||
<pre class="prettyprint source lang-javascript"><code>const browser = bowser.getParsers(window.navigator.userAgent);
|
||||
<pre class="prettyprint source lang-javascript"><code>const browser = bowser.getParser(window.navigator.userAgent);
|
||||
const isValidBrowser = browser.satisfies({
|
||||
// declare browsers per OS
|
||||
windows: {
|
||||
@ -120,6 +119,13 @@ const isValidBrowser = browser.satisfies({
|
||||
chrome: ">20.1.1432",
|
||||
firefox: ">31",
|
||||
opera: ">22"
|
||||
|
||||
// also supports equality operator
|
||||
chrome: "=20.1.1432", // will match particular build only
|
||||
|
||||
// and loose-equality operator
|
||||
chrome: "~20" // will match any 20.* sub-version
|
||||
chrome: "~20.1" // will match any 20.1.* sub-version (20.1.19 as well as 20.1.12.42-alpha.1)
|
||||
});</code></pre><p>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.</p>
|
||||
<p>More of API and possibilities you will find in the <code>docs</code> folder.</p>
|
||||
@ -144,7 +150,7 @@ check if all tests are still passing.</p>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jul 22 2018 19:42:18 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sat Aug 18 2018 14:14:47 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
</footer>
|
||||
|
||||
<script>prettyPrint();</script>
|
||||
|
@ -436,6 +436,7 @@ class Parser {
|
||||
compareVersion(version) {
|
||||
let expectedResult = 0;
|
||||
let comparableVersion = version;
|
||||
let isLoose = false;
|
||||
|
||||
if (version[0] === '>') {
|
||||
expectedResult = 1;
|
||||
@ -445,8 +446,12 @@ class Parser {
|
||||
comparableVersion = version.substr(1);
|
||||
} else if (version[0] === '=') {
|
||||
comparableVersion = version.substr(1);
|
||||
} else if (version[0] === '~') {
|
||||
isLoose = true;
|
||||
comparableVersion = version.substr(1);
|
||||
}
|
||||
return compareVersions(this.getBrowserVersion(), comparableVersion) === expectedResult;
|
||||
|
||||
return compareVersions(this.getBrowserVersion(), comparableVersion, isLoose) === expectedResult;
|
||||
}
|
||||
|
||||
isOS(osName) {
|
||||
@ -490,7 +495,7 @@ export default Parser;
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jul 22 2018 19:42:18 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sat Aug 18 2018 14:14:47 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
</footer>
|
||||
|
||||
<script>prettyPrint();</script>
|
||||
|
@ -107,23 +107,26 @@
|
||||
* 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
|
||||
* 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
|
||||
* compareVersions('1.10.2.1', '1.10', true); // 0
|
||||
*
|
||||
* @param {String} versionA versions versions to compare
|
||||
* @param {String} versionB versions versions to compare
|
||||
* @param {boolean} [isLoose] enable loose comparison
|
||||
* @return {Number} comparison result: -1 when versionA is lower,
|
||||
* 1 when versionA is bigger, 0 when both equal
|
||||
*/
|
||||
/* eslint consistent-return: 1 */
|
||||
static compareVersions(versionA, versionB) {
|
||||
static compareVersions(versionA, versionB, isLoose = false) {
|
||||
// 1) get common precision for both versions, for example for "10.0" and "9" it should be 2
|
||||
let precision = Math.max(
|
||||
Utils.getVersionPrecision(versionA),
|
||||
Utils.getVersionPrecision(versionB),
|
||||
);
|
||||
const versionAPrecision = Utils.getVersionPrecision(versionA);
|
||||
const versionBPrecision = Utils.getVersionPrecision(versionB);
|
||||
|
||||
let precision = Math.max(versionAPrecision, versionBPrecision);
|
||||
let lastPrecision = 0;
|
||||
|
||||
const chunks = Utils.map([versionA, versionB], (version) => {
|
||||
const delta = precision - Utils.getVersionPrecision(version);
|
||||
@ -135,14 +138,19 @@
|
||||
return Utils.map(_version.split('.'), chunk => new Array(20 - chunk.length).join('0') + chunk).reverse();
|
||||
});
|
||||
|
||||
// adjust precision for loose comparison
|
||||
if (isLoose) {
|
||||
lastPrecision = precision - Math.min(versionAPrecision, versionBPrecision);
|
||||
}
|
||||
|
||||
// iterate in reverse order by reversed chunks array
|
||||
precision -= 1;
|
||||
while (precision >= 0) {
|
||||
while (precision >= lastPrecision) {
|
||||
// 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) {
|
||||
if (precision === lastPrecision) {
|
||||
// all version chunks are same
|
||||
return 0;
|
||||
}
|
||||
@ -186,7 +194,7 @@ module.exports = Utils;
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jul 22 2018 19:42:18 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sat Aug 18 2018 14:14:47 GMT+0300 (EEST) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||||
</footer>
|
||||
|
||||
<script>prettyPrint();</script>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bowser",
|
||||
"version": "2.0.0-alpha.4",
|
||||
"version": "2.0.0-beta.1",
|
||||
"description": "Lightweight browser detector",
|
||||
"keywords": [
|
||||
"browser",
|
||||
|
@ -397,6 +397,7 @@ class Parser {
|
||||
compareVersion(version) {
|
||||
let expectedResult = 0;
|
||||
let comparableVersion = version;
|
||||
let isLoose = false;
|
||||
|
||||
if (version[0] === '>') {
|
||||
expectedResult = 1;
|
||||
@ -406,8 +407,12 @@ class Parser {
|
||||
comparableVersion = version.substr(1);
|
||||
} else if (version[0] === '=') {
|
||||
comparableVersion = version.substr(1);
|
||||
} else if (version[0] === '~') {
|
||||
isLoose = true;
|
||||
comparableVersion = version.substr(1);
|
||||
}
|
||||
return compareVersions(this.getBrowserVersion(), comparableVersion) === expectedResult;
|
||||
|
||||
return compareVersions(this.getBrowserVersion(), comparableVersion, isLoose) === expectedResult;
|
||||
}
|
||||
|
||||
isOS(osName) {
|
||||
|
30
src/utils.js
30
src/utils.js
@ -68,23 +68,26 @@ class Utils {
|
||||
* 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
|
||||
* 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
|
||||
* compareVersions('1.10.2.1', '1.10', true); // 0
|
||||
*
|
||||
* @param {String} versionA versions versions to compare
|
||||
* @param {String} versionB versions versions to compare
|
||||
* @param {boolean} [isLoose] enable loose comparison
|
||||
* @return {Number} comparison result: -1 when versionA is lower,
|
||||
* 1 when versionA is bigger, 0 when both equal
|
||||
*/
|
||||
/* eslint consistent-return: 1 */
|
||||
static compareVersions(versionA, versionB) {
|
||||
static compareVersions(versionA, versionB, isLoose = false) {
|
||||
// 1) get common precision for both versions, for example for "10.0" and "9" it should be 2
|
||||
let precision = Math.max(
|
||||
Utils.getVersionPrecision(versionA),
|
||||
Utils.getVersionPrecision(versionB),
|
||||
);
|
||||
const versionAPrecision = Utils.getVersionPrecision(versionA);
|
||||
const versionBPrecision = Utils.getVersionPrecision(versionB);
|
||||
|
||||
let precision = Math.max(versionAPrecision, versionBPrecision);
|
||||
let lastPrecision = 0;
|
||||
|
||||
const chunks = Utils.map([versionA, versionB], (version) => {
|
||||
const delta = precision - Utils.getVersionPrecision(version);
|
||||
@ -96,14 +99,19 @@ class Utils {
|
||||
return Utils.map(_version.split('.'), chunk => new Array(20 - chunk.length).join('0') + chunk).reverse();
|
||||
});
|
||||
|
||||
// adjust precision for loose comparison
|
||||
if (isLoose) {
|
||||
lastPrecision = precision - Math.min(versionAPrecision, versionBPrecision);
|
||||
}
|
||||
|
||||
// iterate in reverse order by reversed chunks array
|
||||
precision -= 1;
|
||||
while (precision >= 0) {
|
||||
while (precision >= lastPrecision) {
|
||||
// 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) {
|
||||
if (precision === lastPrecision) {
|
||||
// all version chunks are same
|
||||
return 0;
|
||||
}
|
||||
|
@ -57,8 +57,13 @@ test('Skip parsing shouldn\'t parse', (t) => {
|
||||
t.deepEqual((new Parser(UA, true)).getResult(), {});
|
||||
});
|
||||
|
||||
test('Parser.check should make simple comparison', (t) => {
|
||||
test('Parser.check should make simple comparisons', (t) => {
|
||||
// also covers Parser.compareVersion() method
|
||||
t.is(parser.satisfies({ opera: '>42' }), true);
|
||||
t.is(parser.satisfies({ opera: '<44' }), true);
|
||||
t.is(parser.satisfies({ opera: '=43.0.2442.1165' }), true);
|
||||
t.is(parser.satisfies({ opera: '~43.0' }), true);
|
||||
t.is(parser.satisfies({ opera: '~43' }), true);
|
||||
});
|
||||
|
||||
test('Parser.check should make complex comparison', (t) => {
|
||||
|
@ -22,6 +22,9 @@ test('compareVersions', (t) => {
|
||||
['1.10.2.1', '1.8.2.1.90', 1],
|
||||
['1.010.2.1', '1.08.2.1.90', 1],
|
||||
['1.10.2.1', '1.10.2.1', 0],
|
||||
['1.10.2.1', '1.10.2', 0, true],
|
||||
['1.10.2.1', '1.10', 0, true],
|
||||
['1.10.2.1', '1', 0, true],
|
||||
['1.10.2.1', '1.0800.2', -1],
|
||||
['1.0.0-alpha', '1.0.0-alpha.1', -1],
|
||||
['1.0.0-alpha.1', '1.0.0-alpha.beta', -1],
|
||||
@ -35,7 +38,8 @@ test('compareVersions', (t) => {
|
||||
const versionA = testingParams[0];
|
||||
const versionB = testingParams[1];
|
||||
const result = testingParams[2];
|
||||
let matching = ' == ';
|
||||
const isLoose = testingParams.length > 3 ? testingParams[3] : false;
|
||||
let matching = isLoose ? '~' : ' == ';
|
||||
|
||||
if (result > 0) {
|
||||
matching = ' > ';
|
||||
@ -43,6 +47,6 @@ test('compareVersions', (t) => {
|
||||
matching = ' < ';
|
||||
}
|
||||
|
||||
t.is(compareVersions(versionA, versionB), result, `version ${versionA} should be ${matching} version ${versionB}`);
|
||||
t.is(compareVersions(versionA, versionB, isLoose), result, `version ${versionA} should be ${matching} version ${versionB}`);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user