From a794b10797194b08143d0f61d2f8b6b920d3b8f6 Mon Sep 17 00:00:00 2001 From: Denis Demchenko Date: Fri, 9 Jun 2017 23:04:43 +0300 Subject: [PATCH] Add an engines parser --- src/parser-browsers.js | 18 ------- src/parser-engines.js | 110 +++++++++++++++++++++++++++++++++++++++++ src/parser.js | 48 +++++++++++++++++- 3 files changed, 157 insertions(+), 19 deletions(-) create mode 100644 src/parser-engines.js diff --git a/src/parser-browsers.js b/src/parser-browsers.js index 360d91c..061633e 100644 --- a/src/parser-browsers.js +++ b/src/parser-browsers.js @@ -29,13 +29,6 @@ import { } from './utils'; const commonVersionIdentifier = /version\/(\d+(\.?_?\d+)+)/i; -const RENDERING_ENGINES_NAMES = { - blink: 'Blink', - webkit: 'WebKit', - gecko: 'Gecko', - presto: 'Presto', - edgehtml: 'EdgeHTML' -}; const browsersList = [ { @@ -177,7 +170,6 @@ const browsersList = [ return { name: 'Microsoft Edge', - engine: 'EdgeHTML', version } } @@ -199,7 +191,6 @@ const browsersList = [ const version = getFirstMatch(/seamonkey\/(\d+(\.?_?\d+)+)/i, ua); return { name: 'SeaMonkey', - engine: RENDERING_ENGINES_NAMES.gecko, version } } @@ -210,7 +201,6 @@ const browsersList = [ const version = getFirstMatch(/(?:firefox|iceweasel|fxios)[ \/](\d+(\.?_?\d+)+)/i, ua); return { name: 'Firefox', - engine: RENDERING_ENGINES_NAMES.gecko, version } } @@ -317,16 +307,9 @@ const browsersList = [ test: [/chrome|crios|crmo/i], describe(ua) { const version = getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.?_?\d+)+)/i, ua); - let engine; - if (/(apple)?webkit\/537\.36/i.test(ua)) { - engine = RENDERING_ENGINES_NAMES.blink; - } else { - engine = RENDERING_ENGINES_NAMES.webkit; - } return { name: 'Chrome', - engine, version } } @@ -357,7 +340,6 @@ const browsersList = [ return { name: 'Safari', - engine: RENDERING_ENGINES_NAMES.webkit, version } } diff --git a/src/parser-engines.js b/src/parser-engines.js new file mode 100644 index 0000000..9479752 --- /dev/null +++ b/src/parser-engines.js @@ -0,0 +1,110 @@ +import { + getFirstMatch +} from './utils'; + +/* + * More specific goes first + */ +export default [ + /* EdgeHTML */ + { + test(parser) { + return parser.getBrowserName(true) === 'microsoft edge'; + }, + describe(ua) { + const version = getFirstMatch(/edge\/(\d+(\.?_?\d+)+)/i, ua); + return { + name: 'EdgeHTML', + version + }; + } + }, + + /* Trident */ + { + test: [/trident/i], + describe(ua) { + const engine = { + name: 'Trident' + }; + + const version = getFirstMatch(/trident\/(\d+(\.?_?\d+)+)/i, ua); + + if (version) { + engine.version = version; + } + + return engine; + } + }, + + /* Presto */ + { + test(parser) { + return parser.test(/presto/i); + }, + describe(ua) { + const engine = { + name: 'Presto' + }; + + const version = getFirstMatch(/presto\/(\d+(\.?_?\d+)+)/i, ua); + + if (version) { + engine.version = version; + } + + return engine; + } + }, + + /* Gecko */ + { + test(parser) { + const isGecko = parser.test(/gecko/i); + const likeGecko = parser.test(/like gecko/i); + return isGecko && !likeGecko; + }, + describe(ua) { + const engine = { + name: 'Gecko' + }; + + const version = getFirstMatch(/gecko\/(\d+(\.?_?\d+)+)/i, ua); + + if (version) { + engine.version = version; + } + + return engine; + } + }, + + /* Blink */ + { + test: [/(apple)?webkit\/537\.36/i], + describe() { + return { + name: 'Blink' + }; + } + }, + + /* WebKit */ + { + test: [/(apple)?webkit/i], + describe(ua) { + const engine = { + name: 'WebKit' + }; + + const version = getFirstMatch(/webkit\/(\d+(\.?_?\d+)+)/i, ua); + + if (version) { + engine.version = version; + } + + return engine; + } + } +]; diff --git a/src/parser.js b/src/parser.js index 7da181d..2421928 100644 --- a/src/parser.js +++ b/src/parser.js @@ -1,6 +1,7 @@ import browserParsersList from './parser-browsers'; import osParsersList from './parser-os'; import platformParsersList from './parser-platforms'; +import enginesParsersList from './parser-engines'; class Parser { /** @@ -87,7 +88,10 @@ class Parser { * * @public */ - getBrowserName() { + getBrowserName(toLowerCase) { + if (toLowerCase) { + return String(this.getBrowser().name).toLowerCase(); + } return this.getBrowser().name; } @@ -214,6 +218,47 @@ class Parser { return this.parsedResult.platform; } + /** + * Get parsed engine + * @return {{}} + */ + getEngine() { + if (this.parsedResult.engine) { + return this.parsedResult.engine; + } + + return this._parseEngine(); + } + + /** + * Get parsed platform + * @return {{}} + * @private + */ + _parseEngine() { + this.parsedResult.engine = {}; + + const engine = enginesParsersList.find(_engine => { + if (typeof _engine.test === 'function') { + return _engine.test(this); + } + + if (_engine.test instanceof Array) { + return _engine.test.some((condition) => { + return this.test(condition); + }); + } + + throw new Error("Browser's test function is not valid"); + }); + + if (engine) { + this.parsedResult.engine = engine.describe(this.getUA()); + } + + return this.parsedResult.engine; + } + /** * Parse full information about the browser */ @@ -221,6 +266,7 @@ class Parser { this._parseBrowser(); this._parseOS(); this._parsePlatform(); + this._parseEngine(); return this; }