From 36fc5abae543840484b3d8f7abff85f57de66ada Mon Sep 17 00:00:00 2001
From: toasted-nutbread <toasted-nutbread@users.noreply.github.com>
Date: Tue, 8 Sep 2020 10:53:41 -0400
Subject: Modifier key refactor (#784)

* Add functions for getting keyboard key information

* Use os + DocumentUtil to get modifier key names

* Remove keyboard modifier info from environment info
---
 ext/bg/js/settings/keyboard-mouse-input-field.js |  8 ++--
 ext/bg/js/settings/main.js                       |  9 ++--
 ext/bg/js/settings/profile-conditions-ui.js      | 17 ++++---
 ext/bg/js/settings/profiles.js                   |  4 +-
 ext/mixed/js/document-util.js                    | 40 ++++++++++++++++
 ext/mixed/js/environment.js                      | 61 +-----------------------
 6 files changed, 60 insertions(+), 79 deletions(-)

diff --git a/ext/bg/js/settings/keyboard-mouse-input-field.js b/ext/bg/js/settings/keyboard-mouse-input-field.js
index d1dc76e0..b1530c1b 100644
--- a/ext/bg/js/settings/keyboard-mouse-input-field.js
+++ b/ext/bg/js/settings/keyboard-mouse-input-field.js
@@ -20,18 +20,18 @@
  */
 
 class KeyboardMouseInputField extends EventDispatcher {
-    constructor(inputNode, mouseButton, inputNameMap, keySeparator) {
+    constructor(inputNode, mouseButton, os) {
         super();
         this._inputNode = inputNode;
-        this._keySeparator = keySeparator;
+        this._mouseButton = mouseButton;
+        this._keySeparator = ' + ';
+        this._inputNameMap = new Map(DocumentUtil.getModifierKeys(os));
         this._keyPriorities = new Map([
             ['meta', -4],
             ['ctrl', -3],
             ['alt', -2],
             ['shift', -1]
         ]);
-        this._mouseButton = mouseButton;
-        this._inputNameMap = inputNameMap;
         this._mouseInputNamePattern = /^mouse(\d+)$/;
         this._eventListeners = new EventListenerCollection();
         this._value = '';
diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js
index b29744ac..f775cd57 100644
--- a/ext/bg/js/settings/main.js
+++ b/ext/bg/js/settings/main.js
@@ -22,6 +22,7 @@
  * ClipboardPopupsController
  * DictionaryController
  * DictionaryImportController
+ * DocumentUtil
  * GenericSettingController
  * PopupPreviewController
  * ProfileController
@@ -43,12 +44,12 @@ async function settingsPopulateModifierKeys() {
     const scanModifierKeySelect = document.querySelector('#scan-modifier-key');
     scanModifierKeySelect.textContent = '';
 
-    const environment = await api.getEnvironmentInfo();
+    const {platform: {os}} = await api.getEnvironmentInfo();
     const modifierKeys = [
-        {value: 'none', name: 'None'},
-        ...environment.modifiers.keys
+        ['none', 'None'],
+        DocumentUtil.getModifierKeys(os)
     ];
-    for (const {value, name} of modifierKeys) {
+    for (const [value, name] of modifierKeys) {
         const option = document.createElement('option');
         option.value = value;
         option.textContent = name;
diff --git a/ext/bg/js/settings/profile-conditions-ui.js b/ext/bg/js/settings/profile-conditions-ui.js
index 4fb181cf..d88f932b 100644
--- a/ext/bg/js/settings/profile-conditions-ui.js
+++ b/ext/bg/js/settings/profile-conditions-ui.js
@@ -22,8 +22,7 @@
 class ProfileConditionsUI {
     constructor(settingsController) {
         this._settingsController = settingsController;
-        this._keySeparator = '';
-        this._keyNames = new Map();
+        this._os = null;
         this._conditionGroupsContainer = null;
         this._addConditionGroupButton = null;
         this._children = [];
@@ -80,12 +79,12 @@ class ProfileConditionsUI {
         return this._settingsController.profileIndex;
     }
 
-    setKeyInfo(separator, keyNames) {
-        this._keySeparator = separator;
-        this._keyNames.clear();
-        for (const {value, name} of keyNames) {
-            this._keyNames.set(value, name);
-        }
+    get os() {
+        return this._os;
+    }
+
+    set os(value) {
+        this._os = value;
     }
 
     prepare(conditionGroups) {
@@ -209,7 +208,7 @@ class ProfileConditionsUI {
     }
 
     createKeyboardMouseInputField(inputNode, mouseButton) {
-        return new KeyboardMouseInputField(inputNode, mouseButton, this._keyNames, this._keySeparator);
+        return new KeyboardMouseInputField(inputNode, mouseButton, this._os);
     }
 
     // Private
diff --git a/ext/bg/js/settings/profiles.js b/ext/bg/js/settings/profiles.js
index c1961e20..6cd95d9c 100644
--- a/ext/bg/js/settings/profiles.js
+++ b/ext/bg/js/settings/profiles.js
@@ -47,8 +47,8 @@ class ProfileController {
     // Private
 
     async _onOptionsChanged() {
-        const {modifiers} = await api.getEnvironmentInfo();
-        this._profileConditionsUI.setKeyInfo(modifiers.separator, modifiers.keys);
+        const {platform: {os}} = await api.getEnvironmentInfo();
+        this._profileConditionsUI.os = os;
 
         const optionsFull = await this._settingsController.getOptionsFullMutable();
         this._formWrite(optionsFull);
diff --git a/ext/mixed/js/document-util.js b/ext/mixed/js/document-util.js
index ba39942d..0b72ff9a 100644
--- a/ext/mixed/js/document-util.js
+++ b/ext/mixed/js/document-util.js
@@ -259,6 +259,46 @@ class DocumentUtil {
         return false;
     }
 
+    static getModifierKeys(os) {
+        switch (os) {
+            case 'win':
+                return [
+                    ['alt', 'Alt'],
+                    ['ctrl', 'Ctrl'],
+                    ['shift', 'Shift'],
+                    ['meta', 'Windows']
+                ];
+            case 'mac':
+                return [
+                    ['alt', 'Opt'],
+                    ['ctrl', 'Ctrl'],
+                    ['shift', 'Shift'],
+                    ['meta', 'Cmd']
+                ];
+            case 'linux':
+            case 'openbsd':
+            case 'cros':
+            case 'android':
+                return [
+                    ['alt', 'Alt'],
+                    ['ctrl', 'Ctrl'],
+                    ['shift', 'Shift'],
+                    ['meta', 'Super']
+                ];
+            default: // 'unknown', etc
+                return [
+                    ['alt', 'Alt'],
+                    ['ctrl', 'Ctrl'],
+                    ['shift', 'Shift'],
+                    ['meta', 'Meta']
+                ];
+        }
+    }
+
+    static isMetaKeySupported(os, browser) {
+        return !(browser === 'firefox' || browser === 'firefox-mobile') || os === 'mac';
+    }
+
     // Private
 
     _setImposterStyle(style, propertyName, value) {
diff --git a/ext/mixed/js/environment.js b/ext/mixed/js/environment.js
index 1f4038d2..3ed9f5cf 100644
--- a/ext/mixed/js/environment.js
+++ b/ext/mixed/js/environment.js
@@ -33,11 +33,9 @@ class Environment {
     async _loadEnvironmentInfo() {
         const browser = await this._getBrowser();
         const os = await this._getOperatingSystem();
-        const modifierInfo = this._getModifierInfo(browser, os);
         return {
             browser,
-            platform: {os},
-            modifiers: modifierInfo
+            platform: {os}
         };
     }
 
@@ -91,61 +89,4 @@ class Environment {
             return 'chrome';
         }
     }
-
-    _getModifierInfo(browser, os) {
-        let osKeys;
-        let separator;
-        switch (os) {
-            case 'win':
-                separator = ' + ';
-                osKeys = [
-                    ['alt', 'Alt'],
-                    ['ctrl', 'Ctrl'],
-                    ['shift', 'Shift'],
-                    ['meta', 'Windows']
-                ];
-                break;
-            case 'mac':
-                separator = '';
-                osKeys = [
-                    ['alt', '⌥'],
-                    ['ctrl', '⌃'],
-                    ['shift', '⇧'],
-                    ['meta', '⌘']
-                ];
-                break;
-            case 'linux':
-            case 'openbsd':
-            case 'cros':
-            case 'android':
-                separator = ' + ';
-                osKeys = [
-                    ['alt', 'Alt'],
-                    ['ctrl', 'Ctrl'],
-                    ['shift', 'Shift'],
-                    ['meta', 'Super']
-                ];
-                break;
-            default: // 'unknown', etc
-                separator = ' + ';
-                osKeys = [
-                    ['alt', 'Alt'],
-                    ['ctrl', 'Ctrl'],
-                    ['shift', 'Shift'],
-                    ['meta', 'Meta']
-                ];
-                break;
-        }
-
-        const isFirefox = (browser === 'firefox' || browser === 'firefox-mobile');
-        const keys = [];
-
-        for (const [value, name] of osKeys) {
-            // Firefox doesn't support event.metaKey on platforms other than macOS
-            if (value === 'meta' && isFirefox && os !== 'mac') { continue; }
-            keys.push({value, name});
-        }
-
-        return {keys, separator};
-    }
 }
-- 
cgit v1.2.3