/** * Browsers' descriptors * * The idea of descriptors is simple. You should know about them two simple things: * 1. Every descriptor has a method or property called `test` and a `describe` method. * 2. Order of descriptors is important. * * More details: * 1. Method or property `test` serves as a way to detect whether the UA string * matches some certain browser or not. The `describe` method helps to make a result * object with params that show some browser-specific things: name, version, etc. * 2. Order of descriptors is important because a Parser goes through them one by one * in course. For example, if you insert Chrome's descriptor as the first one, * more then a half of browsers will be described as Chrome, because they will pass * the Chrome descriptor's test. * * Descriptor's `test` could be a property with an array of RegExps, where every RegExp * will be applied to a UA string to test it whether it matches or not. * If a descriptor has two or more regexps in the `test` array it tests them one by one * with a logical sum operation. Parser stops if it has found any RegExp that matches the UA. * * Or `test` could be a method. In that case it gets a Parser instance and should * return true/false to get the Parser know if this browser descriptor matches the UA or not. */ import { getFirstMatch, getSecondMatch, } from './utils'; const commonVersionIdentifier = /version\/(\d+(\.?_?\d+)+)/i; const browsersList = [ /* Opera < 13.0 */ { test: [/opera/i], describe(ua) { const browser = { name: 'Opera', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/(?:opera)[\s/](\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, /* Opera > 13.0 */ { test: [/opr|opios/i], describe(ua) { const browser = { name: 'Opera', }; const version = getFirstMatch(/(?:opr|opios)[\s/](\S+)/i, ua) || getFirstMatch(commonVersionIdentifier, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/SamsungBrowser/i], describe(ua) { const browser = { name: 'Samsung Internet for Android', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/(?:SamsungBrowser)[\s/](\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/Whale/i], describe(ua) { const browser = { name: 'NAVER Whale Browser', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/(?:whale)[\s/](\d+(?:\.\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/MZBrowser/i], describe(ua) { const browser = { name: 'MZ Browser', }; const version = getFirstMatch(/(?:MZBrowser)[\s/](\d+(?:\.\d+)+)/i, ua) || getFirstMatch(commonVersionIdentifier, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/focus/i], describe(ua) { const browser = { name: 'Focus', }; const version = getFirstMatch(/(?:focus)[\s/](\d+(?:\.\d+)+)/i, ua) || getFirstMatch(commonVersionIdentifier, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/coast/i], describe(ua) { const browser = { name: 'Opera Coast', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/(?:coast)[\s/](\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/yabrowser/i], describe(ua) { const browser = { name: 'Yandex Browser', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/(?:yabrowser)[\s/](\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/ucbrowser/i], describe(ua) { const browser = { name: 'UC Browser', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/(?:ucbrowser)[\s/](\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/mxios/i], describe(ua) { const browser = { name: 'Maxthon', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/(?:mxios)[\s/](\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/epiphany/i], describe(ua) { const browser = { name: 'Epiphany', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/(?:epiphany)[\s/](\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/puffin/i], describe(ua) { const browser = { name: 'Puffin', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/(?:puffin)[\s/](\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/sleipnir/i], describe(ua) { const browser = { name: 'Sleipnir', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/(?:sleipnir)[\s/](\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/k-meleon/i], describe(ua) { const browser = { name: 'K-Meleon', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/(?:k-meleon)[\s/](\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/msie|trident/i], describe(ua) { const browser = { name: 'Internet Explorer', }; const version = getFirstMatch(/(?:msie |rv:)(\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/edg([ea]|ios)/i], describe(ua) { const browser = { name: 'Microsoft Edge', }; const version = getSecondMatch(/edg([ea]|ios)\/(\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/vivaldi/i], describe(ua) { const browser = { name: 'Vivaldi', }; const version = getFirstMatch(/vivaldi\/(\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/seamonkey/i], describe(ua) { const browser = { name: 'SeaMonkey', }; const version = getFirstMatch(/seamonkey\/(\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/sailfish/i], describe(ua) { const browser = { name: 'Sailfish', }; const version = getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/silk/i], describe(ua) { const browser = { name: 'Amazon Silk', }; const version = getFirstMatch(/silk\/(\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/phantom/i], describe(ua) { const browser = { name: 'PhantomJS', }; const version = getFirstMatch(/phantomjs\/(\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/slimerjs/i], describe(ua) { const browser = { name: 'SlimerJS', }; const version = getFirstMatch(/slimerjs\/(\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/blackberry|\bbb\d+/i, /rim\stablet/i], describe(ua) { const browser = { name: 'BlackBerry', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/blackberry[\d]+\/(\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/(web|hpw)[o0]s/i], describe(ua) { const browser = { name: 'WebOS Browser', }; const version = getFirstMatch(commonVersionIdentifier, ua) || getFirstMatch(/w(?:eb)?[o0]sbrowser\/(\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/bada/i], describe(ua) { const browser = { name: 'Bada', }; const version = getFirstMatch(/dolfin\/(\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/tizen/i], describe(ua) { const browser = { name: 'Tizen', }; const version = getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.?_?\d+)+)/i, ua) || getFirstMatch(commonVersionIdentifier, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/qupzilla/i], describe(ua) { const browser = { name: 'QupZilla', }; const version = getFirstMatch(/(?:qupzilla)[\s/](\d+(\.?_?\d+)+)/i, ua) || getFirstMatch(commonVersionIdentifier, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/firefox|iceweasel|fxios/i], describe(ua) { const browser = { name: 'Firefox', }; const version = getFirstMatch(/(?:firefox|iceweasel|fxios)[\s/](\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/chromium/i], describe(ua) { const browser = { name: 'Chromium', }; const version = getFirstMatch(/(?:chromium)[\s/](\d+(\.?_?\d+)+)/i, ua) || getFirstMatch(commonVersionIdentifier, ua); if (version) { browser.version = version; } return browser; }, }, { test: [/chrome|crios|crmo/i], describe(ua) { const browser = { name: 'Chrome', }; const version = getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.?_?\d+)+)/i, ua); if (version) { browser.version = version; } return browser; }, }, /* Android Browser */ { test(parser) { const notLikeAndroid = !parser.test(/like android/i); const butAndroid = parser.test(/android/i); return notLikeAndroid && butAndroid; }, describe(ua) { const browser = { name: 'Android Browser', }; const version = getFirstMatch(commonVersionIdentifier, ua); if (version) { browser.version = version; } return browser; }, }, /* Safari */ { test: [/safari|applewebkit/i], describe(ua) { const browser = { name: 'Safari', }; const version = getFirstMatch(commonVersionIdentifier, ua); if (version) { browser.version = version; } return browser; }, }, /* Googlebot */ { test: [/googlebot/i], describe(ua) { const browser = { name: 'Googlebot', }; const version = getFirstMatch(/googlebot\/(\d+(\.\d+))/i, ua) || getFirstMatch(commonVersionIdentifier, ua); if (version) { browser.version = version; } return browser; }, }, /* Something else */ { test: [/.*/i], describe(ua) { return { name: getFirstMatch(/^(.*)\/(.*) /, ua), version: getSecondMatch(/^(.*)\/(.*) /, ua), }; }, }, ]; export default browsersList;