リファクタリングなど

This commit is contained in:
syuilo 2018-09-18 12:34:41 +09:00
parent dc8f592c1f
commit 6ed3f9e414
No known key found for this signature in database
GPG Key ID: BDC4C49D06AB9D69
4 changed files with 78 additions and 154 deletions

View File

@ -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) {
if (matched) {
e.preventDefault();
e.stopPropagation();
callback(e);
action.callback(e);
return true;
} else {
return false;
}
});
if (matched) {
break;
}
}
};

View File

@ -1,116 +1,20 @@
export default searchInput => {
// Keyboard Events
if (searchInput && typeof searchInput === 'object') {
const hasKeyCode = searchInput.which || searchInput.keyCode || searchInput.charCode;
if (hasKeyCode) {
searchInput = hasKeyCode;
export default (input: string): string[] => {
if (Object.keys(aliases).some(a => a.toLowerCase() == input.toLowerCase())) {
const codes = aliases[input];
return Array.isArray(codes) ? codes : [codes];
} else {
return [input];
}
}
// Numbers
// if (typeof searchInput === 'number') {
// return names[searchInput]
// }
// Everything else (cast to string)
const search = String(searchInput);
// check codes
const foundNamedKeyCodes = codes[search.toLowerCase()];
if (foundNamedKeyCodes) {
return foundNamedKeyCodes;
}
// check aliases
const foundNamedKeyAliases = aliases[search.toLowerCase()];
if (foundNamedKeyAliases) {
return foundNamedKeyAliases;
}
// weird character?
if (search.length === 1) {
return search.charCodeAt(0);
}
return undefined;
};
/**
* Get by name
*
* exports.code['enter'] // => 13
*/
export const codes = {
'backspace': 8,
'tab': 9,
'enter': 13,
'shift': 16,
'ctrl': 17,
'alt': 18,
'pause/break': 19,
'caps lock': 20,
'esc': 27,
'space': 32,
'page up': 33,
'page down': 34,
'end': 35,
'home': 36,
'left': 37,
'up': 38,
'right': 39,
'down': 40,
// 'add': 43,
'insert': 45,
'delete': 46,
'command': 91,
'left command': 91,
'right command': 93,
'numpad *': 106,
'numpad plus': [43, 107],
'numpad add': 43, // as a trick
'numpad -': 109,
'numpad .': 110,
'numpad /': 111,
'num lock': 144,
'scroll lock': 145,
'my computer': 182,
'my calculator': 183,
';': 186,
'=': 187,
',': 188,
'-': 189,
'.': 190,
'/': 191,
'`': 192,
'[': 219,
'\\': 220,
']': 221,
"'": 222
};
// Helper aliases
export const aliases = {
'windows': 91,
'⇧': 16,
'⌥': 18,
'⌃': 17,
'⌘': 91,
'ctl': 17,
'control': 17,
'option': 18,
'pause': 19,
'break': 19,
'caps': 20,
'return': 13,
'escape': 27,
'spc': 32,
'pgup': 33,
'pgdn': 34,
'ins': 45,
'del': 46,
'cmd': 91
'esc': 'Escape',
'enter': ['Enter', 'NumpadEnter'],
'up': 'ArrowUp',
'down': 'ArrowDown',
'left': 'ArrowLeft',
'right': 'ArrowRight',
'plus': ['NumpadAdd', 'Semicolon'],
};
/*!
@ -119,15 +23,11 @@ export const aliases = {
// lower case chars
for (let i = 97; i < 123; i++) {
codes[String.fromCharCode(i)] = i - 32;
const char = String.fromCharCode(i);
aliases[char] = `Key${char.toUpperCase()}`;
}
// numbers
for (let i = 48; i < 58; i++) {
codes[i - 48] = [i, (i - 48) + 96];
}
// function keys
for (let i = 1; i < 13; i++) {
codes['f' + i] = i + 111;
for (let i = 0; i < 10; i++) {
aliases[i] = [`Numpad${i}`, `Digit${i}`];
}

View File

@ -72,7 +72,7 @@ export default Vue.extend({
'esc': this.close,
'enter': this.choose,
'space': this.choose,
'numpad plus': this.choose,
'plus': this.choose,
'up': this.focusUp,
'right': this.focusRight,
'down': this.focusDown,

View File

@ -115,7 +115,7 @@ export default Vue.extend({
return {
'r': this.reply,
'a': () => this.react(true),
'numpad plus': () => this.react(true),
'plus': () => this.react(true),
'n': this.renote,
'up': this.focusBefore,
'shift+tab': this.focusBefore,