2020-09-26 06:02:29 +08:00
|
|
|
|
|
|
|
(win => {
|
|
|
|
|
2021-08-13 16:03:13 +08:00
|
|
|
let
|
|
|
|
scope = {},
|
|
|
|
_scope = 'all';
|
|
|
|
|
2020-09-26 06:02:29 +08:00
|
|
|
const
|
|
|
|
doc = document,
|
2021-08-13 16:03:13 +08:00
|
|
|
// On Mac we use ⌘ else the Ctrl key
|
2020-09-26 06:02:29 +08:00
|
|
|
meta = /Mac OS X/.test(navigator.userAgent) ? 'meta' : 'ctrl',
|
2021-02-20 02:39:04 +08:00
|
|
|
_scopes = {
|
|
|
|
all: {}
|
|
|
|
},
|
2020-09-26 16:20:24 +08:00
|
|
|
toArray = v => Array.isArray(v) ? v : v.split(/\s*,\s*/),
|
2020-09-26 06:02:29 +08:00
|
|
|
|
2022-02-26 00:02:08 +08:00
|
|
|
exec = (event, cmd) => {
|
|
|
|
try {
|
|
|
|
// call the handler and stop the event if neccessary
|
|
|
|
if (!event.defaultPrevented && cmd(event) === false) {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
}
|
|
|
|
},
|
2021-08-13 16:03:13 +08:00
|
|
|
|
|
|
|
shortcuts = {
|
|
|
|
on: () => doc.addEventListener('keydown', keydown),
|
|
|
|
off: () => doc.removeEventListener('keydown', keydown),
|
|
|
|
add: (keys, modifiers, scopes, method) => {
|
2022-02-26 00:02:08 +08:00
|
|
|
if (null == method) {
|
2021-08-13 16:03:13 +08:00
|
|
|
method = scopes;
|
|
|
|
scopes = 'all';
|
|
|
|
}
|
|
|
|
toArray(scopes).forEach(scope => {
|
|
|
|
if (!_scopes[scope]) {
|
|
|
|
_scopes[scope] = {};
|
|
|
|
}
|
|
|
|
toArray(keys).forEach(key => {
|
|
|
|
key = key.toLowerCase();
|
|
|
|
if (!_scopes[scope][key]) {
|
|
|
|
_scopes[scope][key] = {};
|
|
|
|
}
|
|
|
|
modifiers = toArray(modifiers)
|
|
|
|
.map(key => 'meta' == key ? meta : key)
|
|
|
|
.unique().sort().join('+');
|
|
|
|
if (!_scopes[scope][key][modifiers]) {
|
|
|
|
_scopes[scope][key][modifiers] = [];
|
|
|
|
}
|
|
|
|
_scopes[scope][key][modifiers].push(method);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
setScope: value => {
|
|
|
|
_scope = value || 'all';
|
|
|
|
scope = _scopes[_scope] || {};
|
|
|
|
},
|
|
|
|
getScope: () => _scope,
|
|
|
|
getMetaKey: () => 'meta' === meta ? '⌘' : 'Ctrl'
|
|
|
|
},
|
|
|
|
|
2020-10-09 17:58:15 +08:00
|
|
|
keydown = event => {
|
2021-08-13 02:33:13 +08:00
|
|
|
let key = (event.key || '').toLowerCase().replace(' ','space'),
|
2022-03-02 16:26:30 +08:00
|
|
|
modifiers = ['alt','ctrl','meta','shift'].filter(v => event[v+'Key']).join('+');
|
|
|
|
scope[key] && scope[key][modifiers] && scope[key][modifiers].forEach(cmd => exec(event, cmd));
|
|
|
|
!event.defaultPrevented && _scope !== 'all' && _scopes.all[key] && _scopes.all[key][modifiers]
|
|
|
|
&& _scopes.all[key][modifiers].forEach(cmd => exec(event, cmd));
|
2020-09-26 15:34:23 +08:00
|
|
|
};
|
|
|
|
|
2021-08-13 16:03:13 +08:00
|
|
|
win.shortcuts = shortcuts;
|
2020-09-26 06:02:29 +08:00
|
|
|
|
2021-08-13 16:03:13 +08:00
|
|
|
shortcuts.on();
|
2020-09-26 15:34:23 +08:00
|
|
|
|
2020-09-26 06:02:29 +08:00
|
|
|
})(this);
|