summaryrefslogtreecommitdiffstats
path: root/devtools/client/responsive/utils/ua.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/responsive/utils/ua.js')
-rw-r--r--devtools/client/responsive/utils/ua.js129
1 files changed, 129 insertions, 0 deletions
diff --git a/devtools/client/responsive/utils/ua.js b/devtools/client/responsive/utils/ua.js
new file mode 100644
index 0000000000..70c99c552d
--- /dev/null
+++ b/devtools/client/responsive/utils/ua.js
@@ -0,0 +1,129 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const BROWSERS = [
+ {
+ name: "Firefox",
+ mustContain: new RegExp(`(?:Firefox|FxiOS)\/(${getVersionRegex(1, 1)})`),
+ },
+ {
+ name: "Opera",
+ mustContain: new RegExp(`(?:OPR|Opera)\/(${getVersionRegex(1, 1)})`),
+ },
+ {
+ name: "Safari",
+ mustContain: new RegExp(`Version\/(${getVersionRegex(1, 1)}).+Safari`),
+ mustNotContain: new RegExp("Chrome|Chromium"),
+ },
+ {
+ name: "Edge",
+ mustContain: new RegExp(`Edge\/(${getVersionRegex(0, 1)})`),
+ },
+ {
+ name: "Chrome",
+ mustContain: new RegExp(`(?:Chrome|CriOS)\/(${getVersionRegex(1, 1)})`),
+ },
+ {
+ name: "IE",
+ mustContain: new RegExp(`MSIE (${getVersionRegex(1, 1)})`),
+ },
+];
+
+const OSES = [
+ {
+ name: "iOS",
+ minMinorVersionCount: 0,
+ mustContain: new RegExp(`CPU iPhone OS (${getVersionRegex(0, 2)})`),
+ },
+ {
+ name: "iPadOS",
+ minMinorVersionCount: 0,
+ mustContain: new RegExp(`CPU OS (${getVersionRegex(0, 2)})`),
+ },
+ {
+ name: "Windows Phone",
+ minMinorVersionCount: 1,
+ mustContain: new RegExp(`Windows Phone (${getVersionRegex(1, 2)})`),
+ },
+ {
+ name: "Chrome OS",
+ minMinorVersionCount: 1,
+ mustContain: new RegExp(`CrOS .+ (${getVersionRegex(1, 2)})`),
+ },
+ {
+ name: "Android",
+ minMinorVersionCount: 0,
+ mustContain: new RegExp(`Android (${getVersionRegex(0, 2)})`),
+ },
+ {
+ name: "Windows NT",
+ minMinorVersionCount: 1,
+ mustContain: new RegExp(`Windows NT (${getVersionRegex(1, 2)})`),
+ },
+ {
+ name: "Mac OSX",
+ minMinorVersionCount: 1,
+ mustContain: new RegExp(`Intel Mac OS X (${getVersionRegex(1, 2)})`),
+ },
+ {
+ name: "Linux",
+ mustContain: new RegExp("Linux"),
+ },
+];
+
+function getVersionRegex(minMinorVersionCount, maxMinorVersionCount) {
+ return `\\d+(?:[._][0-9a-z]+){${minMinorVersionCount},${maxMinorVersionCount}}`;
+}
+
+function detect(ua, dataset) {
+ for (const {
+ name,
+ mustContain,
+ mustNotContain,
+ minMinorVersionCount,
+ } of dataset) {
+ const result = mustContain.exec(ua);
+
+ if (!result) {
+ continue;
+ }
+
+ if (mustNotContain && mustNotContain.test(ua)) {
+ continue;
+ }
+
+ let version = null;
+
+ if (result && result.length === 2) {
+ // Remove most minor version if that expresses 0.
+ let parts = result[1].match(/([0-9a-z]+)/g);
+ parts = parts.reverse();
+ const validVersionIndex = parts.findIndex(
+ part => parseInt(part, 10) !== 0
+ );
+ if (validVersionIndex !== -1) {
+ parts = parts.splice(validVersionIndex);
+ for (let i = 0; i < minMinorVersionCount + 1 - parts.length; i++) {
+ parts.unshift(0);
+ }
+ }
+ version = parts.reverse().join(".");
+ }
+
+ return { name, version };
+ }
+
+ return null;
+}
+
+function parseUserAgent(ua) {
+ return {
+ browser: detect(ua, BROWSERS),
+ os: detect(ua, OSES),
+ };
+}
+
+module.exports = { parseUserAgent };