From c364714c8188ab1503b53b096a70b1fd5b6b3055 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 26 Sep 2021 18:14:00 -0400 Subject: [PATCH] Fix hotkey input field conflict (#1963) * Move comment * Add DocumentUtil.isInputElement * Use DocumentUtil.isInputElement * Fix simple hotkeys (shift or no modifier) preventing text field input * Improve input detection * Validate key is an input character before blocking hotkey * Simplify * Fix incorrect property --- ext/js/dom/document-util.js | 18 ++++++++++++++-- ext/js/input/hotkey-handler.js | 21 ++++++++++++++----- .../settings/settings-display-controller.js | 15 ++----------- ext/permissions.html | 1 + 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/ext/js/dom/document-util.js b/ext/js/dom/document-util.js index da4d3e61..0338d452 100644 --- a/ext/js/dom/document-util.js +++ b/ext/js/dom/document-util.js @@ -311,6 +311,22 @@ class DocumentUtil { return !(browser === 'firefox' || browser === 'firefox-mobile') || os === 'mac'; } + static isInputElementFocused() { + const element = document.activeElement; + if (element === null) { return false; } + const type = element.nodeName.toUpperCase(); + switch (type) { + case 'INPUT': + case 'TEXTAREA': + case 'SELECT': + return true; + default: + return element.isContentEditable; + } + } + + // Private + static _getActiveButtons(event, array) { let {buttons} = event; if (typeof buttons === 'number' && buttons > 0) { @@ -325,8 +341,6 @@ class DocumentUtil { } } - // Private - _setImposterStyle(style, propertyName, value) { style.setProperty(propertyName, value, 'important'); } diff --git a/ext/js/input/hotkey-handler.js b/ext/js/input/hotkey-handler.js index 8388302d..6c63aebb 100644 --- a/ext/js/input/hotkey-handler.js +++ b/ext/js/input/hotkey-handler.js @@ -153,11 +153,10 @@ class HotkeyHandler extends EventDispatcher { // Private _onKeyDown(e) { - const key = e.code; - const hotkeyInfo = this._hotkeys.get(key); + const hotkeyInfo = this._hotkeys.get(e.code); if (typeof hotkeyInfo !== 'undefined') { const eventModifiers = DocumentUtil.getActiveModifiers(e); - if (this._invokeHandlers(eventModifiers, hotkeyInfo)) { + if (this._invokeHandlers(eventModifiers, hotkeyInfo, e.key)) { e.preventDefault(); return; } @@ -165,9 +164,9 @@ class HotkeyHandler extends EventDispatcher { this.trigger('keydownNonHotkey', e); } - _invokeHandlers(modifiers, hotkeyInfo) { + _invokeHandlers(modifiers, hotkeyInfo, key) { for (const {modifiers: handlerModifiers, action, argument} of hotkeyInfo.handlers) { - if (!this._areSame(handlerModifiers, modifiers)) { continue; } + if (!this._areSame(handlerModifiers, modifiers) || !this._isHotkeyPermitted(modifiers, key)) { continue; } const actionHandler = this._actions.get(action); if (typeof actionHandler !== 'undefined') { @@ -223,4 +222,16 @@ class HotkeyHandler extends EventDispatcher { this._eventListeners.removeAllEventListeners(); } } + + _isHotkeyPermitted(modifiers, key) { + return !( + (modifiers.length === 0 || (modifiers.length === 1 && modifiers[0] === 'shift')) && + DocumentUtil.isInputElementFocused() && + this._isKeyCharacterInput(key) + ); + } + + _isKeyCharacterInput(key) { + return key.length === 1; + } } diff --git a/ext/js/pages/settings/settings-display-controller.js b/ext/js/pages/settings/settings-display-controller.js index 9d3e5459..7a40381b 100644 --- a/ext/js/pages/settings/settings-display-controller.js +++ b/ext/js/pages/settings/settings-display-controller.js @@ -16,6 +16,7 @@ */ /* global + * DocumentUtil * PopupMenu * SelectorObserver */ @@ -155,7 +156,7 @@ class SettingsDisplayController { _onKeyDown(e) { switch (e.code) { case 'Escape': - if (!this._isElementAnInput(document.activeElement)) { + if (!DocumentUtil.isInputElementFocused()) { this._closeTopMenuOrModal(); e.preventDefault(); } @@ -357,18 +358,6 @@ class SettingsDisplayController { } } - _isElementAnInput(element) { - const type = element !== null ? element.nodeName.toUpperCase() : null; - switch (type) { - case 'INPUT': - case 'TEXTAREA': - case 'SELECT': - return true; - default: - return false; - } - } - _setupDeferLoadIframe(element) { const parent = this._getMoreContainer(element); if (parent === null) { return; } diff --git a/ext/permissions.html b/ext/permissions.html index 49daa940..04d1d5fa 100644 --- a/ext/permissions.html +++ b/ext/permissions.html @@ -263,6 +263,7 @@ +