diff --git a/src/parser.js b/src/parser.js index db10657..d9df31c 100644 --- a/src/parser.js +++ b/src/parser.js @@ -398,8 +398,17 @@ class Parser { const browserNames = Object.keys(browsers); const matchingDefinition = Utils.find(browserNames, name => (this.isBrowser(name, true))); - if (matchingDefinition !== void 0) { - return this.compareVersion(browsers[matchingDefinition]); + if (matchingDefinition !== void 0 && !checkTree.OS) { + return this.compareBrowserVersion(browsers[matchingDefinition]); + } + + if (matchingDefinition !== void 0 && checkTree.OS) { + return this.compareBrowserVersion(browsers[matchingDefinition]) + && this.compareOSVersion(checkTree.OS); + } + + if (checkTree.OS) { + return this.compareOSVersion(checkTree.OS); } } @@ -423,39 +432,47 @@ class Parser { return browserNameLower === defaultBrowserName; } - compareVersion(version) { + compareBrowserVersion(versionToCompare) { + const currentBrowserVersion = this.getBrowserVersion(); + return this.compareVersion(currentBrowserVersion, versionToCompare); + } + + compareOSVersion(versionToCompare) { + const currentOSVersion = this.getOSVersion(); + return this.compareVersion(currentOSVersion, versionToCompare); + } + + compareVersion = (version, versionToCompare) => { let expectedResults = [0]; - let comparableVersion = version; + let comparableVersion = versionToCompare; let isLoose = false; - const currentBrowserVersion = this.getBrowserVersion(); - - if (typeof currentBrowserVersion !== 'string') { + if (typeof version !== 'string') { return void 0; } - if (version[0] === '>' || version[0] === '<') { - comparableVersion = version.substr(1); - if (version[1] === '=') { + if (versionToCompare[0] === '>' || versionToCompare[0] === '<') { + comparableVersion = versionToCompare.substr(1); + if (versionToCompare[1] === '=') { isLoose = true; - comparableVersion = version.substr(2); + comparableVersion = versionToCompare.substr(2); } else { expectedResults = []; } - if (version[0] === '>') { + if (versionToCompare[0] === '>') { expectedResults.push(1); } else { expectedResults.push(-1); } - } else if (version[0] === '=') { - comparableVersion = version.substr(1); - } else if (version[0] === '~') { + } else if (versionToCompare[0] === '=') { + comparableVersion = versionToCompare.substr(1); + } else if (versionToCompare[0] === '~') { isLoose = true; - comparableVersion = version.substr(1); + comparableVersion = versionToCompare.substr(1); } return expectedResults.indexOf( - Utils.compareVersions(currentBrowserVersion, comparableVersion, isLoose), + Utils.compareVersions(version, comparableVersion, isLoose), ) > -1; } diff --git a/test/unit/parser.js b/test/unit/parser.js index 66036fd..86a2f8a 100644 --- a/test/unit/parser.js +++ b/test/unit/parser.js @@ -12,6 +12,9 @@ const edgeParser = new Parser(EDGE_UA, true); const FOCUS_UA = 'Mozilla/5.0 (Linux; Android 7.1.1) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.2.1 Chrome/59.0.3071.125'; const focusParser = new Parser(FOCUS_UA, true); +const IPHONE_UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1'; +const iphoneParser = new Parser(IPHONE_UA, true); + test('constructor', (t) => { t.truthy(parser instanceof Parser); }); @@ -155,8 +158,27 @@ test('Parser.satisfies for versionless UA strings', (t) => { test('Parser.satisfies should consider aliases while handling browsers', (t) => { t.is(edgeParser.satisfies({ 'Microsoft Edge': '=41.1.35.1' }), true); t.is(edgeParser.satisfies({ 'microsoft edge': '=41.1.35.1' }), true); - t.is(edgeParser.satisfies({ 'edge': '=41.1.35.1' }), true); - t.is(edgeParser.satisfies({ 'Edge': '=41.1.35.1' }), true); + t.is(edgeParser.satisfies({ edge: '=41.1.35.1' }), true); + t.is(edgeParser.satisfies({ Edge: '=41.1.35.1' }), true); +}); + +test('Parser.satisfies should consider OS while handling browsers', (t) => { + t.is(parser.satisfies({ macos: { OS: '>=8.0.0' } }), true); + t.is(parser.satisfies({ macos: { OS: '>=8.0.0', chrome: '>50' } }), true); + t.is(iphoneParser.satisfies({ + windows: { + OS: '>=10', + }, + macos: { + OS: '>=10.13', + }, + android: { + OS: '>=7', + }, + iOS: { + OS: '>=8.4', + }, + }), true); }); test('Parser.is should pass', (t) => {