Skip to content

Commit 505f19f

Browse files
committed
Merge branch 'release/2.0.0-beta.1'
2 parents 2c5ab93 + 486f718 commit 505f19f

15 files changed

+102
-42
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Bowser Changelog
22

3+
### 2.0.0-beta.1 (August 18, 2018)
4+
- [ADD] Add loose version comparison to `Parser.compareVersion()` and `Parser.satisfies()`
5+
- [CHORE] Add CONTRIBUTING.md
6+
- [DOCS] Regenerate docs
7+
38
### 2.0.0-alpha.4 (August 2, 2018)
49
- [DOCS] Fix usage docs (#238)
510
- [CHANGE] Make `./es5.js` the main file of the package (#239)

CONTRIBUTING.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Contributing
2+
3+
The project runs Git-flow, where the `master` branch is the production one and the `develop` is the developing one.
4+
5+
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.
6+
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.
7+
Following these simple rules will help to maintain the repo a lot! Thanks ❤️

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ const isValidBrowser = browser.satisfies({
111111
chrome: ">20.1.1432",
112112
firefox: ">31",
113113
opera: ">22"
114+
115+
// also supports equality operator
116+
chrome: "=20.1.1432", // will match particular build only
117+
118+
// and loose-equality operator
119+
chrome: "~20" // will match any 20.* sub-version
120+
chrome: "~20.1" // will match any 20.1.* sub-version (20.1.19 as well as 20.1.12.42-alpha.1)
114121
});
115122
```
116123

docs/Bowser.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ <h5>Returns:</h5>
559559
<br class="clear">
560560

561561
<footer>
562-
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.
562+
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.
563563
</footer>
564564

565565
<script>prettyPrint();</script>

docs/Parser.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,7 +1558,7 @@ <h4 class="name" id="is"><span class="type-signature"></span>is<span class="sign
15581558

15591559
<dt class="tag-source">Source:</dt>
15601560
<dd class="tag-source"><ul class="dummy"><li>
1561-
<a href="parser.js.html">parser.js</a>, <a href="parser.js.html#line427">line 427</a>
1561+
<a href="parser.js.html">parser.js</a>, <a href="parser.js.html#line432">line 432</a>
15621562
</li></ul></dd>
15631563

15641564

@@ -2376,7 +2376,7 @@ <h4 class="name" id="some"><span class="type-signature"></span>some<span class="
23762376

23772377
<dt class="tag-source">Source:</dt>
23782378
<dd class="tag-source"><ul class="dummy"><li>
2379-
<a href="parser.js.html">parser.js</a>, <a href="parser.js.html#line436">line 436</a>
2379+
<a href="parser.js.html">parser.js</a>, <a href="parser.js.html#line441">line 441</a>
23802380
</li></ul></dd>
23812381

23822382

@@ -2679,7 +2679,7 @@ <h5>Returns:</h5>
26792679
<br class="clear">
26802680

26812681
<footer>
2682-
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.
2682+
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.
26832683
</footer>
26842684

26852685
<script>prettyPrint();</script>

docs/bowser.js.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ <h1 class="page-title">bowser.js</h1>
6565
* const bowser = new Bowser(window.navigator.userAgent);
6666
* bowser.getResult()
6767
*/
68-
static getParser(UA, skipParsing=false) {
68+
static getParser(UA, skipParsing = false) {
6969
if (typeof UA !== 'string') {
7070
throw new Error('UserAgent should be a string');
7171
}
@@ -96,7 +96,7 @@ <h1 class="page-title">bowser.js</h1>
9696
<br class="clear">
9797

9898
<footer>
99-
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.
99+
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.
100100
</footer>
101101

102102
<script>prettyPrint();</script>

docs/global.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ <h6>Properties</h6>
758758
<br class="clear">
759759

760760
<footer>
761-
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.
761+
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.
762762
</footer>
763763

764764
<script>prettyPrint();</script>

docs/index.html

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,12 @@ <h1>Overview</h1><p>The library is made to help to detect what browser your user
5959
<p><strong>Changes of the 2.0</strong>
6060
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>
6161
<h1>Use cases</h1><p>First of all, require the library:</p>
62-
<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
62+
<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
6363
<strong>do not</strong> include any polyfills.</p>
6464
<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.
6565
So, for you it's suitable to require bowser like this: <code>require('bowser/bundled')</code>.
6666
As the result, you get a ES5 version of bowser with <code>babel-polyfill</code> bundled together.</p>
67-
<p>If you use bowser for Node.js, you'd better use <code>require('bowser/es5')</code>,
68-
since source files have <code>import</code> statements, which are not compatible with Node.js yet.</p>
67+
<p>You may need to use the source files, so they will be available in the package as well.</p>
6968
<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>
7069
<pre class="prettyprint source lang-javascript"><code>const browser = bowser.getParser(window.navigator.userAgent);
7170

@@ -100,7 +99,7 @@ <h2>Browser props detection</h2><p>Often we need to pick users' browser properti
10099
}
101100
}</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.
102101
It could look like this:</p>
103-
<pre class="prettyprint source lang-javascript"><code>const browser = bowser.getParsers(window.navigator.userAgent);
102+
<pre class="prettyprint source lang-javascript"><code>const browser = bowser.getParser(window.navigator.userAgent);
104103
const isValidBrowser = browser.satisfies({
105104
// declare browsers per OS
106105
windows: {
@@ -120,6 +119,13 @@ <h2>Browser props detection</h2><p>Often we need to pick users' browser properti
120119
chrome: &quot;>20.1.1432&quot;,
121120
firefox: &quot;>31&quot;,
122121
opera: &quot;>22&quot;
122+
123+
// also supports equality operator
124+
chrome: &quot;=20.1.1432&quot;, // will match particular build only
125+
126+
// and loose-equality operator
127+
chrome: &quot;~20&quot; // will match any 20.* sub-version
128+
chrome: &quot;~20.1&quot; // will match any 20.1.* sub-version (20.1.19 as well as 20.1.12.42-alpha.1)
123129
});</code></pre><p>Settings for any particular OS or platform has more priority and redefines settings of standalone browsers.
124130
Thus, you can define OS or platform specific rules and they will have more priority in the end.</p>
125131
<p>More of API and possibilities you will find in the <code>docs</code> folder.</p>
@@ -144,7 +150,7 @@ <h3>License</h3><p>Licensed as MIT. All rights not explicitly granted in the MIT
144150
<br class="clear">
145151

146152
<footer>
147-
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.
153+
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.
148154
</footer>
149155

150156
<script>prettyPrint();</script>

docs/parser.js.html

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ <h1 class="page-title">parser.js</h1>
436436
compareVersion(version) {
437437
let expectedResult = 0;
438438
let comparableVersion = version;
439+
let isLoose = false;
439440

440441
if (version[0] === '>') {
441442
expectedResult = 1;
@@ -445,8 +446,12 @@ <h1 class="page-title">parser.js</h1>
445446
comparableVersion = version.substr(1);
446447
} else if (version[0] === '=') {
447448
comparableVersion = version.substr(1);
449+
} else if (version[0] === '~') {
450+
isLoose = true;
451+
comparableVersion = version.substr(1);
448452
}
449-
return compareVersions(this.getBrowserVersion(), comparableVersion) === expectedResult;
453+
454+
return compareVersions(this.getBrowserVersion(), comparableVersion, isLoose) === expectedResult;
450455
}
451456

452457
isOS(osName) {
@@ -490,7 +495,7 @@ <h1 class="page-title">parser.js</h1>
490495
<br class="clear">
491496

492497
<footer>
493-
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.
498+
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.
494499
</footer>
495500

496501
<script>prettyPrint();</script>

docs/utils.js.html

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -107,23 +107,26 @@ <h1 class="page-title">utils.js</h1>
107107
* Calculate browser version weight
108108
*
109109
* @example
110-
* compareVersions(['1.10.2.1', '1.8.2.1.90']) // 1
111-
* compareVersions(['1.010.2.1', '1.09.2.1.90']); // 1
112-
* compareVersions(['1.10.2.1', '1.10.2.1']); // 0
113-
* compareVersions(['1.10.2.1', '1.0800.2']); // -1
110+
* compareVersions('1.10.2.1', '1.8.2.1.90') // 1
111+
* compareVersions('1.010.2.1', '1.09.2.1.90'); // 1
112+
* compareVersions('1.10.2.1', '1.10.2.1'); // 0
113+
* compareVersions('1.10.2.1', '1.0800.2'); // -1
114+
* compareVersions('1.10.2.1', '1.10', true); // 0
114115
*
115116
* @param {String} versionA versions versions to compare
116117
* @param {String} versionB versions versions to compare
118+
* @param {boolean} [isLoose] enable loose comparison
117119
* @return {Number} comparison result: -1 when versionA is lower,
118120
* 1 when versionA is bigger, 0 when both equal
119121
*/
120122
/* eslint consistent-return: 1 */
121-
static compareVersions(versionA, versionB) {
123+
static compareVersions(versionA, versionB, isLoose = false) {
122124
// 1) get common precision for both versions, for example for "10.0" and "9" it should be 2
123-
let precision = Math.max(
124-
Utils.getVersionPrecision(versionA),
125-
Utils.getVersionPrecision(versionB),
126-
);
125+
const versionAPrecision = Utils.getVersionPrecision(versionA);
126+
const versionBPrecision = Utils.getVersionPrecision(versionB);
127+
128+
let precision = Math.max(versionAPrecision, versionBPrecision);
129+
let lastPrecision = 0;
127130

128131
const chunks = Utils.map([versionA, versionB], (version) => {
129132
const delta = precision - Utils.getVersionPrecision(version);
@@ -135,14 +138,19 @@ <h1 class="page-title">utils.js</h1>
135138
return Utils.map(_version.split('.'), chunk => new Array(20 - chunk.length).join('0') + chunk).reverse();
136139
});
137140

141+
// adjust precision for loose comparison
142+
if (isLoose) {
143+
lastPrecision = precision - Math.min(versionAPrecision, versionBPrecision);
144+
}
145+
138146
// iterate in reverse order by reversed chunks array
139147
precision -= 1;
140-
while (precision >= 0) {
148+
while (precision >= lastPrecision) {
141149
// 4) compare: "000000009" > "000000010" = false (but "9" > "10" = true)
142150
if (chunks[0][precision] > chunks[1][precision]) {
143151
return 1;
144152
} else if (chunks[0][precision] === chunks[1][precision]) {
145-
if (precision === 0) {
153+
if (precision === lastPrecision) {
146154
// all version chunks are same
147155
return 0;
148156
}
@@ -186,7 +194,7 @@ <h1 class="page-title">utils.js</h1>
186194
<br class="clear">
187195

188196
<footer>
189-
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.
197+
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.
190198
</footer>
191199

192200
<script>prettyPrint();</script>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bowser",
3-
"version": "2.0.0-alpha.4",
3+
"version": "2.0.0-beta.1",
44
"description": "Lightweight browser detector",
55
"keywords": [
66
"browser",

src/parser.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ class Parser {
397397
compareVersion(version) {
398398
let expectedResult = 0;
399399
let comparableVersion = version;
400+
let isLoose = false;
400401

401402
if (version[0] === '>') {
402403
expectedResult = 1;
@@ -406,8 +407,12 @@ class Parser {
406407
comparableVersion = version.substr(1);
407408
} else if (version[0] === '=') {
408409
comparableVersion = version.substr(1);
410+
} else if (version[0] === '~') {
411+
isLoose = true;
412+
comparableVersion = version.substr(1);
409413
}
410-
return compareVersions(this.getBrowserVersion(), comparableVersion) === expectedResult;
414+
415+
return compareVersions(this.getBrowserVersion(), comparableVersion, isLoose) === expectedResult;
411416
}
412417

413418
isOS(osName) {

src/utils.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,26 @@ class Utils {
6868
* Calculate browser version weight
6969
*
7070
* @example
71-
* compareVersions(['1.10.2.1', '1.8.2.1.90']) // 1
72-
* compareVersions(['1.010.2.1', '1.09.2.1.90']); // 1
73-
* compareVersions(['1.10.2.1', '1.10.2.1']); // 0
74-
* compareVersions(['1.10.2.1', '1.0800.2']); // -1
71+
* compareVersions('1.10.2.1', '1.8.2.1.90') // 1
72+
* compareVersions('1.010.2.1', '1.09.2.1.90'); // 1
73+
* compareVersions('1.10.2.1', '1.10.2.1'); // 0
74+
* compareVersions('1.10.2.1', '1.0800.2'); // -1
75+
* compareVersions('1.10.2.1', '1.10', true); // 0
7576
*
7677
* @param {String} versionA versions versions to compare
7778
* @param {String} versionB versions versions to compare
79+
* @param {boolean} [isLoose] enable loose comparison
7880
* @return {Number} comparison result: -1 when versionA is lower,
7981
* 1 when versionA is bigger, 0 when both equal
8082
*/
8183
/* eslint consistent-return: 1 */
82-
static compareVersions(versionA, versionB) {
84+
static compareVersions(versionA, versionB, isLoose = false) {
8385
// 1) get common precision for both versions, for example for "10.0" and "9" it should be 2
84-
let precision = Math.max(
85-
Utils.getVersionPrecision(versionA),
86-
Utils.getVersionPrecision(versionB),
87-
);
86+
const versionAPrecision = Utils.getVersionPrecision(versionA);
87+
const versionBPrecision = Utils.getVersionPrecision(versionB);
88+
89+
let precision = Math.max(versionAPrecision, versionBPrecision);
90+
let lastPrecision = 0;
8891

8992
const chunks = Utils.map([versionA, versionB], (version) => {
9093
const delta = precision - Utils.getVersionPrecision(version);
@@ -96,14 +99,19 @@ class Utils {
9699
return Utils.map(_version.split('.'), chunk => new Array(20 - chunk.length).join('0') + chunk).reverse();
97100
});
98101

102+
// adjust precision for loose comparison
103+
if (isLoose) {
104+
lastPrecision = precision - Math.min(versionAPrecision, versionBPrecision);
105+
}
106+
99107
// iterate in reverse order by reversed chunks array
100108
precision -= 1;
101-
while (precision >= 0) {
109+
while (precision >= lastPrecision) {
102110
// 4) compare: "000000009" > "000000010" = false (but "9" > "10" = true)
103111
if (chunks[0][precision] > chunks[1][precision]) {
104112
return 1;
105113
} else if (chunks[0][precision] === chunks[1][precision]) {
106-
if (precision === 0) {
114+
if (precision === lastPrecision) {
107115
// all version chunks are same
108116
return 0;
109117
}

test/unit/parser.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,13 @@ test('Skip parsing shouldn\'t parse', (t) => {
5757
t.deepEqual((new Parser(UA, true)).getResult(), {});
5858
});
5959

60-
test('Parser.check should make simple comparison', (t) => {
60+
test('Parser.check should make simple comparisons', (t) => {
61+
// also covers Parser.compareVersion() method
6162
t.is(parser.satisfies({ opera: '>42' }), true);
63+
t.is(parser.satisfies({ opera: '<44' }), true);
64+
t.is(parser.satisfies({ opera: '=43.0.2442.1165' }), true);
65+
t.is(parser.satisfies({ opera: '~43.0' }), true);
66+
t.is(parser.satisfies({ opera: '~43' }), true);
6267
});
6368

6469
test('Parser.check should make complex comparison', (t) => {

test/unit/utils.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ test('compareVersions', (t) => {
2222
['1.10.2.1', '1.8.2.1.90', 1],
2323
['1.010.2.1', '1.08.2.1.90', 1],
2424
['1.10.2.1', '1.10.2.1', 0],
25+
['1.10.2.1', '1.10.2', 0, true],
26+
['1.10.2.1', '1.10', 0, true],
27+
['1.10.2.1', '1', 0, true],
2528
['1.10.2.1', '1.0800.2', -1],
2629
['1.0.0-alpha', '1.0.0-alpha.1', -1],
2730
['1.0.0-alpha.1', '1.0.0-alpha.beta', -1],
@@ -35,14 +38,15 @@ test('compareVersions', (t) => {
3538
const versionA = testingParams[0];
3639
const versionB = testingParams[1];
3740
const result = testingParams[2];
38-
let matching = ' == ';
41+
const isLoose = testingParams.length > 3 ? testingParams[3] : false;
42+
let matching = isLoose ? '~' : ' == ';
3943

4044
if (result > 0) {
4145
matching = ' > ';
4246
} else if (result < 0) {
4347
matching = ' < ';
4448
}
4549

46-
t.is(compareVersions(versionA, versionB), result, `version ${versionA} should be ${matching} version ${versionB}`);
50+
t.is(compareVersions(versionA, versionB, isLoose), result, `version ${versionA} should be ${matching} version ${versionB}`);
4751
});
4852
});

0 commit comments

Comments
 (0)