keeweb/app/scripts/comp/browser/key-handler.js

140 lines
4.0 KiB
JavaScript
Raw Normal View History

2019-09-17 19:01:12 +02:00
import { Events } from 'framework/events';
2019-09-15 14:16:32 +02:00
import { IdleTracker } from 'comp/browser/idle-tracker';
import { Keys } from 'const/keys';
2019-10-12 12:26:22 +02:00
import { FocusManager } from 'comp/app/focus-manager';
2015-10-17 23:49:24 +02:00
2017-01-31 07:50:28 +01:00
const shortcutKeyProp = navigator.platform.indexOf('Mac') >= 0 ? 'metaKey' : 'ctrlKey';
2015-10-17 23:49:24 +02:00
2019-09-17 19:01:12 +02:00
class KeyHandler {
2019-09-16 23:32:05 +02:00
SHORTCUT_ACTION = 1;
SHORTCUT_OPT = 2;
SHORTCUT_SHIFT = 4;
2015-10-17 23:49:24 +02:00
2019-09-16 23:32:05 +02:00
shortcuts = {};
2019-08-18 10:17:09 +02:00
init() {
2015-10-17 23:49:24 +02:00
$(document).bind('keypress', this.keypress.bind(this));
$(document).bind('keydown', this.keydown.bind(this));
2019-08-16 23:05:39 +02:00
this.shortcuts[Keys.DOM_VK_A] = [
2019-08-18 08:05:38 +02:00
{
handler: this.handleAKey,
thisArg: this,
shortcut: this.SHORTCUT_ACTION,
modal: true,
noPrevent: true
}
2019-08-16 23:05:39 +02:00
];
2019-09-16 23:32:05 +02:00
}
2019-08-18 10:17:09 +02:00
onKey(key, handler, thisArg, shortcut, modal, noPrevent) {
2017-01-31 07:50:28 +01:00
let keyShortcuts = this.shortcuts[key];
2015-10-17 23:49:24 +02:00
if (!keyShortcuts) {
this.shortcuts[key] = keyShortcuts = [];
}
2019-08-16 23:05:39 +02:00
keyShortcuts.push({
2019-08-18 10:17:09 +02:00
handler,
thisArg,
shortcut,
modal,
noPrevent
2019-08-16 23:05:39 +02:00
});
2019-09-16 23:32:05 +02:00
}
2019-08-18 10:17:09 +02:00
offKey(key, handler, thisArg) {
2015-10-17 23:49:24 +02:00
if (this.shortcuts[key]) {
2019-09-17 23:48:31 +02:00
this.shortcuts[key] = this.shortcuts[key].filter(
2020-06-01 16:53:51 +02:00
(sh) => sh.handler !== handler || sh.thisArg !== thisArg
2019-09-17 23:48:31 +02:00
);
2015-10-17 23:49:24 +02:00
}
2019-09-16 23:32:05 +02:00
}
2019-08-18 10:17:09 +02:00
isActionKey(e) {
2015-10-17 23:49:24 +02:00
return e[shortcutKeyProp];
2019-09-16 23:32:05 +02:00
}
2019-08-18 10:17:09 +02:00
keydown(e) {
2015-11-17 22:49:12 +01:00
IdleTracker.regUserAction();
2017-01-31 07:50:28 +01:00
const code = e.keyCode || e.which;
const keyShortcuts = this.shortcuts[code];
2015-10-17 23:49:24 +02:00
if (keyShortcuts && keyShortcuts.length) {
for (const sh of keyShortcuts) {
2020-03-14 20:29:55 +01:00
if (FocusManager.modal && sh.modal !== FocusManager.modal && sh.modal !== '*') {
2015-10-17 23:49:24 +02:00
e.stopPropagation();
continue;
2015-10-17 23:49:24 +02:00
}
2017-01-31 07:50:28 +01:00
const isActionKey = this.isActionKey(e);
2015-10-17 23:49:24 +02:00
switch (sh.shortcut) {
case this.SHORTCUT_ACTION:
2019-08-16 23:05:39 +02:00
if (!isActionKey) {
continue;
}
2015-10-17 23:49:24 +02:00
break;
case this.SHORTCUT_OPT:
2019-08-16 23:05:39 +02:00
if (!e.altKey) {
continue;
}
2015-10-17 23:49:24 +02:00
break;
2019-09-12 19:59:35 +02:00
case this.SHORTCUT_SHIFT:
if (!e.shiftKey) {
continue;
}
break;
case this.SHORTCUT_ACTION + this.SHORTCUT_OPT:
2019-08-16 23:05:39 +02:00
if (!e.altKey || !isActionKey) {
continue;
}
break;
2015-10-17 23:49:24 +02:00
default:
2019-09-12 19:59:35 +02:00
if (e.metaKey || e.ctrlKey || e.altKey || e.shiftKey) {
2019-08-16 23:05:39 +02:00
continue;
}
2015-10-17 23:49:24 +02:00
break;
}
sh.handler.call(sh.thisArg, e, code);
if (isActionKey && !sh.noPrevent) {
e.preventDefault();
}
if (e.isImmediatePropagationStopped()) {
break;
}
}
2015-10-17 23:49:24 +02:00
}
2019-09-16 23:32:05 +02:00
}
2019-08-18 10:17:09 +02:00
keypress(e) {
2019-08-16 23:05:39 +02:00
if (
2019-10-12 12:26:22 +02:00
!FocusManager.modal &&
2019-09-16 23:32:05 +02:00
e.which !== Keys.DOM_VK_RETURN &&
e.which !== Keys.DOM_VK_ESCAPE &&
e.which !== Keys.DOM_VK_TAB &&
2019-08-16 23:05:39 +02:00
!e.altKey &&
!e.ctrlKey &&
!e.metaKey
) {
2019-09-17 19:01:12 +02:00
Events.emit('keypress', e);
2019-10-12 12:26:22 +02:00
} else if (FocusManager.modal) {
Events.emit('keypress:' + FocusManager.modal, e);
2015-10-17 23:49:24 +02:00
}
2019-09-16 23:32:05 +02:00
}
2019-08-18 10:17:09 +02:00
reg() {
2015-11-17 22:49:12 +01:00
IdleTracker.regUserAction();
2019-09-16 23:32:05 +02:00
}
2019-08-18 10:17:09 +02:00
handleAKey(e) {
2019-08-18 08:05:38 +02:00
if (
e.target.tagName.toLowerCase() === 'input' &&
['password', 'text'].indexOf(e.target.type) >= 0
) {
e.stopImmediatePropagation();
} else {
e.preventDefault();
}
2015-10-17 23:49:24 +02:00
}
2019-09-16 23:32:05 +02:00
}
2015-10-17 23:49:24 +02:00
2019-09-16 23:32:05 +02:00
const instance = new KeyHandler();
2015-10-17 23:49:24 +02:00
2019-09-16 23:32:05 +02:00
export { instance as KeyHandler };