diff --git a/src/HotKeyManager.ts b/src/HotKeyManager.ts index 6d80fa8..1971c03 100644 --- a/src/HotKeyManager.ts +++ b/src/HotKeyManager.ts @@ -66,11 +66,19 @@ export class HotKeyManager( hotkeyName: HotkeyName, callback: HotkeyListener>, + order = 100, ) { const { callbacks } = this.hotKeys[hotkeyName]; - callbacks.push(callback); + const callbackElement = { order, callback }; + for (let i = 0; i <= callbacks.length; i++) { + if (i === callbacks.length || callbacks[i].order > order) { + callbacks.splice(i, 0, callbackElement); + break; + } + } + return () => { - const index = callbacks.indexOf(callback); + const index = callbacks.indexOf(callbackElement); if (index > -1) { callbacks.splice(index, 1); } @@ -146,6 +154,10 @@ export class HotKeyManager { + this.clearMap(); + }); } getHotKeysPressedMap() { @@ -198,23 +210,25 @@ export class HotKeyManager[keyof HotkeyConfig], isRepeated: boolean, ) { const pressedEntry = this.hotKeysPressedMap[key]; - this.hotKeys[key].callbacks.forEach((callback) => - callback({ - event, - subKeys: pressedEntry.subKeys, - isPressed: pressedEntry.isPressed, - previous: oldKeyMap, - isRepeated, - }), - ); + this.hotKeys[key].callbacks.some((callback) => { + return ( + callback.callback({ + event, + subKeys: pressedEntry.subKeys, + isPressed: pressedEntry.isPressed, + previous: oldKeyMap, + isRepeated, + }) === true + ); + }); } - private checkHotkeys(event: KeyboardEvent) { + private checkHotkeys(event?: KeyboardEvent) { const hotkeysToTrigger: (keyof HotkeyConfig)[] = []; const oldMap = this.hotKeysPressedMap; @@ -232,21 +246,21 @@ export class HotKeyManager { + const eventKey = event?.key.toLowerCase(); + const hotkeysToTriggerAgain = hotkeysToCheckAffection.filter(([key]) => { const keyDefinition = this.hotKeys[key]; - if (HotKeyManager.checkAffections(keyDefinition.keys, eventKey)) { + if (eventKey && HotKeyManager.checkAffections(keyDefinition.keys, eventKey)) { return true; } return ObjectHelper.values(keyDefinition.subKeys).some((subKeyDefinitions) => { - return HotKeyManager.checkAffections(subKeyDefinitions, eventKey); + return eventKey && HotKeyManager.checkAffections(subKeyDefinitions, eventKey); }); }); hotkeysToTrigger.forEach((key) => this.triggerListenerFor(key, event, oldMap[key], false)); - hotkeysToTroggerAgain.forEach(([key]) => this.triggerListenerFor(key, event, oldMap[key], true)); + hotkeysToTriggerAgain.forEach(([key]) => this.triggerListenerFor(key, event, oldMap[key], true)); } - private clearMap(event: KeyboardEvent) { + private clearMap(event?: KeyboardEvent) { this.keyPressedMap.clear(); this.checkHotkeys(event); } diff --git a/src/HotkeyEntry.ts b/src/HotkeyEntry.ts index 74c50ea..36a0a69 100644 --- a/src/HotkeyEntry.ts +++ b/src/HotkeyEntry.ts @@ -4,5 +4,5 @@ import { HotkeyListener } from './HotkeyListener'; export type HotkeyEntry = { keys: HotkeyDefinitionType[]; subKeys: { [key in SubKeys]: HotkeyDefinitionType[] }; - callbacks: HotkeyListener[]; + callbacks: { order: number; callback: HotkeyListener }[]; }; diff --git a/src/HotkeyListener.ts b/src/HotkeyListener.ts index 163d476..7c26da8 100644 --- a/src/HotkeyListener.ts +++ b/src/HotkeyListener.ts @@ -1,5 +1,5 @@ export type HotkeyListenerEvent = { - event: KeyboardEvent; + event: KeyboardEvent | undefined; subKeys: Record; isPressed: boolean; previous: { @@ -9,4 +9,6 @@ export type HotkeyListenerEvent = { isRepeated: boolean; }; -export type HotkeyListener = (ev: HotkeyListenerEvent) => unknown; +export type HotkeyListener = ( + ev: HotkeyListenerEvent, +) => unknown | boolean;