UNPKG

ui-framework-jps

Version:

A simple UI framework for state management and UI components

210 lines 10.5 kB
import debug from 'debug'; import { copyObject } from "../../util/MiscFunctions"; const logger = debug('key-binding-manager'); export class KeyBindingManager { constructor() { this.defaultContextBinding = null; this.currentContextBinding = null; this.contextBindings = []; this.contextStack = []; this.handleKeyBinding = this.handleKeyBinding.bind(this); } static getInstance() { if (!(KeyBindingManager._instance)) { KeyBindingManager._instance = new KeyBindingManager(); } return KeyBindingManager._instance; } onDocumentLoaded() { window.addEventListener('keyup', this.handleKeyBinding); } handleKeyBinding(event) { const key = event.code; if (this.currentContextBinding) { let foundAllBindings = false; let foundIndex = -1; while (!foundAllBindings) { foundIndex = this.currentContextBinding.keyBindings.findIndex((keyBinding, index) => ((keyBinding.keyCode === key) && (index > foundIndex))); if (foundIndex >= 0) { const binding = this.currentContextBinding.keyBindings[foundIndex]; if (event.altKey === binding.altKeyRequired) { if (event.ctrlKey === binding.controlKeyRequired) { if (event.shiftKey === binding.shiftKeyRequired) { if (event.metaKey === binding.metaKeyRequired) { if (binding.receiver) { if (binding.contextName) { event.preventDefault(); event.stopPropagation(); logger(`Key binding activated for context ${binding.contextName} with key ${key} and action ${binding.actionName}`); binding.receiver.keyActionEvent({ actionName: binding.actionName, contextName: binding.contextName }); } } } } } } } else { foundAllBindings = true; } } } } setDefaultKeyBindings(defaultContextBinding) { logger('Setting default key bindings'); defaultContextBinding.contextName = KeyBindingManager.CONTEXT_Default; this.defaultContextBinding = defaultContextBinding; this.resetToDefaultBindings(); this.contextStack.push(KeyBindingManager.CONTEXT_Default); } addContextKeyBindings(contextBinding) { logger(`Adding key bindings for context ${contextBinding.contextName}`); contextBinding.keyBindings.forEach((keyBinding) => { keyBinding.contextName = contextBinding.contextName; keyBinding.receiver = contextBinding.receiver; }); this.contextBindings.push(contextBinding); } activateContext(contextName) { const foundIndex = this.contextBindings.findIndex((binding) => binding.contextName === contextName); if (foundIndex >= 0) { logger(`Activating key bindings for context ${contextName}`); const keyBinding = this.contextBindings[foundIndex]; this.addContextToStackAndKeyBindings(keyBinding); logger(`Activating key bindings for context ${contextName}, stack is now ${this.contextStack}`); } } deactivateContext(contextName) { const foundIndex = this.contextBindings.findIndex((binding) => binding.contextName === contextName); if (foundIndex >= 0) { logger(`Deactivating key bindings for context ${contextName}`); this.removeContextFromStackAndKeyBindings(contextName); } } keyActionEvent(event) { } resetToDefaultBindings() { var _a; if (this.defaultContextBinding) { const defaultReceiver = (_a = this.defaultContextBinding) === null || _a === void 0 ? void 0 : _a.receiver; this.defaultContextBinding.receiver = undefined; this.currentContextBinding = copyObject(this.defaultContextBinding); this.defaultContextBinding.receiver = defaultReceiver; if (this.currentContextBinding) { this.currentContextBinding.receiver = defaultReceiver; if (this.currentContextBinding && this.defaultContextBinding) { this.currentContextBinding.keyBindings.forEach((keyBinding) => { // @ts-ignore keyBinding.contextName = this.currentContextBinding.contextName; // @ts-ignore keyBinding.receiver = this.currentContextBinding.receiver; }); } } } } isSameKeyBinding(keyBinding1, keyBinding2) { let result = false; if (keyBinding1.keyCode === keyBinding2.keyCode) { if (keyBinding1.controlKeyRequired === keyBinding2.controlKeyRequired) { if (keyBinding1.altKeyRequired === keyBinding2.altKeyRequired) { if (keyBinding1.shiftKeyRequired === keyBinding2.shiftKeyRequired) { if (keyBinding1.metaKeyRequired === keyBinding2.metaKeyRequired) { result = true; } } } } } return result; } combineBindings(startingBinding, addOrReplaceWithBinding) { let results = []; let usedKeyBindingsFromReplacementSet = []; logger(`Combining key bindings for contexts ${startingBinding.contextName} and ${addOrReplaceWithBinding.contextName}`); startingBinding.keyBindings.forEach((keyBinding) => { let index = addOrReplaceWithBinding.keyBindings.length - 1; let replaced = false; while (index >= 0) { let addOrReplaceWithBindingKeyBinding = addOrReplaceWithBinding.keyBindings[index]; if (this.isSameKeyBinding(keyBinding, addOrReplaceWithBindingKeyBinding)) { logger(`Context ${addOrReplaceWithBinding.contextName} key binding for key ${addOrReplaceWithBindingKeyBinding.keyCode} replacing context ${startingBinding.contextName}`); replaced = true; usedKeyBindingsFromReplacementSet.push(index); addOrReplaceWithBindingKeyBinding.receiver = addOrReplaceWithBinding.receiver; addOrReplaceWithBindingKeyBinding.contextName = addOrReplaceWithBinding.contextName; results.push(addOrReplaceWithBindingKeyBinding); } index--; } if (!replaced) { keyBinding.receiver = startingBinding.receiver; keyBinding.contextName = startingBinding.contextName; results.push(keyBinding); } }); // add the unused key bindings addOrReplaceWithBinding.keyBindings.forEach((keyBinding, index) => { const foundIndex = usedKeyBindingsFromReplacementSet.findIndex((usedIndex) => usedIndex === index); if (foundIndex < 0) { let addOrReplaceWithBindingKeyBinding = addOrReplaceWithBinding.keyBindings[index]; logger(`Adding new key binding for context ${addOrReplaceWithBinding.contextName} for key ${addOrReplaceWithBindingKeyBinding.keyCode}`); addOrReplaceWithBindingKeyBinding.receiver = addOrReplaceWithBinding.receiver; addOrReplaceWithBindingKeyBinding.contextName = addOrReplaceWithBinding.contextName; results.push(addOrReplaceWithBinding.keyBindings[index]); } }); return results; } addContextToStackAndKeyBindings(keyBinding) { const foundIndex = this.contextStack.findIndex((item) => item === keyBinding.contextName); if (foundIndex < 0) { this.contextStack.push(keyBinding.contextName); if (this.currentContextBinding) { let newKeyBindings = this.combineBindings(this.currentContextBinding, keyBinding); this.currentContextBinding = { keyBindings: newKeyBindings, contextName: '', receiver: this }; } } } getKeyBindingForContext(contextName) { let result = null; const foundIndex = this.contextBindings.findIndex((binding) => binding.contextName === contextName); if (foundIndex >= 0) { result = this.contextBindings[foundIndex]; } return result; } removeContextFromStackAndKeyBindings(contextName) { logger(`Removing key bindings for context ${contextName}`); const foundIndex = this.contextStack.findIndex((stackItem) => stackItem === contextName); if (foundIndex >= 0) { this.contextStack.splice(foundIndex, 1); logger(`Removing key bindings for context ${contextName}, stack is now ${this.contextStack} with length ${this.contextStack.length}`); } this.resetToDefaultBindings(); if (this.contextStack.length > 1) { for (let index = 1; index < this.contextStack.length; index++) { const stackContextName = this.contextStack[index]; const keyBinding = this.getKeyBindingForContext(stackContextName); if (this.currentContextBinding && keyBinding) { logger(`Adding key bindings back in for context ${stackContextName}`); let newKeyBindings = this.combineBindings(this.currentContextBinding, keyBinding); this.currentContextBinding = { keyBindings: newKeyBindings, contextName: '', receiver: this }; } } } } } KeyBindingManager.CONTEXT_Default = 'DEFAULT'; //# sourceMappingURL=KeyBindingManager.js.map