Improve shortcut key detection
This commit is contained in:
parent
ef978a6364
commit
c66155ed48
|
@ -46,6 +46,16 @@ const getKeyMap = keymap => Object.entries(keymap).map(([patterns, callback]): a
|
||||||
|
|
||||||
const ignoreElemens = ['input', 'textarea'];
|
const ignoreElemens = ['input', 'textarea'];
|
||||||
|
|
||||||
|
function match(e: KeyboardEvent, patterns: action['patterns']): boolean {
|
||||||
|
const key = e.code.toLowerCase();
|
||||||
|
return patterns.some(pattern => pattern.which.includes(key) &&
|
||||||
|
pattern.ctrl == e.ctrlKey &&
|
||||||
|
pattern.shift == e.shiftKey &&
|
||||||
|
pattern.alt == e.altKey &&
|
||||||
|
e.metaKey == false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install(Vue) {
|
install(Vue) {
|
||||||
Vue.directive('hotkey', {
|
Vue.directive('hotkey', {
|
||||||
|
@ -55,37 +65,27 @@ export default {
|
||||||
const actions = getKeyMap(binding.value);
|
const actions = getKeyMap(binding.value);
|
||||||
|
|
||||||
// flatten
|
// flatten
|
||||||
const reservedKeys = concat(concat(actions.map(a => a.patterns.map(p => p.which))));
|
const reservedKeys = concat(actions.map(a => a.patterns));
|
||||||
|
|
||||||
el.dataset.reservedKeys = reservedKeys.map(key => `'${key}'`).join(' ');
|
el.dataset.reservedKeys = JSON.stringify(reservedKeys);
|
||||||
|
|
||||||
el._keyHandler = (e: KeyboardEvent) => {
|
el._keyHandler = (e: KeyboardEvent) => {
|
||||||
const key = e.code.toLowerCase();
|
const targetReservedKeys = JSON.parse(document.activeElement ? ((document.activeElement as any).dataset || {}).reservedKeys || '[]' : '[]');
|
||||||
|
|
||||||
const targetReservedKeys = document.activeElement ? ((document.activeElement as any).dataset || {}).reservedKeys || '' : '';
|
|
||||||
if (document.activeElement && ignoreElemens.some(el => document.activeElement.matches(el))) return;
|
if (document.activeElement && ignoreElemens.some(el => document.activeElement.matches(el))) return;
|
||||||
|
|
||||||
for (const action of actions) {
|
for (const action of actions) {
|
||||||
if (el._hotkey_global && targetReservedKeys.includes(`'${key}'`)) break;
|
const matched = match(e, action.patterns);
|
||||||
|
|
||||||
const matched = action.patterns.some(pattern => {
|
|
||||||
const matched = pattern.which.includes(key) &&
|
|
||||||
pattern.ctrl == e.ctrlKey &&
|
|
||||||
pattern.shift == e.shiftKey &&
|
|
||||||
pattern.alt == e.altKey &&
|
|
||||||
e.metaKey == false;
|
|
||||||
|
|
||||||
if (matched) {
|
if (matched) {
|
||||||
|
if (el._hotkey_global) {
|
||||||
|
if (match(e, targetReservedKeys)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
action.callback(e);
|
action.callback(e);
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (matched) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue