@peter.naydenov/shortcuts 3.4.0 → 3.5.1
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/Changelog.md +11 -0
- package/README.md +38 -9
- package/dist/main.d.ts +120 -0
- package/dist/methods/_normalizeWithPlugins.d.ts +2 -0
- package/dist/methods/_readShortcutWithPlugins.d.ts +2 -0
- package/dist/methods/_systemAction.d.ts +2 -0
- package/dist/methods/changeContext.d.ts +2 -0
- package/dist/methods/index.d.ts +17 -0
- package/dist/methods/listShortcuts.d.ts +17 -0
- package/dist/methods/load.d.ts +2 -0
- package/dist/methods/unload.d.ts +2 -0
- package/dist/plugins/click/_findTarget.d.ts +2 -0
- package/dist/plugins/click/_listenDOM.d.ts +5 -0
- package/dist/plugins/click/_normalizeShortcutName.d.ts +2 -0
- package/dist/plugins/click/_readClickEvent.d.ts +2 -0
- package/dist/plugins/click/_registerShortcutEvents.d.ts +2 -0
- package/dist/plugins/click/index.d.ts +15 -0
- package/dist/plugins/form/_defaults.d.ts +5 -0
- package/dist/plugins/form/_listenDOM.d.ts +5 -0
- package/dist/plugins/form/_normalizeShortcutName.d.ts +2 -0
- package/dist/plugins/form/_registerShortcutEvents.d.ts +2 -0
- package/dist/plugins/form/index.d.ts +10 -0
- package/dist/plugins/key/_listenDOM.d.ts +5 -0
- package/dist/plugins/key/_normalizeShortcutName.d.ts +2 -0
- package/dist/plugins/key/_readKeyEvent.d.ts +2 -0
- package/dist/plugins/key/_registerShortcutEvents.d.ts +2 -0
- package/dist/plugins/key/_specialChars.d.ts +32 -0
- package/dist/plugins/key/index.d.ts +15 -0
- package/dist/shortcuts.cjs +1 -1
- package/dist/shortcuts.esm.mjs +1 -1
- package/dist/shortcuts.umd.js +1 -1
- package/package.json +9 -5
- package/src/main.js +74 -20
- package/src/methods/changeContext.js +2 -1
- package/src/methods/load.js +4 -3
- package/src/methods/unload.js +3 -3
- package/src/plugins/click/_listenDOM.js +1 -1
- package/src/plugins/click/index.js +10 -0
- package/src/plugins/form/index.js +8 -13
- package/src/plugins/key/index.js +10 -0
- package/test/01-general.test.js +64 -5
- package/test/02-key.test.js +136 -38
- package/test/03-click.test.js +88 -56
- package/test/04-form.test.js +52 -9
- package/tsconfig.json +23 -0
package/Changelog.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
### 3.5.1 ( 2025-10-20 )
|
|
6
|
+
- [x] Update in package.json. Field 'types' was added;
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### 3.5.0 ( 2025-10-19)
|
|
11
|
+
- [x] Featire: New method 'listPlugins' to get list of enabled plugins;
|
|
12
|
+
- [x] Upgrade: Improvment of type definitions. New d.ts files were added;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
5
16
|
### 3.4.0 ( 2025-10-18)
|
|
6
17
|
- [x] Feature: New method 'reset' to reset the library instance;
|
|
7
18
|
- [x] Refactoring: Added 'active' state property to 'click' plugin state management;
|
package/README.md
CHANGED
|
@@ -6,14 +6,15 @@
|
|
|
6
6
|

