UNPKG

hotkeys-js

Version:

A simple micro-library for defining and dispatching keyboard shortcuts. It has no dependencies.

1 lines 40.2 kB
{"version":3,"file":"hotkeys-js.umd.cjs","sources":["../src/utils.ts","../src/var.ts","../src/index.ts"],"sourcesContent":["const isff: boolean =\n typeof navigator !== 'undefined'\n ? navigator.userAgent.toLowerCase().indexOf('firefox') > 0\n : false;\n\n/** Bind event */\nfunction addEvent(\n object: HTMLElement | Document | Window,\n event: string,\n method: EventListenerOrEventListenerObject,\n useCapture?: boolean\n): void {\n if (object.addEventListener) {\n object.addEventListener(event, method, useCapture);\n // @ts-expect-error - attachEvent is only available on IE\n } else if (object.attachEvent) {\n // @ts-expect-error - attachEvent is only available on IE\n object.attachEvent(`on${event}`, method);\n }\n}\n\nfunction removeEvent(\n object: HTMLElement | Document | Window | null,\n event: string,\n method: EventListenerOrEventListenerObject,\n useCapture?: boolean\n): void {\n if (!object) return;\n if (object.removeEventListener) {\n object.removeEventListener(event, method, useCapture);\n // @ts-expect-error - removeEvent is only available on IE\n } else if (object.detachEvent) {\n // @ts-expect-error - detachEvent is only available on IE\n object.detachEvent(`on${event}`, method);\n }\n}\n\n/** Convert modifier keys to their corresponding key codes */\nfunction getMods(modifier: Record<string, number>, key: string[]): number[] {\n const modsKeys = key.slice(0, key.length - 1);\n const modsCodes: number[] = [];\n for (let i = 0; i < modsKeys.length; i++) {\n modsCodes.push(modifier[modsKeys[i].toLowerCase()]);\n }\n return modsCodes;\n}\n\n/** Process the input key string and convert it to an array */\nfunction getKeys(key: string | undefined): string[] {\n if (typeof key !== 'string') key = '';\n key = key.replace(/\\s/g, ''); // Match any whitespace character, including spaces, tabs, form feeds, etc.\n const keys = key.split(','); // Allow multiple shortcuts separated by ','\n let index = keys.lastIndexOf('');\n\n // Shortcut may include ',' — special handling needed\n for (; index >= 0; ) {\n keys[index - 1] += ',';\n keys.splice(index, 1);\n index = keys.lastIndexOf('');\n }\n\n return keys;\n}\n\n/** Compare arrays of modifier keys */\nfunction compareArray(a1: number[], a2: number[]): boolean {\n const arr1 = a1.length >= a2.length ? a1 : a2;\n const arr2 = a1.length >= a2.length ? a2 : a1;\n let isIndex = true;\n\n for (let i = 0; i < arr1.length; i++) {\n if (arr2.indexOf(arr1[i]) === -1) isIndex = false;\n }\n return isIndex;\n}\n\n/**\n * Get layout-independent key code from keyboard event\n * This makes hotkeys work regardless of keyboard layout (Russian, German, etc.)\n * Uses event.code (physical key) instead of keyCode (character) for letter keys\n */\nfunction getLayoutIndependentKeyCode(event: KeyboardEvent): number {\n let key = event.keyCode || event.which || event.charCode;\n\n // Convert physical key code (KeyA-KeyZ) to corresponding ASCII code (65-90)\n // This makes 'ctrl+a' work on any keyboard layout\n if (event.code && /^Key[A-Z]$/.test(event.code)) {\n key = event.code.charCodeAt(3); // \"KeyA\"[3] = \"A\" -> 65\n }\n\n return key;\n}\n\nexport {\n isff,\n getMods,\n getKeys,\n addEvent,\n removeEvent,\n compareArray,\n getLayoutIndependentKeyCode,\n};\n","import { HotkeysEvent } from './types';\nimport { isff } from './utils';\n\n// Special Keys\nconst _keyMap: Record<string, number> = {\n backspace: 8,\n '⌫': 8,\n tab: 9,\n clear: 12,\n enter: 13,\n '↩': 13,\n return: 13,\n esc: 27,\n escape: 27,\n space: 32,\n left: 37,\n up: 38,\n right: 39,\n down: 40,\n /// https://w3c.github.io/uievents/#events-keyboard-key-location\n arrowup: 38,\n arrowdown: 40,\n arrowleft: 37,\n arrowright: 39,\n del: 46,\n delete: 46,\n ins: 45,\n insert: 45,\n home: 36,\n end: 35,\n pageup: 33,\n pagedown: 34,\n capslock: 20,\n num_0: 96,\n num_1: 97,\n num_2: 98,\n num_3: 99,\n num_4: 100,\n num_5: 101,\n num_6: 102,\n num_7: 103,\n num_8: 104,\n num_9: 105,\n num_multiply: 106,\n num_add: 107,\n num_enter: 108,\n num_subtract: 109,\n num_decimal: 110,\n num_divide: 111,\n '⇪': 20,\n ',': 188,\n '.': 190,\n '/': 191,\n '`': 192,\n '-': isff ? 173 : 189,\n '=': isff ? 61 : 187,\n ';': isff ? 59 : 186,\n '\\'': 222,\n '{': 219,\n '}': 221,\n '[': 219,\n ']': 221,\n '\\\\': 220,\n};\n\n// Modifier Keys\nconst _modifier: Record<string, number> = {\n // shiftKey\n '⇧': 16,\n shift: 16,\n // altKey\n '⌥': 18,\n alt: 18,\n option: 18,\n // ctrlKey\n '⌃': 17,\n ctrl: 17,\n control: 17,\n // metaKey\n '⌘': 91,\n cmd: 91,\n meta: 91,\n command: 91,\n};\n\nconst modifierMap: Record<string | number, number | string> = {\n 16: 'shiftKey',\n 18: 'altKey',\n 17: 'ctrlKey',\n 91: 'metaKey',\n\n shiftKey: 16,\n ctrlKey: 17,\n altKey: 18,\n metaKey: 91,\n};\n\nconst _mods: Record<number, boolean> = {\n 16: false,\n 18: false,\n 17: false,\n 91: false,\n};\n\nconst _handlers: Record<string | number, HotkeysEvent[]> = {};\n\n// F1~F12 special key\nfor (let k = 1; k < 20; k++) {\n _keyMap[`f${k}`] = 111 + k;\n}\n\nexport { _keyMap, _modifier, modifierMap, _mods, _handlers };\n","import {\n KeyCodeInfo,\n HotkeysEvent,\n UnbindInfo,\n HotkeysOptions,\n KeyHandler,\n HotkeysInterface,\n SetScope,\n GetScope,\n GetPressedKeyCodes,\n GetPressedKeyString,\n GetAllKeyCodes,\n Filter,\n IsPressed,\n DeleteScope,\n Unbind,\n HotkeysAPI,\n} from './types';\nimport { addEvent, removeEvent, getMods, getKeys, compareArray, getLayoutIndependentKeyCode } from './utils';\nimport { _keyMap, _modifier, modifierMap, _mods, _handlers } from './var';\n\n/** Record the pressed keys */\nlet _downKeys: number[] = [];\n/** Whether the window has already listened to the focus event */\nlet winListendFocus: { listener: EventListener; capture: boolean } | null =\n null;\n/** Whether we already listen to fullscreen change (to clear stuck _downKeys) */\nlet winListendFullscreen: { fullscreen: EventListener; webkit: EventListener } | null = null;\n/** Default hotkey scope */\nlet _scope: string = 'all';\n/** Map to record elements with bound events */\nconst elementEventMap = new Map<\n HTMLElement | Document,\n {\n keydownListener: EventListener;\n keyupListenr: EventListener;\n capture: boolean;\n }\n>();\n\n/** Return key code */\nconst code = (x: string): number =>\n _keyMap[x.toLowerCase()] ||\n _modifier[x.toLowerCase()] ||\n x.toUpperCase().charCodeAt(0);\n\nconst getKey = (x: number): string | undefined =>\n Object.keys(_keyMap).find((k) => _keyMap[k] === x);\nconst getModifier = (x: number): string | undefined =>\n Object.keys(_modifier).find((k) => _modifier[k] === x);\n\n/** Set or get the current scope (defaults to 'all') */\nconst setScope: SetScope = (scope) => {\n _scope = scope || 'all';\n};\n/** Get the current scope */\nconst getScope: GetScope = () => {\n return _scope || 'all';\n};\n/** Get the key codes of the currently pressed keys */\nconst getPressedKeyCodes: GetPressedKeyCodes = () => {\n return _downKeys.slice(0);\n};\n\nconst getPressedKeyString: GetPressedKeyString = () => {\n return _downKeys.map(\n (c) => getKey(c) || getModifier(c) || String.fromCharCode(c)\n );\n};\n\nconst getAllKeyCodes: GetAllKeyCodes = () => {\n const result: KeyCodeInfo[] = [];\n Object.keys(_handlers).forEach((k) => {\n _handlers[k].forEach(({ key, scope, mods, shortcut }) => {\n result.push({\n scope,\n shortcut,\n mods,\n keys: key.split('+').map((v) => code(v)),\n });\n });\n });\n return result;\n};\n\n/** hotkey is effective only when filter return true */\nconst filter: Filter = (event) => {\n const target = (event.target || event.srcElement) as HTMLElement;\n const { tagName } = target;\n let flag = true;\n const isInput =\n tagName === 'INPUT' &&\n ![\n 'checkbox',\n 'radio',\n 'range',\n 'button',\n 'file',\n 'reset',\n 'submit',\n 'color',\n ].includes((target as HTMLInputElement).type);\n // ignore: isContentEditable === 'true', <input> and <textarea> when readOnly state is false, <select>\n if (\n target.isContentEditable ||\n ((isInput || tagName === 'TEXTAREA' || tagName === 'SELECT') &&\n !(target as HTMLInputElement | HTMLTextAreaElement).readOnly)\n ) {\n flag = false;\n }\n return flag;\n};\n\n/** Determine whether the pressed key matches a specific key, returns true or false */\nconst isPressed: IsPressed = (keyCode) => {\n if (typeof keyCode === 'string') {\n keyCode = code(keyCode); // Convert to key code\n }\n return _downKeys.indexOf(keyCode) !== -1;\n};\n\n/** Loop through and delete all handlers with the specified scope */\nconst deleteScope: DeleteScope = (scope, newScope) => {\n let handlers: HotkeysEvent[];\n let i: number;\n\n // If no scope is specified, get the current scope\n if (!scope) scope = getScope();\n\n for (const key in _handlers) {\n if (Object.prototype.hasOwnProperty.call(_handlers, key)) {\n handlers = _handlers[key];\n for (i = 0; i < handlers.length; ) {\n if (handlers[i].scope === scope) {\n const deleteItems = handlers.splice(i, 1);\n deleteItems.forEach(({ element }) => removeKeyEvent(element));\n } else {\n i++;\n }\n }\n }\n }\n\n // If the current scope has been deleted, reset the scope to 'all'\n if (getScope() === scope) setScope(newScope || 'all');\n};\n\n/** Clear modifier keys */\nfunction clearModifier(event: KeyboardEvent): void {\n let key = getLayoutIndependentKeyCode(event);\n\n if (event.key && event.key.toLowerCase() === 'capslock') {\n // Ensure that when capturing keystrokes in modern browsers,\n // uppercase and lowercase letters (such as R and r) return the same key value.\n // https://github.com/jaywcjlove/hotkeys-js/pull/514\n // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key\n key = code(event.key);\n }\n const i = _downKeys.indexOf(key);\n\n // Remove the pressed key from the list\n if (i >= 0) {\n _downKeys.splice(i, 1);\n }\n // Special handling for the command key: fix the issue where keyup only triggers once for command combos\n if (event.key && event.key.toLowerCase() === 'meta') {\n _downKeys.splice(0, _downKeys.length);\n }\n\n // Clear modifier keys: shiftKey, altKey, ctrlKey, (command || metaKey)\n if (key === 93 || key === 224) key = 91;\n if (key in _mods) {\n _mods[key] = false;\n\n // Reset the modifier key status to false\n for (const k in _modifier)\n if (_modifier[k] === key) (hotkeys as any)[k] = false;\n }\n}\n\nconst unbind: Unbind = (\n keysInfo?: string | UnbindInfo | UnbindInfo[],\n ...args: any[]\n): void => {\n // unbind(), unbind all keys\n if (typeof keysInfo === 'undefined') {\n Object.keys(_handlers).forEach((key) => {\n if (Array.isArray(_handlers[key])) {\n _handlers[key].forEach((info) => eachUnbind(info));\n }\n delete _handlers[key];\n });\n removeKeyEvent(null);\n } else if (Array.isArray(keysInfo)) {\n // support like : unbind([{key: 'ctrl+a', scope: 's1'}, {key: 'ctrl-a', scope: 's2', splitKey: '-'}])\n keysInfo.forEach((info) => {\n if (info.key) eachUnbind(info);\n });\n } else if (typeof keysInfo === 'object') {\n // support like unbind({key: 'ctrl+a, ctrl+b', scope:'abc'})\n if (keysInfo.key) eachUnbind(keysInfo);\n } else if (typeof keysInfo === 'string') {\n // support old method\n let [scope, method] = args;\n if (typeof scope === 'function') {\n method = scope;\n scope = '';\n }\n eachUnbind({\n key: keysInfo,\n scope,\n method,\n splitKey: '+',\n });\n }\n};\n\n/** Unbind hotkeys for a specific scope */\nconst eachUnbind = ({\n key,\n scope,\n method,\n splitKey = '+',\n}: UnbindInfo): void => {\n const multipleKeys = getKeys(key);\n multipleKeys.forEach((originKey) => {\n const unbindKeys = originKey.split(splitKey);\n const len = unbindKeys.length;\n const lastKey = unbindKeys[len - 1];\n const keyCode = lastKey === '*' ? '*' : code(lastKey);\n if (!_handlers[keyCode]) return;\n // If scope is not provided, get the current scope\n if (!scope) scope = getScope();\n const mods = len > 1 ? getMods(_modifier, unbindKeys) : [];\n const unbindElements: (HTMLElement | Document)[] = [];\n _handlers[keyCode] = _handlers[keyCode].filter((record) => {\n // Check if the method matches; if method is provided, must be equal to unbind\n const isMatchingMethod = method ? record.method === method : true;\n const isUnbind =\n isMatchingMethod &&\n record.scope === scope &&\n compareArray(record.mods, mods);\n if (isUnbind) unbindElements.push(record.element);\n return !isUnbind;\n });\n unbindElements.forEach((element) => removeKeyEvent(element));\n });\n};\n\n/** Handle the callback function for the corresponding hotkey */\nfunction eventHandler(\n event: KeyboardEvent,\n handler: HotkeysEvent,\n scope: string,\n element: HTMLElement | Document\n): void {\n if (handler.element !== element) {\n return;\n }\n let modifiersMatch: boolean;\n\n // Check if it is within the current scope\n if (handler.scope === scope || handler.scope === 'all') {\n // Check whether modifier keys match (returns true if they do)\n modifiersMatch = handler.mods.length > 0;\n\n for (const y in _mods) {\n if (Object.prototype.hasOwnProperty.call(_mods, y)) {\n if (\n (!_mods[y] && handler.mods.indexOf(+y) > -1) ||\n (_mods[y] && handler.mods.indexOf(+y) === -1)\n ) {\n modifiersMatch = false;\n }\n }\n }\n\n // Call the handler function; ignore if it's only a modifier key\n if (\n (handler.mods.length === 0 &&\n !_mods[16] &&\n !_mods[18] &&\n !_mods[17] &&\n !_mods[91]) ||\n modifiersMatch ||\n handler.shortcut === '*'\n ) {\n handler.keys = [];\n handler.keys = handler.keys.concat(_downKeys);\n if (handler.method(event, handler) === false) {\n if (event.preventDefault) event.preventDefault();\n else event.returnValue = false;\n if (event.stopPropagation) event.stopPropagation();\n if (event.cancelBubble) event.cancelBubble = true;\n }\n }\n }\n}\n\n/** Handle the keydown event */\nfunction dispatch(\n this: any,\n event: KeyboardEvent,\n element: HTMLElement | Document\n): void {\n const asterisk = _handlers['*'];\n let key = getLayoutIndependentKeyCode(event);\n\n // Ensure that when capturing keystrokes in modern browsers,\n // uppercase and lowercase letters (such as R and r) return the same key value.\n // https://github.com/jaywcjlove/hotkeys-js/pull/514\n // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key\n // CapsLock key\n // There's an issue where `keydown` and `keyup` events are not triggered after CapsLock is enabled to activate uppercase.\n if (event.key && event.key.toLowerCase() === 'capslock') {\n return;\n }\n // Form control filter: by default, shortcut keys are not triggered in form elements\n const filterFn = (hotkeys as any).filter || filter;\n if (!filterFn.call(this, event)) return;\n\n // In Gecko (Firefox), the command key code is 224; unify it with WebKit (Chrome)\n // In WebKit, left and right command keys have different codes\n if (key === 93 || key === 224) key = 91;\n\n /**\n * Collect bound keys\n * If an Input Method Editor is processing key input and the event is keydown, return 229.\n * https://stackoverflow.com/questions/25043934/is-it-ok-to-ignore-keydown-events-with-keycode-229\n * http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html\n */\n if (_downKeys.indexOf(key) === -1 && key !== 229) _downKeys.push(key);\n /**\n * Jest test cases are required.\n * ===============================\n */\n ['metaKey', 'ctrlKey', 'altKey', 'shiftKey'].forEach((keyName) => {\n const keyNum = (modifierMap as any)[keyName] as number;\n if ((event as any)[keyName] && _downKeys.indexOf(keyNum) === -1) {\n _downKeys.push(keyNum);\n } else if (!(event as any)[keyName] && _downKeys.indexOf(keyNum) > -1) {\n _downKeys.splice(_downKeys.indexOf(keyNum), 1);\n } else if (keyName === 'metaKey' && (event as any)[keyName]) {\n // If the command key is pressed, clear all non-modifier keys except the current event key.\n // This is because keyup for non-modifier keys will NEVER be triggered when command is pressed.\n // This is a known browser limitation.\n _downKeys = _downKeys.filter((k) => k in modifierMap || k === key);\n }\n });\n /**\n * -------------------------------\n */\n if (key in _mods) {\n _mods[key] = true;\n // Register special modifier keys to the `hotkeys` object\n for (const k in _modifier) {\n if (Object.prototype.hasOwnProperty.call(_modifier, k)) {\n const eventKey = (modifierMap as any)[_modifier[k]] as string;\n (hotkeys as any)[k] = (event as any)[eventKey];\n }\n }\n\n if (!asterisk) return;\n }\n\n // Bind the modifier keys in modifierMap to the event\n for (const e in _mods) {\n if (Object.prototype.hasOwnProperty.call(_mods, e)) {\n _mods[e] = (event as any)[(modifierMap as any)[e]];\n }\n }\n /**\n * https://github.com/jaywcjlove/hotkeys/pull/129\n * This solves the issue in Firefox on Windows where hotkeys corresponding to special characters would not trigger.\n * An example of this is ctrl+alt+m on a Swedish keyboard which is used to type μ.\n * Browser support: https://caniuse.com/#feat=keyboardevent-getmodifierstate\n */\n if (\n event.getModifierState &&\n !(event.altKey && !event.ctrlKey) &&\n event.getModifierState('AltGraph')\n ) {\n if (_downKeys.indexOf(17) === -1) {\n _downKeys.push(17);\n }\n\n if (_downKeys.indexOf(18) === -1) {\n _downKeys.push(18);\n }\n\n _mods[17] = true;\n _mods[18] = true;\n }\n\n // Get the current scope (defaults to 'all')\n const scope = getScope();\n // Handle any hotkeys registered as '*'\n if (asterisk) {\n for (let i = 0; i < asterisk.length; i++) {\n if (\n asterisk[i].scope === scope &&\n ((event.type === 'keydown' && asterisk[i].keydown) ||\n (event.type === 'keyup' && asterisk[i].keyup))\n ) {\n eventHandler(event, asterisk[i], scope, element);\n }\n }\n }\n // If the key is not registered, return\n if (!(key in _handlers)) return;\n\n const handlerKey = _handlers[key];\n const keyLen = handlerKey.length;\n for (let i = 0; i < keyLen; i++) {\n if (\n (event.type === 'keydown' && handlerKey[i].keydown) ||\n (event.type === 'keyup' && handlerKey[i].keyup)\n ) {\n if (handlerKey[i].key) {\n const record = handlerKey[i];\n const { splitKey } = record;\n const keyShortcut = record.key.split(splitKey);\n const _downKeysCurrent: number[] = []; // Store the current key codes\n for (let a = 0; a < keyShortcut.length; a++) {\n _downKeysCurrent.push(code(keyShortcut[a]));\n }\n if (_downKeysCurrent.sort().join('') === _downKeys.sort().join('')) {\n // Match found, call the handler\n eventHandler(event, record, scope, element);\n }\n }\n }\n }\n}\n\nconst hotkeys = function hotkeys(\n key: string,\n option?: string | HotkeysOptions | KeyHandler,\n method?: KeyHandler\n): void {\n _downKeys = [];\n /** List of hotkeys to handle */\n const keys = getKeys(key);\n let mods: number[] = [];\n /** Default scope is 'all', meaning effective in all scopes */\n let scope: string = 'all';\n /** Element to which the hotkey events are bound */\n let element: HTMLElement | Document = document;\n let i = 0;\n let keyup = false;\n let keydown = true;\n let splitKey = '+';\n let capture = false;\n /** Allow only a single callback */\n let single = false;\n\n // Determine if the second argument is a function (no options provided)\n if (method === undefined && typeof option === 'function') {\n method = option;\n }\n\n // Parse options object\n if (Object.prototype.toString.call(option) === '[object Object]') {\n const opts = option as HotkeysOptions;\n if (opts.scope) scope = opts.scope; // Set scope\n if (opts.element) element = opts.element; // Set binding element\n if (opts.keyup) keyup = opts.keyup;\n if (opts.keydown !== undefined) keydown = opts.keydown;\n if (opts.capture !== undefined) capture = opts.capture;\n if (typeof opts.splitKey === 'string') splitKey = opts.splitKey;\n if (opts.single === true) single = true;\n }\n\n if (typeof option === 'string') scope = option;\n\n // If only one callback is allowed, unbind the existing one first\n if (single) unbind(key, scope);\n\n // Handle each hotkey\n for (; i < keys.length; i++) {\n const currentKey = keys[i].split(splitKey); // Split into individual keys\n mods = [];\n\n // If it's a combination, extract modifier keys\n if (currentKey.length > 1) mods = getMods(_modifier, currentKey);\n\n // Convert non-modifier key to key code\n let finalKey: string | number = currentKey[currentKey.length - 1];\n finalKey = finalKey === '*' ? '*' : code(finalKey); // '*' means match all hotkeys\n\n // Initialize handler array if this key has no handlers yet\n if (!(finalKey in _handlers)) _handlers[finalKey] = [];\n\n _handlers[finalKey].push({\n keyup,\n keydown,\n scope,\n mods,\n shortcut: keys[i],\n method: method!,\n key: keys[i],\n splitKey,\n element,\n });\n }\n // Register hotkey event listeners on the global document\n if (typeof element !== 'undefined' && typeof window !== 'undefined') {\n if (!elementEventMap.has(element)) {\n // @ts-expect-error - window.event is deprecated IE property\n const keydownListener = (event: Event = window.event) =>\n dispatch(event as KeyboardEvent, element);\n // @ts-expect-error - window.event is deprecated IE property\n const keyupListenr = (event: Event = window.event) => {\n dispatch(event as KeyboardEvent, element);\n clearModifier(event as KeyboardEvent);\n };\n elementEventMap.set(element, { keydownListener, keyupListenr, capture });\n addEvent(element, 'keydown', keydownListener, capture);\n addEvent(element, 'keyup', keyupListenr, capture);\n }\n // Register focus event listener once to clear pressed keys on window focus\n if (!winListendFocus) {\n const listener = () => {\n _downKeys = [];\n };\n winListendFocus = { listener, capture };\n addEvent(window, 'focus', listener, capture);\n }\n // Register fullscreen change once: keyup can be lost when entering fullscreen (e.g. Alt+F), so clear stuck keys\n if (!winListendFullscreen && typeof document !== 'undefined') {\n const onFullscreenChange = () => {\n _downKeys = [];\n for (const k in _mods) _mods[k] = false;\n for (const k in _modifier) (hotkeys as any)[k] = false;\n };\n const fullscreenListener = onFullscreenChange as EventListener;\n const webkitListener = onFullscreenChange as EventListener;\n document.addEventListener('fullscreenchange', fullscreenListener);\n document.addEventListener('webkitfullscreenchange', webkitListener);\n winListendFullscreen = { fullscreen: fullscreenListener, webkit: webkitListener };\n }\n }\n} as HotkeysInterface;\n\nfunction trigger(shortcut: string, scope: string = 'all'): void {\n Object.keys(_handlers).forEach((key) => {\n const dataList = _handlers[key].filter(\n (item) => item.scope === scope && item.shortcut === shortcut\n );\n dataList.forEach((data) => {\n if (data && data.method) {\n data.method({} as KeyboardEvent, data);\n }\n });\n });\n}\n\n/** Clean up event listeners. After unbinding, check whether the element still has any hotkeys bound. If not, remove its event listeners. */\nfunction removeKeyEvent(element: HTMLElement | Document | null): void {\n const values = Object.values(_handlers).flat();\n const findindex = values.findIndex(({ element: el }) => el === element);\n\n if (findindex < 0 && element) {\n const { keydownListener, keyupListenr, capture } =\n elementEventMap.get(element) || {};\n if (keydownListener && keyupListenr) {\n removeEvent(element, 'keyup', keyupListenr, capture);\n removeEvent(element, 'keydown', keydownListener, capture);\n elementEventMap.delete(element);\n }\n }\n\n if (values.length <= 0 || elementEventMap.size <= 0) {\n // Remove all event listeners from all elements\n const eventKeys = Array.from(elementEventMap.keys());\n eventKeys.forEach((el) => {\n const { keydownListener, keyupListenr, capture } =\n elementEventMap.get(el) || {};\n if (keydownListener && keyupListenr) {\n removeEvent(el, 'keyup', keyupListenr, capture);\n removeEvent(el, 'keydown', keydownListener, capture);\n elementEventMap.delete(el);\n }\n });\n // Clear the elementEventMap\n elementEventMap.clear();\n // Clear all handlers\n Object.keys(_handlers).forEach((key) => delete _handlers[key]);\n // Remove the global window focus event listener\n if (winListendFocus) {\n const { listener, capture } = winListendFocus;\n removeEvent(window, 'focus', listener, capture);\n winListendFocus = null;\n }\n // Remove fullscreen change listeners\n if (winListendFullscreen && typeof document !== 'undefined') {\n document.removeEventListener('fullscreenchange', winListendFullscreen.fullscreen);\n document.removeEventListener('webkitfullscreenchange', winListendFullscreen.webkit);\n winListendFullscreen = null;\n }\n }\n}\n\nconst _api: Omit<HotkeysAPI, 'noConflict'> = {\n getPressedKeyString,\n setScope,\n getScope,\n deleteScope,\n getPressedKeyCodes,\n getAllKeyCodes,\n isPressed,\n filter,\n trigger,\n unbind,\n keyMap: _keyMap,\n modifier: _modifier,\n modifierMap,\n};\n\nfor (const a in _api) {\n const key = a as keyof typeof _api;\n if (Object.prototype.hasOwnProperty.call(_api, key)) {\n (hotkeys as any)[key] = _api[key];\n }\n}\n\nif (typeof window !== 'undefined') {\n const _hotkeys = (window as any).hotkeys;\n (hotkeys as HotkeysInterface).noConflict = (deep?: boolean) => {\n if (deep && (window as any).hotkeys === hotkeys) {\n (window as any).hotkeys = _hotkeys;\n }\n return hotkeys as HotkeysInterface;\n };\n (window as any).hotkeys = hotkeys;\n}\n\n// Export for both ESM and CommonJS\nexport default hotkeys as HotkeysInterface;\nexport type { KeyHandler, HotkeysEvent };\n"],"names":["hotkeys"],"mappings":"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"}