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
This commit is contained in:
toasted-nutbread 2021-09-26 18:14:00 -04:00 committed by GitHub
parent d739ccd63f
commit c364714c81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 20 deletions

View File

@ -311,6 +311,22 @@ class DocumentUtil {
return !(browser === 'firefox' || browser === 'firefox-mobile') || os === 'mac'; 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) { static _getActiveButtons(event, array) {
let {buttons} = event; let {buttons} = event;
if (typeof buttons === 'number' && buttons > 0) { if (typeof buttons === 'number' && buttons > 0) {
@ -325,8 +341,6 @@ class DocumentUtil {
} }
} }
// Private
_setImposterStyle(style, propertyName, value) { _setImposterStyle(style, propertyName, value) {
style.setProperty(propertyName, value, 'important'); style.setProperty(propertyName, value, 'important');
} }

View File

@ -153,11 +153,10 @@ class HotkeyHandler extends EventDispatcher {
// Private // Private
_onKeyDown(e) { _onKeyDown(e) {
const key = e.code; const hotkeyInfo = this._hotkeys.get(e.code);
const hotkeyInfo = this._hotkeys.get(key);
if (typeof hotkeyInfo !== 'undefined') { if (typeof hotkeyInfo !== 'undefined') {
const eventModifiers = DocumentUtil.getActiveModifiers(e); const eventModifiers = DocumentUtil.getActiveModifiers(e);
if (this._invokeHandlers(eventModifiers, hotkeyInfo)) { if (this._invokeHandlers(eventModifiers, hotkeyInfo, e.key)) {
e.preventDefault(); e.preventDefault();
return; return;
} }
@ -165,9 +164,9 @@ class HotkeyHandler extends EventDispatcher {
this.trigger('keydownNonHotkey', e); this.trigger('keydownNonHotkey', e);
} }
_invokeHandlers(modifiers, hotkeyInfo) { _invokeHandlers(modifiers, hotkeyInfo, key) {
for (const {modifiers: handlerModifiers, action, argument} of hotkeyInfo.handlers) { 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); const actionHandler = this._actions.get(action);
if (typeof actionHandler !== 'undefined') { if (typeof actionHandler !== 'undefined') {
@ -223,4 +222,16 @@ class HotkeyHandler extends EventDispatcher {
this._eventListeners.removeAllEventListeners(); 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;
}
} }

View File

@ -16,6 +16,7 @@
*/ */
/* global /* global
* DocumentUtil
* PopupMenu * PopupMenu
* SelectorObserver * SelectorObserver
*/ */
@ -155,7 +156,7 @@ class SettingsDisplayController {
_onKeyDown(e) { _onKeyDown(e) {
switch (e.code) { switch (e.code) {
case 'Escape': case 'Escape':
if (!this._isElementAnInput(document.activeElement)) { if (!DocumentUtil.isInputElementFocused()) {
this._closeTopMenuOrModal(); this._closeTopMenuOrModal();
e.preventDefault(); 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) { _setupDeferLoadIframe(element) {
const parent = this._getMoreContainer(element); const parent = this._getMoreContainer(element);
if (parent === null) { return; } if (parent === null) { return; }

View File

@ -263,6 +263,7 @@
<script src="/js/data/anki-util.js"></script> <script src="/js/data/anki-util.js"></script>
<script src="/js/data/permissions-util.js"></script> <script src="/js/data/permissions-util.js"></script>
<script src="/js/dom/document-focus-controller.js"></script> <script src="/js/dom/document-focus-controller.js"></script>
<script src="/js/dom/document-util.js"></script>
<script src="/js/dom/html-template-collection.js"></script> <script src="/js/dom/html-template-collection.js"></script>
<script src="/js/dom/panel-element.js"></script> <script src="/js/dom/panel-element.js"></script>
<script src="/js/dom/popup-menu.js"></script> <script src="/js/dom/popup-menu.js"></script>