silex-website-builder-goodevent
Version:
Free and easy website builder for everyone.
87 lines (78 loc) • 2.37 kB
text/typescript
import {SilexNotification} from '../utils/notification';
export interface Shortcut {
label?: string;
id?: string;
key: string;
altKey?: boolean;
ctrlKey?: boolean;
shiftKey?: boolean;
modifiers?: boolean;
input?: boolean;
}
interface ShortcutItem {
s: Shortcut;
cbk: (e: KeyboardEvent) => void;
}
/**
* @class Keyboard
*/
export class Keyboard {
static isInput(target: HTMLElement) {
return !target.tagName ||
// this is in-iframe forwarding case
target.tagName.toUpperCase() === 'INPUT' ||
target.tagName.toUpperCase() === 'TEXTAREA' ||
target.getAttribute('contenteditable') === 'true';
}
shortcuts: Map<string, ShortcutItem[]>;
constructor(doc: Document) {
this.shortcuts = new Map();
doc.addEventListener('keydown', (e) => this.handleKeyDown(e));
}
addShortcut(s: Shortcut, cbk: (p1: Event) => void) {
const key = s.key.toLowerCase();
if (!cbk || !key) {
throw new Error('Can not add shortcut, callback and key are required');
}
if (!this.shortcuts.has(key)) {
this.shortcuts.set(key, []);
}
this.shortcuts.get(key).push({s, cbk});
}
handleKeyDown(e) {
if (!e.defaultPrevented) {
if (SilexNotification.isActive) {
if (e.key === 'Enter') { SilexNotification.close(true); }
if (e.key === 'Escape') { SilexNotification.close(false); }
} else {
const shortcuts = this.getShortcutsFromEvent(e);
if (shortcuts.length > 0) {
shortcuts.forEach((shortcut) => {
shortcut.cbk(e);
});
e.preventDefault();
e.stopPropagation();
}
}
}
}
getShortcutsFromEvent(e): ShortcutItem[] {
const key = e.key.toLowerCase();
if (!this.shortcuts.has(key)) {
return [];
}
const shortcuts = this.shortcuts.get(key);
return shortcuts.filter((shortcut) => {
return (
// accept all modifiers if modifiers is set to false
shortcut.s.modifiers === false || (
// otherwise check the modifiers
!!(shortcut.s.shiftKey) === !!(e.shiftKey) &&
!!(shortcut.s.altKey) === !!(e.altKey) &&
!!(shortcut.s.ctrlKey) === !!(e.ctrlKey)) &&
// not when in an input field
(shortcut.s.input !== false || !Keyboard.isInput(e.target as HTMLElement))
);
});
}
}