リファクタリングなど
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; | ||||
| 						} | ||||
| 					} | ||||
| 				}; | ||||
|   | ||||
| @@ -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}`]; | ||||
| } | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo