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

121 lines
3.8 KiB
JavaScript
Raw Normal View History

2017-01-31 07:50:28 +01:00
const Backbone = require('backbone');
const Keys = require('../const/keys');
const IdleTracker = require('../comp/idle-tracker');
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
2017-01-31 07:50:28 +01:00
const KeyHandler = {
2015-10-17 23:49:24 +02:00
SHORTCUT_ACTION: 1,
SHORTCUT_OPT: 2,
shortcuts: {},
modal: false,
2015-11-17 22:49:12 +01:00
2015-10-17 23:49:24 +02:00
init: function() {
$(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] = [
{ handler: this.handleAKey, thisArg: this, shortcut: this.SHORTCUT_ACTION, modal: true, noPrevent: true }
];
2015-10-17 23:49:24 +02:00
},
onKey: function(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({
handler: handler,
thisArg: thisArg,
shortcut: shortcut,
modal: modal,
noPrevent: noPrevent
});
2015-10-17 23:49:24 +02:00
},
offKey: function(key, handler, thisArg) {
if (this.shortcuts[key]) {
2016-07-17 13:30:38 +02:00
this.shortcuts[key] = _.reject(this.shortcuts[key], sh => {
2015-10-17 23:49:24 +02:00
return sh.handler === handler && sh.thisArg === thisArg;
});
}
},
setModal: function(modal) {
this.modal = modal;
},
isActionKey: function(e) {
return e[shortcutKeyProp];
},
keydown: function(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) {
2015-10-17 23:49:24 +02:00
if (this.modal && !sh.modal) {
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;
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-08-16 23:05:39 +02:00
if (e.metaKey || e.ctrlKey || e.altKey) {
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
}
},
keypress: function(e) {
2019-08-16 23:05:39 +02:00
if (
!this.modal &&
2015-10-17 23:49:24 +02:00
e.charCode !== Keys.DOM_VK_RETURN &&
e.charCode !== Keys.DOM_VK_ESCAPE &&
e.charCode !== Keys.DOM_VK_TAB &&
2019-08-16 23:05:39 +02:00
!e.altKey &&
!e.ctrlKey &&
!e.metaKey
) {
2015-10-17 23:49:24 +02:00
this.trigger('keypress', e);
2016-07-24 22:57:12 +02:00
} else if (this.modal) {
this.trigger('keypress:' + this.modal, e);
2015-10-17 23:49:24 +02:00
}
2015-11-17 22:49:12 +01:00
},
reg: function() {
IdleTracker.regUserAction();
},
handleAKey: function(e) {
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
}
};
_.extend(KeyHandler, Backbone.Events);
module.exports = KeyHandler;