@dxos/keyboard 0.9.0 → 0.9.1-staging.ee54ba693a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +6 -2
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +6 -2
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/keyboard.d.ts +7 -0
- package/dist/types/src/keyboard.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/keyboard.stories.tsx +1 -1
- package/src/keyboard.test.ts +30 -3
- package/src/keyboard.ts +18 -4
|
@@ -35,6 +35,8 @@ var KeyboardContext = class {
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
var ROOT = "";
|
|
38
|
+
var GRAPH_ROOT_ID = "root";
|
|
39
|
+
var nestKeyboardContext = (segment) => segment ? segment === GRAPH_ROOT_ID || segment.startsWith(`${GRAPH_ROOT_ID}/`) ? segment : `${GRAPH_ROOT_ID}/${segment}` : GRAPH_ROOT_ID;
|
|
38
40
|
var Keyboard = class _Keyboard {
|
|
39
41
|
static singleton = new _Keyboard();
|
|
40
42
|
_root = new KeyboardContext();
|
|
@@ -90,13 +92,13 @@ var Keyboard = class _Keyboard {
|
|
|
90
92
|
if (key !== "Alt" && key !== "Control" && key !== "Meta" && key !== "Shift") {
|
|
91
93
|
const tagName = event.target?.tagName;
|
|
92
94
|
const isInput = tagName === "INPUT" || tagName === "TEXTAREA" || event.target?.getAttribute("contenteditable");
|
|
93
|
-
const str = [
|
|
95
|
+
const str = parseShortcut([
|
|
94
96
|
ctrlKey && "ctrl",
|
|
95
97
|
shiftKey && "shift",
|
|
96
98
|
altKey && "alt",
|
|
97
99
|
metaKey && "meta",
|
|
98
100
|
key
|
|
99
|
-
].filter(Boolean).join("+");
|
|
101
|
+
].filter(Boolean).join("+"));
|
|
100
102
|
for (let i = this._contexts.length - 1; i >= 0; --i) {
|
|
101
103
|
const path = this._contexts[i];
|
|
102
104
|
if (this._path.startsWith(path)) {
|
|
@@ -177,8 +179,10 @@ var keySymbols = (keyBinding) => {
|
|
|
177
179
|
return parts.map(getSymbol);
|
|
178
180
|
};
|
|
179
181
|
export {
|
|
182
|
+
GRAPH_ROOT_ID,
|
|
180
183
|
Keyboard,
|
|
181
184
|
keySymbols,
|
|
185
|
+
nestKeyboardContext,
|
|
182
186
|
parseShortcut
|
|
183
187
|
};
|
|
184
188
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/keyboard.ts", "../../../src/util.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { type MaybePromise } from '@dxos/util';\n\n// TODO(burdon): Replace with hotkeys-js, react-hotkeys, and react-hotkeys-hook.\n\nexport type KeyHandler = (props: {\n context: string;\n shortcut: string;\n data?: any;\n event: KeyboardEvent;\n}) => MaybePromise<boolean | void>;\n\nexport type KeyBinding = {\n shortcut: string;\n handler: KeyHandler;\n disableInput?: boolean;\n data?: any;\n};\n\n// Keybinding is normalized to this order.\n// https://support.apple.com/en-us/HT201236\nconst modifiers = ['ctrl', 'shift', 'alt', 'meta'];\n\n// Normalize order and case of modifiers.\nexport const parseShortcut = (shortcut: string, delimiter = /[+-]/): string => {\n const parts = shortcut.toLowerCase().split(delimiter);\n const mods = modifiers.filter((key) => parts.includes(key));\n invariant(mods.length === 0 || mods.length === parts.length - 1);\n // Assume single natural key.\n return mods.length ? [...mods, parts[parts.length - 1]].join('+') : shortcut;\n};\n\nclass KeyboardContext {\n readonly _keyMap = new Map<string, KeyBinding>();\n\n get bindings() {\n return Array.from(this._keyMap.values());\n }\n\n get(binding: string): KeyBinding | undefined {\n return this._keyMap.get(binding);\n }\n\n bind(config: KeyBinding): void {\n config.shortcut = parseShortcut(config.shortcut);\n this._keyMap.set(config.shortcut, config);\n }\n\n unbind(binding: string): void {\n this._keyMap.delete(binding);\n }\n}\n\nconst ROOT = '';\n\n/**\n * Manages context-aware key bindings.\n */\nexport class Keyboard {\n static singleton = new Keyboard();\n\n private readonly _root = new KeyboardContext();\n private readonly _keyMap = new Map<string, KeyboardContext>([[ROOT, this._root]]);\n private readonly _contexts: string[] = [ROOT];\n private readonly _keyHandler = this.handleKeyDown.bind(this);\n private _path = ROOT;\n\n initialize(): void {\n document.addEventListener('keydown', this._keyHandler);\n }\n\n destroy(): void {\n document.removeEventListener('keydown', this._keyHandler);\n }\n\n bind = this._root.bind.bind(this._root);\n unbind = this._root.unbind.bind(this._root);\n\n setCurrentContext(path = ROOT): void {\n this._path = path;\n }\n\n getCurrentContext(): string {\n return this._path;\n }\n\n getContext(path = ROOT): KeyboardContext {\n let context = this._keyMap.get(path);\n if (!context) {\n context = new KeyboardContext();\n this._keyMap.set(path, context);\n this._contexts.push(path);\n this._contexts.sort();\n }\n\n return context;\n }\n\n getBindings(): KeyBinding[] {\n const bindings = new Map<string, KeyBinding>();\n for (let i = 0; i < this._contexts.length; ++i) {\n const path = this._contexts[i];\n if (this._path.startsWith(path)) {\n this.getContext(path).bindings.forEach((binding) => {\n bindings.set(binding.shortcut, binding);\n });\n }\n }\n\n return Array.from(bindings.values());\n }\n\n async handleKeyDown(event: KeyboardEvent): Promise<void> {\n const { altKey, ctrlKey, metaKey, shiftKey, key } = event;\n\n if (key !== 'Alt' && key !== 'Control' && key !== 'Meta' && key !== 'Shift') {\n // Binding option to check for input or contenteditable.\n const tagName = (event.target as any)?.tagName;\n const isInput =\n tagName === 'INPUT' || tagName === 'TEXTAREA' || (event.target as any)?.getAttribute('contenteditable');\n\n // Normalized key binding (order
|
|
5
|
-
"mappings": ";;;AAIA,SAASA,iBAAiB;AAmB1B,IAAA,eAAA;IAE2B,YAAA;EAAS;EAAO;EAAO;EAElD;AACA;AAEE,IAAMC,gBAAiBC,CAAAA,UAAQC,YAAcC,WAASD;AACtDH,QAAAA,QAAUC,SAAW,YAAUA,EAAKI,MAAM,SAAKC;AAC/C,QAAA,OAAA,UAAA,OAA6B,CAAA,QAAA,MAAA,SAAA,GAAA,CAAA;AAC7B,YAAOL,KAAKI,WAAS,KAAA,KAAA,WAAA,MAAA,SAAA,GAAA,QAAA,EAAA,YAAA,YAAA,GAAA,cAAA,GAAA,IAAA,GAAA,QAAA,GAAA,CAAA,yDAAA,EAAA,EAAA,CAAA;SAAUC,KAAMA,SAAMD;IAAaE,GAAK;IAC7D,MAAA,MAAA,SAAA,CAAA;EAEF,EAAMC,KAAAA,GAAAA,IAAAA;;IAGJ,wBAAe;YACb,oBAAOC,IAAMC;EACf,IAAA,WAAA;AAEIC,WAAe,MAA0B,KAAA,KAAA,QAAA,OAAA,CAAA;;EAE7C,IAAA,SAAA;AAEAC,WAAuB,KAAQ,QAAA,IAAA,OAAA;;OAE7B,QAAKC;AACP,WAAA,WAAA,cAAA,OAAA,QAAA;AAEAC,SAAOH,QAAuB,IAAA,OAAA,UAAA,MAAA;;EAE9B,OAAA,SAAA;AACF,SAAA,QAAA,OAAA,OAAA;EAEA;AAEA
|
|
6
|
-
"names": ["invariant", "mods", "filter", "key", "includes", "length", "parts", "join", "KeyboardContext", "Array", "from", "binding", "bind", "_keyMap", "unbind", "_root", "ROOT", "_contexts", "_keyHandler", "_path", "initialize", "document", "destroy", "setCurrentContext", "path", "getCurrentContext", "getContext", "context", "sort", "getBindings", "i", "startsWith", "bindings", "shortcut", "handleKeyDown", "event", "tagName", "target", "str", "shiftKey", "altKey", "metaKey", "Boolean", "data", "handler", "disableInput", "isInput", "result", "getHostPlatform", "ctrl", "macos", "ios", "windows", "linux", "unknown", "alt", "meta", "getSymbol", "part", "platform", "toLowerCase", "toUpperCase", "keySymbols", "keyBinding", "parts", "split", "map"]
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { type MaybePromise } from '@dxos/util';\n\n// TODO(burdon): Replace with hotkeys-js, react-hotkeys, and react-hotkeys-hook.\n\nexport type KeyHandler = (props: {\n context: string;\n shortcut: string;\n data?: any;\n event: KeyboardEvent;\n}) => MaybePromise<boolean | void>;\n\nexport type KeyBinding = {\n shortcut: string;\n handler: KeyHandler;\n disableInput?: boolean;\n data?: any;\n};\n\n// Keybinding is normalized to this order.\n// https://support.apple.com/en-us/HT201236\nconst modifiers = ['ctrl', 'shift', 'alt', 'meta'];\n\n// Normalize order and case of modifiers.\nexport const parseShortcut = (shortcut: string, delimiter = /[+-]/): string => {\n const parts = shortcut.toLowerCase().split(delimiter);\n const mods = modifiers.filter((key) => parts.includes(key));\n invariant(mods.length === 0 || mods.length === parts.length - 1);\n // Assume single natural key.\n return mods.length ? [...mods, parts[parts.length - 1]].join('+') : shortcut;\n};\n\nclass KeyboardContext {\n readonly _keyMap = new Map<string, KeyBinding>();\n\n get bindings() {\n return Array.from(this._keyMap.values());\n }\n\n get(binding: string): KeyBinding | undefined {\n return this._keyMap.get(binding);\n }\n\n bind(config: KeyBinding): void {\n config.shortcut = parseShortcut(config.shortcut);\n this._keyMap.set(config.shortcut, config);\n }\n\n unbind(binding: string): void {\n this._keyMap.delete(binding);\n }\n}\n\nconst ROOT = '';\n\n/** Graph root segment; matches `@dxos/plugin-graph` `Node.RootId`. */\nexport const GRAPH_ROOT_ID = 'root';\n\n/**\n * Nest an attendable segment under the graph root so plank context inherits root-level bindings.\n * An empty/absent segment resolves to the graph root itself.\n */\nexport const nestKeyboardContext = (segment?: string): string =>\n segment\n ? segment === GRAPH_ROOT_ID || segment.startsWith(`${GRAPH_ROOT_ID}/`)\n ? segment\n : `${GRAPH_ROOT_ID}/${segment}`\n : GRAPH_ROOT_ID;\n\n/**\n * Manages context-aware key bindings.\n */\nexport class Keyboard {\n static singleton = new Keyboard();\n\n private readonly _root = new KeyboardContext();\n private readonly _keyMap = new Map<string, KeyboardContext>([[ROOT, this._root]]);\n private readonly _contexts: string[] = [ROOT];\n private readonly _keyHandler = this.handleKeyDown.bind(this);\n private _path = ROOT;\n\n initialize(): void {\n document.addEventListener('keydown', this._keyHandler);\n }\n\n destroy(): void {\n document.removeEventListener('keydown', this._keyHandler);\n }\n\n bind = this._root.bind.bind(this._root);\n unbind = this._root.unbind.bind(this._root);\n\n setCurrentContext(path = ROOT): void {\n this._path = path;\n }\n\n getCurrentContext(): string {\n return this._path;\n }\n\n getContext(path = ROOT): KeyboardContext {\n let context = this._keyMap.get(path);\n if (!context) {\n context = new KeyboardContext();\n this._keyMap.set(path, context);\n this._contexts.push(path);\n this._contexts.sort();\n }\n\n return context;\n }\n\n getBindings(): KeyBinding[] {\n const bindings = new Map<string, KeyBinding>();\n for (let i = 0; i < this._contexts.length; ++i) {\n const path = this._contexts[i];\n if (this._path.startsWith(path)) {\n this.getContext(path).bindings.forEach((binding) => {\n bindings.set(binding.shortcut, binding);\n });\n }\n }\n\n return Array.from(bindings.values());\n }\n\n async handleKeyDown(event: KeyboardEvent): Promise<void> {\n const { altKey, ctrlKey, metaKey, shiftKey, key } = event;\n\n if (key !== 'Alt' && key !== 'Control' && key !== 'Meta' && key !== 'Shift') {\n // Binding option to check for input or contenteditable.\n const tagName = (event.target as any)?.tagName;\n const isInput =\n tagName === 'INPUT' || tagName === 'TEXTAREA' || (event.target as any)?.getAttribute('contenteditable');\n\n // Normalized key binding (order and case; see parseShortcut).\n const str = parseShortcut(\n [ctrlKey && 'ctrl', shiftKey && 'shift', altKey && 'alt', metaKey && 'meta', key].filter(Boolean).join('+'),\n );\n\n // Scan matching contexts.\n for (let i = this._contexts.length - 1; i >= 0; --i) {\n const path = this._contexts[i];\n if (this._path.startsWith(path)) {\n const { data, handler, disableInput } = this.getContext(path).get(str) ?? {};\n if (handler && (!isInput || !disableInput)) {\n const result = await handler({ context: path, shortcut: str, data, event });\n if (result !== false) {\n // TODO(burdon): This doesn't prevent actions in markdown editor.\n // Reference: https://codemirror.net/docs/ref/#view.KeyBinding\n event.preventDefault();\n event.stopPropagation();\n }\n\n return;\n }\n }\n }\n }\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { getHostPlatform } from '@dxos/util';\n\n// Resources.\n// https://www.w3.org/TR/DOM-Level-3-Events/#events-keyboardevents\n// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key\n// https://developer.apple.com/design/human-interface-guidelines/designing-for-macos\n// https://support.apple.com/en-us/HT201236\n// https://support.apple.com/guide/mac-help/what-are-those-symbols-shown-in-menus-cpmh0011/mac\n\nconst ctrl: Record<string, string> = {\n macos: '⌃',\n ios: '⌃',\n windows: 'Ctrl',\n linux: 'Ctrl',\n unknown: 'Ctrl',\n};\n\nconst alt: Record<string, string> = {\n macos: '⌥',\n ios: '⌥',\n windows: 'Alt',\n linux: 'Alt',\n unknown: 'Alt',\n};\n\nconst meta: Record<string, string> = {\n macos: '⌘',\n ios: '⌘',\n windows: '⊞',\n // TODO(wittjosiah): Use ⌘ or ⊞ instead? Wait for user feedback.\n // From https://en.wikipedia.org/wiki/Super_key_(keyboard_button).\n linux: '❖',\n unknown: '❖',\n};\n\nconst getSymbol = (part: string) => {\n const platform = getHostPlatform();\n switch (part.toLowerCase()) {\n // Mods.\n case 'alt':\n return alt[platform];\n case 'ctrl':\n return ctrl[platform];\n case 'meta':\n return meta[platform];\n case 'shift':\n return '⇧';\n // Special keys.\n case 'backspace':\n return '⌫';\n case 'enter':\n return '⏎';\n case 'escape':\n return '⎋';\n case 'space':\n return '␣';\n case 'tab':\n return '⇥';\n default:\n return part.toUpperCase();\n }\n};\n\nexport const keySymbols = (keyBinding: string): string[] => {\n const parts = keyBinding.split('+');\n return parts.map(getSymbol);\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["invariant", "mods", "filter", "key", "includes", "length", "parts", "join", "KeyboardContext", "Array", "from", "binding", "bind", "_keyMap", "unbind", "_root", "ROOT", "_contexts", "_keyHandler", "_path", "initialize", "document", "destroy", "setCurrentContext", "path", "getCurrentContext", "getContext", "context", "sort", "getBindings", "i", "startsWith", "bindings", "shortcut", "handleKeyDown", "event", "tagName", "target", "str", "parseShortcut", "shiftKey", "altKey", "metaKey", "Boolean", "data", "handler", "disableInput", "isInput", "result", "getHostPlatform", "ctrl", "macos", "ios", "windows", "linux", "unknown", "alt", "meta", "getSymbol", "part", "platform", "toLowerCase", "toUpperCase", "keySymbols", "keyBinding", "parts", "split", "map"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"src/keyboard.ts":{"bytes":
|
|
1
|
+
{"inputs":{"src/keyboard.ts":{"bytes":17511,"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"src/util.ts":{"bytes":5581,"imports":[{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":456,"imports":[{"path":"src/keyboard.ts","kind":"import-statement","original":"./keyboard"},{"path":"src/util.ts","kind":"import-statement","original":"./util"}],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":10753},"dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["GRAPH_ROOT_ID","Keyboard","keySymbols","nestKeyboardContext","parseShortcut"],"entryPoint":"src/index.ts","inputs":{"src/keyboard.ts":{"bytesInOutput":3715},"src/index.ts":{"bytesInOutput":0},"src/util.ts":{"bytesInOutput":1184}},"bytes":5097}}}
|
|
@@ -35,6 +35,8 @@ var KeyboardContext = class {
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
var ROOT = "";
|
|
38
|
+
var GRAPH_ROOT_ID = "root";
|
|
39
|
+
var nestKeyboardContext = (segment) => segment ? segment === GRAPH_ROOT_ID || segment.startsWith(`${GRAPH_ROOT_ID}/`) ? segment : `${GRAPH_ROOT_ID}/${segment}` : GRAPH_ROOT_ID;
|
|
38
40
|
var Keyboard = class _Keyboard {
|
|
39
41
|
static singleton = new _Keyboard();
|
|
40
42
|
_root = new KeyboardContext();
|
|
@@ -90,13 +92,13 @@ var Keyboard = class _Keyboard {
|
|
|
90
92
|
if (key !== "Alt" && key !== "Control" && key !== "Meta" && key !== "Shift") {
|
|
91
93
|
const tagName = event.target?.tagName;
|
|
92
94
|
const isInput = tagName === "INPUT" || tagName === "TEXTAREA" || event.target?.getAttribute("contenteditable");
|
|
93
|
-
const str = [
|
|
95
|
+
const str = parseShortcut([
|
|
94
96
|
ctrlKey && "ctrl",
|
|
95
97
|
shiftKey && "shift",
|
|
96
98
|
altKey && "alt",
|
|
97
99
|
metaKey && "meta",
|
|
98
100
|
key
|
|
99
|
-
].filter(Boolean).join("+");
|
|
101
|
+
].filter(Boolean).join("+"));
|
|
100
102
|
for (let i = this._contexts.length - 1; i >= 0; --i) {
|
|
101
103
|
const path = this._contexts[i];
|
|
102
104
|
if (this._path.startsWith(path)) {
|
|
@@ -177,8 +179,10 @@ var keySymbols = (keyBinding) => {
|
|
|
177
179
|
return parts.map(getSymbol);
|
|
178
180
|
};
|
|
179
181
|
export {
|
|
182
|
+
GRAPH_ROOT_ID,
|
|
180
183
|
Keyboard,
|
|
181
184
|
keySymbols,
|
|
185
|
+
nestKeyboardContext,
|
|
182
186
|
parseShortcut
|
|
183
187
|
};
|
|
184
188
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/keyboard.ts", "../../../src/util.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { type MaybePromise } from '@dxos/util';\n\n// TODO(burdon): Replace with hotkeys-js, react-hotkeys, and react-hotkeys-hook.\n\nexport type KeyHandler = (props: {\n context: string;\n shortcut: string;\n data?: any;\n event: KeyboardEvent;\n}) => MaybePromise<boolean | void>;\n\nexport type KeyBinding = {\n shortcut: string;\n handler: KeyHandler;\n disableInput?: boolean;\n data?: any;\n};\n\n// Keybinding is normalized to this order.\n// https://support.apple.com/en-us/HT201236\nconst modifiers = ['ctrl', 'shift', 'alt', 'meta'];\n\n// Normalize order and case of modifiers.\nexport const parseShortcut = (shortcut: string, delimiter = /[+-]/): string => {\n const parts = shortcut.toLowerCase().split(delimiter);\n const mods = modifiers.filter((key) => parts.includes(key));\n invariant(mods.length === 0 || mods.length === parts.length - 1);\n // Assume single natural key.\n return mods.length ? [...mods, parts[parts.length - 1]].join('+') : shortcut;\n};\n\nclass KeyboardContext {\n readonly _keyMap = new Map<string, KeyBinding>();\n\n get bindings() {\n return Array.from(this._keyMap.values());\n }\n\n get(binding: string): KeyBinding | undefined {\n return this._keyMap.get(binding);\n }\n\n bind(config: KeyBinding): void {\n config.shortcut = parseShortcut(config.shortcut);\n this._keyMap.set(config.shortcut, config);\n }\n\n unbind(binding: string): void {\n this._keyMap.delete(binding);\n }\n}\n\nconst ROOT = '';\n\n/**\n * Manages context-aware key bindings.\n */\nexport class Keyboard {\n static singleton = new Keyboard();\n\n private readonly _root = new KeyboardContext();\n private readonly _keyMap = new Map<string, KeyboardContext>([[ROOT, this._root]]);\n private readonly _contexts: string[] = [ROOT];\n private readonly _keyHandler = this.handleKeyDown.bind(this);\n private _path = ROOT;\n\n initialize(): void {\n document.addEventListener('keydown', this._keyHandler);\n }\n\n destroy(): void {\n document.removeEventListener('keydown', this._keyHandler);\n }\n\n bind = this._root.bind.bind(this._root);\n unbind = this._root.unbind.bind(this._root);\n\n setCurrentContext(path = ROOT): void {\n this._path = path;\n }\n\n getCurrentContext(): string {\n return this._path;\n }\n\n getContext(path = ROOT): KeyboardContext {\n let context = this._keyMap.get(path);\n if (!context) {\n context = new KeyboardContext();\n this._keyMap.set(path, context);\n this._contexts.push(path);\n this._contexts.sort();\n }\n\n return context;\n }\n\n getBindings(): KeyBinding[] {\n const bindings = new Map<string, KeyBinding>();\n for (let i = 0; i < this._contexts.length; ++i) {\n const path = this._contexts[i];\n if (this._path.startsWith(path)) {\n this.getContext(path).bindings.forEach((binding) => {\n bindings.set(binding.shortcut, binding);\n });\n }\n }\n\n return Array.from(bindings.values());\n }\n\n async handleKeyDown(event: KeyboardEvent): Promise<void> {\n const { altKey, ctrlKey, metaKey, shiftKey, key } = event;\n\n if (key !== 'Alt' && key !== 'Control' && key !== 'Meta' && key !== 'Shift') {\n // Binding option to check for input or contenteditable.\n const tagName = (event.target as any)?.tagName;\n const isInput =\n tagName === 'INPUT' || tagName === 'TEXTAREA' || (event.target as any)?.getAttribute('contenteditable');\n\n // Normalized key binding (order
|
|
5
|
-
"mappings": ";;;AAIA,SAASA,iBAAiB;AAmB1B,IAAA,eAAA;IAE2B,YAAA;EAAS;EAAO;EAAO;EAElD;AACA;AAEE,IAAMC,gBAAiBC,CAAAA,UAAQC,YAAcC,WAASD;AACtDH,QAAAA,QAAUC,SAAW,YAAUA,EAAKI,MAAM,SAAKC;AAC/C,QAAA,OAAA,UAAA,OAA6B,CAAA,QAAA,MAAA,SAAA,GAAA,CAAA;AAC7B,YAAOL,KAAKI,WAAS,KAAA,KAAA,WAAA,MAAA,SAAA,GAAA,QAAA,EAAA,YAAA,YAAA,GAAA,cAAA,GAAA,IAAA,GAAA,QAAA,GAAA,CAAA,yDAAA,EAAA,EAAA,CAAA;SAAUC,KAAMA,SAAMD;IAAaE,GAAK;IAC7D,MAAA,MAAA,SAAA,CAAA;EAEF,EAAMC,KAAAA,GAAAA,IAAAA;;IAGJ,wBAAe;YACb,oBAAOC,IAAMC;EACf,IAAA,WAAA;AAEIC,WAAe,MAA0B,KAAA,KAAA,QAAA,OAAA,CAAA;;EAE7C,IAAA,SAAA;AAEAC,WAAuB,KAAQ,QAAA,IAAA,OAAA;;OAE7B,QAAKC;AACP,WAAA,WAAA,cAAA,OAAA,QAAA;AAEAC,SAAOH,QAAuB,IAAA,OAAA,UAAA,MAAA;;EAE9B,OAAA,SAAA;AACF,SAAA,QAAA,OAAA,OAAA;EAEA;AAEA
|
|
6
|
-
"names": ["invariant", "mods", "filter", "key", "includes", "length", "parts", "join", "KeyboardContext", "Array", "from", "binding", "bind", "_keyMap", "unbind", "_root", "ROOT", "_contexts", "_keyHandler", "_path", "initialize", "document", "destroy", "setCurrentContext", "path", "getCurrentContext", "getContext", "context", "sort", "getBindings", "i", "startsWith", "bindings", "shortcut", "handleKeyDown", "event", "tagName", "target", "str", "shiftKey", "altKey", "metaKey", "Boolean", "data", "handler", "disableInput", "isInput", "result", "getHostPlatform", "ctrl", "macos", "ios", "windows", "linux", "unknown", "alt", "meta", "getSymbol", "part", "platform", "toLowerCase", "toUpperCase", "keySymbols", "keyBinding", "parts", "split", "map"]
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { type MaybePromise } from '@dxos/util';\n\n// TODO(burdon): Replace with hotkeys-js, react-hotkeys, and react-hotkeys-hook.\n\nexport type KeyHandler = (props: {\n context: string;\n shortcut: string;\n data?: any;\n event: KeyboardEvent;\n}) => MaybePromise<boolean | void>;\n\nexport type KeyBinding = {\n shortcut: string;\n handler: KeyHandler;\n disableInput?: boolean;\n data?: any;\n};\n\n// Keybinding is normalized to this order.\n// https://support.apple.com/en-us/HT201236\nconst modifiers = ['ctrl', 'shift', 'alt', 'meta'];\n\n// Normalize order and case of modifiers.\nexport const parseShortcut = (shortcut: string, delimiter = /[+-]/): string => {\n const parts = shortcut.toLowerCase().split(delimiter);\n const mods = modifiers.filter((key) => parts.includes(key));\n invariant(mods.length === 0 || mods.length === parts.length - 1);\n // Assume single natural key.\n return mods.length ? [...mods, parts[parts.length - 1]].join('+') : shortcut;\n};\n\nclass KeyboardContext {\n readonly _keyMap = new Map<string, KeyBinding>();\n\n get bindings() {\n return Array.from(this._keyMap.values());\n }\n\n get(binding: string): KeyBinding | undefined {\n return this._keyMap.get(binding);\n }\n\n bind(config: KeyBinding): void {\n config.shortcut = parseShortcut(config.shortcut);\n this._keyMap.set(config.shortcut, config);\n }\n\n unbind(binding: string): void {\n this._keyMap.delete(binding);\n }\n}\n\nconst ROOT = '';\n\n/** Graph root segment; matches `@dxos/plugin-graph` `Node.RootId`. */\nexport const GRAPH_ROOT_ID = 'root';\n\n/**\n * Nest an attendable segment under the graph root so plank context inherits root-level bindings.\n * An empty/absent segment resolves to the graph root itself.\n */\nexport const nestKeyboardContext = (segment?: string): string =>\n segment\n ? segment === GRAPH_ROOT_ID || segment.startsWith(`${GRAPH_ROOT_ID}/`)\n ? segment\n : `${GRAPH_ROOT_ID}/${segment}`\n : GRAPH_ROOT_ID;\n\n/**\n * Manages context-aware key bindings.\n */\nexport class Keyboard {\n static singleton = new Keyboard();\n\n private readonly _root = new KeyboardContext();\n private readonly _keyMap = new Map<string, KeyboardContext>([[ROOT, this._root]]);\n private readonly _contexts: string[] = [ROOT];\n private readonly _keyHandler = this.handleKeyDown.bind(this);\n private _path = ROOT;\n\n initialize(): void {\n document.addEventListener('keydown', this._keyHandler);\n }\n\n destroy(): void {\n document.removeEventListener('keydown', this._keyHandler);\n }\n\n bind = this._root.bind.bind(this._root);\n unbind = this._root.unbind.bind(this._root);\n\n setCurrentContext(path = ROOT): void {\n this._path = path;\n }\n\n getCurrentContext(): string {\n return this._path;\n }\n\n getContext(path = ROOT): KeyboardContext {\n let context = this._keyMap.get(path);\n if (!context) {\n context = new KeyboardContext();\n this._keyMap.set(path, context);\n this._contexts.push(path);\n this._contexts.sort();\n }\n\n return context;\n }\n\n getBindings(): KeyBinding[] {\n const bindings = new Map<string, KeyBinding>();\n for (let i = 0; i < this._contexts.length; ++i) {\n const path = this._contexts[i];\n if (this._path.startsWith(path)) {\n this.getContext(path).bindings.forEach((binding) => {\n bindings.set(binding.shortcut, binding);\n });\n }\n }\n\n return Array.from(bindings.values());\n }\n\n async handleKeyDown(event: KeyboardEvent): Promise<void> {\n const { altKey, ctrlKey, metaKey, shiftKey, key } = event;\n\n if (key !== 'Alt' && key !== 'Control' && key !== 'Meta' && key !== 'Shift') {\n // Binding option to check for input or contenteditable.\n const tagName = (event.target as any)?.tagName;\n const isInput =\n tagName === 'INPUT' || tagName === 'TEXTAREA' || (event.target as any)?.getAttribute('contenteditable');\n\n // Normalized key binding (order and case; see parseShortcut).\n const str = parseShortcut(\n [ctrlKey && 'ctrl', shiftKey && 'shift', altKey && 'alt', metaKey && 'meta', key].filter(Boolean).join('+'),\n );\n\n // Scan matching contexts.\n for (let i = this._contexts.length - 1; i >= 0; --i) {\n const path = this._contexts[i];\n if (this._path.startsWith(path)) {\n const { data, handler, disableInput } = this.getContext(path).get(str) ?? {};\n if (handler && (!isInput || !disableInput)) {\n const result = await handler({ context: path, shortcut: str, data, event });\n if (result !== false) {\n // TODO(burdon): This doesn't prevent actions in markdown editor.\n // Reference: https://codemirror.net/docs/ref/#view.KeyBinding\n event.preventDefault();\n event.stopPropagation();\n }\n\n return;\n }\n }\n }\n }\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { getHostPlatform } from '@dxos/util';\n\n// Resources.\n// https://www.w3.org/TR/DOM-Level-3-Events/#events-keyboardevents\n// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key\n// https://developer.apple.com/design/human-interface-guidelines/designing-for-macos\n// https://support.apple.com/en-us/HT201236\n// https://support.apple.com/guide/mac-help/what-are-those-symbols-shown-in-menus-cpmh0011/mac\n\nconst ctrl: Record<string, string> = {\n macos: '⌃',\n ios: '⌃',\n windows: 'Ctrl',\n linux: 'Ctrl',\n unknown: 'Ctrl',\n};\n\nconst alt: Record<string, string> = {\n macos: '⌥',\n ios: '⌥',\n windows: 'Alt',\n linux: 'Alt',\n unknown: 'Alt',\n};\n\nconst meta: Record<string, string> = {\n macos: '⌘',\n ios: '⌘',\n windows: '⊞',\n // TODO(wittjosiah): Use ⌘ or ⊞ instead? Wait for user feedback.\n // From https://en.wikipedia.org/wiki/Super_key_(keyboard_button).\n linux: '❖',\n unknown: '❖',\n};\n\nconst getSymbol = (part: string) => {\n const platform = getHostPlatform();\n switch (part.toLowerCase()) {\n // Mods.\n case 'alt':\n return alt[platform];\n case 'ctrl':\n return ctrl[platform];\n case 'meta':\n return meta[platform];\n case 'shift':\n return '⇧';\n // Special keys.\n case 'backspace':\n return '⌫';\n case 'enter':\n return '⏎';\n case 'escape':\n return '⎋';\n case 'space':\n return '␣';\n case 'tab':\n return '⇥';\n default:\n return part.toUpperCase();\n }\n};\n\nexport const keySymbols = (keyBinding: string): string[] => {\n const parts = keyBinding.split('+');\n return parts.map(getSymbol);\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["invariant", "mods", "filter", "key", "includes", "length", "parts", "join", "KeyboardContext", "Array", "from", "binding", "bind", "_keyMap", "unbind", "_root", "ROOT", "_contexts", "_keyHandler", "_path", "initialize", "document", "destroy", "setCurrentContext", "path", "getCurrentContext", "getContext", "context", "sort", "getBindings", "i", "startsWith", "bindings", "shortcut", "handleKeyDown", "event", "tagName", "target", "str", "parseShortcut", "shiftKey", "altKey", "metaKey", "Boolean", "data", "handler", "disableInput", "isInput", "result", "getHostPlatform", "ctrl", "macos", "ios", "windows", "linux", "unknown", "alt", "meta", "getSymbol", "part", "platform", "toLowerCase", "toUpperCase", "keySymbols", "keyBinding", "parts", "split", "map"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"src/keyboard.ts":{"bytes":
|
|
1
|
+
{"inputs":{"src/keyboard.ts":{"bytes":17511,"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"src/util.ts":{"bytes":5581,"imports":[{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":456,"imports":[{"path":"src/keyboard.ts","kind":"import-statement","original":"./keyboard"},{"path":"src/util.ts","kind":"import-statement","original":"./util"}],"format":"esm"}},"outputs":{"dist/lib/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":10753},"dist/lib/node-esm/index.mjs":{"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["GRAPH_ROOT_ID","Keyboard","keySymbols","nestKeyboardContext","parseShortcut"],"entryPoint":"src/index.ts","inputs":{"src/keyboard.ts":{"bytesInOutput":3715},"src/index.ts":{"bytesInOutput":0},"src/util.ts":{"bytesInOutput":1184}},"bytes":5156}}}
|
|
@@ -19,6 +19,13 @@ declare class KeyboardContext {
|
|
|
19
19
|
bind(config: KeyBinding): void;
|
|
20
20
|
unbind(binding: string): void;
|
|
21
21
|
}
|
|
22
|
+
/** Graph root segment; matches `@dxos/plugin-graph` `Node.RootId`. */
|
|
23
|
+
export declare const GRAPH_ROOT_ID = "root";
|
|
24
|
+
/**
|
|
25
|
+
* Nest an attendable segment under the graph root so plank context inherits root-level bindings.
|
|
26
|
+
* An empty/absent segment resolves to the graph root itself.
|
|
27
|
+
*/
|
|
28
|
+
export declare const nestKeyboardContext: (segment?: string) => string;
|
|
22
29
|
/**
|
|
23
30
|
* Manages context-aware key bindings.
|
|
24
31
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../../src/keyboard.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,EAAE,aAAa,CAAC;CACtB,KAAK,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;AAEnC,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ,CAAC;AAOF,eAAO,MAAM,aAAa,aAAc,MAAM,yBAAuB,MAMpE,CAAC;AAEF,cAAM,eAAe;IACnB,QAAQ,CAAC,OAAO,0BAAiC;IAEjD,IAAI,QAAQ,iBAEX;IAED,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE3C;IAED,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAG7B;IAED,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE5B;CACF;AAID;;GAEG;AACH,qBAAa,QAAQ;IACnB,MAAM,CAAC,SAAS,WAAkB;IAElC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0D;IAClF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;IAC7D,OAAO,CAAC,KAAK,CAAQ;IAErB,UAAU,IAAI,IAAI,CAEjB;IAED,OAAO,IAAI,IAAI,CAEd;IAED,IAAI,
|
|
1
|
+
{"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../../src/keyboard.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,EAAE,aAAa,CAAC;CACtB,KAAK,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;AAEnC,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ,CAAC;AAOF,eAAO,MAAM,aAAa,aAAc,MAAM,yBAAuB,MAMpE,CAAC;AAEF,cAAM,eAAe;IACnB,QAAQ,CAAC,OAAO,0BAAiC;IAEjD,IAAI,QAAQ,iBAEX;IAED,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE3C;IAED,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAG7B;IAED,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE5B;CACF;AAID,sEAAsE;AACtE,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,aAAc,MAAM,KAAG,MAKpC,CAAC;AAEpB;;GAEG;AACH,qBAAa,QAAQ;IACnB,MAAM,CAAC,SAAS,WAAkB;IAElC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0D;IAClF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;IAC7D,OAAO,CAAC,KAAK,CAAQ;IAErB,UAAU,IAAI,IAAI,CAEjB;IAED,OAAO,IAAI,IAAI,CAEd;IAED,IAAI,WA9CS,UAAU,KAAG,IAAI,CA8CU;IACxC,MAAM,YA1CU,MAAM,KAAG,IAAI,CA0Ce;IAE5C,iBAAiB,CAAC,IAAI,SAAO,GAAG,IAAI,CAEnC;IAED,iBAAiB,IAAI,MAAM,CAE1B;IAED,UAAU,CAAC,IAAI,SAAO,GAAG,eAAe,CAUvC;IAED,WAAW,IAAI,UAAU,EAAE,CAY1B;IAEK,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCvD;CACF"}
|