リファクタリングなど
This commit is contained in:
@@ -1,29 +1,42 @@
|
||||
import keyCode from './keycode';
|
||||
import { concat } from '../../../prelude/array';
|
||||
|
||||
const getKeyMap = keymap => Object.keys(keymap).map(input => {
|
||||
const result = {} as any;
|
||||
type pattern = {
|
||||
which: string[];
|
||||
ctrl?: boolean;
|
||||
shift?: boolean;
|
||||
alt?: boolean;
|
||||
};
|
||||
|
||||
const { keyup, keydown } = keymap[input];
|
||||
type action = {
|
||||
patterns: pattern[];
|
||||
|
||||
input.split('+').forEach(keyName => {
|
||||
switch (keyName.toLowerCase()) {
|
||||
case 'ctrl':
|
||||
case 'alt':
|
||||
case 'shift':
|
||||
case 'meta':
|
||||
result[keyName] = true;
|
||||
break;
|
||||
default: {
|
||||
result.keyCode = keyCode(keyName);
|
||||
if (!Array.isArray(result.keyCode)) result.keyCode = [result.keyCode];
|
||||
callback: Function;
|
||||
};
|
||||
|
||||
const getKeyMap = keymap => Object.entries(keymap).map(([patterns, callback]): action => {
|
||||
const result = {
|
||||
patterns: [],
|
||||
callback: callback
|
||||
} as action;
|
||||
|
||||
result.patterns = patterns.split('|').map(part => {
|
||||
const pattern = {
|
||||
which: []
|
||||
} as pattern;
|
||||
|
||||
part.trim().split('+').forEach(key => {
|
||||
key = key.trim().toLowerCase();
|
||||
switch (key) {
|
||||
case 'ctrl': pattern.ctrl = true; break;
|
||||
case 'alt': pattern.alt = true; break;
|
||||
case 'shift': pattern.shift = true; break;
|
||||
default: pattern.which = keyCode(key).map(k => k.toLowerCase());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
result.callback = {
|
||||
keydown: keydown || keymap[input],
|
||||
keyup
|
||||
};
|
||||
return pattern;
|
||||
});
|
||||
|
||||
return result;
|
||||
});
|
||||
@@ -36,28 +49,39 @@ export default {
|
||||
bind(el, binding) {
|
||||
el._hotkey_global = binding.modifiers.global === true;
|
||||
|
||||
el._keymap = getKeyMap(binding.value);
|
||||
const actions = getKeyMap(binding.value);
|
||||
|
||||
el.dataset.reservedKeyCodes = el._keymap.map(key => `'${key.keyCode}'`).join(' ');
|
||||
const reservedKeys = concat(actions.map(a => a.patterns.map(p => p.which)));
|
||||
|
||||
el.dataset.reservedKeys = reservedKeys.map(key => `'${key}'`).join(' ');
|
||||
|
||||
el._keyHandler = e => {
|
||||
const reservedKeyCodes = document.activeElement ? ((document.activeElement as any).dataset || {}).reservedKeyCodes || '' : '';
|
||||
const key = e.code.toLowerCase();
|
||||
|
||||
const targetReservedKeys = document.activeElement ? ((document.activeElement as any).dataset || {}).reservedKeys || '' : '';
|
||||
if (document.activeElement && ignoreElemens.some(el => document.activeElement.matches(el))) return;
|
||||
|
||||
for (const hotkey of el._keymap) {
|
||||
if (el._hotkey_global && reservedKeyCodes.includes(`'${e.keyCode}'`)) break;
|
||||
for (const action of actions) {
|
||||
if (el._hotkey_global && targetReservedKeys.includes(`'${key}'`)) break;
|
||||
|
||||
const callback = hotkey.keyCode.includes(e.keyCode) &&
|
||||
!!hotkey.ctrl === e.ctrlKey &&
|
||||
!!hotkey.alt === e.altKey &&
|
||||
!!hotkey.shift === e.shiftKey &&
|
||||
!!hotkey.meta === e.metaKey &&
|
||||
hotkey.callback[e.type];
|
||||
const matched = action.patterns.some(pattern => {
|
||||
let matched = pattern.which.includes(key);
|
||||
if (pattern.ctrl && !e.ctrlKey) matched = false;
|
||||
if (pattern.shift && !e.shiftKey) matched = false;
|
||||
if (pattern.alt && !e.altKey) matched = false;
|
||||
|
||||
if (callback) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
callback(e);
|
||||
if (matched) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
action.callback(e);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (matched) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user