2018-09-09 12:08:48 +00:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< title > parser.js - Documentation< / title >
< script src = "scripts/prettify/prettify.js" > < / script >
< script src = "scripts/prettify/lang-css.js" > < / script >
<!-- [if lt IE 9]>
< script src = "//html5shiv.googlecode.com/svn/trunk/html5.js" > < / script >
<![endif]-->
< link type = "text/css" rel = "stylesheet" href = "styles/prettify.css" >
< link type = "text/css" rel = "stylesheet" href = "styles/jsdoc.css" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< / head >
< body >
< input type = "checkbox" id = "nav-trigger" class = "nav-trigger" / >
< label for = "nav-trigger" class = "navicon-button x" >
< div class = "navicon" > < / div >
< / label >
< label for = "nav-trigger" class = "overlay" > < / label >
< nav >
2019-03-06 12:31:37 +00:00
< h2 > < a href = "index.html" > Home< / a > < / h2 > < h3 > Classes< / h3 > < ul > < li > < a href = "Bowser.html" > Bowser< / a > < ul class = 'methods' > < li data-type = 'method' > < a href = "Bowser.html#.getParser" > getParser< / a > < / li > < li data-type = 'method' > < a href = "Bowser.html#.parse" > parse< / a > < / li > < / ul > < / li > < li > < a href = "Parser.html" > Parser< / a > < ul class = 'methods' > < li data-type = 'method' > < a href = "Parser.html#getBrowser" > getBrowser< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#getBrowserName" > getBrowserName< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#getBrowserVersion" > getBrowserVersion< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#getEngine" > getEngine< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#getEngineName" > getEngineName< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#getOS" > getOS< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#getOSName" > getOSName< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#getOSVersion" > getOSVersion< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#getPlatform" > getPlatform< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#getPlatformType" > getPlatformType< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#getResult" > getResult< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#getUA" > getUA< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#is" > is< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#parse" > parse< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#parseBrowser" > parseBrowser< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#parseEngine" > parseEngine< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#parseOS" > parseOS< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#parsePlatform" > parsePlatform< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#satisfies" > satisfies< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#some" > some< / a > < / li > < li data-type = 'method' > < a href = "Parser.html#test" > test< / a > < / li > < / ul > < / li > < / ul > < h3 > Global< / h3 > < ul > < li > < a href = "global.html#getAndroidVersionName" > getAndroidVersionName< / a > < / li > < li > < a href = "global.html#getFirstMatch" > getFirstMatch< / a > < / li > < li > < a href = "global.html#getSecondMatch" > getSecondMatch< / a > < / li > < li > < a href = "global.html#getVersionPrecision" > getVersionPrecision< / a > < / li > < li > < a href = "global.html#map" > map< / a > < / li > < li > < a href = "global.html#matchAndReturnConst" > matchAndReturnConst< / a > < / li > < / ul >
2018-09-09 12:08:48 +00:00
< / nav >
< div id = "main" >
< h1 class = "page-title" > parser.js< / h1 >
< section >
< article >
2019-03-06 12:31:37 +00:00
< pre class = "prettyprint source linenums" > < code > import browserParsersList from './parser-browsers.js';
import osParsersList from './parser-os.js';
import platformParsersList from './parser-platforms.js';
import enginesParsersList from './parser-engines.js';
import Utils from './utils.js';
2018-07-05 19:44:43 +00:00
/**
* The main class that arranges the whole parsing process.
*/
class Parser {
/**
* Create instance of Parser
*
* @param {String} UA User-Agent string
* @param {Boolean} [skipParsing=false] parser can skip parsing in purpose of performance
* improvements if you need to make a more particular parsing
* like {@link Parser#parseBrowser} or {@link Parser#parsePlatform}
*
* @throw {Error} in case of empty UA String
*
* @constructor
*/
constructor(UA, skipParsing = false) {
if (UA === void (0) || UA === null || UA === '') {
throw new Error("UserAgent parameter can't be empty");
}
this._ua = UA;
/**
* @typedef ParsedResult
* @property {Object} browser
2018-07-08 09:31:23 +00:00
* @property {String|undefined} [browser.name]
* Browser name, like `"Chrome"` or `"Internet Explorer"`
* @property {String|undefined} [browser.version] Browser version as a String `"12.01.45334.10"`
2018-07-05 19:44:43 +00:00
* @property {Object} os
2018-07-08 09:31:23 +00:00
* @property {String|undefined} [os.name] OS name, like `"Windows"` or `"macOS"`
* @property {String|undefined} [os.version] OS version, like `"NT 5.1"` or `"10.11.1"`
* @property {String|undefined} [os.versionName] OS name, like `"XP"` or `"High Sierra"`
2018-07-05 19:44:43 +00:00
* @property {Object} platform
2018-07-08 09:31:23 +00:00
* @property {String|undefined} [platform.type]
* platform type, can be either `"desktop"`, `"tablet"` or `"mobile"`
* @property {String|undefined} [platform.vendor] Vendor of the device,
* like `"Apple"` or `"Samsung"`
* @property {String|undefined} [platform.model] Device model,
* like `"iPhone"` or `"Kindle Fire HD 7"`
2018-07-05 19:44:43 +00:00
* @property {Object} engine
2018-07-08 09:31:23 +00:00
* @property {String|undefined} [engine.name]
* Can be any of this: `WebKit`, `Blink`, `Gecko`, `Trident`, `Presto`, `EdgeHTML`
* @property {String|undefined} [engine.version] String version of the engine
2018-07-05 19:44:43 +00:00
*/
this.parsedResult = {};
if (skipParsing !== true) {
this.parse();
}
}
/**
* Get UserAgent string of current Parser instance
* @return {String} User-Agent String of the current < Parser> object
*
* @public
*/
getUA() {
return this._ua;
}
/**
* Test a UA string for a regexp
* @param {RegExp} regex
* @return {Boolean}
*/
test(regex) {
return regex.test(this._ua);
}
/**
* Get parsed browser object
* @return {Object}
*/
parseBrowser() {
this.parsedResult.browser = {};
const browserDescriptor = browserParsersList.find((_browser) => {
if (typeof _browser.test === 'function') {
return _browser.test(this);
}
if (_browser.test instanceof Array) {
return _browser.test.some(condition => this.test(condition));
}
throw new Error("Browser's test function is not valid");
});
if (browserDescriptor) {
this.parsedResult.browser = browserDescriptor.describe(this.getUA());
}
return this.parsedResult.browser;
}
/**
* Get parsed browser object
* @return {Object}
*
* @public
*/
getBrowser() {
if (this.parsedResult.browser) {
return this.parsedResult.browser;
}
return this.parseBrowser();
}
/**
* Get browser's name
* @return {String} Browser's name or an empty string
*
* @public
*/
getBrowserName(toLowerCase) {
if (toLowerCase) {
return String(this.getBrowser().name).toLowerCase() || '';
}
return this.getBrowser().name || '';
}
/**
* Get browser's version
* @return {String} version of browser
*
* @public
*/
getBrowserVersion() {
return this.getBrowser().version;
}
/**
* Get OS
* @return {Object}
*
* @example
* this.getOS();
* {
* name: 'macOS',
* version: '10.11.12'
* }
*/
getOS() {
if (this.parsedResult.os) {
return this.parsedResult.os;
}
return this.parseOS();
}
/**
* Parse OS and save it to this.parsedResult.os
* @return {*|{}}
*/
parseOS() {
this.parsedResult.os = {};
const os = osParsersList.find((_os) => {
if (typeof _os.test === 'function') {
return _os.test(this);
}
if (_os.test instanceof Array) {
return _os.test.some(condition => this.test(condition));
}
throw new Error("Browser's test function is not valid");
});
if (os) {
this.parsedResult.os = os.describe(this.getUA());
}
return this.parsedResult.os;
}
/**
* Get OS name
* @param {Boolean} [toLowerCase] return lower-cased value
* @return {String} name of the OS — macOS, Windows, Linux, etc.
*/
getOSName(toLowerCase) {
const { name } = this.getOS();
if (toLowerCase) {
return String(name).toLowerCase() || '';
}
return name || '';
}
/**
* Get OS version
* @return {String} full version with dots ('10.11.12', '5.6', etc)
*/
getOSVersion() {
return this.getOS().version;
}
/**
* Get parsed platform
* @return {{}}
*/
getPlatform() {
if (this.parsedResult.platform) {
return this.parsedResult.platform;
}
return this.parsePlatform();
}
/**
* Get platform name
2018-07-08 09:09:27 +00:00
* @param {Boolean} [toLowerCase=false]
2018-07-05 19:44:43 +00:00
* @return {*}
*/
2018-07-08 09:09:27 +00:00
getPlatformType(toLowerCase = false) {
2018-07-05 19:44:43 +00:00
const { type } = this.getPlatform();
if (toLowerCase) {
return String(type).toLowerCase() || '';
}
return type || '';
}
/**
* Get parsed platform
* @return {{}}
*/
parsePlatform() {
this.parsedResult.platform = {};
const platform = platformParsersList.find((_platform) => {
if (typeof _platform.test === 'function') {
return _platform.test(this);
}
if (_platform.test instanceof Array) {
return _platform.test.some(condition => this.test(condition));
}
throw new Error("Browser's test function is not valid");
});
if (platform) {
this.parsedResult.platform = platform.describe(this.getUA());
}
return this.parsedResult.platform;
}
/**
* Get parsed engine
* @return {{}}
*/
getEngine() {
if (this.parsedResult.engine) {
return this.parsedResult.engine;
}
return this.parseEngine();
}
2019-02-14 03:41:45 +00:00
/**
* 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 || '';
}
2018-07-05 19:44:43 +00:00
/**
* Get parsed platform
* @return {{}}
*/
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 => 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
*/
parse() {
this.parseBrowser();
this.parseOS();
this.parsePlatform();
this.parseEngine();
return this;
}
/**
* Get parsed result
* @return {ParsedResult}
*/
getResult() {
2019-01-19 13:44:08 +00:00
return Object.assign({}, this.parsedResult);
2018-07-05 19:44:43 +00:00
}
/**
* Check if parsed browser matches certain conditions
*
* @param {Object} checkTree It's one or two layered object,
* which can include a platform or an OS on the first layer
* and should have browsers specs on the bottom-laying layer
*
2018-07-08 09:09:27 +00:00
* @returns {Boolean|undefined} Whether the browser satisfies the set conditions or not.
* Returns `undefined` when the browser is no described in the checkTree object.
2018-07-05 19:44:43 +00:00
*
* @example
* const browser = new Bowser(UA);
* if (browser.check({chrome: '>118.01.1322' }))
* // or with os
* if (browser.check({windows: { chrome: '>118.01.1322' } }))
* // or with platforms
* if (browser.check({desktop: { chrome: '>118.01.1322' } }))
*/
2018-07-08 09:09:27 +00:00
satisfies(checkTree) {
const platformsAndOSes = {};
let platformsAndOSCounter = 0;
const browsers = {};
let browsersCounter = 0;
const allDefinitions = Object.keys(checkTree);
allDefinitions.forEach((key) => {
const currentDefinition = checkTree[key];
if (typeof currentDefinition === 'string') {
browsers[key] = currentDefinition;
browsersCounter += 1;
} else if (typeof currentDefinition === 'object') {
platformsAndOSes[key] = currentDefinition;
platformsAndOSCounter += 1;
2018-07-05 19:44:43 +00:00
}
});
2018-07-08 09:09:27 +00:00
if (platformsAndOSCounter > 0) {
const platformsAndOSNames = Object.keys(platformsAndOSes);
const OSMatchingDefinition = platformsAndOSNames.find(name => (this.isOS(name)));
if (OSMatchingDefinition) {
const osResult = this.satisfies(platformsAndOSes[OSMatchingDefinition]);
if (osResult !== void 0) {
return osResult;
}
}
const platformMatchingDefinition = platformsAndOSNames.find(name => (this.isPlatform(name)));
if (platformMatchingDefinition) {
const platformResult = this.satisfies(platformsAndOSes[platformMatchingDefinition]);
if (platformResult !== void 0) {
return platformResult;
}
}
}
if (browsersCounter > 0) {
const browserNames = Object.keys(browsers);
const matchingDefinition = browserNames.find(name => (this.isBrowser(name)));
if (matchingDefinition !== void 0) {
return this.compareVersion(browsers[matchingDefinition]);
}
}
return undefined;
2018-07-05 19:44:43 +00:00
}
isBrowser(browserName) {
return this.getBrowserName(true) === String(browserName).toLowerCase();
}
2018-07-08 09:09:27 +00:00
compareVersion(version) {
2019-01-19 13:44:08 +00:00
let expectedResults = [0];
2018-07-05 19:44:43 +00:00
let comparableVersion = version;
2018-08-18 11:14:56 +00:00
let isLoose = false;
2018-07-05 19:44:43 +00:00
2018-09-09 12:08:48 +00:00
const currentBrowserVersion = this.getBrowserVersion();
if (typeof currentBrowserVersion !== 'string') {
return void 0;
}
2019-01-19 13:44:08 +00:00
if (version[0] === '>' || version[0] === '< ') {
2018-07-05 19:44:43 +00:00
comparableVersion = version.substr(1);
2019-01-19 13:44:08 +00:00
if (version[1] === '=') {
isLoose = true;
comparableVersion = version.substr(2);
} else {
expectedResults = [];
}
if (version[0] === '>') {
expectedResults.push(1);
} else {
expectedResults.push(-1);
}
2018-07-05 19:44:43 +00:00
} else if (version[0] === '=') {
comparableVersion = version.substr(1);
2018-08-18 11:14:56 +00:00
} else if (version[0] === '~') {
isLoose = true;
comparableVersion = version.substr(1);
2018-07-05 19:44:43 +00:00
}
2018-08-18 11:14:56 +00:00
2019-01-19 13:44:08 +00:00
return expectedResults.indexOf(
2019-03-06 12:31:37 +00:00
Utils.compareVersions(currentBrowserVersion, comparableVersion, isLoose),
2019-01-19 13:44:08 +00:00
) > -1;
2018-07-05 19:44:43 +00:00
}
2018-07-08 09:09:27 +00:00
isOS(osName) {
2018-07-05 19:44:43 +00:00
return this.getOSName(true) === String(osName).toLowerCase();
}
isPlatform(platformType) {
return this.getPlatformType(true) === String(platformType).toLowerCase();
}
2019-02-14 03:41:45 +00:00
isEngine(engineName) {
return this.getEngineName(true) === String(engineName).toLowerCase();
}
2018-07-05 19:44:43 +00:00
/**
* Is anything? Check if the browser is called "anything",
* the OS called "anything" or the platform called "anything"
* @param {String} anything
* @returns {Boolean}
*/
is(anything) {
2018-07-08 09:09:27 +00:00
return this.isBrowser(anything) || this.isOS(anything) || this.isPlatform(anything);
2018-07-05 19:44:43 +00:00
}
2018-07-22 16:42:46 +00:00
/**
2019-01-19 13:44:08 +00:00
* Check if any of the given values satisfies this.is(anything)
2018-07-22 16:42:46 +00:00
* @param {String[]} anythings
* @returns {Boolean}
*/
some(anythings = []) {
return anythings.some(anything => this.is(anything));
}
2018-07-05 19:44:43 +00:00
}
export default Parser;
2018-09-09 12:08:48 +00:00
< / code > < / pre >
< / article >
< / section >
< / div >
< br class = "clear" >
< footer >
2019-03-06 12:31:37 +00:00
Documentation generated by < a href = "https://github.com/jsdoc3/jsdoc" > JSDoc 3.5.5< / a > on Wed Mar 06 2019 14:31:23 GMT+0200 (EET) using the < a href = "https://github.com/clenemt/docdash" > docdash< / a > theme.
2018-09-09 12:08:48 +00:00
< / footer >
< script > prettyPrint ( ) ; < / script >
< script src = "scripts/linenumber.js" > < / script >
< / body >
< / html >