diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2021-01-16 23:07:21 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-16 23:07:21 -0500 |
commit | 5d9d96996e1b80ecca94023e20476e5e2f85bbff (patch) | |
tree | 3f85be406655768f7378b62aa30795f7ac9deb32 /ext | |
parent | a39eede04ba458b9f198006f62658d9ebb1b970f (diff) |
Optimize hotkey handler to not hook any events if cannot do anything (#1260)
Diffstat (limited to 'ext')
-rw-r--r-- | ext/mixed/js/hotkey-handler.js | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/ext/mixed/js/hotkey-handler.js b/ext/mixed/js/hotkey-handler.js index ef04ea0d..0a9ec81f 100644 --- a/ext/mixed/js/hotkey-handler.js +++ b/ext/mixed/js/hotkey-handler.js @@ -33,6 +33,8 @@ class HotkeyHandler extends EventDispatcher { this._hotkeys = new Map(); this._actions = new Map(); this._eventListeners = new EventListenerCollection(); + this._isPrepared = false; + this._hasEventListeners = false; } /** @@ -53,14 +55,16 @@ class HotkeyHandler extends EventDispatcher { * Begins listening to key press events in order to detect hotkeys. */ prepare() { - this._eventListeners.addEventListener(document, 'keydown', this._onKeyDown.bind(this), false); + this._isPrepared = true; + this._updateEventHandlers(); } /** * Stops listening to key press events. */ cleanup() { - this._eventListeners.removeAllEventListeners(); + this._isPrepared = false; + this._updateEventHandlers(); } /** @@ -93,6 +97,7 @@ class HotkeyHandler extends EventDispatcher { this._registerHotkey(key, modifiers, action); } } + this._updateEventHandlers(); } /** @@ -102,6 +107,31 @@ class HotkeyHandler extends EventDispatcher { this._hotkeys.clear(); } + /** + * Adds a single event listener to a specific event. + * @param eventName The string representing the event's name. + * @param callback The event listener callback to add. + */ + on(eventName, callback) { + const result = super.on(eventName, callback); + this._updateHasEventListeners(); + this._updateEventHandlers(); + return result; + } + + /** + * Removes a single event listener from a specific event. + * @param eventName The string representing the event's name. + * @param callback The event listener callback to add. + * @returns `true` if the callback was removed, `false` otherwise. + */ + off(eventName, callback) { + const result = super.off(eventName, callback); + this._updateHasEventListeners(); + this._updateEventHandlers(); + return result; + } + // Private _onKeyDown(e) { @@ -144,4 +174,17 @@ class HotkeyHandler extends EventDispatcher { } return true; } + + _updateHasEventListeners() { + this._hasEventListeners = this.hasListeners('keydownNonHotkey'); + } + + _updateEventHandlers() { + if (this._isPrepared && (this._hotkeys.size > 0 || this._hasEventListeners)) { + if (this._eventListeners.size !== 0) { return; } + this._eventListeners.addEventListener(document, 'keydown', this._onKeyDown.bind(this), false); + } else { + this._eventListeners.removeAllEventListeners(); + } + } } |