Skip to content

Instantly share code, notes, and snippets.

@stipsan
Created April 23, 2022 20:11
Show Gist options
  • Save stipsan/45adc10350e749bf7c8a15e27a194722 to your computer and use it in GitHub Desktop.
Save stipsan/45adc10350e749bf7c8a15e27a194722 to your computer and use it in GitHub Desktop.
Workaround is-hotkey + skypack issue
/**
* Constants.
*/
const IS_MAC = (
typeof window != 'undefined' &&
/Mac|iPod|iPhone|iPad/.test(window.navigator.platform)
)
const MODIFIERS = {
alt: 'altKey',
control: 'ctrlKey',
meta: 'metaKey',
shift: 'shiftKey',
}
const ALIASES = {
add: '+',
break: 'pause',
cmd: 'meta',
command: 'meta',
ctl: 'control',
ctrl: 'control',
del: 'delete',
down: 'arrowdown',
esc: 'escape',
ins: 'insert',
left: 'arrowleft',
mod: IS_MAC ? 'meta' : 'control',
opt: 'alt',
option: 'alt',
return: 'enter',
right: 'arrowright',
space: ' ',
spacebar: ' ',
up: 'arrowup',
win: 'meta',
windows: 'meta',
}
const CODES = {
backspace: 8,
tab: 9,
enter: 13,
shift: 16,
control: 17,
alt: 18,
pause: 19,
capslock: 20,
escape: 27,
' ': 32,
pageup: 33,
pagedown: 34,
end: 35,
home: 36,
arrowleft: 37,
arrowup: 38,
arrowright: 39,
arrowdown: 40,
insert: 45,
delete: 46,
meta: 91,
numlock: 144,
scrolllock: 145,
';': 186,
'=': 187,
',': 188,
'-': 189,
'.': 190,
'/': 191,
'`': 192,
'[': 219,
'\\': 220,
']': 221,
'\'': 222,
}
for (var f = 1; f < 20; f++) {
CODES['f' + f] = 111 + f
}
/**
* Is hotkey?
*/
function isHotkey(hotkey, options, event) {
if (options && !('byKey' in options)) {
event = options
options = null
}
if (!Array.isArray(hotkey)) {
hotkey = [hotkey]
}
const array = hotkey.map(string => parseHotkey(string, options))
const check = e => array.some(object => compareHotkey(object, e))
const ret = event == null ? check : check(event)
return ret
}
function isCodeHotkey(hotkey, event) {
return isHotkey(hotkey, event)
}
function isKeyHotkey(hotkey, event) {
return isHotkey(hotkey, { byKey: true }, event)
}
/**
* Parse.
*/
function parseHotkey(hotkey, options) {
const byKey = options && options.byKey
const ret = {}
// Special case to handle the `+` key since we use it as a separator.
hotkey = hotkey.replace('++', '+add')
const values = hotkey.split('+')
const { length } = values
// Ensure that all the modifiers are set to false unless the hotkey has them.
for (const k in MODIFIERS) {
ret[MODIFIERS[k]] = false
}
for (let value of values) {
const optional = value.endsWith('?') && value.length > 1;
if (optional) {
value = value.slice(0, -1)
}
const name = toKeyName(value)
const modifier = MODIFIERS[name]
if (value.length > 1 && !modifier && !ALIASES[value] && !CODES[name]) {
throw new TypeError(`Unknown modifier: "${value}"`)
}
if (length === 1 || !modifier) {
if (byKey) {
ret.key = name
} else {
ret.which = toKeyCode(value)
}
}
if (modifier) {
ret[modifier] = optional ? null : true
}
}
return ret
}
/**
* Compare.
*/
function compareHotkey(object, event) {
for (const key in object) {
const expected = object[key]
let actual
if (expected == null) {
continue
}
if (key === 'key' && event.key != null) {
actual = event.key.toLowerCase()
} else if (key === 'which') {
actual = expected === 91 && event.which === 93 ? 91 : event.which
} else {
actual = event[key]
}
if (actual == null && expected === false) {
continue
}
if (actual !== expected) {
return false
}
}
return true
}
/**
* Utils.
*/
function toKeyCode(name) {
name = toKeyName(name)
const code = CODES[name] || name.toUpperCase().charCodeAt(0)
return code
}
function toKeyName(name) {
name = name.toLowerCase()
name = ALIASES[name] || name
return name
}
/**
* Export.
*/
export default isHotkey
export {
isHotkey,
isCodeHotkey,
isKeyHotkey,
parseHotkey,
compareHotkey,
toKeyCode,
toKeyName,
}
// TODO: THIS IS THE MONKEYPATCH
Object.assign(isHotkey, {isHotkey, isCodeHotkey, isKeyHotkey, parseHotkey, compareHotkey, toKeyCode, toKeyName})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment