hotkey-router 0.2.3 → 0.3.0
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/ADDITIONAL_TERMS.md +122 -122
- package/LICENSE +694 -694
- package/README.md +99 -2
- package/data/browser-hotkeys.json +349 -349
- package/data/site-hotkeys.json +4571 -0
- package/data/site-hotkeys.runtime.json +1 -0
- package/dist/auto.js +52 -5
- package/dist/auto.js.map +2 -2
- package/dist/auto.min.js +2 -2
- package/dist/hotkey-router.cjs +55 -6
- package/dist/hotkey-router.cjs.map +2 -2
- package/dist/hotkey-router.js +55 -6
- package/dist/hotkey-router.js.map +2 -2
- package/dist/hotkey-router.min.js +2 -2
- package/dist/reservations.js +1 -1
- package/dist/reservations.js.map +1 -1
- package/dist/sites.js +185 -0
- package/dist/sites.js.map +7 -0
- package/dist/types/auto.d.ts +2 -0
- package/dist/types/hotkey-router.d.ts +196 -0
- package/dist/types/reservations.d.ts +80 -0
- package/dist/types/sites.d.ts +109 -0
- package/dist/types/validate.d.ts +42 -0
- package/dist/validate.js +106 -0
- package/dist/validate.js.map +7 -0
- package/package.json +18 -7
- package/robots.txt +79 -79
package/README.md
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/hotkey-router)
|
|
4
4
|
[](https://www.npmjs.com/package/hotkey-router)
|
|
5
5
|
[](https://bundlephobia.com/package/hotkey-router)
|
|
6
|
-
[](https://github.com/iWhatty/hotkey-router
|
|
7
|
-
[](https://github.com/iWhatty/hotkey-router/blob/main/LICENSE)
|
|
7
|
+
[](https://github.com/iWhatty/hotkey-router)
|
|
8
|
+
[](https://www.npmjs.com/package/hotkey-router)
|
|
8
9
|
|
|
9
10
|
A tiny, deterministic keyboard routing engine for modern web apps. Not a key utility, a predictable plugin-first routing layer for keyboard shortcuts.
|
|
10
11
|
|
|
@@ -113,9 +114,17 @@ off()
|
|
|
113
114
|
allowIn?: (event) => boolean
|
|
114
115
|
priority?: number // default 0
|
|
115
116
|
warnOnReserved?: boolean // only read when conflict warnings are installed
|
|
117
|
+
capture?: boolean // v0.3.0+: run in the capture phase, before the page's listeners
|
|
118
|
+
altGraph?: boolean // v0.3.0+: also fire on an AltGr keystroke that types a character
|
|
119
|
+
composing?: boolean // v0.3.0+: also fire during IME composition
|
|
116
120
|
}
|
|
117
121
|
```
|
|
118
122
|
|
|
123
|
+
By default (v0.3.0+), a binding is skipped when the keystroke is AltGr typing
|
|
124
|
+
a character (Windows reports AltGr as Ctrl+Alt, so `ctrl+alt+code:Comma`
|
|
125
|
+
would otherwise swallow the `<` a Polish or Czech user typed) and while an
|
|
126
|
+
IME is composing.
|
|
127
|
+
|
|
119
128
|
**Examples**
|
|
120
129
|
|
|
121
130
|
Ignore repeat keydown (default behavior):
|
|
@@ -218,6 +227,27 @@ hotkeys.init({
|
|
|
218
227
|
|
|
219
228
|
Auto-initializes on `window` by default (browser environments).
|
|
220
229
|
|
|
230
|
+
With `capture: false` (the default), bindings run in the bubble phase except
|
|
231
|
+
those bound with `{ capture: true }`, which a second, capture-phase listener
|
|
232
|
+
handles (v0.3.0+). `capture: true` here runs every binding in the capture
|
|
233
|
+
phase.
|
|
234
|
+
|
|
235
|
+
### `parseHotkey(hotkey)` / `comboFromEvent(event, options?)` (v0.3.0+)
|
|
236
|
+
|
|
237
|
+
Named exports (also on the default object). `comboFromEvent` turns a
|
|
238
|
+
keyboard event into a hotkey string for a "press your keys" recorder:
|
|
239
|
+
physical by default, `{ useMod: true }` writes the platform's primary
|
|
240
|
+
modifier as `mod`, and it returns `null` while only a modifier is held.
|
|
241
|
+
|
|
242
|
+
```js
|
|
243
|
+
import { comboFromEvent } from 'hotkey-router'
|
|
244
|
+
|
|
245
|
+
input.addEventListener('keydown', (e) => {
|
|
246
|
+
const combo = comboFromEvent(e, { useMod: true }) // 'mod+shift+code:Period'
|
|
247
|
+
if (combo) save(combo)
|
|
248
|
+
})
|
|
249
|
+
```
|
|
250
|
+
|
|
221
251
|
### `destroy()`
|
|
222
252
|
|
|
223
253
|
Removes all listeners and clears internal state.
|
|
@@ -363,6 +393,73 @@ const off = hotkeys.onBind(({ combo, raw, options, plugin, id }) => {
|
|
|
363
393
|
// off() unsubscribes.
|
|
364
394
|
```
|
|
365
395
|
|
|
396
|
+
### Website shortcuts (v0.3.0+)
|
|
397
|
+
|
|
398
|
+
Apps that run on other people's pages (browser extensions, embedded widgets)
|
|
399
|
+
collide with the page's own shortcuts: Google Docs uses Ctrl+Shift+. for font
|
|
400
|
+
size, GitHub for "quote". Unlike browser keys, those reach the page, so the
|
|
401
|
+
app can choose. `hotkey-router/sites` knows which popular sites use which
|
|
402
|
+
chords in the Ctrl/Cmd+Shift, Ctrl/Cmd+Alt, Shift+Alt and Ctrl/Cmd+Alt+Shift
|
|
403
|
+
families ([docs/site-hotkeys.md](docs/site-hotkeys.md), sourced data in
|
|
404
|
+
`data/site-hotkeys.json`) and builds a `when()` gate that yields to the site
|
|
405
|
+
unless the user is focused on the app:
|
|
406
|
+
|
|
407
|
+
```js
|
|
408
|
+
import hotkeys from 'hotkey-router'
|
|
409
|
+
import { siteAware } from 'hotkey-router/sites'
|
|
410
|
+
|
|
411
|
+
hotkeys.bind('mod+shift+code:Period', nextTypo, null, {
|
|
412
|
+
capture: true, // see the key before the page's editor
|
|
413
|
+
preventDefault: true,
|
|
414
|
+
stopPropagation: true, // when we take it, the page doesn't run it too
|
|
415
|
+
allowIn: () => true,
|
|
416
|
+
when: siteAware('mod+shift+code:Period', {
|
|
417
|
+
engaged: () => popupIsOpen() || panelHasFocus(),
|
|
418
|
+
}),
|
|
419
|
+
})
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
On sites that don't use the chord the gate is always true. On sites that do
|
|
423
|
+
(Docs, Slides, Confluence, GitHub, WordPress ...), it returns `engaged()`;
|
|
424
|
+
when that is false, the router leaves the event untouched and the site's
|
|
425
|
+
shortcut runs.
|
|
426
|
+
|
|
427
|
+
Also exported: `lookupSiteConflicts(combo, { url, platform, verifiedOnly })`,
|
|
428
|
+
`matchSites(url)`, `siteLookupKey(combo, platform)`, `detectSitePlatform()`
|
|
429
|
+
and `listSites()`. Platforms: `windows` (also used for Linux), `mac`,
|
|
430
|
+
`chromeos`. The runtime table is ~7 KB gzipped and imports nothing from the
|
|
431
|
+
core, so it never creates a second router.
|
|
432
|
+
|
|
433
|
+
### Validating a recorded combo (v0.3.0+)
|
|
434
|
+
|
|
435
|
+
For a "press your keys" setting: record with `comboFromEvent`, then check
|
|
436
|
+
with `hotkey-router/validate` before saving. Reasons come in plain language,
|
|
437
|
+
ready to show.
|
|
438
|
+
|
|
439
|
+
```js
|
|
440
|
+
import { comboFromEvent } from 'hotkey-router'
|
|
441
|
+
import { validateCombo } from 'hotkey-router/validate'
|
|
442
|
+
|
|
443
|
+
field.addEventListener('keydown', (e) => {
|
|
444
|
+
e.preventDefault()
|
|
445
|
+
const combo = comboFromEvent(e, { useMod: true })
|
|
446
|
+
if (!combo) return // still holding modifiers
|
|
447
|
+
const { ok, reasons } = validateCombo(combo, {
|
|
448
|
+
requirePrimary: true, // must include Ctrl (Cmd on macOS)
|
|
449
|
+
minModifiers: 2,
|
|
450
|
+
taken: ['mod+shift+code:Space'],
|
|
451
|
+
})
|
|
452
|
+
show(reasons.map((r) => r.message))
|
|
453
|
+
if (ok) save(combo)
|
|
454
|
+
})
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
Errors (`ok: false`): no key, no modifier, Alt as the only modifier on
|
|
458
|
+
Windows/Linux, a rule you asked for (`requirePrimary`, `minModifiers`),
|
|
459
|
+
already in `taken`, or reserved by a browser/OS (never reaches the page).
|
|
460
|
+
Warnings (`ok: true`): reserved only in some situations, Ctrl+Alt acting as
|
|
461
|
+
AltGr on some Windows layouts, and sites that use the same keys.
|
|
462
|
+
|
|
366
463
|
### Supported syntax
|
|
367
464
|
|
|
368
465
|
**Standard:**
|