diff --git a/ts/domtools.classes.keyboard.ts b/ts/domtools.classes.keyboard.ts index 5ebb290..db7bfcd 100644 --- a/ts/domtools.classes.keyboard.ts +++ b/ts/domtools.classes.keyboard.ts @@ -1,3 +1,5 @@ +import * as plugins from './domtools.plugins.js'; + export enum Key { Backspace = 8, Tab = 9, @@ -123,102 +125,96 @@ export enum Key { OpenBracket = 219, ClosedBracket = 221, - Quote = 222 + Quote = 222, } -type KeyCombo = Array - -/** - * @param {KeyboardEvent} event - pressed key event, in case of multi-key combos - * the last pressed key event is passed to this handler - */ -type Handler = (event: KeyboardEvent) => void +type KeyCombo = Array; export class Keyboard { - private mapCombosToHandlers = new Map(); + private mapCombosToHandlers = new Map>(); private pressedKeys = new Set(); - constructor( - private domNode: Element | Document - ) { - this.startListening() + constructor(private domNode: Element | Document) { + this.startListening(); } - on(keys: Key[] | KeyCombo[], callback: Handler) { - const combos = this.toCombos(keys) - - combos.forEach(combo => { - this.registerComboCallback(combo, callback) - }) + public on(keys: Key[] | KeyCombo[]) { + const combos = this.toCombos(keys); + const subject = new plugins.smartrx.rxjs.Subject(); + combos.forEach((combo) => { + this.registerComboCallback(combo, subject); + }); } - startListening() { - this.domNode.addEventListener('keydown', this.handleKeyDown) - this.domNode.addEventListener('keyup', this.handleKeyUp) + public startListening() { + this.domNode.addEventListener('keydown', this.handleKeyDown); + this.domNode.addEventListener('keyup', this.handleKeyUp); } - stopListening() { - this.domNode.removeEventListener('keydown', this.handleKeyDown) - this.domNode.removeEventListener('keyup', this.handleKeyUp) + public stopListening() { + this.domNode.removeEventListener('keydown', this.handleKeyDown); + this.domNode.removeEventListener('keyup', this.handleKeyUp); } - clear() { - this.stopListening() - this.mapCombosToHandlers.clear() - this.pressedKeys.clear() + public clear() { + this.stopListening(); + this.mapCombosToHandlers.clear(); + this.pressedKeys.clear(); } private handleKeyDown = (event: KeyboardEvent) => { - this.pressedKeys.add(event.keyCode) + this.pressedKeys.add(event.keyCode); - this.mapCombosToHandlers.forEach((handlers, combo) => { - if (this.isComboPressed(combo)) { - handlers.forEach(handler => handler(event)) - } - }) - } + this.mapCombosToHandlers.forEach((subjectArg, comboArg) => { + if (this.isComboPressed(comboArg)) { + subjectArg.next(event); + } + }); + }; private handleKeyUp = (event: KeyboardEvent) => { - this.pressedKeys.delete(event.keyCode) - } + this.pressedKeys.delete(event.keyCode); + }; private isComboPressed(combo: number[]) { - let result = true + let result = true; - combo.forEach(key => { - if (!this.pressedKeys.has(key)) { - result = false - } - }) + combo.forEach((key) => { + if (!this.pressedKeys.has(key)) { + result = false; + } + }); - return result + return result; } - private registerComboCallback(combo: Array, callback: Handler) { - if (!this.mapCombosToHandlers.has(combo)) { - this.mapCombosToHandlers.set(combo, []) - } - - const handlers = this.mapCombosToHandlers.get(combo) - - handlers!.push(callback) + private registerComboCallback( + comboArg: Array, + subjectArg: plugins.smartrx.rxjs.Subject + ) { + if (!this.mapCombosToHandlers.has(comboArg)) { + this.mapCombosToHandlers.set(comboArg, subjectArg); + } else { + const subject = this.mapCombosToHandlers.get(comboArg); + return subject; + } } private toCombos(keys: KeyCombo[] | Key[]) { - if (keys.length === 0) { - return [] - } + if (keys.length === 0) { + return []; + } - const isKeys = !Array.isArray(keys[0]) - let combos: KeyCombo[] = [] + const isKeys = !Array.isArray(keys[0]); + let combos: KeyCombo[] = []; - if (isKeys) { - combos = (keys as Key[]).map(key => [key]) - } else { - combos = keys as KeyCombo[] - combos = combos.filter(combo => combo.length > 0) - } + if (isKeys) { + combos = (keys as Key[]).map((key) => [key]); + } else { + combos = keys as KeyCombo[]; + combos = combos.filter((combo) => combo.length > 0); + } - return combos + return combos; } -} \ No newline at end of file +}