|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
Describe all page activities as list of shortcuts wrapped in contexts. Switch among available contexts.
|
|
11
|
-
Library has a plugin system to extend the possible `shortcut names`/`event coverage`. Plugins role is to convert DOM events to shortcut strings, then the core part will trigger the action functions related to the shortcut. At the moment we have 3 plugins:
|
|
12
|
-
- `key` - converts keyboard events to shortcut names;
|
|
13
|
-
- `click` - converts mouse events to shortcut names;
|
|
14
|
-
- `form` - watches for form elements changes;
|
|
15
9
|
|
|
16
|
-
|
|
10
|
+
A shortcut management library that wrappes shortcut definitions in a context and allows to switch between contexts. Shortcuts are events triggered by keyboard, mouse, and DOM events. The library has a plugin system that makes the library extensible.
|
|
11
|
+
|
|
12
|
+
Currently existing plugins:
|
|
13
|
+
- `key` - Converts keyboard events to shortcuts;
|
|
14
|
+
- `click` - Converts mouse events to shortcuts;
|
|
15
|
+
- `form` - Form element changes to shortcuts;
|
|
16
|
+
|
|
17
|
+
Planned work on plugins: `scroll`, `drag-drop`, etc.
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
|
|
@@ -49,9 +50,9 @@ Load a shortcut definition by calling `load` method.
|
|
|
49
50
|
|
|
50
51
|
```js
|
|
51
52
|
// for es6 module projects:
|
|
52
|
-
|
|
53
|
+
import { shortcuts, pluginKey, pluginClick, pluginForm } from '@peter.naydenov/shortcuts'
|
|
53
54
|
// for commonjs projects:
|
|
54
|
-
const { shortcuts, pluginKey, pluginClick } = require('@peter.naydenov/shortcuts')
|
|
55
|
+
const { shortcuts, pluginKey, pluginClick, pluginForm } = require('@peter.naydenov/shortcuts')
|
|
55
56
|
|
|
56
57
|
|
|
57
58
|
|
|
@@ -393,12 +394,14 @@ Description of the methods of shortcut instance:
|
|
|
393
394
|
, emit : 'Trigger a shortcut or custom event programmatically.'
|
|
394
395
|
, pause : 'Stop listening for shortcuts.'
|
|
395
396
|
, resume : 'Resume listening for shortcuts.'
|
|
397
|
+
, listPlugins : "Return list of enabled plugins. Plugins are represented by plugin's prefixes."
|
|
396
398
|
, listContexts : 'Return list of available contexts.'
|
|
397
399
|
, listShortcuts : 'Return list of shortcuts per context.'
|
|
398
400
|
, getNote : `Return a name of current note or null if note isn't set`
|
|
399
401
|
, setNote : 'Set a note to current context.'
|
|
400
402
|
, setDependencies : 'Set dependencies that will be available in action functions.'
|
|
401
403
|
, getDependencies : 'Return a dependencies object.'
|
|
404
|
+
, reset : 'Reset shortcut instance.'
|
|
402
405
|
```
|
|
403
406
|
|
|
404
407
|
### How to 'pause' and 'resume'?
|
|
@@ -482,6 +485,32 @@ Plugin options are provided as a second argument during the plugin enabling. It'
|
|
|
482
485
|
|
|
483
486
|
|
|
484
487
|
|
|
488
|
+
## TypeScript Support
|
|
489
|
+
|
|
490
|
+
The library includes TypeScript definitions. Install the package and TypeScript will automatically detect the types.
|
|
491
|
+
|
|
492
|
+
```typescript
|
|
493
|
+
import { shortcuts, pluginKey, pluginClick, pluginForm } from '@peter.naydenov/shortcuts';
|
|
494
|
+
|
|
495
|
+
const short: ShortcutsAPI = shortcuts();
|
|
496
|
+
short.enablePlugin(pluginKey);
|
|
497
|
+
short.enablePlugin(pluginClick);
|
|
498
|
+
short.enablePlugin(pluginForm);
|
|
499
|
+
|
|
500
|
+
// Type-safe shortcut definitions
|
|
501
|
+
const shortcutDefinition = {
|
|
502
|
+
myContext: {
|
|
503
|
+
'key:ctrl+s': () => console.log('Saved'),
|
|
504
|
+
'click:left-1': (args: { target: HTMLElement }) => console.log('Clicked', args.target)
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
short.load(shortcutDefinition);
|
|
509
|
+
short.changeContext('myContext');
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
The `ShortcutsAPI` interface provides full type safety for all methods and their parameters.
|
|
513
|
+
|
|
485
514
|
## Links
|
|
486
515
|
|
|
487
516
|
- [History of changes](https://github.com/PeterNaydenov/shortcuts/blob/main/Changelog.md)
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export type PluginAPI = {
|
|
2
|
+
/**
|
|
3
|
+
* - Get plugin prefix
|
|
4
|
+
*/
|
|
5
|
+
getPrefix: () => string;
|
|
6
|
+
/**
|
|
7
|
+
* - Format shortcut name
|
|
8
|
+
*/
|
|
9
|
+
shortcutName: (arg0: string) => string;
|
|
10
|
+
/**
|
|
11
|
+
* - Handle context change
|
|
12
|
+
*/
|
|
13
|
+
contextChange: (arg0: string) => void;
|
|
14
|
+
/**
|
|
15
|
+
* - Mute the plugin
|
|
16
|
+
*/
|
|
17
|
+
mute: () => void;
|
|
18
|
+
/**
|
|
19
|
+
* - Unmute the plugin
|
|
20
|
+
*/
|
|
21
|
+
unmute: () => void;
|
|
22
|
+
/**
|
|
23
|
+
* - Destroy the plugin
|
|
24
|
+
*/
|
|
25
|
+
destroy: () => void;
|
|
26
|
+
};
|
|
27
|
+
export type ShortcutsAPI = {
|
|
28
|
+
/**
|
|
29
|
+
* - Enable a plugin
|
|
30
|
+
*/
|
|
31
|
+
enablePlugin: (arg0: Function, arg1: any) => void;
|
|
32
|
+
/**
|
|
33
|
+
* - Disable a plugin
|
|
34
|
+
*/
|
|
35
|
+
disablePlugin: (arg0: string) => void;
|
|
36
|
+
/**
|
|
37
|
+
* - Mute a plugin
|
|
38
|
+
*/
|
|
39
|
+
mutePlugin: (arg0: string) => number;
|
|
40
|
+
/**
|
|
41
|
+
* - Unmute a plugin
|
|
42
|
+
*/
|
|
43
|
+
unmutePlugin: (arg0: string) => number;
|
|
44
|
+
/**
|
|
45
|
+
* - List enabled plugins
|
|
46
|
+
*/
|
|
47
|
+
listPlugins: () => string[];
|
|
48
|
+
/**
|
|
49
|
+
* - Get current context name
|
|
50
|
+
*/
|
|
51
|
+
getContext: () => string | null;
|
|
52
|
+
/**
|
|
53
|
+
* - Get current context note
|
|
54
|
+
*/
|
|
55
|
+
getNote: () => string | null;
|
|
56
|
+
/**
|
|
57
|
+
* - Set current context note
|
|
58
|
+
*/
|
|
59
|
+
setNote: (arg0: string | null) => void;
|
|
60
|
+
/**
|
|
61
|
+
* - Pause shortcuts in current context
|
|
62
|
+
*/
|
|
63
|
+
pause: (arg0: string) => void;
|
|
64
|
+
/**
|
|
65
|
+
* - Resume shortcuts in current context
|
|
66
|
+
*/
|
|
67
|
+
resume: (arg0: string) => void;
|
|
68
|
+
/**
|
|
69
|
+
* - Emit event for shortcut
|
|
70
|
+
*/
|
|
71
|
+
emit: (arg0: string, ...args: any[]) => void;
|
|
72
|
+
/**
|
|
73
|
+
* - List all context names
|
|
74
|
+
*/
|
|
75
|
+
listContexts: () => string[];
|
|
76
|
+
/**
|
|
77
|
+
* - Set external dependencies
|
|
78
|
+
*/
|
|
79
|
+
setDependencies: (arg0: any) => void;
|
|
80
|
+
/**
|
|
81
|
+
* - Get external dependencies
|
|
82
|
+
*/
|
|
83
|
+
getDependencies: () => any;
|
|
84
|
+
/**
|
|
85
|
+
* - Reset the library instance
|
|
86
|
+
*/
|
|
87
|
+
reset: () => void;
|
|
88
|
+
/**
|
|
89
|
+
* - Change current context
|
|
90
|
+
*/
|
|
91
|
+
changeContext: (arg0: string | boolean) => void;
|
|
92
|
+
/**
|
|
93
|
+
* - List shortcuts
|
|
94
|
+
*/
|
|
95
|
+
listShortcuts: (arg0: string | null) => string[] | any[];
|
|
96
|
+
/**
|
|
97
|
+
* - Load shortcuts into contexts
|
|
98
|
+
*/
|
|
99
|
+
load: (arg0: any) => void;
|
|
100
|
+
/**
|
|
101
|
+
* - Unload a context
|
|
102
|
+
*/
|
|
103
|
+
unload: (arg0: string) => void;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* @function shortcuts
|
|
107
|
+
* @description Create a shortcuts instance
|
|
108
|
+
* @param {Object} [options={}] - Configuration options
|
|
109
|
+
* @param {function} [options.onShortcut] - Function to log shortcut events
|
|
110
|
+
* @param {string} [options.errorEventName='@shortcuts-error'] - Name for error events
|
|
111
|
+
* @returns {ShortcutsAPI} The shortcuts API
|
|
112
|
+
*/
|
|
113
|
+
declare function main(options?: {
|
|
114
|
+
onShortcut?: Function;
|
|
115
|
+
errorEventName?: string;
|
|
116
|
+
}): ShortcutsAPI;
|
|
117
|
+
import pluginKey from './plugins/key/index.js';
|
|
118
|
+
import pluginClick from './plugins/click/index.js';
|
|
119
|
+
import pluginForm from './plugins/form/index.js';
|
|
120
|
+
export { main as shortcuts, pluginKey, pluginClick, pluginForm };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
declare namespace _default {
|
|
2
|
+
export { _normalizeWithPlugins };
|
|
3
|
+
export { _readShortcutWithPlugins };
|
|
4
|
+
export { _systemAction };
|
|
5
|
+
export { changeContext };
|
|
6
|
+
export { listShortcuts };
|
|
7
|
+
export { load };
|
|
8
|
+
export { unload };
|
|
9
|
+
}
|
|
10
|
+
export default _default;
|
|
11
|
+
import _normalizeWithPlugins from './_normalizeWithPlugins.js';
|
|
12
|
+
import _readShortcutWithPlugins from './_readShortcutWithPlugins.js';
|
|
13
|
+
import _systemAction from './_systemAction.js';
|
|
14
|
+
import changeContext from './changeContext.js';
|
|
15
|
+
import listShortcuts from './listShortcuts.js';
|
|
16
|
+
import load from './load.js';
|
|
17
|
+
import unload from './unload.js';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export default listShortcuts;
|
|
2
|
+
export type contextShortcuts = {
|
|
3
|
+
/**
|
|
4
|
+
* - Context name
|
|
5
|
+
*/
|
|
6
|
+
context: string;
|
|
7
|
+
/**
|
|
8
|
+
* - List of shortcuts in a context
|
|
9
|
+
*/
|
|
10
|
+
shortcuts: string[];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {object} contextShortcuts
|
|
14
|
+
* @property {string} context - Context name
|
|
15
|
+
* @property {string[]} shortcuts - List of shortcuts in a context
|
|
16
|
+
*/
|
|
17
|
+
declare function listShortcuts(dependencies: any, state: any): (contextName?: string) => string[] | contextShortcuts[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export default pluginClick;
|
|
2
|
+
/**
|
|
3
|
+
* @function pluginClick
|
|
4
|
+
* @description Plugin for mouse click shortcuts
|
|
5
|
+
* @param {Object} dependencies - Internal dependencies
|
|
6
|
+
* @param {Object} state - Library state
|
|
7
|
+
* @param {Object} [options={}] - Plugin options
|
|
8
|
+
* @param {number} [options.mouseWait=320] - Time to wait for click sequence in ms
|
|
9
|
+
* @param {string} [options.clickTarget='click'] - Data attribute name for click targets
|
|
10
|
+
* @returns {PluginAPI} Plugin API
|
|
11
|
+
*/
|
|
12
|
+
declare function pluginClick(dependencies: any, state: any, options?: {
|
|
13
|
+
mouseWait?: number;
|
|
14
|
+
clickTarget?: string;
|
|
15
|
+
}): PluginAPI;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default pluginForm;
|
|
2
|
+
/**
|
|
3
|
+
* @function pluginForm
|
|
4
|
+
* @description Plugin for form element shortcuts
|
|
5
|
+
* @param {Object} dependencies - Internal dependencies
|
|
6
|
+
* @param {Object} state - Library state
|
|
7
|
+
* @param {Object} [options={}] - Plugin options
|
|
8
|
+
* @returns {PluginAPI} Plugin API
|
|
9
|
+
*/
|
|
10
|
+
declare function pluginForm(dependencies: any, state: any, options?: any): PluginAPI;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export default _specialChars;
|
|
2
|
+
declare function _specialChars(): {
|
|
3
|
+
ArrowLeft: string;
|
|
4
|
+
ArrowUp: string;
|
|
5
|
+
ArrowRight: string;
|
|
6
|
+
ArrowDown: string;
|
|
7
|
+
Enter: string;
|
|
8
|
+
NumpadEnter: string;
|
|
9
|
+
Escape: string;
|
|
10
|
+
Backspace: string;
|
|
11
|
+
Space: string;
|
|
12
|
+
Tab: string;
|
|
13
|
+
Backquote: string;
|
|
14
|
+
BracketLeft: string;
|
|
15
|
+
BracketRight: string;
|
|
16
|
+
Equal: string;
|
|
17
|
+
Slash: string;
|
|
18
|
+
Backslash: string;
|
|
19
|
+
IntlBackslash: string;
|
|
20
|
+
F1: string;
|
|
21
|
+
F2: string;
|
|
22
|
+
F3: string;
|
|
23
|
+
F4: string;
|
|
24
|
+
F5: string;
|
|
25
|
+
F6: string;
|
|
26
|
+
F7: string;
|
|
27
|
+
F8: string;
|
|
28
|
+
F9: string;
|
|
29
|
+
F10: string;
|
|
30
|
+
F11: string;
|
|
31
|
+
F12: string;
|
|
32
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export default pluginKey;
|
|
2
|
+
/**
|
|
3
|
+
* @function pluginKey
|
|
4
|
+
* @description Plugin for keyboard shortcuts
|
|
5
|
+
* @param {Object} dependencies - Internal dependencies
|
|
6
|
+
* @param {Object} state - Library state
|
|
7
|
+
* @param {Object} [options={}] - Plugin options
|
|
8
|
+
* @param {number} [options.keyWait=480] - Time to wait for key sequence in ms
|
|
9
|
+
* @param {function} [options.streamKeys] - Function to stream key presses
|
|
10
|
+
* @returns {PluginAPI} Plugin API
|
|
11
|
+
*/
|
|
12
|
+
declare function pluginKey(dependencies: any, state: any, options?: {
|
|
13
|
+
keyWait?: number;
|
|
14
|
+
streamKeys?: Function;
|
|
15
|
+
}): PluginAPI;
|
package/dist/shortcuts.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t=require("@peter.naydenov/notice");var e={_normalizeWithPlugins:function(t,e){return function(t){const n=e.shortcuts;Object.keys(n).forEach(e=>{Object.entries(n[e]).forEach(([o,r])=>{const i=t(o);i!==o&&(delete n[e][o],n[e][i]=r)})})}},_readShortcutWithPlugins:function(t,e){return function(n){const{inAPI:o}=t,r=n.split(":")[0].toLowerCase().trim(),i=o._systemAction(r,"none");let s=n;return-1!==i&&(s=e.plugins[i].shortcutName(n)),s}},_systemAction:function(t,e){return function(t,n,o=null){return e.plugins.findIndex(e=>e.getPrefix()===t&&(e[n]&&e[n](o),!0))}},changeContext:function(t,e){const{shortcuts:n,currentContext:o}=e,{ev:r}=t;return function(t=!1){const i=o.name;if(!t)return r.reset(),void(o.name=null);i!==t&&(n[t]?(n[i]&&r.reset(),o.name=t,e.plugins.forEach(e=>e.contextChange(t)),Object.entries(n[t]).forEach(([t,e])=>{e.forEach(e=>r.on(t,e))}),r.on("*",(...t)=>{e.exposeShortcut&&e.exposeShortcut(...t)})):r.emit("@shortcuts-error",`Context '${t}' does not exist`))}},listShortcuts:function(t,e){const n=e.shortcuts;return function(t=null){if(null!=t){let e=n[t];return null==e?null:Object.entries(e).map(([t,e])=>t)}return Object.keys(n).map(t=>{let e={};return e.context=t,e.shortcuts=Object.entries(n[t]).map(([t,e])=>t),e})}},load:function(t,e){const{shortcuts:n,plugins:o}=e,{API:{changeContext:r,getContext:i}}=t;return function(t){const e=i(),s=o.map(t=>t.getPrefix().toUpperCase());let c=!1;Object.entries(t).forEach(([t,r])=>{t===e&&(c=!0),n[t]={},Object.entries(r).forEach(([e,r])=>{let i=e,c=e.toUpperCase().trim(),u=s.map((t,e)=>c.startsWith(t)?e:null).filter(t=>null!==t);if(u.length){let t=u[0];i=o[t].shortcutName(e)}r instanceof Function&&(r=[r]),n[t][i]=r})}),c&&(r(),r(e))}},unload:function(t,e){const{currentContext:n,shortcuts:o}=e,{ev:r}=t;return function(t){n.name!==t?o[t]?delete o[t]:r.emit("shortcuts-error",`Context '${t}' does not exist`):r.emit("shortcuts-error",`Context '${t}' can't be removed during is current active context. Change the context first`)}}};function n(t){const e=t.toUpperCase(),n=/KEY\s*\:/i.test(e),o=e.indexOf(":");if(!n)return t;return`KEY:${e.slice(o+1).split(",").map(t=>t.trim()).map(t=>t.split("+").map(t=>t.trim()).sort().join("+")).join(",")}`}function o(t,e){let{shiftKey:n,altKey:o,ctrlKey:r}=t,i=e(),s=t.code.replace("Key","").replace("Digit",""),c=[];return r&&c.push("CTRL"),n&&c.push("SHIFT"),o&&c.push("ALT"),i.hasOwnProperty(s)?c.push(i[s].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(s)||c.push(s.toUpperCase()),c.sort()}function r(t,e){let n=0;const{regex:o}=t,{listenOptions:r,currentContext:{name:i},shortcuts:s}=e;return null==i?0:(Object.entries(s[i]).forEach(([t,e])=>{if(!o.test(t))return;n++;let i=t.slice(4).split(",").length;r.maxSequence<i&&(r.maxSequence=i)}),n)}function i(){return{ArrowLeft:"LEFT",ArrowUp:"UP",ArrowRight:"RIGHT",ArrowDown:"DOWN",Enter:"ENTER",NumpadEnter:"ENTER",Escape:"ESC",Backspace:"BACKSPACE",Space:"SPACE",Tab:"TAB",Backquote:"`",BracketLeft:"[",BracketRight:"]",Equal:"=",Slash:"/",Backslash:"\\",IntlBackslash:"`",F1:"F1",F2:"F2",F3:"F3",F4:"F4",F5:"F5",F6:"F6",F7:"F7",F8:"F8",F9:"F9",F10:"F10",F11:"F11",F12:"F12"}}function s(t,e,n){const{listenOptions:{clickTarget:o}}=e;let r=n;return r===document||r===document.body?null:r.dataset[o]||"A"===r.nodeName?r:s(t,e,r.parentNode)}function c(t){const e=t.toUpperCase(),n=/CLICK\s*\:/i.test(e),o=["LEFT","MIDDLE","RIGHT"],r=["ALT","SHIFT","CTRL"];let i=null,s=[],c=0,u=e.indexOf(":");return n?(e.slice(u+1).trim().split("-").map(t=>t.trim()).forEach(t=>{o.includes(t)?i=t:r.includes(t)?s.push(t):isNaN(t)||(c=t)}),`CLICK:${i}-${c}${s.length>0?"-":""}${s.sort().join("-")}`):t}function u(t,e){let{shiftKey:n,altKey:o,ctrlKey:r,key:i,button:s}=t,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][s]}-${e}`,u=[];return r&&u.push("CTRL"),n&&u.push("SHIFT"),o&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function a(t,e){let n=0;const{regex:o}=t,{listenOptions:r,currentContext:{name:i},shortcuts:s}=e;return null==i?0:(Object.entries(s[i]).forEach(([t,e])=>{if(!o.test(t))return;n++;let[,i]=t.slice(6).split("-");r.maxClicks<i&&(r.maxClicks=i)}),n)}function l(t){const e=t.toUpperCase(),n=/FORM\s*\:/i.test(e),o=e.indexOf(":");if(!n)return t;return`FORM:${e.slice(o+1).trim()}`}function m(t,e){const{regex:n,_defaults:o,ev:r}=t,{currentContext:{name:i},shortcuts:s,callbacks:c}=e;let u=[],a=[],l=[];if(null==i)return!1;if(Object.entries(s[i]).forEach(([t,e])=>{n.test(t)&&("FORM:WATCH"===t&&(u=e),"FORM:DEFINE"===t&&(a=e),"FORM:ACTION"===t&&(l=e))}),0===l.length)return!1;let m=new Set;0===a.length&&(a=[o.define]),0===u.length&&(u=[o.watch]);let p=u.map(t=>t()).reduce((t,e)=>(t.push(e),t),[]);return e.watchList=document.querySelectorAll(p),e.watchList.forEach(t=>m.add(a[0](t))),e.typeFn=a[0]?a[0]:o.define,l.forEach(t=>{if(!(t instanceof Function))return console.warn("Warning: The 'form:action' should be a function."),!1;if(!(t()instanceof Array))return console.warn("Warning: The 'form:action' function should RETURN an array."),!1;t().forEach(({fn:t,type:n,timing:o,wait:i=0})=>{if(m.has(n)&&t instanceof Function){let e=`${n}/${o}`;const i=c.hasOwnProperty(e);i?c[e].push(t):c[e]=[t],i||r.on(e,(t,e)=>{e.forEach(e=>{e instanceof Function&&e(t)})})}"instant"===o&&(e.wait[`${n}`]=i)})}),Object.keys(e.callbacks).length>0}const p={watch:()=>"input, select, textarea, button, a",define:t=>"checkbox"===t.type||"radio"===t.type?"checkbox":"button"==t.type||"submit"==t.type?"button":"input"};exports.pluginClick=function(t,e,n){let{currentContext:o,shortcuts:r}=e,{inAPI:i}=t,l={ev:t.ev,_findTarget:s,_readClickEvent:u,mainDependencies:t,regex:/CLICK\s*\:/i},m={currentContext:o,active:!1,shortcuts:r,listenOptions:{mouseWait:n.mouseWait?n.mouseWait:320,maxClicks:1,clickTarget:n.clickTarget?n.clickTarget:"click"}};i._normalizeWithPlugins(c);let p=function(t,e){const{ev:n,_findTarget:o,_readClickEvent:r,mainDependencies:i}=t,{listenOptions:s,currentContext:c}=e,{mouseWait:u}=s;let a=null,l=null,m=null,p=null,f=0;function h(){const t=r(l,f),e={target:a,targetProps:a?a.getBoundingClientRect():null,x:l.clientX,y:l.clientY,context:c.name,note:c.note,event:l,dependencies:i.extra,type:"click"};n.emit(t,e),m=null,p=null,a=null,l=null,f=0}function d(n){let r=s.maxClicks;return clearTimeout(m),p?(clearTimeout(p),void(p=setTimeout(()=>p=null,u))):(a=o(t,e,n.target),a&&a.dataset.hasOwnProperty("quickClick")&&(r=1),a&&"A"===a.tagName&&(r=1),l=n,f++,f>=r?(h(),void(r>1&&(p=setTimeout(()=>p=null,u)))):void(m=setTimeout(h,u)))}function g(n){let r=s.maxClicks;return clearTimeout(m),p?(clearTimeout(p),void(p=setTimeout(()=>p=null,u))):(a=o(t,e,n.target),a&&a.dataset.hasOwnProperty("quickClick")&&(r=1),a&&"A"===a.tagName&&(r=1),l=n,f++,f>=r?(h(),void(r>1&&(p=setTimeout(()=>p=null,u)))):void(m=setTimeout(h,u)))}return{start:function(){e.active||(window.addEventListener("contextmenu",g),document.addEventListener("click",d),e.active=!0)},stop:function(){e.active&&(window.removeEventListener("contextmenu",g),document.removeEventListener("click",d),e.active=!1,m&&(clearTimeout(m),m=null),p&&(clearTimeout(p),p=null),f=0)}}}(l,m),f=a(l,m);f>0&&p.start();let h={getPrefix:()=>"click",shortcutName:t=>c(t),contextChange:()=>{f=a(l,m),f<1&&p.stop(),f>0&&p.start()},mute:()=>{p.stop()},unmute:()=>p.start(),destroy:()=>p.stop()};return Object.freeze(h),h},exports.pluginForm=function(t,e,n){let{currentContext:o,shortcuts:r}=e,{inAPI:i}=t,s={ev:t.ev,mainDependencies:t,regex:/FORM\s*\:/i,_defaults:p},c={currentContext:o,shortcuts:r,callbacks:{},typeFn:"",watchList:[],wait:{}};i._normalizeWithPlugins(l);let u=function(t,e){const{ev:n}=t;let o=null;function r(t,e,n,o){return{target:n.target,context:e.currentContext.name,note:e.currentContext.note,event:n,dependencies:t.mainDependencies.extra,type:o}}function i(o){const{callbacks:i,typeFn:s}=e,c=s(o.target),u=r(t,e,o,c),a=`${c}/in`;null!=i[a]&&n.emit(a,u,i[a])}function s(o){const{callbacks:i,typeFn:s}=e,c=r(t,e,o,"form-out"),u=`${s(o.target)}/out`;null!=i[u]&&n.emit(u,c,i[u])}function c(i){const{callbacks:s,typeFn:c}=e,u=r(t,e,i,"form-instant"),a=c(i.target),l=e.wait[`${a}`],m=`${a}/instant`;null!=s[m]&&(0!==l?(clearTimeout(o),o=setTimeout(()=>n.emit(m,u,s[m]),l)):n.emit(m,u,s[m]))}return{start:function(){e.active||(document.addEventListener("focusin",i),document.addEventListener("focusout",s),document.addEventListener("input",c),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("focusin",i),document.removeEventListener("focusout",s),document.removeEventListener("input",c),e.active=!1)}}}(s,c);if(o.name){m(s,c)&&u.start()}let a={getPrefix:()=>"form",shortcutName:t=>l(t),contextChange:()=>{c.callbacks={},c.typeFn="",c.watchList=[],c.wait={},m(s,c)?u.start():u.stop()},mute:()=>u.stop(),unmute:()=>u.start(),destroy:()=>{u.stop()}};return Object.freeze(a),a},exports.pluginKey=function(t,e,s={}){let{currentContext:c,shortcuts:u,exposeShortcut:a}=e,{inAPI:l}=t,m={ev:t.ev,_specialChars:i,_readKeyEvent:o,mainDependencies:t,regex:/KEY\s*\:/i},p={currentContext:c,shortcuts:u,active:!1,listenOptions:{keyWait:s.keyWait?s.keyWait:480,maxSequence:1,keyIgnore:null},streamKeys:!(!s.streamKeys||"function"!=typeof s.streamKeys)&&s.streamKeys};l._normalizeWithPlugins(n);let f=function(t,e){const{ev:n,_specialChars:o,_readKeyEvent:r,mainDependencies:i}=t,{currentContext:s,streamKeys:c,listenOptions:u}=e,{keyWait:a}=u;let l=[],m=null,p=!0,f=!1;const h=()=>p=!1,d=()=>p=!0,g=()=>f=!0,x=()=>!1===p;function y(){let t=l.map(t=>[t.join("+")]);const e={wait:h,end:d,ignore:g,isWaiting:x,note:s.note,context:s.name,dependencies:i.extra,type:"key"};if(!p){let o=t.at(-1);n.emit(o,e),f&&(t=t.slice(0,-1),f=!1)}if(p){const o=`KEY:${t.join(",")}`;n.emit(o,e),l=[],m=null}}function C(e){if(clearTimeout(m),o().hasOwnProperty(e.code))return l.push(r(e,o)),c&&c({key:e.key,context:s.name,note:s.note,dependencies:t.extra}),u.keyIgnore?(clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a))):p&&l.length===u.maxSequence?(y(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a))):void(p?m=setTimeout(y,a):y())}function k(e){if(!o().hasOwnProperty(e.code)){if(clearTimeout(m),c&&c({key:e.key,context:s.name,note:s.note,dependencies:t.extra}),u.keyIgnore)return clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a));if(l.push(r(e,o)),p&&l.length===u.maxSequence)return y(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a));p?m=setTimeout(y,a):y()}}return{start:function(){e.active||(document.addEventListener("keydown",C),document.addEventListener("keypress",k),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("keydown",C),document.removeEventListener("keypress",k),e.active=!1,m&&(clearTimeout(m),m=null),u.keyIgnore&&(clearTimeout(u.keyIgnore),u.keyIgnore=null),l=[],p=!0,f=!1)}}}(m,p),h=r(m,p);h>0&&f.start();let d={getPrefix:()=>"key",shortcutName:t=>n(t),contextChange:t=>{h=r(m,p),h<1&&f.stop(),h>0&&f.start()},mute:()=>f.stop(),unmute:()=>f.start(),destroy:()=>f.stop()};return Object.freeze(d),d},exports.shortcuts=function(n={}){let o={},r={};const i=t(),s={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!n.onShortcut||"function"!=typeof n.onShortcut)&&n.onShortcut};let c={ev:i,inAPI:o,API:r,extra:{}};return r.enablePlugin=(t,e={})=>{const n=t.name.replace("plugin","").toLowerCase();if(-1===o._systemAction(n,"none")){let n=t(c,s,e);s.plugins.push(n)}},r.disablePlugin=t=>{const e=o._systemAction(t,"destroy");-1!==e&&(s.plugins=s.plugins.filter((t,n)=>n!==e))},r.mutePlugin=t=>o._systemAction(t,"mute"),r.unmutePlugin=t=>o._systemAction(t,"unmute"),r.getContext=()=>s.currentContext.name,r.getNote=()=>s.currentContext.note,r.setNote=(t=null)=>{"string"!=typeof t&&null!=t||(s.currentContext.note=t)},r.pause=(t="*")=>{let e=o._readShortcutWithPlugins(t);i.stop(e)},r.resume=(t="*")=>{const e=o._readShortcutWithPlugins(t);i.start(e)},r.emit=(t,...e)=>i.emit(o._readShortcutWithPlugins(t),...e),r.listContexts=()=>Object.keys(s.shortcuts),r.setDependencies=t=>c.extra={...c.extra,...t},r.getDependencies=()=>c.extra,r.reset=function(){i.reset(),r.changeContext(),s.plugins.forEach(t=>t.destroy()),r.listContexts().map(t=>r.unload(t)),c.extra={},s.exposeShortcut=null},Object.entries(e).forEach(([t,e])=>{t.startsWith("_")?o[t]=e(c,s):r[t]=e(c,s)}),r};
|
|
1
|
+
"use strict";var t=require("@peter.naydenov/notice");var e={_normalizeWithPlugins:function(t,e){return function(t){const n=e.shortcuts;Object.keys(n).forEach(e=>{Object.entries(n[e]).forEach(([o,r])=>{const i=t(o);i!==o&&(delete n[e][o],n[e][i]=r)})})}},_readShortcutWithPlugins:function(t,e){return function(n){const{inAPI:o}=t,r=n.split(":")[0].toLowerCase().trim(),i=o._systemAction(r,"none");let s=n;return-1!==i&&(s=e.plugins[i].shortcutName(n)),s}},_systemAction:function(t,e){return function(t,n,o=null){return e.plugins.findIndex(e=>e.getPrefix()===t&&(e[n]&&e[n](o),!0))}},changeContext:function(t,e){const{shortcuts:n,currentContext:o,ERROR_EVENT_NAME:r}=e,{ev:i}=t;return function(t=!1){const s=o.name;if(!t)return i.reset(),void(o.name=null);s!==t&&(n[t]?(n[s]&&i.reset(),o.name=t,e.plugins.forEach(e=>e.contextChange(t)),Object.entries(n[t]).forEach(([t,e])=>{e.forEach(e=>i.on(t,e))}),i.on("*",(...t)=>{e.exposeShortcut&&e.exposeShortcut(...t)})):i.emit(r,`Context '${t}' does not exist`))}},listShortcuts:function(t,e){const n=e.shortcuts;return function(t=null){if(null!=t){let e=n[t];return null==e?null:Object.entries(e).map(([t,e])=>t)}return Object.keys(n).map(t=>{let e={};return e.context=t,e.shortcuts=Object.entries(n[t]).map(([t,e])=>t),e})}},load:function(t,e){const{shortcuts:n,plugins:o}=e,{API:{changeContext:r,getContext:i}}=t;return function(t){const e=i(),s=o.map(t=>t.getPrefix().toUpperCase());let c=!1;Object.entries(t).forEach(([t,r])=>{t===e&&(c=!0),n[t]={},Object.entries(r).forEach(([e,r])=>{let i=e,c=e.toUpperCase().trim(),u=s.map((t,e)=>c.startsWith(t)?e:null).filter(t=>null!==t);if(u.length){let t=u[0];i=o[t].shortcutName(e)}r instanceof Function&&(r=[r]),n[t][i]=r})}),c&&(r(),r(e))}},unload:function(t,e){const{currentContext:n,shortcuts:o,ERROR_EVENT_NAME:r}=e,{ev:i}=t;return function(t){n.name!==t?o[t]?delete o[t]:i.emit(r,`Context '${t}' does not exist`):i.emit(r,`Context '${t}' can't be removed during is current active context. Change the context first`)}}};function n(t){const e=t.toUpperCase(),n=/KEY\s*\:/i.test(e),o=e.indexOf(":");if(!n)return t;return`KEY:${e.slice(o+1).split(",").map(t=>t.trim()).map(t=>t.split("+").map(t=>t.trim()).sort().join("+")).join(",")}`}function o(t,e){let{shiftKey:n,altKey:o,ctrlKey:r}=t,i=e(),s=t.code.replace("Key","").replace("Digit",""),c=[];return r&&c.push("CTRL"),n&&c.push("SHIFT"),o&&c.push("ALT"),i.hasOwnProperty(s)?c.push(i[s].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(s)||c.push(s.toUpperCase()),c.sort()}function r(t,e){let n=0;const{regex:o}=t,{listenOptions:r,currentContext:{name:i},shortcuts:s}=e;return null==i?0:(Object.entries(s[i]).forEach(([t,e])=>{if(!o.test(t))return;n++;let i=t.slice(4).split(",").length;r.maxSequence<i&&(r.maxSequence=i)}),n)}function i(){return{ArrowLeft:"LEFT",ArrowUp:"UP",ArrowRight:"RIGHT",ArrowDown:"DOWN",Enter:"ENTER",NumpadEnter:"ENTER",Escape:"ESC",Backspace:"BACKSPACE",Space:"SPACE",Tab:"TAB",Backquote:"`",BracketLeft:"[",BracketRight:"]",Equal:"=",Slash:"/",Backslash:"\\",IntlBackslash:"`",F1:"F1",F2:"F2",F3:"F3",F4:"F4",F5:"F5",F6:"F6",F7:"F7",F8:"F8",F9:"F9",F10:"F10",F11:"F11",F12:"F12"}}function s(t,e,n){const{listenOptions:{clickTarget:o}}=e;let r=n;return r===document||r===document.body?null:r.dataset[o]||"A"===r.nodeName?r:s(t,e,r.parentNode)}function c(t){const e=t.toUpperCase(),n=/CLICK\s*\:/i.test(e),o=["LEFT","MIDDLE","RIGHT"],r=["ALT","SHIFT","CTRL"];let i=null,s=[],c=0,u=e.indexOf(":");return n?(e.slice(u+1).trim().split("-").map(t=>t.trim()).forEach(t=>{o.includes(t)?i=t:r.includes(t)?s.push(t):isNaN(t)||(c=t)}),`CLICK:${i}-${c}${s.length>0?"-":""}${s.sort().join("-")}`):t}function u(t,e){let{shiftKey:n,altKey:o,ctrlKey:r,key:i,button:s}=t,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][s]}-${e}`,u=[];return r&&u.push("CTRL"),n&&u.push("SHIFT"),o&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function a(t,e){let n=0;const{regex:o}=t,{listenOptions:r,currentContext:{name:i},shortcuts:s}=e;return null==i?0:(Object.entries(s[i]).forEach(([t,e])=>{if(!o.test(t))return;n++;let[,i]=t.slice(6).split("-");r.maxClicks<i&&(r.maxClicks=i)}),n)}function l(t){const e=t.toUpperCase(),n=/FORM\s*\:/i.test(e),o=e.indexOf(":");if(!n)return t;return`FORM:${e.slice(o+1).trim()}`}function m(t,e){const{regex:n,_defaults:o,ev:r}=t,{currentContext:{name:i},shortcuts:s,callbacks:c}=e;let u=[],a=[],l=[];if(null==i)return!1;if(Object.entries(s[i]).forEach(([t,e])=>{n.test(t)&&("FORM:WATCH"===t&&(u=e),"FORM:DEFINE"===t&&(a=e),"FORM:ACTION"===t&&(l=e))}),0===l.length)return!1;let m=new Set;0===a.length&&(a=[o.define]),0===u.length&&(u=[o.watch]);let p=u.map(t=>t()).reduce((t,e)=>(t.push(e),t),[]);return e.watchList=document.querySelectorAll(p),e.watchList.forEach(t=>m.add(a[0](t))),e.typeFn=a[0]?a[0]:o.define,l.forEach(t=>{if(!(t instanceof Function))return console.warn("Warning: The 'form:action' should be a function."),!1;if(!(t()instanceof Array))return console.warn("Warning: The 'form:action' function should RETURN an array."),!1;t().forEach(({fn:t,type:n,timing:o,wait:i=0})=>{if(m.has(n)&&t instanceof Function){let e=`${n}/${o}`;const i=c.hasOwnProperty(e);i?c[e].push(t):c[e]=[t],i||r.on(e,(t,e)=>{e.forEach(e=>{e instanceof Function&&e(t)})})}"instant"===o&&(e.wait[`${n}`]=i)})}),Object.keys(e.callbacks).length>0}const p={watch:()=>"input, select, textarea, button, a",define:t=>"checkbox"===t.type||"radio"===t.type?"checkbox":"button"==t.type||"submit"==t.type?"button":"input"};exports.pluginClick=function(t,e,n){let{currentContext:o,shortcuts:r}=e,{inAPI:i}=t,l={ev:t.ev,_findTarget:s,_readClickEvent:u,mainDependencies:t,regex:/CLICK\s*\:/i},m={currentContext:o,active:!1,shortcuts:r,listenOptions:{mouseWait:n.mouseWait?n.mouseWait:320,maxClicks:1,clickTarget:n.clickTarget?n.clickTarget:"click"}};i._normalizeWithPlugins(c);let p=function(t,e){const{ev:n,_findTarget:o,_readClickEvent:r,mainDependencies:i}=t,{listenOptions:s,currentContext:c}=e,{mouseWait:u}=s;let a=null,l=null,m=null,p=null,f=0;function h(){const t=r(l,f),e={target:a,targetProps:a?a.getBoundingClientRect():null,x:l.clientX,y:l.clientY,context:c.name,note:c.note,event:l,dependencies:i.extra,type:"click"};n.emit(t,e),m=null,p=null,a=null,l=null,f=0}function d(n){let r=s.maxClicks;return clearTimeout(m),p?(clearTimeout(p),void(p=setTimeout(()=>p=null,u))):(a=o(t,e,n.target),a&&a.dataset.hasOwnProperty("quickClick")&&(r=1),a&&"A"===a.tagName&&(r=1),l=n,f++,f>=r?(h(),void(r>1&&(p=setTimeout(()=>p=null,u)))):void(m=setTimeout(h,u)))}function g(n){let r=s.maxClicks;return clearTimeout(m),p?(clearTimeout(p),void(p=setTimeout(()=>p=null,u))):(a=o(t,e,n.target),a&&a.dataset.hasOwnProperty("quickClick")&&(r=1),a&&"A"===a.tagName&&(r=1),l=n,f++,f>=r?(h(),void(r>1&&(p=setTimeout(()=>p=null,u)))):void(m=setTimeout(h,u)))}return{start:function(){e.active||(window.addEventListener("contextmenu",g),document.addEventListener("click",d),e.active=!0)},stop:function(){e.active&&(window.removeEventListener("contextmenu",g),document.removeEventListener("click",d),e.active=!1,m&&(clearTimeout(m),m=null),p&&(clearTimeout(p),p=null),f=0)}}}(l,m),f=a(l,m);f>0&&p.start();let h={getPrefix:()=>"click",shortcutName:t=>c(t),contextChange:()=>{f=a(l,m),f<1&&p.stop(),f>0&&p.start()},mute:()=>{p.stop()},unmute:()=>p.start(),destroy:()=>p.stop()};return Object.freeze(h),h},exports.pluginForm=function(t,e,n){let{currentContext:o,shortcuts:r}=e,{inAPI:i}=t,s={ev:t.ev,mainDependencies:t,regex:/FORM\s*\:/i,_defaults:p},c={currentContext:o,shortcuts:r,callbacks:{},typeFn:"",watchList:[],wait:{}};i._normalizeWithPlugins(l);let u=function(t,e){const{ev:n}=t;let o=null;function r(t,e,n,o){return{target:n.target,context:e.currentContext.name,note:e.currentContext.note,event:n,dependencies:t.mainDependencies.extra,type:o}}function i(o){const{callbacks:i,typeFn:s}=e,c=s(o.target),u=r(t,e,o,c),a=`${c}/in`;null!=i[a]&&n.emit(a,u,i[a])}function s(o){const{callbacks:i,typeFn:s}=e,c=r(t,e,o,"form-out"),u=`${s(o.target)}/out`;null!=i[u]&&n.emit(u,c,i[u])}function c(i){const{callbacks:s,typeFn:c}=e,u=r(t,e,i,"form-instant"),a=c(i.target),l=e.wait[`${a}`],m=`${a}/instant`;null!=s[m]&&(0!==l?(clearTimeout(o),o=setTimeout(()=>n.emit(m,u,s[m]),l)):n.emit(m,u,s[m]))}return{start:function(){e.active||(document.addEventListener("focusin",i),document.addEventListener("focusout",s),document.addEventListener("input",c),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("focusin",i),document.removeEventListener("focusout",s),document.removeEventListener("input",c),e.active=!1)}}}(s,c);if(o.name){m(s,c)&&u.start()}let a={getPrefix:()=>"form",shortcutName:t=>l(t),contextChange:()=>{c.callbacks={},c.typeFn="",c.watchList=[],c.wait={},m(s,c)?u.start():u.stop()},mute:()=>u.stop(),unmute:()=>u.start(),destroy:()=>{u.stop()}};return Object.freeze(a),a},exports.pluginKey=function(t,e,s={}){let{currentContext:c,shortcuts:u,exposeShortcut:a}=e,{inAPI:l}=t,m={ev:t.ev,_specialChars:i,_readKeyEvent:o,mainDependencies:t,regex:/KEY\s*\:/i},p={currentContext:c,shortcuts:u,active:!1,listenOptions:{keyWait:s.keyWait?s.keyWait:480,maxSequence:1,keyIgnore:null},streamKeys:!(!s.streamKeys||"function"!=typeof s.streamKeys)&&s.streamKeys};l._normalizeWithPlugins(n);let f=function(t,e){const{ev:n,_specialChars:o,_readKeyEvent:r,mainDependencies:i}=t,{currentContext:s,streamKeys:c,listenOptions:u}=e,{keyWait:a}=u;let l=[],m=null,p=!0,f=!1;const h=()=>p=!1,d=()=>p=!0,g=()=>f=!0,x=()=>!1===p;function y(){let t=l.map(t=>[t.join("+")]);const e={wait:h,end:d,ignore:g,isWaiting:x,note:s.note,context:s.name,dependencies:i.extra,type:"key"};if(!p){let o=t.at(-1);n.emit(o,e),f&&(t=t.slice(0,-1),f=!1)}if(p){const o=`KEY:${t.join(",")}`;n.emit(o,e),l=[],m=null}}function C(e){if(clearTimeout(m),o().hasOwnProperty(e.code))return l.push(r(e,o)),c&&c({key:e.key,context:s.name,note:s.note,dependencies:t.extra}),u.keyIgnore?(clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a))):p&&l.length===u.maxSequence?(y(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a))):void(p?m=setTimeout(y,a):y())}function v(e){if(!o().hasOwnProperty(e.code)){if(clearTimeout(m),c&&c({key:e.key,context:s.name,note:s.note,dependencies:t.extra}),u.keyIgnore)return clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a));if(l.push(r(e,o)),p&&l.length===u.maxSequence)return y(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a));p?m=setTimeout(y,a):y()}}return{start:function(){e.active||(document.addEventListener("keydown",C),document.addEventListener("keypress",v),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("keydown",C),document.removeEventListener("keypress",v),e.active=!1,m&&(clearTimeout(m),m=null),u.keyIgnore&&(clearTimeout(u.keyIgnore),u.keyIgnore=null),l=[],p=!0,f=!1)}}}(m,p),h=r(m,p);h>0&&f.start();let d={getPrefix:()=>"key",shortcutName:t=>n(t),contextChange:t=>{h=r(m,p),h<1&&f.stop(),h>0&&f.start()},mute:()=>f.stop(),unmute:()=>f.start(),destroy:()=>f.stop()};return Object.freeze(d),d},exports.shortcuts=function(n={}){let o={},r={};const i=t(),s={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!n.onShortcut||"function"!=typeof n.onShortcut)&&n.onShortcut,ERROR_EVENT_NAME:n.errorEventName?n.errorEventName:"@shortcuts-error"};let c={ev:i,inAPI:o,API:r,extra:{}};return r.enablePlugin=(t,e={})=>{if("function"!=typeof t)return;let n=t(c,s,e);const r=n.getPrefix();-1===o._systemAction(r,"none")?s.plugins.push(n):n.destroy()},r.disablePlugin=t=>{const e=o._systemAction(t,"destroy");-1!==e&&(s.plugins=s.plugins.filter((t,n)=>n!==e))},r.mutePlugin=t=>o._systemAction(t,"mute"),r.unmutePlugin=t=>o._systemAction(t,"unmute"),r.listPlugins=()=>s.plugins.map(t=>t.getPrefix()),r.getContext=()=>s.currentContext.name,r.getNote=()=>s.currentContext.note,r.setNote=(t=null)=>{"string"!=typeof t&&null!=t||(s.currentContext.note=t)},r.pause=(t="*")=>{let e=o._readShortcutWithPlugins(t);i.stop(e)},r.resume=(t="*")=>{const e=o._readShortcutWithPlugins(t);i.start(e)},r.emit=(t,...e)=>i.emit(o._readShortcutWithPlugins(t),...e),r.listContexts=()=>Object.keys(s.shortcuts),r.setDependencies=t=>c.extra={...c.extra,...t},r.getDependencies=()=>c.extra,r.reset=function(){i.reset(),r.changeContext(),s.plugins.forEach(t=>t.destroy()),r.listContexts().map(t=>r.unload(t)),c.extra={},s.exposeShortcut=null},Object.entries(e).forEach(([t,e])=>{t.startsWith("_")?o[t]=e(c,s):r[t]=e(c,s)}),r};
|
package/dist/shortcuts.esm.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import t from"@peter.naydenov/notice";var e={_normalizeWithPlugins:function(t,e){return function(t){const n=e.shortcuts;Object.keys(n).forEach(e=>{Object.entries(n[e]).forEach(([o,r])=>{const i=t(o);i!==o&&(delete n[e][o],n[e][i]=r)})})}},_readShortcutWithPlugins:function(t,e){return function(n){const{inAPI:o}=t,r=n.split(":")[0].toLowerCase().trim(),i=o._systemAction(r,"none");let s=n;return-1!==i&&(s=e.plugins[i].shortcutName(n)),s}},_systemAction:function(t,e){return function(t,n,o=null){return e.plugins.findIndex(e=>e.getPrefix()===t&&(e[n]&&e[n](o),!0))}},changeContext:function(t,e){const{shortcuts:n,currentContext:o}=e,{ev:r}=t;return function(t=!1){const i=o.name;if(!t)return r.reset(),void(o.name=null);i!==t&&(n[t]?(n[i]&&r.reset(),o.name=t,e.plugins.forEach(e=>e.contextChange(t)),Object.entries(n[t]).forEach(([t,e])=>{e.forEach(e=>r.on(t,e))}),r.on("*",(...t)=>{e.exposeShortcut&&e.exposeShortcut(...t)})):r.emit("@shortcuts-error",`Context '${t}' does not exist`))}},listShortcuts:function(t,e){const n=e.shortcuts;return function(t=null){if(null!=t){let e=n[t];return null==e?null:Object.entries(e).map(([t,e])=>t)}return Object.keys(n).map(t=>{let e={};return e.context=t,e.shortcuts=Object.entries(n[t]).map(([t,e])=>t),e})}},load:function(t,e){const{shortcuts:n,plugins:o}=e,{API:{changeContext:r,getContext:i}}=t;return function(t){const e=i(),s=o.map(t=>t.getPrefix().toUpperCase());let c=!1;Object.entries(t).forEach(([t,r])=>{t===e&&(c=!0),n[t]={},Object.entries(r).forEach(([e,r])=>{let i=e,c=e.toUpperCase().trim(),u=s.map((t,e)=>c.startsWith(t)?e:null).filter(t=>null!==t);if(u.length){let t=u[0];i=o[t].shortcutName(e)}r instanceof Function&&(r=[r]),n[t][i]=r})}),c&&(r(),r(e))}},unload:function(t,e){const{currentContext:n,shortcuts:o}=e,{ev:r}=t;return function(t){n.name!==t?o[t]?delete o[t]:r.emit("shortcuts-error",`Context '${t}' does not exist`):r.emit("shortcuts-error",`Context '${t}' can't be removed during is current active context. Change the context first`)}}};function n(t){const e=t.toUpperCase(),n=/KEY\s*\:/i.test(e),o=e.indexOf(":");if(!n)return t;return`KEY:${e.slice(o+1).split(",").map(t=>t.trim()).map(t=>t.split("+").map(t=>t.trim()).sort().join("+")).join(",")}`}function o(t,e){let{shiftKey:n,altKey:o,ctrlKey:r}=t,i=e(),s=t.code.replace("Key","").replace("Digit",""),c=[];return r&&c.push("CTRL"),n&&c.push("SHIFT"),o&&c.push("ALT"),i.hasOwnProperty(s)?c.push(i[s].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(s)||c.push(s.toUpperCase()),c.sort()}function r(t,e){let n=0;const{regex:o}=t,{listenOptions:r,currentContext:{name:i},shortcuts:s}=e;return null==i?0:(Object.entries(s[i]).forEach(([t,e])=>{if(!o.test(t))return;n++;let i=t.slice(4).split(",").length;r.maxSequence<i&&(r.maxSequence=i)}),n)}function i(){return{ArrowLeft:"LEFT",ArrowUp:"UP",ArrowRight:"RIGHT",ArrowDown:"DOWN",Enter:"ENTER",NumpadEnter:"ENTER",Escape:"ESC",Backspace:"BACKSPACE",Space:"SPACE",Tab:"TAB",Backquote:"`",BracketLeft:"[",BracketRight:"]",Equal:"=",Slash:"/",Backslash:"\\",IntlBackslash:"`",F1:"F1",F2:"F2",F3:"F3",F4:"F4",F5:"F5",F6:"F6",F7:"F7",F8:"F8",F9:"F9",F10:"F10",F11:"F11",F12:"F12"}}function s(t,e,s={}){let{currentContext:c,shortcuts:u,exposeShortcut:a}=e,{inAPI:l}=t,m={ev:t.ev,_specialChars:i,_readKeyEvent:o,mainDependencies:t,regex:/KEY\s*\:/i},f={currentContext:c,shortcuts:u,active:!1,listenOptions:{keyWait:s.keyWait?s.keyWait:480,maxSequence:1,keyIgnore:null},streamKeys:!(!s.streamKeys||"function"!=typeof s.streamKeys)&&s.streamKeys};l._normalizeWithPlugins(n);let p=function(t,e){const{ev:n,_specialChars:o,_readKeyEvent:r,mainDependencies:i}=t,{currentContext:s,streamKeys:c,listenOptions:u}=e,{keyWait:a}=u;let l=[],m=null,f=!0,p=!1;const h=()=>f=!1,d=()=>f=!0,g=()=>p=!0,x=()=>!1===f;function y(){let t=l.map(t=>[t.join("+")]);const e={wait:h,end:d,ignore:g,isWaiting:x,note:s.note,context:s.name,dependencies:i.extra,type:"key"};if(!f){let o=t.at(-1);n.emit(o,e),p&&(t=t.slice(0,-1),p=!1)}if(f){const o=`KEY:${t.join(",")}`;n.emit(o,e),l=[],m=null}}function C(e){if(clearTimeout(m),o().hasOwnProperty(e.code))return l.push(r(e,o)),c&&c({key:e.key,context:s.name,note:s.note,dependencies:t.extra}),u.keyIgnore?(clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a))):f&&l.length===u.maxSequence?(y(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a))):void(f?m=setTimeout(y,a):y())}function k(e){if(!o().hasOwnProperty(e.code)){if(clearTimeout(m),c&&c({key:e.key,context:s.name,note:s.note,dependencies:t.extra}),u.keyIgnore)return clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a));if(l.push(r(e,o)),f&&l.length===u.maxSequence)return y(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a));f?m=setTimeout(y,a):y()}}return{start:function(){e.active||(document.addEventListener("keydown",C),document.addEventListener("keypress",k),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("keydown",C),document.removeEventListener("keypress",k),e.active=!1,m&&(clearTimeout(m),m=null),u.keyIgnore&&(clearTimeout(u.keyIgnore),u.keyIgnore=null),l=[],f=!0,p=!1)}}}(m,f),h=r(m,f);h>0&&p.start();let d={getPrefix:()=>"key",shortcutName:t=>n(t),contextChange:t=>{h=r(m,f),h<1&&p.stop(),h>0&&p.start()},mute:()=>p.stop(),unmute:()=>p.start(),destroy:()=>p.stop()};return Object.freeze(d),d}function c(t,e,n){const{listenOptions:{clickTarget:o}}=e;let r=n;return r===document||r===document.body?null:r.dataset[o]||"A"===r.nodeName?r:c(t,e,r.parentNode)}function u(t){const e=t.toUpperCase(),n=/CLICK\s*\:/i.test(e),o=["LEFT","MIDDLE","RIGHT"],r=["ALT","SHIFT","CTRL"];let i=null,s=[],c=0,u=e.indexOf(":");return n?(e.slice(u+1).trim().split("-").map(t=>t.trim()).forEach(t=>{o.includes(t)?i=t:r.includes(t)?s.push(t):isNaN(t)||(c=t)}),`CLICK:${i}-${c}${s.length>0?"-":""}${s.sort().join("-")}`):t}function a(t,e){let{shiftKey:n,altKey:o,ctrlKey:r,key:i,button:s}=t,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][s]}-${e}`,u=[];return r&&u.push("CTRL"),n&&u.push("SHIFT"),o&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function l(t,e){let n=0;const{regex:o}=t,{listenOptions:r,currentContext:{name:i},shortcuts:s}=e;return null==i?0:(Object.entries(s[i]).forEach(([t,e])=>{if(!o.test(t))return;n++;let[,i]=t.slice(6).split("-");r.maxClicks<i&&(r.maxClicks=i)}),n)}function m(t,e,n){let{currentContext:o,shortcuts:r}=e,{inAPI:i}=t,s={ev:t.ev,_findTarget:c,_readClickEvent:a,mainDependencies:t,regex:/CLICK\s*\:/i},m={currentContext:o,active:!1,shortcuts:r,listenOptions:{mouseWait:n.mouseWait?n.mouseWait:320,maxClicks:1,clickTarget:n.clickTarget?n.clickTarget:"click"}};i._normalizeWithPlugins(u);let f=function(t,e){const{ev:n,_findTarget:o,_readClickEvent:r,mainDependencies:i}=t,{listenOptions:s,currentContext:c}=e,{mouseWait:u}=s;let a=null,l=null,m=null,f=null,p=0;function h(){const t=r(l,p),e={target:a,targetProps:a?a.getBoundingClientRect():null,x:l.clientX,y:l.clientY,context:c.name,note:c.note,event:l,dependencies:i.extra,type:"click"};n.emit(t,e),m=null,f=null,a=null,l=null,p=0}function d(n){let r=s.maxClicks;return clearTimeout(m),f?(clearTimeout(f),void(f=setTimeout(()=>f=null,u))):(a=o(t,e,n.target),a&&a.dataset.hasOwnProperty("quickClick")&&(r=1),a&&"A"===a.tagName&&(r=1),l=n,p++,p>=r?(h(),void(r>1&&(f=setTimeout(()=>f=null,u)))):void(m=setTimeout(h,u)))}function g(n){let r=s.maxClicks;return clearTimeout(m),f?(clearTimeout(f),void(f=setTimeout(()=>f=null,u))):(a=o(t,e,n.target),a&&a.dataset.hasOwnProperty("quickClick")&&(r=1),a&&"A"===a.tagName&&(r=1),l=n,p++,p>=r?(h(),void(r>1&&(f=setTimeout(()=>f=null,u)))):void(m=setTimeout(h,u)))}return{start:function(){e.active||(window.addEventListener("contextmenu",g),document.addEventListener("click",d),e.active=!0)},stop:function(){e.active&&(window.removeEventListener("contextmenu",g),document.removeEventListener("click",d),e.active=!1,m&&(clearTimeout(m),m=null),f&&(clearTimeout(f),f=null),p=0)}}}(s,m),p=l(s,m);p>0&&f.start();let h={getPrefix:()=>"click",shortcutName:t=>u(t),contextChange:()=>{p=l(s,m),p<1&&f.stop(),p>0&&f.start()},mute:()=>{f.stop()},unmute:()=>f.start(),destroy:()=>f.stop()};return Object.freeze(h),h}function f(t){const e=t.toUpperCase(),n=/FORM\s*\:/i.test(e),o=e.indexOf(":");if(!n)return t;return`FORM:${e.slice(o+1).trim()}`}function p(t,e){const{regex:n,_defaults:o,ev:r}=t,{currentContext:{name:i},shortcuts:s,callbacks:c}=e;let u=[],a=[],l=[];if(null==i)return!1;if(Object.entries(s[i]).forEach(([t,e])=>{n.test(t)&&("FORM:WATCH"===t&&(u=e),"FORM:DEFINE"===t&&(a=e),"FORM:ACTION"===t&&(l=e))}),0===l.length)return!1;let m=new Set;0===a.length&&(a=[o.define]),0===u.length&&(u=[o.watch]);let f=u.map(t=>t()).reduce((t,e)=>(t.push(e),t),[]);return e.watchList=document.querySelectorAll(f),e.watchList.forEach(t=>m.add(a[0](t))),e.typeFn=a[0]?a[0]:o.define,l.forEach(t=>{if(!(t instanceof Function))return console.warn("Warning: The 'form:action' should be a function."),!1;if(!(t()instanceof Array))return console.warn("Warning: The 'form:action' function should RETURN an array."),!1;t().forEach(({fn:t,type:n,timing:o,wait:i=0})=>{if(m.has(n)&&t instanceof Function){let e=`${n}/${o}`;const i=c.hasOwnProperty(e);i?c[e].push(t):c[e]=[t],i||r.on(e,(t,e)=>{e.forEach(e=>{e instanceof Function&&e(t)})})}"instant"===o&&(e.wait[`${n}`]=i)})}),Object.keys(e.callbacks).length>0}const h={watch:()=>"input, select, textarea, button, a",define:t=>"checkbox"===t.type||"radio"===t.type?"checkbox":"button"==t.type||"submit"==t.type?"button":"input"};function d(t,e,n){let{currentContext:o,shortcuts:r}=e,{inAPI:i}=t,s={ev:t.ev,mainDependencies:t,regex:/FORM\s*\:/i,_defaults:h},c={currentContext:o,shortcuts:r,callbacks:{},typeFn:"",watchList:[],wait:{}};i._normalizeWithPlugins(f);let u=function(t,e){const{ev:n}=t;let o=null;function r(t,e,n,o){return{target:n.target,context:e.currentContext.name,note:e.currentContext.note,event:n,dependencies:t.mainDependencies.extra,type:o}}function i(o){const{callbacks:i,typeFn:s}=e,c=s(o.target),u=r(t,e,o,c),a=`${c}/in`;null!=i[a]&&n.emit(a,u,i[a])}function s(o){const{callbacks:i,typeFn:s}=e,c=r(t,e,o,"form-out"),u=`${s(o.target)}/out`;null!=i[u]&&n.emit(u,c,i[u])}function c(i){const{callbacks:s,typeFn:c}=e,u=r(t,e,i,"form-instant"),a=c(i.target),l=e.wait[`${a}`],m=`${a}/instant`;null!=s[m]&&(0!==l?(clearTimeout(o),o=setTimeout(()=>n.emit(m,u,s[m]),l)):n.emit(m,u,s[m]))}return{start:function(){e.active||(document.addEventListener("focusin",i),document.addEventListener("focusout",s),document.addEventListener("input",c),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("focusin",i),document.removeEventListener("focusout",s),document.removeEventListener("input",c),e.active=!1)}}}(s,c);if(o.name){p(s,c)&&u.start()}let a={getPrefix:()=>"form",shortcutName:t=>f(t),contextChange:()=>{c.callbacks={},c.typeFn="",c.watchList=[],c.wait={},p(s,c)?u.start():u.stop()},mute:()=>u.stop(),unmute:()=>u.start(),destroy:()=>{u.stop()}};return Object.freeze(a),a}function g(n={}){let o={},r={};const i=t(),s={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!n.onShortcut||"function"!=typeof n.onShortcut)&&n.onShortcut};let c={ev:i,inAPI:o,API:r,extra:{}};return r.enablePlugin=(t,e={})=>{const n=t.name.replace("plugin","").toLowerCase();if(-1===o._systemAction(n,"none")){let n=t(c,s,e);s.plugins.push(n)}},r.disablePlugin=t=>{const e=o._systemAction(t,"destroy");-1!==e&&(s.plugins=s.plugins.filter((t,n)=>n!==e))},r.mutePlugin=t=>o._systemAction(t,"mute"),r.unmutePlugin=t=>o._systemAction(t,"unmute"),r.getContext=()=>s.currentContext.name,r.getNote=()=>s.currentContext.note,r.setNote=(t=null)=>{"string"!=typeof t&&null!=t||(s.currentContext.note=t)},r.pause=(t="*")=>{let e=o._readShortcutWithPlugins(t);i.stop(e)},r.resume=(t="*")=>{const e=o._readShortcutWithPlugins(t);i.start(e)},r.emit=(t,...e)=>i.emit(o._readShortcutWithPlugins(t),...e),r.listContexts=()=>Object.keys(s.shortcuts),r.setDependencies=t=>c.extra={...c.extra,...t},r.getDependencies=()=>c.extra,r.reset=function(){i.reset(),r.changeContext(),s.plugins.forEach(t=>t.destroy()),r.listContexts().map(t=>r.unload(t)),c.extra={},s.exposeShortcut=null},Object.entries(e).forEach(([t,e])=>{t.startsWith("_")?o[t]=e(c,s):r[t]=e(c,s)}),r}export{m as pluginClick,d as pluginForm,s as pluginKey,g as shortcuts};
|
|
1
|
+
import t from"@peter.naydenov/notice";var e={_normalizeWithPlugins:function(t,e){return function(t){const n=e.shortcuts;Object.keys(n).forEach(e=>{Object.entries(n[e]).forEach(([o,r])=>{const i=t(o);i!==o&&(delete n[e][o],n[e][i]=r)})})}},_readShortcutWithPlugins:function(t,e){return function(n){const{inAPI:o}=t,r=n.split(":")[0].toLowerCase().trim(),i=o._systemAction(r,"none");let s=n;return-1!==i&&(s=e.plugins[i].shortcutName(n)),s}},_systemAction:function(t,e){return function(t,n,o=null){return e.plugins.findIndex(e=>e.getPrefix()===t&&(e[n]&&e[n](o),!0))}},changeContext:function(t,e){const{shortcuts:n,currentContext:o,ERROR_EVENT_NAME:r}=e,{ev:i}=t;return function(t=!1){const s=o.name;if(!t)return i.reset(),void(o.name=null);s!==t&&(n[t]?(n[s]&&i.reset(),o.name=t,e.plugins.forEach(e=>e.contextChange(t)),Object.entries(n[t]).forEach(([t,e])=>{e.forEach(e=>i.on(t,e))}),i.on("*",(...t)=>{e.exposeShortcut&&e.exposeShortcut(...t)})):i.emit(r,`Context '${t}' does not exist`))}},listShortcuts:function(t,e){const n=e.shortcuts;return function(t=null){if(null!=t){let e=n[t];return null==e?null:Object.entries(e).map(([t,e])=>t)}return Object.keys(n).map(t=>{let e={};return e.context=t,e.shortcuts=Object.entries(n[t]).map(([t,e])=>t),e})}},load:function(t,e){const{shortcuts:n,plugins:o}=e,{API:{changeContext:r,getContext:i}}=t;return function(t){const e=i(),s=o.map(t=>t.getPrefix().toUpperCase());let c=!1;Object.entries(t).forEach(([t,r])=>{t===e&&(c=!0),n[t]={},Object.entries(r).forEach(([e,r])=>{let i=e,c=e.toUpperCase().trim(),u=s.map((t,e)=>c.startsWith(t)?e:null).filter(t=>null!==t);if(u.length){let t=u[0];i=o[t].shortcutName(e)}r instanceof Function&&(r=[r]),n[t][i]=r})}),c&&(r(),r(e))}},unload:function(t,e){const{currentContext:n,shortcuts:o,ERROR_EVENT_NAME:r}=e,{ev:i}=t;return function(t){n.name!==t?o[t]?delete o[t]:i.emit(r,`Context '${t}' does not exist`):i.emit(r,`Context '${t}' can't be removed during is current active context. Change the context first`)}}};function n(t){const e=t.toUpperCase(),n=/KEY\s*\:/i.test(e),o=e.indexOf(":");if(!n)return t;return`KEY:${e.slice(o+1).split(",").map(t=>t.trim()).map(t=>t.split("+").map(t=>t.trim()).sort().join("+")).join(",")}`}function o(t,e){let{shiftKey:n,altKey:o,ctrlKey:r}=t,i=e(),s=t.code.replace("Key","").replace("Digit",""),c=[];return r&&c.push("CTRL"),n&&c.push("SHIFT"),o&&c.push("ALT"),i.hasOwnProperty(s)?c.push(i[s].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(s)||c.push(s.toUpperCase()),c.sort()}function r(t,e){let n=0;const{regex:o}=t,{listenOptions:r,currentContext:{name:i},shortcuts:s}=e;return null==i?0:(Object.entries(s[i]).forEach(([t,e])=>{if(!o.test(t))return;n++;let i=t.slice(4).split(",").length;r.maxSequence<i&&(r.maxSequence=i)}),n)}function i(){return{ArrowLeft:"LEFT",ArrowUp:"UP",ArrowRight:"RIGHT",ArrowDown:"DOWN",Enter:"ENTER",NumpadEnter:"ENTER",Escape:"ESC",Backspace:"BACKSPACE",Space:"SPACE",Tab:"TAB",Backquote:"`",BracketLeft:"[",BracketRight:"]",Equal:"=",Slash:"/",Backslash:"\\",IntlBackslash:"`",F1:"F1",F2:"F2",F3:"F3",F4:"F4",F5:"F5",F6:"F6",F7:"F7",F8:"F8",F9:"F9",F10:"F10",F11:"F11",F12:"F12"}}function s(t,e,s={}){let{currentContext:c,shortcuts:u,exposeShortcut:a}=e,{inAPI:l}=t,m={ev:t.ev,_specialChars:i,_readKeyEvent:o,mainDependencies:t,regex:/KEY\s*\:/i},f={currentContext:c,shortcuts:u,active:!1,listenOptions:{keyWait:s.keyWait?s.keyWait:480,maxSequence:1,keyIgnore:null},streamKeys:!(!s.streamKeys||"function"!=typeof s.streamKeys)&&s.streamKeys};l._normalizeWithPlugins(n);let p=function(t,e){const{ev:n,_specialChars:o,_readKeyEvent:r,mainDependencies:i}=t,{currentContext:s,streamKeys:c,listenOptions:u}=e,{keyWait:a}=u;let l=[],m=null,f=!0,p=!1;const h=()=>f=!1,d=()=>f=!0,g=()=>p=!0,x=()=>!1===f;function y(){let t=l.map(t=>[t.join("+")]);const e={wait:h,end:d,ignore:g,isWaiting:x,note:s.note,context:s.name,dependencies:i.extra,type:"key"};if(!f){let o=t.at(-1);n.emit(o,e),p&&(t=t.slice(0,-1),p=!1)}if(f){const o=`KEY:${t.join(",")}`;n.emit(o,e),l=[],m=null}}function C(e){if(clearTimeout(m),o().hasOwnProperty(e.code))return l.push(r(e,o)),c&&c({key:e.key,context:s.name,note:s.note,dependencies:t.extra}),u.keyIgnore?(clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a))):f&&l.length===u.maxSequence?(y(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a))):void(f?m=setTimeout(y,a):y())}function v(e){if(!o().hasOwnProperty(e.code)){if(clearTimeout(m),c&&c({key:e.key,context:s.name,note:s.note,dependencies:t.extra}),u.keyIgnore)return clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a));if(l.push(r(e,o)),f&&l.length===u.maxSequence)return y(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,a));f?m=setTimeout(y,a):y()}}return{start:function(){e.active||(document.addEventListener("keydown",C),document.addEventListener("keypress",v),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("keydown",C),document.removeEventListener("keypress",v),e.active=!1,m&&(clearTimeout(m),m=null),u.keyIgnore&&(clearTimeout(u.keyIgnore),u.keyIgnore=null),l=[],f=!0,p=!1)}}}(m,f),h=r(m,f);h>0&&p.start();let d={getPrefix:()=>"key",shortcutName:t=>n(t),contextChange:t=>{h=r(m,f),h<1&&p.stop(),h>0&&p.start()},mute:()=>p.stop(),unmute:()=>p.start(),destroy:()=>p.stop()};return Object.freeze(d),d}function c(t,e,n){const{listenOptions:{clickTarget:o}}=e;let r=n;return r===document||r===document.body?null:r.dataset[o]||"A"===r.nodeName?r:c(t,e,r.parentNode)}function u(t){const e=t.toUpperCase(),n=/CLICK\s*\:/i.test(e),o=["LEFT","MIDDLE","RIGHT"],r=["ALT","SHIFT","CTRL"];let i=null,s=[],c=0,u=e.indexOf(":");return n?(e.slice(u+1).trim().split("-").map(t=>t.trim()).forEach(t=>{o.includes(t)?i=t:r.includes(t)?s.push(t):isNaN(t)||(c=t)}),`CLICK:${i}-${c}${s.length>0?"-":""}${s.sort().join("-")}`):t}function a(t,e){let{shiftKey:n,altKey:o,ctrlKey:r,key:i,button:s}=t,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][s]}-${e}`,u=[];return r&&u.push("CTRL"),n&&u.push("SHIFT"),o&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function l(t,e){let n=0;const{regex:o}=t,{listenOptions:r,currentContext:{name:i},shortcuts:s}=e;return null==i?0:(Object.entries(s[i]).forEach(([t,e])=>{if(!o.test(t))return;n++;let[,i]=t.slice(6).split("-");r.maxClicks<i&&(r.maxClicks=i)}),n)}function m(t,e,n){let{currentContext:o,shortcuts:r}=e,{inAPI:i}=t,s={ev:t.ev,_findTarget:c,_readClickEvent:a,mainDependencies:t,regex:/CLICK\s*\:/i},m={currentContext:o,active:!1,shortcuts:r,listenOptions:{mouseWait:n.mouseWait?n.mouseWait:320,maxClicks:1,clickTarget:n.clickTarget?n.clickTarget:"click"}};i._normalizeWithPlugins(u);let f=function(t,e){const{ev:n,_findTarget:o,_readClickEvent:r,mainDependencies:i}=t,{listenOptions:s,currentContext:c}=e,{mouseWait:u}=s;let a=null,l=null,m=null,f=null,p=0;function h(){const t=r(l,p),e={target:a,targetProps:a?a.getBoundingClientRect():null,x:l.clientX,y:l.clientY,context:c.name,note:c.note,event:l,dependencies:i.extra,type:"click"};n.emit(t,e),m=null,f=null,a=null,l=null,p=0}function d(n){let r=s.maxClicks;return clearTimeout(m),f?(clearTimeout(f),void(f=setTimeout(()=>f=null,u))):(a=o(t,e,n.target),a&&a.dataset.hasOwnProperty("quickClick")&&(r=1),a&&"A"===a.tagName&&(r=1),l=n,p++,p>=r?(h(),void(r>1&&(f=setTimeout(()=>f=null,u)))):void(m=setTimeout(h,u)))}function g(n){let r=s.maxClicks;return clearTimeout(m),f?(clearTimeout(f),void(f=setTimeout(()=>f=null,u))):(a=o(t,e,n.target),a&&a.dataset.hasOwnProperty("quickClick")&&(r=1),a&&"A"===a.tagName&&(r=1),l=n,p++,p>=r?(h(),void(r>1&&(f=setTimeout(()=>f=null,u)))):void(m=setTimeout(h,u)))}return{start:function(){e.active||(window.addEventListener("contextmenu",g),document.addEventListener("click",d),e.active=!0)},stop:function(){e.active&&(window.removeEventListener("contextmenu",g),document.removeEventListener("click",d),e.active=!1,m&&(clearTimeout(m),m=null),f&&(clearTimeout(f),f=null),p=0)}}}(s,m),p=l(s,m);p>0&&f.start();let h={getPrefix:()=>"click",shortcutName:t=>u(t),contextChange:()=>{p=l(s,m),p<1&&f.stop(),p>0&&f.start()},mute:()=>{f.stop()},unmute:()=>f.start(),destroy:()=>f.stop()};return Object.freeze(h),h}function f(t){const e=t.toUpperCase(),n=/FORM\s*\:/i.test(e),o=e.indexOf(":");if(!n)return t;return`FORM:${e.slice(o+1).trim()}`}function p(t,e){const{regex:n,_defaults:o,ev:r}=t,{currentContext:{name:i},shortcuts:s,callbacks:c}=e;let u=[],a=[],l=[];if(null==i)return!1;if(Object.entries(s[i]).forEach(([t,e])=>{n.test(t)&&("FORM:WATCH"===t&&(u=e),"FORM:DEFINE"===t&&(a=e),"FORM:ACTION"===t&&(l=e))}),0===l.length)return!1;let m=new Set;0===a.length&&(a=[o.define]),0===u.length&&(u=[o.watch]);let f=u.map(t=>t()).reduce((t,e)=>(t.push(e),t),[]);return e.watchList=document.querySelectorAll(f),e.watchList.forEach(t=>m.add(a[0](t))),e.typeFn=a[0]?a[0]:o.define,l.forEach(t=>{if(!(t instanceof Function))return console.warn("Warning: The 'form:action' should be a function."),!1;if(!(t()instanceof Array))return console.warn("Warning: The 'form:action' function should RETURN an array."),!1;t().forEach(({fn:t,type:n,timing:o,wait:i=0})=>{if(m.has(n)&&t instanceof Function){let e=`${n}/${o}`;const i=c.hasOwnProperty(e);i?c[e].push(t):c[e]=[t],i||r.on(e,(t,e)=>{e.forEach(e=>{e instanceof Function&&e(t)})})}"instant"===o&&(e.wait[`${n}`]=i)})}),Object.keys(e.callbacks).length>0}const h={watch:()=>"input, select, textarea, button, a",define:t=>"checkbox"===t.type||"radio"===t.type?"checkbox":"button"==t.type||"submit"==t.type?"button":"input"};function d(t,e,n){let{currentContext:o,shortcuts:r}=e,{inAPI:i}=t,s={ev:t.ev,mainDependencies:t,regex:/FORM\s*\:/i,_defaults:h},c={currentContext:o,shortcuts:r,callbacks:{},typeFn:"",watchList:[],wait:{}};i._normalizeWithPlugins(f);let u=function(t,e){const{ev:n}=t;let o=null;function r(t,e,n,o){return{target:n.target,context:e.currentContext.name,note:e.currentContext.note,event:n,dependencies:t.mainDependencies.extra,type:o}}function i(o){const{callbacks:i,typeFn:s}=e,c=s(o.target),u=r(t,e,o,c),a=`${c}/in`;null!=i[a]&&n.emit(a,u,i[a])}function s(o){const{callbacks:i,typeFn:s}=e,c=r(t,e,o,"form-out"),u=`${s(o.target)}/out`;null!=i[u]&&n.emit(u,c,i[u])}function c(i){const{callbacks:s,typeFn:c}=e,u=r(t,e,i,"form-instant"),a=c(i.target),l=e.wait[`${a}`],m=`${a}/instant`;null!=s[m]&&(0!==l?(clearTimeout(o),o=setTimeout(()=>n.emit(m,u,s[m]),l)):n.emit(m,u,s[m]))}return{start:function(){e.active||(document.addEventListener("focusin",i),document.addEventListener("focusout",s),document.addEventListener("input",c),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("focusin",i),document.removeEventListener("focusout",s),document.removeEventListener("input",c),e.active=!1)}}}(s,c);if(o.name){p(s,c)&&u.start()}let a={getPrefix:()=>"form",shortcutName:t=>f(t),contextChange:()=>{c.callbacks={},c.typeFn="",c.watchList=[],c.wait={},p(s,c)?u.start():u.stop()},mute:()=>u.stop(),unmute:()=>u.start(),destroy:()=>{u.stop()}};return Object.freeze(a),a}function g(n={}){let o={},r={};const i=t(),s={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!n.onShortcut||"function"!=typeof n.onShortcut)&&n.onShortcut,ERROR_EVENT_NAME:n.errorEventName?n.errorEventName:"@shortcuts-error"};let c={ev:i,inAPI:o,API:r,extra:{}};return r.enablePlugin=(t,e={})=>{if("function"!=typeof t)return;let n=t(c,s,e);const r=n.getPrefix();-1===o._systemAction(r,"none")?s.plugins.push(n):n.destroy()},r.disablePlugin=t=>{const e=o._systemAction(t,"destroy");-1!==e&&(s.plugins=s.plugins.filter((t,n)=>n!==e))},r.mutePlugin=t=>o._systemAction(t,"mute"),r.unmutePlugin=t=>o._systemAction(t,"unmute"),r.listPlugins=()=>s.plugins.map(t=>t.getPrefix()),r.getContext=()=>s.currentContext.name,r.getNote=()=>s.currentContext.note,r.setNote=(t=null)=>{"string"!=typeof t&&null!=t||(s.currentContext.note=t)},r.pause=(t="*")=>{let e=o._readShortcutWithPlugins(t);i.stop(e)},r.resume=(t="*")=>{const e=o._readShortcutWithPlugins(t);i.start(e)},r.emit=(t,...e)=>i.emit(o._readShortcutWithPlugins(t),...e),r.listContexts=()=>Object.keys(s.shortcuts),r.setDependencies=t=>c.extra={...c.extra,...t},r.getDependencies=()=>c.extra,r.reset=function(){i.reset(),r.changeContext(),s.plugins.forEach(t=>t.destroy()),r.listContexts().map(t=>r.unload(t)),c.extra={},s.exposeShortcut=null},Object.entries(e).forEach(([t,e])=>{t.startsWith("_")?o[t]=e(c,s):r[t]=e(c,s)}),r}export{m as pluginClick,d as pluginForm,s as pluginKey,g as shortcuts};
|