{
  "version": 3,
  "sources": ["../../../../src/lib/ui/hooks/useKeyboardShortcuts.ts"],
  "sourcesContent": ["/*!\n * The kbd-string splitter (`getKeys`) and the form-input filter pattern in `shouldSkipEvent`\n * (including its list of non-text INPUT types) are adapted from hotkeys-js, which this hook\n * previously depended on.\n *\n * MIT License: https://github.com/jaywcjlove/hotkeys-js/blob/master/LICENSE\n * Copyright (c) 2015-present, Kenny Wong\n * Copyright (c) 2011-2013 Thomas Fuchs (https://github.com/madrobby/keymaster)\n * Source: https://github.com/jaywcjlove/hotkeys-js\n */\n\nimport {\n\tEditor,\n\tTLPointerEventInfo,\n\tisAccelKey,\n\tpreventDefault,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { useEffect } from 'react'\nimport { useActions } from '../context/actions'\nimport { useReadonly } from './useReadonly'\nimport { useTools } from './useTools'\n\nconst SKIP_KBDS = [\n\t// we set these in useNativeClipboardEvents instead\n\t'copy',\n\t'cut',\n\t'paste',\n\t// There's also an upload asset action, so we don't want to set the kbd twice\n\t'asset',\n]\n\n/** @public */\nexport function useKeyboardShortcuts() {\n\tconst editor = useEditor()\n\n\tconst isReadonlyMode = useReadonly()\n\tconst actions = useActions()\n\tconst tools = useTools()\n\tconst isFocused = useValue('is focused', () => editor.getInstanceState().isFocused, [editor])\n\tuseEffect(() => {\n\t\tif (!isFocused) return\n\n\t\tconst registry: Registration[] = []\n\n\t\tconst register = (kbd: string, onKeyDown?: KbdHandler, onKeyUp?: KbdHandler) => {\n\t\t\tconst parsed = parseKbd(kbd)\n\t\t\tif (parsed.length === 0) return\n\t\t\tregistry.push({ parsed, onKeyDown, onKeyUp })\n\t\t}\n\n\t\t// Add hotkeys for actions and tools.\n\t\t// Except those that in SKIP_KBDS!\n\t\tfor (const action of Object.values(actions)) {\n\t\t\tif (!action.kbd) continue\n\t\t\tif (isReadonlyMode && !action.readonlyOk) continue\n\t\t\tif (SKIP_KBDS.includes(action.id)) continue\n\n\t\t\tregister(getHotkeysStringFromKbd(action.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor) && !action.isRequiredA11yAction) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\taction.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\tfor (const tool of Object.values(tools)) {\n\t\t\tif (!tool.kbd || (!tool.readonlyOk && editor.getIsReadonly())) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (SKIP_KBDS.includes(tool.id)) continue\n\n\t\t\tregister(getHotkeysStringFromKbd(tool.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\ttool.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\tregister(\n\t\t\t',',\n\t\t\t(e) => {\n\t\t\t\t// Skip if shortcuts are disabled\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\n\t\t\t\t// Don't press again if already pressed\n\t\t\t\tif (editor.inputs.keys.has('Comma')) return\n\n\t\t\t\tpreventDefault(e) // prevent whatever would normally happen\n\t\t\t\teditor.focus() // Focus if not already focused\n\n\t\t\t\teditor.inputs.keys.add('Comma')\n\n\t\t\t\tconst { x, y, z } = editor.inputs.getCurrentPagePoint()\n\t\t\t\tconst screenpoints = editor.pageToScreen({ x, y })\n\n\t\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\tpoint: { x: screenpoints.x, y: screenpoints.y, z },\n\t\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\t\taltKey: e.altKey,\n\t\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t\t\tpointerId: 0,\n\t\t\t\t\tbutton: 0,\n\t\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t}\n\n\t\t\t\teditor.dispatch(info)\n\t\t\t},\n\t\t\t(e) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tif (!editor.inputs.keys.has('Comma')) return\n\n\t\t\t\teditor.inputs.keys.delete('Comma')\n\n\t\t\t\tconst { x, y, z } = editor.inputs.getCurrentPagePoint()\n\t\t\t\tconst screenPoint = editor.pageToScreen({ x, y })\n\t\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\tpoint: { x: screenPoint.x, y: screenPoint.y, z },\n\t\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\t\taltKey: e.altKey,\n\t\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t\t\tpointerId: 0,\n\t\t\t\t\tbutton: 0,\n\t\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t}\n\n\t\t\t\teditor.dispatch(info)\n\t\t\t}\n\t\t)\n\n\t\tconst body = editor.getContainerDocument().body\n\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (shouldSkipEvent(e)) return\n\t\t\tfor (const reg of registry) {\n\t\t\t\tif (!reg.onKeyDown) continue\n\t\t\t\tfor (const p of reg.parsed) {\n\t\t\t\t\tif (matchesEvent(e, p)) {\n\t\t\t\t\t\treg.onKeyDown(e)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst handleKeyUp = (e: KeyboardEvent) => {\n\t\t\tif (shouldSkipEvent(e)) return\n\t\t\tfor (const reg of registry) {\n\t\t\t\tif (!reg.onKeyUp) continue\n\t\t\t\tfor (const p of reg.parsed) {\n\t\t\t\t\tif (matchesEvent(e, p)) {\n\t\t\t\t\t\treg.onKeyUp(e)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbody.addEventListener('keydown', handleKeyDown)\n\t\tbody.addEventListener('keyup', handleKeyUp)\n\n\t\treturn () => {\n\t\t\tbody.removeEventListener('keydown', handleKeyDown)\n\t\t\tbody.removeEventListener('keyup', handleKeyUp)\n\t\t}\n\t}, [actions, tools, isReadonlyMode, editor, isFocused])\n}\n\nexport function areShortcutsDisabled(editor: Editor) {\n\treturn (\n\t\teditor.menus.hasAnyOpenMenus() ||\n\t\teditor.getEditingShapeId() !== null ||\n\t\teditor.getCrashingError() ||\n\t\t!editor.user.getAreKeyboardShortcutsEnabled()\n\t)\n}\n\n// kbd parsing & native event matching\n// -----------------------------------\n// We deliberately do NOT use `event.code` (physical key position) for primary matching.\n// Doing so breaks alternative Latin keyboard layouts (Dvorak, Colemak, AZERTY) because\n// `event.code` always reflects the US-QWERTY position regardless of what the user typed.\n// Instead we match the typed character (`event.key`) and only fall back to `event.code` for\n// non-Latin layouts (Cyrillic, Greek, etc.) and macOS Option-letter dead-key combinations,\n// where `event.key` is a non-ASCII glyph.\n\ninterface ParsedKbd {\n\tkey: string\n\tshift: boolean\n\talt: boolean\n\tctrl: boolean\n\tmeta: boolean\n}\n\ntype KbdHandler = (event: KeyboardEvent) => void\n\ninterface Registration {\n\tparsed: ParsedKbd[]\n\tonKeyDown?: KbdHandler\n\tonKeyUp?: KbdHandler\n}\n\nconst MODIFIER_ALIASES: Record<string, 'shift' | 'alt' | 'ctrl' | 'meta'> = {\n\tshift: 'shift',\n\t'\u21E7': 'shift',\n\talt: 'alt',\n\toption: 'alt',\n\t'\u2325': 'alt',\n\tctrl: 'ctrl',\n\tcontrol: 'ctrl',\n\t'\u2303': 'ctrl',\n\tcmd: 'meta',\n\tcommand: 'meta',\n\tmeta: 'meta',\n\t'\u2318': 'meta',\n}\n\n// Aliases for named keys. Values match the lowercased `event.key` for that key.\nconst KEY_ALIASES: Record<string, string> = {\n\t'\u232B': 'backspace',\n\t'\u21A9': 'enter',\n\treturn: 'enter',\n\tesc: 'escape',\n\tdel: 'delete',\n\tins: 'insert',\n\tleft: 'arrowleft',\n\tright: 'arrowright',\n\tup: 'arrowup',\n\tdown: 'arrowdown',\n\tspace: ' ',\n}\n\n// When shift is held, `event.key` reports the shifted character (e.g. '<' for shift+,).\n// Map those back so a `shift+,` shortcut definition matches.\nconst SHIFT_KEY_TO_BASE: Record<string, string> = {\n\t'<': ',',\n\t'>': '.',\n\t'?': '/',\n\t':': ';',\n\t'\"': \"'\",\n\t'{': '[',\n\t'}': ']',\n\t'|': '\\\\',\n\t_: '-',\n\t'+': '=',\n\t'~': '`',\n\t'!': '1',\n\t'@': '2',\n\t'#': '3',\n\t$: '4',\n\t'%': '5',\n\t'^': '6',\n\t'&': '7',\n\t'*': '8',\n\t'(': '9',\n\t')': '0',\n}\n\n// Physical key code -> US-QWERTY-equivalent character. Used as a fallback when `event.key`\n// is non-ASCII (Cyrillic, Greek, macOS Option dead-keys, etc.).\nconst PHYSICAL_KEY_MAP: Record<string, string> = {\n\tKeyA: 'a',\n\tKeyB: 'b',\n\tKeyC: 'c',\n\tKeyD: 'd',\n\tKeyE: 'e',\n\tKeyF: 'f',\n\tKeyG: 'g',\n\tKeyH: 'h',\n\tKeyI: 'i',\n\tKeyJ: 'j',\n\tKeyK: 'k',\n\tKeyL: 'l',\n\tKeyM: 'm',\n\tKeyN: 'n',\n\tKeyO: 'o',\n\tKeyP: 'p',\n\tKeyQ: 'q',\n\tKeyR: 'r',\n\tKeyS: 's',\n\tKeyT: 't',\n\tKeyU: 'u',\n\tKeyV: 'v',\n\tKeyW: 'w',\n\tKeyX: 'x',\n\tKeyY: 'y',\n\tKeyZ: 'z',\n\tDigit0: '0',\n\tDigit1: '1',\n\tDigit2: '2',\n\tDigit3: '3',\n\tDigit4: '4',\n\tDigit5: '5',\n\tDigit6: '6',\n\tDigit7: '7',\n\tDigit8: '8',\n\tDigit9: '9',\n\tComma: ',',\n\tPeriod: '.',\n\tSlash: '/',\n\tSemicolon: ';',\n\tQuote: \"'\",\n\tBracketLeft: '[',\n\tBracketRight: ']',\n\tBackslash: '\\\\',\n\tMinus: '-',\n\tEqual: '=',\n\tBackquote: '`',\n}\n\nfunction parseKbd(kbd: string): ParsedKbd[] {\n\tconst out: ParsedKbd[] = []\n\tfor (const shortcut of getKeys(kbd)) {\n\t\tconst parsed = parseShortcut(shortcut)\n\t\tif (parsed) out.push(parsed)\n\t}\n\treturn out\n}\n\nfunction parseShortcut(shortcut: string): ParsedKbd | null {\n\tconst parts = shortcut.split('+')\n\tconst result: ParsedKbd = {\n\t\tkey: '',\n\t\tshift: false,\n\t\talt: false,\n\t\tctrl: false,\n\t\tmeta: false,\n\t}\n\n\tlet keyPart = ''\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i]\n\t\tconst isLast = i === parts.length - 1\n\t\tif (!isLast) {\n\t\t\tconst modAlias = MODIFIER_ALIASES[part.toLowerCase()]\n\t\t\tif (modAlias) result[modAlias] = true\n\t\t\t// silently drop unknown leading parts\n\t\t} else {\n\t\t\tkeyPart = part\n\t\t}\n\t}\n\n\tif (!keyPart) return null\n\n\tlet key = keyPart.toLowerCase()\n\tif (KEY_ALIASES[key]) key = KEY_ALIASES[key]\n\tresult.key = key\n\treturn result\n}\n\nfunction getEventKey(e: KeyboardEvent): string {\n\tlet key = e.key.toLowerCase()\n\tif (e.shiftKey && SHIFT_KEY_TO_BASE[key]) {\n\t\tkey = SHIFT_KEY_TO_BASE[key]\n\t}\n\treturn key\n}\n\nfunction matchesEvent(e: KeyboardEvent, parsed: ParsedKbd): boolean {\n\tif (e.shiftKey !== parsed.shift) return false\n\tif (e.altKey !== parsed.alt) return false\n\tif (e.ctrlKey !== parsed.ctrl) return false\n\tif (e.metaKey !== parsed.meta) return false\n\n\tconst eventKey = getEventKey(e)\n\tif (eventKey === parsed.key) return true\n\n\t// Fallback for non-Latin layouts (Cyrillic, Greek, etc.) and macOS Option dead-keys,\n\t// where event.key is a non-ASCII glyph that wouldn't match any of our shortcut keys.\n\t// We re-derive the intended key from event.code's US-QWERTY equivalent. Importantly,\n\t// we only use this fallback when event.key is non-ASCII so that Dvorak/Colemak/AZERTY\n\t// users \u2014 whose event.key IS the Latin character they typed \u2014 keep getting the right match.\n\tif (eventKey.length === 1 && /^[\\x20-\\x7e]$/.test(eventKey)) return false\n\tconst codeKey = PHYSICAL_KEY_MAP[e.code]\n\treturn codeKey === parsed.key\n}\n\nfunction shouldSkipEvent(e: KeyboardEvent): boolean {\n\tif (e.isComposing) return true\n\tconst target = e.target as HTMLElement | null\n\tif (!target) return false\n\tif (target.isContentEditable) return true\n\tconst tagName = target.tagName\n\tif (tagName === 'SELECT') return true\n\tif (tagName === 'TEXTAREA') {\n\t\treturn !(target as HTMLTextAreaElement).readOnly\n\t}\n\tif (tagName === 'INPUT') {\n\t\tconst input = target as HTMLInputElement\n\t\t// Form inputs that don't accept text input should not block shortcuts.\n\t\tif (\n\t\t\t['checkbox', 'radio', 'range', 'button', 'file', 'reset', 'submit', 'color'].includes(\n\t\t\t\tinput.type\n\t\t\t)\n\t\t) {\n\t\t\treturn false\n\t\t}\n\t\treturn !input.readOnly\n\t}\n\treturn false\n}\n\n// The \"raw\" kbd here will look something like \"a\" or a combination of keys \"del,backspace\".\n// We need to first split them up by comma, then parse each key to ensure backwards compatibility\n// with the old kbd format. We used to have symbols to denote cmd/alt/shift,\n// using ! for shift, $ for cmd, and ? for alt.\nfunction getHotkeysStringFromKbd(kbd: string) {\n\treturn getKeys(kbd)\n\t\t.map((kbd) => {\n\t\t\tlet str = ''\n\n\t\t\tconst shift = kbd.includes('!')\n\t\t\tconst alt = kbd.includes('?')\n\t\t\tconst cmd = kbd.includes('$')\n\n\t\t\t// remove the modifiers; the remaining string are the actual key\n\t\t\tconst k = kbd.replace(/[!?$]/g, '')\n\n\t\t\tif (shift && alt && cmd) {\n\t\t\t\tstr = `cmd+shift+alt+${k},ctrl+shift+alt+${k}`\n\t\t\t} else if (shift && cmd) {\n\t\t\t\tstr = `cmd+shift+${k},ctrl+shift+${k}`\n\t\t\t} else if (alt && cmd) {\n\t\t\t\tstr = `cmd+alt+${k},ctrl+alt+${k}`\n\t\t\t} else if (alt && shift) {\n\t\t\t\tstr = `shift+alt+${k}`\n\t\t\t} else if (shift) {\n\t\t\t\tstr = `shift+${k}`\n\t\t\t} else if (alt) {\n\t\t\t\tstr = `alt+${k}`\n\t\t\t} else if (cmd) {\n\t\t\t\tstr = `cmd+${k},ctrl+${k}`\n\t\t\t} else {\n\t\t\t\tstr = k\n\t\t\t}\n\n\t\t\treturn str\n\t\t})\n\t\t.join(',')\n}\n\n// Split a kbd string on commas, treating an empty entry produced by \"x,,\" as a literal\n// trailing comma on the previous entry. Verbatim port of the splitter from hotkeys-js\n// (MIT, see top-of-file attribution).\nfunction getKeys(key: string) {\n\tif (typeof key !== 'string') key = ''\n\tkey = key.replace(/\\s/g, '')\n\tconst keys = key.split(',')\n\tlet index = keys.lastIndexOf('')\n\n\tfor (; index >= 0; ) {\n\t\tkeys[index - 1] += ','\n\t\tkeys.splice(index, 1)\n\t\tindex = keys.lastIndexOf('')\n\t}\n\n\treturn keys\n}\n"],
  "mappings": "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",
  "names": ["kbd"]
}
