@peter.naydenov/shortcuts 3.5.2 → 4.0.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/API.md +939 -0
- package/CODE_OF_CONDUCT.md +84 -0
- package/CONTRIBUTING.md +476 -0
- package/Changelog.md +26 -2
- package/How.to.create.plugins.md +929 -0
- package/Migration.guide.md +48 -0
- package/README.md +396 -24
- package/dist/main.d.ts +54 -2
- package/dist/methods/_normalizeWithPlugins.d.ts +63 -1
- package/dist/methods/_readShortcutWithPlugins.d.ts +8 -1
- package/dist/methods/_setupPlugin.d.ts +9 -0
- package/dist/methods/_systemAction.d.ts +8 -1
- package/dist/methods/changeContext.d.ts +8 -1
- package/dist/methods/index.d.ts +2 -0
- package/dist/methods/listShortcuts.d.ts +1 -16
- package/dist/methods/load.d.ts +8 -1
- package/dist/methods/unload.d.ts +8 -1
- package/dist/plugins/click/_findTarget.d.ts +9 -1
- package/dist/plugins/click/_listenDOM.d.ts +76 -3
- package/dist/plugins/click/_normalizeShortcutName.d.ts +7 -1
- package/dist/plugins/click/_registerShortcutEvents.d.ts +26 -0
- package/dist/plugins/click/index.d.ts +6 -31
- package/dist/plugins/form/_defaults.d.ts +13 -1
- package/dist/plugins/form/_listenDOM.d.ts +66 -3
- package/dist/plugins/form/_registerShortcutEvents.d.ts +95 -1
- package/dist/plugins/form/index.d.ts +2 -29
- package/dist/plugins/hover/_findTarget.d.ts +10 -0
- package/dist/plugins/hover/_listenDOM.d.ts +68 -0
- package/dist/plugins/hover/_normalizeShortcutName.d.ts +2 -0
- package/dist/plugins/hover/_registerShortcutEvents.d.ts +28 -0
- package/dist/plugins/hover/index.d.ts +14 -0
- package/dist/plugins/key/_listenDOM.d.ts +61 -3
- package/dist/plugins/key/_registerShortcutEvents.d.ts +26 -0
- package/dist/plugins/key/_specialChars.d.ts +6 -31
- package/dist/plugins/key/index.d.ts +2 -29
- package/dist/plugins/scroll/_listenDOM.d.ts +58 -0
- package/dist/plugins/scroll/_normalizeShortcutName.d.ts +2 -0
- package/dist/plugins/scroll/_registerShortcutEvents.d.ts +28 -0
- package/dist/plugins/scroll/index.d.ts +16 -0
- package/dist/shortcuts.cjs +1 -1
- package/dist/shortcuts.esm.mjs +1 -1
- package/dist/shortcuts.umd.js +1 -1
- package/eslint.config.js +80 -0
- package/html/assets/index-COTh6lXR.css +1 -0
- package/html/assets/index-DOkKC3NI.js +53 -0
- package/html/bg.png +0 -0
- package/html/favicon.ico +0 -0
- package/html/favicon.svg +5 -0
- package/html/html.meta.json.gz +0 -0
- package/html/index.html +32 -0
- package/package.json +16 -12
- package/shortcuts.png +0 -0
- package/src/main.js +52 -22
- package/src/methods/_normalizeWithPlugins.js +26 -2
- package/src/methods/_readShortcutWithPlugins.js +9 -2
- package/src/methods/_setupPlugin.js +93 -0
- package/src/methods/_systemAction.js +12 -4
- package/src/methods/changeContext.js +11 -3
- package/src/methods/index.js +2 -0
- package/src/methods/listShortcuts.js +5 -12
- package/src/methods/load.js +11 -4
- package/src/methods/unload.js +8 -1
- package/src/plugins/click/_findTarget.js +11 -5
- package/src/plugins/click/_listenDOM.js +58 -20
- package/src/plugins/click/_normalizeShortcutName.js +11 -4
- package/src/plugins/click/_readClickEvent.js +1 -1
- package/src/plugins/click/_registerShortcutEvents.js +33 -5
- package/src/plugins/click/index.js +33 -60
- package/src/plugins/form/_defaults.js +13 -3
- package/src/plugins/form/_listenDOM.js +46 -9
- package/src/plugins/form/_normalizeShortcutName.js +2 -2
- package/src/plugins/form/_registerShortcutEvents.js +93 -17
- package/src/plugins/form/index.js +25 -56
- package/src/plugins/hover/_findTarget.js +26 -0
- package/src/plugins/hover/_listenDOM.js +154 -0
- package/src/plugins/hover/_normalizeShortcutName.js +21 -0
- package/src/plugins/hover/_registerShortcutEvents.js +51 -0
- package/src/plugins/hover/index.js +71 -0
- package/src/plugins/key/_listenDOM.js +67 -33
- package/src/plugins/key/_normalizeShortcutName.js +4 -3
- package/src/plugins/key/_readKeyEvent.js +1 -1
- package/src/plugins/key/_registerShortcutEvents.js +34 -5
- package/src/plugins/key/_specialChars.js +5 -0
- package/src/plugins/key/index.js +34 -59
- package/src/plugins/scroll/_listenDOM.js +141 -0
- package/src/plugins/scroll/_normalizeShortcutName.js +21 -0
- package/src/plugins/scroll/_registerShortcutEvents.js +50 -0
- package/src/plugins/scroll/index.js +61 -0
- package/test/01-general.test.js +92 -23
- package/test/02-key.test.js +241 -40
- package/test/03-click.test.js +291 -47
- package/test/04-form.test.js +241 -47
- package/test/05-hover.test.js +463 -0
- package/test/06-scroll.test.js +374 -0
- package/test-helpers/Block.jsx +3 -2
- package/test-helpers/style.css +6 -1
- package/vitest.config.js +13 -11
- package/How..to.make.plugins.md +0 -41
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export default _registerShortcutEvents;
|
|
2
|
+
export type HoverSetupData = {
|
|
3
|
+
/**
|
|
4
|
+
* - Extra dependencies object
|
|
5
|
+
*/
|
|
6
|
+
dependencies: any;
|
|
7
|
+
/**
|
|
8
|
+
* - Default options (clone of pluginState.defaultOptions)
|
|
9
|
+
*/
|
|
10
|
+
defaults: any;
|
|
11
|
+
/**
|
|
12
|
+
* - Plugin state listenOptions (reference to pluginState.listenOptions)
|
|
13
|
+
*/
|
|
14
|
+
options: any;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* @function _registerShortcutEvents
|
|
18
|
+
* @description Register hover shortcut events and handle setup
|
|
19
|
+
* @param {Object} dependencies - Dependencies object containing regex, _defaults, ev
|
|
20
|
+
* @param {Object} pluginState - Plugin state containing currentContext, shortcuts, ERROR_EVENT_NAME
|
|
21
|
+
* @returns {number} - Number of registered shortcuts
|
|
22
|
+
*
|
|
23
|
+
* @typedef {Object} HoverSetupData
|
|
24
|
+
* @property {Object} dependencies - Extra dependencies object
|
|
25
|
+
* @property {Object} defaults - Default options (clone of pluginState.defaultOptions)
|
|
26
|
+
* @property {Object} options - Plugin state listenOptions (reference to pluginState.listenOptions)
|
|
27
|
+
*/
|
|
28
|
+
declare function _registerShortcutEvents(dependencies: any, pluginState: any): number;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export default pluginHover;
|
|
2
|
+
/**
|
|
3
|
+
* @function pluginHover
|
|
4
|
+
* @description Plugin for mouse hover shortcuts
|
|
5
|
+
* @param {function} setupPlugin - Plugin setup function from the library
|
|
6
|
+
* @param {Object} [options={}] - Plugin options
|
|
7
|
+
* @param {string[]} [options.hoverTarget=['data-hover']] - Array of attribute names for hover targets
|
|
8
|
+
* @param {number} [options.wait=320] - Time to wait for hover sequence in ms
|
|
9
|
+
* @returns {PluginAPI} Plugin API
|
|
10
|
+
*/
|
|
11
|
+
declare function pluginHover(setupPlugin: Function, options?: {
|
|
12
|
+
hoverTarget?: string[];
|
|
13
|
+
wait?: number;
|
|
14
|
+
}): PluginAPI;
|
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
export default _listenDOM;
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
export type KeyEventData = {
|
|
3
|
+
/**
|
|
4
|
+
* - Function to wait for keys (disables key sequence)
|
|
5
|
+
*/
|
|
6
|
+
wait: Function;
|
|
7
|
+
/**
|
|
8
|
+
* - Function to end waiting for keys (enables key sequence)
|
|
9
|
+
*/
|
|
10
|
+
end: Function;
|
|
11
|
+
/**
|
|
12
|
+
* - Function to ignore the last key in sequence
|
|
13
|
+
*/
|
|
14
|
+
ignore: Function;
|
|
15
|
+
/**
|
|
16
|
+
* - Function to check if currently waiting for keys
|
|
17
|
+
*/
|
|
18
|
+
isWaiting: Function;
|
|
19
|
+
/**
|
|
20
|
+
* - Current context note
|
|
21
|
+
*/
|
|
22
|
+
note: string | null;
|
|
23
|
+
/**
|
|
24
|
+
* - Current context name
|
|
25
|
+
*/
|
|
26
|
+
context: string;
|
|
27
|
+
/**
|
|
28
|
+
* - Extra dependencies object
|
|
29
|
+
*/
|
|
30
|
+
dependencies: any;
|
|
31
|
+
/**
|
|
32
|
+
* - Plugin state listenOptions (reference to pluginState.listenOptions)
|
|
33
|
+
*/
|
|
34
|
+
options: any;
|
|
35
|
+
/**
|
|
36
|
+
* - Viewport information with X, Y, width, height
|
|
37
|
+
*/
|
|
38
|
+
viewport: any;
|
|
39
|
+
/**
|
|
40
|
+
* - Event type ('key')
|
|
41
|
+
*/
|
|
42
|
+
type: string;
|
|
5
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* @function _listenDOM
|
|
46
|
+
* @description Set up DOM event listeners for keyboard events
|
|
47
|
+
* @param {Object} dependencies - Dependencies object containing ev, _specialChars, _readKeyEvent, extra, resetState
|
|
48
|
+
* @param {Object} state - Plugin state containing listenOptions and currentContext
|
|
49
|
+
* @returns {Object} - Object containing start and stop methods
|
|
50
|
+
*
|
|
51
|
+
* @typedef {Object} KeyEventData
|
|
52
|
+
* @property {Function} wait - Function to wait for keys (disables key sequence)
|
|
53
|
+
* @property {Function} end - Function to end waiting for keys (enables key sequence)
|
|
54
|
+
* @property {Function} ignore - Function to ignore the last key in sequence
|
|
55
|
+
* @property {Function} isWaiting - Function to check if currently waiting for keys
|
|
56
|
+
* @property {string|null} note - Current context note
|
|
57
|
+
* @property {string} context - Current context name
|
|
58
|
+
* @property {Object} dependencies - Extra dependencies object
|
|
59
|
+
* @property {Object} options - Plugin state listenOptions (reference to pluginState.listenOptions)
|
|
60
|
+
* @property {Object} viewport - Viewport information with X, Y, width, height
|
|
61
|
+
* @property {string} type - Event type ('key')
|
|
62
|
+
*/
|
|
63
|
+
declare function _listenDOM(dependencies: any, state: any): any;
|
|
@@ -1,2 +1,28 @@
|
|
|
1
1
|
export default _registerShortcutEvents;
|
|
2
|
+
export type KeySetupData = {
|
|
3
|
+
/**
|
|
4
|
+
* - Extra dependencies object
|
|
5
|
+
*/
|
|
6
|
+
dependencies: any;
|
|
7
|
+
/**
|
|
8
|
+
* - Default options (clone of pluginState.defaultOptions)
|
|
9
|
+
*/
|
|
10
|
+
defaults: any;
|
|
11
|
+
/**
|
|
12
|
+
* - Plugin state listenOptions (reference to pluginState.listenOptions)
|
|
13
|
+
*/
|
|
14
|
+
options: any;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* @function _registerShortcutEvents
|
|
18
|
+
* @description Register keyboard shortcut events and handle setup
|
|
19
|
+
* @param {Object} dependencies - Dependencies object containing regex
|
|
20
|
+
* @param {Object} pluginState - Plugin state containing currentContext, shortcuts
|
|
21
|
+
* @returns {number} - Number of registered shortcuts
|
|
22
|
+
*
|
|
23
|
+
* @typedef {Object} KeySetupData
|
|
24
|
+
* @property {Object} dependencies - Extra dependencies object
|
|
25
|
+
* @property {Object} defaults - Default options (clone of pluginState.defaultOptions)
|
|
26
|
+
* @property {Object} options - Plugin state listenOptions (reference to pluginState.listenOptions)
|
|
27
|
+
*/
|
|
2
28
|
declare function _registerShortcutEvents(dependencies: any, pluginState: any): number;
|
|
@@ -1,32 +1,7 @@
|
|
|
1
1
|
export default _specialChars;
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
};
|
|
2
|
+
/**
|
|
3
|
+
* @function _specialChars
|
|
4
|
+
* @description Get mapping of special keyboard characters to their normalized names
|
|
5
|
+
* @returns {Object} - Object mapping keyboard event keys to normalized names
|
|
6
|
+
*/
|
|
7
|
+
declare function _specialChars(): any;
|
|
@@ -1,41 +1,14 @@
|
|
|
1
1
|
export default pluginKey;
|
|
2
|
-
export type PluginAPI = {
|
|
3
|
-
/**
|
|
4
|
-
* - Get plugin prefix
|
|
5
|
-
*/
|
|
6
|
-
getPrefix: () => string;
|
|
7
|
-
/**
|
|
8
|
-
* - Format shortcut name
|
|
9
|
-
*/
|
|
10
|
-
shortcutName: (arg0: string) => string;
|
|
11
|
-
/**
|
|
12
|
-
* - Handle context change
|
|
13
|
-
*/
|
|
14
|
-
contextChange: (arg0: string) => void;
|
|
15
|
-
/**
|
|
16
|
-
* - Mute the plugin
|
|
17
|
-
*/
|
|
18
|
-
mute: () => void;
|
|
19
|
-
/**
|
|
20
|
-
* - Unmute the plugin
|
|
21
|
-
*/
|
|
22
|
-
unmute: () => void;
|
|
23
|
-
/**
|
|
24
|
-
* - Destroy the plugin
|
|
25
|
-
*/
|
|
26
|
-
destroy: () => void;
|
|
27
|
-
};
|
|
28
2
|
/**
|
|
29
3
|
* @function pluginKey
|
|
30
4
|
* @description Plugin for keyboard shortcuts
|
|
31
|
-
* @param {
|
|
32
|
-
* @param {Object} state - Library state
|
|
5
|
+
* @param {function} setupPlugin - Plugin setup function from the library
|
|
33
6
|
* @param {Object} [options={}] - Plugin options
|
|
34
7
|
* @param {number} [options.keyWait=480] - Time to wait for key sequence in ms
|
|
35
8
|
* @param {function} [options.streamKeys] - Function to stream key presses
|
|
36
9
|
* @returns {PluginAPI} Plugin API
|
|
37
10
|
*/
|
|
38
|
-
declare function pluginKey(
|
|
11
|
+
declare function pluginKey(setupPlugin: Function, options?: {
|
|
39
12
|
keyWait?: number;
|
|
40
13
|
streamKeys?: Function;
|
|
41
14
|
}): PluginAPI;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export default _listenDOM;
|
|
2
|
+
export type ScrollEventData = {
|
|
3
|
+
/**
|
|
4
|
+
* - Current scroll X position
|
|
5
|
+
*/
|
|
6
|
+
x: number;
|
|
7
|
+
/**
|
|
8
|
+
* - Current scroll Y position
|
|
9
|
+
*/
|
|
10
|
+
y: number;
|
|
11
|
+
/**
|
|
12
|
+
* - Scroll direction ('up', 'down', 'left', 'right')
|
|
13
|
+
*/
|
|
14
|
+
direction: string;
|
|
15
|
+
/**
|
|
16
|
+
* - Current context name
|
|
17
|
+
*/
|
|
18
|
+
context: string;
|
|
19
|
+
/**
|
|
20
|
+
* - Current context note
|
|
21
|
+
*/
|
|
22
|
+
note: string | null;
|
|
23
|
+
/**
|
|
24
|
+
* - Extra dependencies object
|
|
25
|
+
*/
|
|
26
|
+
dependencies: any;
|
|
27
|
+
/**
|
|
28
|
+
* - Plugin state listenOptions (reference to pluginState.listenOptions)
|
|
29
|
+
*/
|
|
30
|
+
options: any;
|
|
31
|
+
/**
|
|
32
|
+
* - Viewport information with X, Y, width, height
|
|
33
|
+
*/
|
|
34
|
+
viewport: any;
|
|
35
|
+
/**
|
|
36
|
+
* - Event type ('scroll')
|
|
37
|
+
*/
|
|
38
|
+
type: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* @function _listenDOM
|
|
42
|
+
* @description Set up DOM event listeners for scroll events
|
|
43
|
+
* @param {Object} dependencies - Dependencies object containing ev, resetState, extra
|
|
44
|
+
* @param {Object} state - Plugin state containing listenOptions and currentContext
|
|
45
|
+
* @returns {Object} - Object containing start and stop methods
|
|
46
|
+
*
|
|
47
|
+
* @typedef {Object} ScrollEventData
|
|
48
|
+
* @property {number} x - Current scroll X position
|
|
49
|
+
* @property {number} y - Current scroll Y position
|
|
50
|
+
* @property {string} direction - Scroll direction ('up', 'down', 'left', 'right')
|
|
51
|
+
* @property {string} context - Current context name
|
|
52
|
+
* @property {string|null} note - Current context note
|
|
53
|
+
* @property {Object} dependencies - Extra dependencies object
|
|
54
|
+
* @property {Object} options - Plugin state listenOptions (reference to pluginState.listenOptions)
|
|
55
|
+
* @property {Object} viewport - Viewport information with X, Y, width, height
|
|
56
|
+
* @property {string} type - Event type ('scroll')
|
|
57
|
+
*/
|
|
58
|
+
declare function _listenDOM(dependencies: any, state: any): any;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export default _registerShortcutEvents;
|
|
2
|
+
export type ScrollSetupData = {
|
|
3
|
+
/**
|
|
4
|
+
* - Extra dependencies object
|
|
5
|
+
*/
|
|
6
|
+
dependencies: any;
|
|
7
|
+
/**
|
|
8
|
+
* - Default options (clone of pluginState.defaultOptions)
|
|
9
|
+
*/
|
|
10
|
+
defaults: any;
|
|
11
|
+
/**
|
|
12
|
+
* - Plugin state listenOptions (reference to pluginState.listenOptions)
|
|
13
|
+
*/
|
|
14
|
+
options: any;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* @function _registerShortcutEvents
|
|
18
|
+
* @description Register scroll shortcut events and handle setup
|
|
19
|
+
* @param {Object} dependencies - Dependencies object containing regex
|
|
20
|
+
* @param {Object} pluginState - Plugin state containing currentContext, shortcuts
|
|
21
|
+
* @returns {number} - Number of registered shortcuts
|
|
22
|
+
*
|
|
23
|
+
* @typedef {Object} ScrollSetupData
|
|
24
|
+
* @property {Object} dependencies - Extra dependencies object
|
|
25
|
+
* @property {Object} defaults - Default options (clone of pluginState.defaultOptions)
|
|
26
|
+
* @property {Object} options - Plugin state listenOptions (reference to pluginState.listenOptions)
|
|
27
|
+
*/
|
|
28
|
+
declare function _registerShortcutEvents(dependencies: any, pluginState: any): number;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default pluginScroll;
|
|
2
|
+
/**
|
|
3
|
+
* @function pluginScroll
|
|
4
|
+
* @description Plugin for scroll event shortcuts
|
|
5
|
+
* @param {function} setupPlugin - Plugin setup function from the library
|
|
6
|
+
* @param {Object} [options={}] - Plugin options
|
|
7
|
+
* @param {number} [options.scrollWait=50] - Delay between scroll events in ms
|
|
8
|
+
* @param {number} [options.endScrollWait=400] - Delay when scroll was stopped in ms
|
|
9
|
+
* @param {number} [options.minSpace=40] - Minimum distance between scroll events in px
|
|
10
|
+
* @returns {PluginAPI} Plugin API
|
|
11
|
+
*/
|
|
12
|
+
declare function pluginScroll(setupPlugin: Function, options?: {
|
|
13
|
+
scrollWait?: number;
|
|
14
|
+
endScrollWait?: number;
|
|
15
|
+
minSpace?: number;
|
|
16
|
+
}): 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,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};
|
|
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(([i,o])=>{const r=t(i);r!==i&&(delete n[e][i],n[e][r]=o)})})}},_readShortcutWithPlugins:function(t,e){return function(n){const{inAPI:i}=t,o=n.split(":")[0].toLowerCase().trim(),r=i._systemAction(o,"none");let s=n;return-1!==r&&(s=e.plugins[r].shortcutName(n)),s}},_setupPlugin:function(t,e){const{inAPI:n}=t,{currentContext:i,shortcuts:o,exposeShortcut:r,ERROR_EVENT_NAME:s}=e;return function(e){const{prefix:c,_normalizeShortcutName:u,_registerShortcutEvents:l,_listenDOM:a,pluginState:p,deps:d}=e,{resetState:f}=d;p.currentContext=i,p.shortcuts=o,p.exposeShortcut=r,p.ERROR_EVENT_NAME=s;const h={ev:t.ev,extra:t.extra,...d};n._normalizeWithPlugins(u);let m=l(h,p);const g=a(h,p);m>0&&g.start();const v={getPrefix:()=>c,shortcutName:t=>u(t),contextChange:()=>{f(),m=l(h,p),m<1&&g.stop(),m>0&&g.start()},mute:()=>g.stop(),unmute:()=>g.start(),destroy:()=>{g.stop(),f()}};return Object.freeze(v),v}},_systemAction:function(t,e){return function(t,n,i=null){return e.plugins.findIndex(e=>e.getPrefix()===t&&(e[n]&&e[n](i),!0))}},changeContext:function(t,e){const{shortcuts:n,currentContext:i,ERROR_EVENT_NAME:o}=e,{ev:r}=t;return function(t=!1){const s=i.name;if(!t)return r.reset(),void(i.name=null);s!==t&&(n[t]?(n[s]&&r.reset(),i.name=t,e.plugins.forEach(e=>e.contextChange(t)),Object.entries(n[t]).forEach(([t,e])=>{t.includes(":SETUP")||e.forEach(e=>r.on(t,e))}),r.on("*",(...t)=>{e.exposeShortcut&&e.exposeShortcut(...t)})):r.emit(o,`Context '${t}' does not exist`))}},listShortcuts:function(t,e){const n=e.shortcuts;return function(t=null){if(null!=t){const e=n[t];return null==e?null:Object.entries(e).map(([t,e])=>t)}return Object.keys(n).map(t=>{const e={};return e.context=t,e.shortcuts=Object.entries(n[t]).map(([t,e])=>t),e})}},load:function(t,e){const{shortcuts:n,plugins:i}=e,{API:{changeContext:o,getContext:r}}=t;return function(t){const e=r(),s=i.map(t=>t.getPrefix().toUpperCase());let c=!1;Object.entries(t).forEach(([t,o])=>{t===e&&(c=!0),n[t]={},Object.entries(o).forEach(([e,o])=>{let r=e;const c=e.toUpperCase().trim(),u=s.map((t,e)=>c.startsWith(t)?e:null).filter(t=>null!==t);if(u.length){const t=u[0];r=i[t].shortcutName(e)}o instanceof Function&&(o=[o]),n[t][r]=o})}),c&&(o(),o(e))}},unload:function(t,e){const{currentContext:n,shortcuts:i,ERROR_EVENT_NAME:o}=e,{ev:r}=t;return function(t){n.name!==t?i[t]?delete i[t]:r.emit(o,`Context '${t}' does not exist`):r.emit(o,`Context '${t}' can't be removed during is current active context. Change the context first`)}}};function n(t,e){const{ev:n,_specialChars:i,_readKeyEvent:o,extra:r,resetState:s}=t,{currentContext:c,streamKeys:u,listenOptions:l}=e;let a=[],p=null,d=!0,f=!1;const h=()=>d=!1,m=()=>d=!0,g=()=>f=!0,v=()=>!1===d;function x(){const t=a.map(t=>[t.join("+")]),i={wait:h,end:m,ignore:g,isWaiting:v,note:c.note,context:c.name,dependencies:r,options:e.listenOptions,viewport:{X:window.scrollX,Y:window.scrollY,width:window.innerWidth,height:window.innerHeight},type:"key"};if(!d){const e=`KEY:${t.at(-1).join("+")}`;n.emit(e,i),f&&(a=a.slice(0,-1),f=!1)}if(d){const o=`KEY:${t.join(",")}`;n.emit(o,i),f&&(a=a.slice(0,-1),f=!1),a=[],clearTimeout(e.keyIgnore),e.keyIgnore=null,clearTimeout(p),p=null}}function E(n){clearTimeout(p);if(i().hasOwnProperty(n.code))return a.push(o(n,i)),u&&u({key:n.key,context:c.name,note:c.note,dependencies:t.extra}),e.keyIgnore?(clearTimeout(e.keyIgnore),e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait),void a.pop()):d&&a.length===e.maxSequence?(x(),void(e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait))):void(d?p=setTimeout(x,l.keyWait):x())}function O(n){if(!i().hasOwnProperty(n.code)){if(clearTimeout(p),u&&u({key:n.key,context:c.name,note:c.note,dependencies:t.extra}),e.keyIgnore)return clearTimeout(e.keyIgnore),void(e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait));if(a.push(o(n,i)),d&&a.length===e.maxSequence)return x(),void(e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait));d?p=setTimeout(x,l.keyWait):x()}}return{start:function(){e.active||(document.addEventListener("keydown",E),document.addEventListener("keypress",O),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("keydown",E),document.removeEventListener("keypress",O),e.active=!1,p&&(clearTimeout(p),p=null),e.keyIgnore&&(clearTimeout(e.keyIgnore),e.keyIgnore=null),a=[],d=!0,f=!1)}}}function i(t){const e=t.toUpperCase(),n=/KEY\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;if(e.includes("SETUP"))return"KEY:SETUP";return`KEY:${e.slice(i+1).split(",").map(t=>t.trim()).map(t=>t.split("+").map(t=>t.trim()).sort().join("+")).join(",")}`}function o(t,e){const{shiftKey:n,altKey:i,ctrlKey:o}=t,r=e(),s=t.code.replace("Key","").replace("Digit",""),c=[];return o&&c.push("CTRL"),n&&c.push("SHIFT"),i&&c.push("ALT"),r.hasOwnProperty(s)?c.push(r[s].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(s)||c.push(s.toUpperCase()),c.sort()}function r(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r}=t,{currentContext:{name:s},shortcuts:c}=e;return null==s?0:(Object.entries(c[s]).forEach(([s,c])=>{if(!r.test(s))return;if("KEY:SETUP"===s){i=!0;const n=c.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++;const u=s.slice(4).split(",").length;e.maxSequence<u&&(e.maxSequence=u)}),i||Object.assign(e.listenOptions,o),n)}function s(){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 c(t,e,n){const{listenOptions:{clickTarget:i}}=e,o=n;if(o===document.body)return null;return i.some(t=>o.hasAttribute(t))?o:c(t,e,o.parentNode)}function u(t,e){const{ev:n,_findTarget:i,_readClickEvent:o,extra:r}=t,{listenOptions:s,currentContext:c}=e;let u=null,l=null,a=null,p=null,d=0;function f(){if(!u)return;const{left:t,top:i,width:s,height:f}=u.getBoundingClientRect(),h=window.scrollX,m=window.scrollY,g=o(l,d),v={target:u,x:l.clientX,y:l.clientY,context:c.name,note:c.note,options:e.listenOptions,event:l,dependencies:r,viewport:{X:h,Y:m,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:f},position:{x:t,y:i},pagePosition:{x:t+h,y:i+m},type:"click"};n.emit(g,v),a=null,p=null,u=null,l=null,d=0}function h(n){let o=e.maxLeftClicks;if(clearTimeout(a),p)return clearTimeout(p),void(p=setTimeout(()=>p=null,s.mouseWait));if(u=i(t,e,n.target),null!=u){if(u&&u.dataset.hasOwnProperty("quickClick")&&(o=1),u&&"A"===u.tagName&&(o=1),l=n,d++,d>=o)return f(),void(o>1&&(p=setTimeout(()=>p=null,s.mouseWait)));a=setTimeout(f,s.mouseWait)}}function m(n){let o=e.maxRightClicks;if(clearTimeout(a),p)return clearTimeout(p),void(p=setTimeout(()=>p=null,s.mouseWait));if(u=i(t,e,n.target),null!=u){if(u&&u.dataset.hasOwnProperty("quickClick")&&(o=1),u&&"A"===u.tagName&&(o=1),l=n,d++,d>=o)return f(),void(o>1&&(p=setTimeout(()=>p=null,s.mouseWait)));a=setTimeout(f,s.mouseWait)}}return{start:function(){e.active||(window.addEventListener("contextmenu",m),document.addEventListener("click",h),e.active=!0)},stop:function(){e.active&&(window.removeEventListener("contextmenu",m),document.removeEventListener("click",h),e.active=!1,p&&(clearTimeout(p),p=null),u=null,l=null,d=0)}}}function l(t){const e=t.toUpperCase(),n=/CLICK\s*\:/i.test(e),i=["LEFT","MIDDLE","RIGHT"],o=["ALT","SHIFT","CTRL"];let r=null,s=0;const c=[],u=e.indexOf(":");if(!n)return t;if(e.includes("SETUP"))return"CLICK:SETUP";return e.slice(u+1).trim().split("-").map(t=>t.trim()).forEach(t=>{i.includes(t)?r=t:o.includes(t)?c.push(t):isNaN(t)||(s=t)}),`CLICK:${r}-${s}${c.length>0?"-":""}${c.sort().join("-")}`}function a(t,e){const{shiftKey:n,altKey:i,ctrlKey:o,key:r,button:s}=t,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][s]}-${e}`,u=[];return o&&u.push("CTRL"),n&&u.push("SHIFT"),i&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function p(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r}=t,{listenOptions:s,currentContext:{name:c},shortcuts:u}=e;return null==c||(Object.entries(u[c]).forEach(([c,u])=>{if(!r.test(c))return;if("CLICK:SETUP"===c){i=!0;const n=u.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:s});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++;const[l,a]=c.slice(6).split("-");"LEFT"===l&&e.maxLeftClicks<a&&(e.maxLeftClicks=a),"RIGHT"===l&&e.maxRightClicks<a&&(e.maxRightClicks=a)}),i||Object.assign(e.listenOptions,o)),n}function d(t,e){const{ev:n}=t;let i=null;function o(t,e,n,i){const{left:o,top:r,width:s,height:c}=n.target.getBoundingClientRect(),u=window.scrollX,l=window.scrollY;return{target:n.target,context:e.currentContext.name,note:e.currentContext.note,event:n,dependencies:t.extra,options:e.listenOptions,viewport:{X:u,Y:l,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:c},position:{x:o,y:r},pagePosition:{x:o+u,y:r+l},type:i}}function r(i){const{callbacks:r,typeFn:s}=e;i.target;const c=o(t,e,i,"form-in"),u=`${s(c)}/in`;null!=r[u]&&n.emit(u,c,r[u])}function s(i){const{callbacks:r,typeFn:s}=e,c=o(t,e,i,"form-out"),u=`${s(c)}/out`;null!=r[u]&&n.emit(u,c,r[u])}function c(r){const{callbacks:s,typeFn:c}=e,u=o(t,e,r,"form-instant"),l=c(u),a=e.wait[`${l}`],p=`${l}/instant`;if(null==s[p])return;if(0===a)return void n.emit(p,u,s[p]);clearTimeout(i),i=setTimeout(()=>n.emit(p,u,s[p]),a)}return{start:function(){e.active||(document.addEventListener("focusin",r),document.addEventListener("focusout",s),document.addEventListener("input",c),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("focusin",r),document.removeEventListener("focusout",s),document.removeEventListener("input",c),e.active=!1,i&&(clearTimeout(i),i=null))}}}function f(t){const e=t.toUpperCase(),n=/FORM\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;return`FORM:${e.slice(i+1).trim()}`}function h(t,e){const{regex:n,_defaults:i,ev:o}=t,{currentContext:{name:r,note:s},shortcuts:c,callbacks:u,ERROR_EVENT_NAME:l,defaultOptions:a}=e;let p=[],d=[],f=[],h=0;if(null==r)return!1;if(Object.entries(c[r]).forEach(([i,o])=>{if(n.test(i)){if(i.includes("SETUP")){const n=o.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},a);return void Object.assign(e.listenOptions,n)}"FORM:WATCH"===i&&(p=o),"FORM:DEFINE"===i&&(d=o),"FORM:ACTION"===i&&(f=o)}}),0===f.length)return h;const m=new Set;0===d.length&&(d=[i.define]),0===p.length&&(p=[i.watch]);const g=p.map(n=>n({dependencies:t.extra,context:r,note:s,options:e.listenOptions})).reduce((t,e)=>(t.push(e),t),[]);return e.watchList=document.querySelectorAll(g),e.watchList.forEach(n=>{const{left:i,top:o,width:c,height:u}=n.getBoundingClientRect(),l=window.scrollX,a=window.scrollY;return m.add(d[0]({target:n,context:r,note:s,dependencies:t.extra,options:e.listenOptions,viewport:{X:l,Y:a,width:window.innerWidth,height:window.innerHeight},sizes:{width:c,height:u},position:{x:i,y:o},pagePosition:{x:i+l,y:o+a}}))}),e.typeFn=d[0]?d[0]:i.define,f.forEach(n=>{if(!(n instanceof Function))return o.emit(l,"The 'form:action' should be a function."),!1;const i=n({dependencies:t.extra,options:e.listenOptions});if(!(i instanceof Array))return o.emit(l,"Warning: The 'form:action' function should RETURN an array."),!1;i.forEach(({fn:t,type:n,timing:i,wait:r=0})=>{if(m.has(n)&&t instanceof Function){const e=`${n}/${i}`,r=u.hasOwnProperty(e);r?u[e].push(t):u[e]=[t],r||o.on(e,(t,e)=>{e.forEach(e=>{e instanceof Function&&e(t)})})}"instant"===i&&(e.wait[`${n}`]=r)})}),h=Object.keys(e.callbacks).length,h}const m={watch:()=>"input, select, textarea, button, a",define:({target:t})=>"checkbox"===t.type||"radio"===t.type?"checkbox":"button"==t.type||"submit"==t.type?"button":"input"};function g(t,e,n){const{listenOptions:{hoverTarget:i}}=e,o=n;if(o===document.body)return!1;if(o===document)return!1;return i.some(t=>o.hasAttribute(t))?o:g(t,e,o.parentNode)}function v(t,e){const{ev:n,_findTarget:i,resetState:o,extra:r}=t;function s(o){const s=o.clientX,c=o.clientY,{hovered:u,hoverRectangle:l,listenOptions:a,hoverTimer:p,leaveTimer:d,lastEvent:f,lastHoverTarget:h}=e,m=i(t,e,o.target);if(!function(t,e,n){return!!t&&e>=t.left&&e<=t.right&&n>=t.top&&n<=t.bottom}(l,s,c)&&m!==u){if(u&&!m){if(e.hovered=!1,e.hoverRectangle=null,p&&(clearTimeout(p),e.hoverTimer=null),"off"===f)return;return void(e.leaveTimer=setTimeout(()=>{n.emit("HOVER:OFF",g(u)),e.leaveTimer=null,e.lastEvent="off"},a.wait))}u&&(n.emit("HOVER:OFF",g(u)),e.leaveTimer=null,e.lastEvent="off"),clearTimeout(d),clearTimeout(p),e.hovered=m,e.hoverRectangle=m.getBoundingClientRect(),e.hoverTimer=setTimeout(()=>{n.emit("HOVER:ON",g(m)),e.hoverTimer=null,e.lastHoverTarget=m,e.lastEvent="on"},a.wait)}function g(t){const{left:n,top:i,width:s,height:c}=t.getBoundingClientRect(),u=window.scrollX,l=window.scrollY;return{target:t,context:e.currentContext.name,note:e.currentContext.note,event:o,dependencies:r,options:e.listenOptions,viewport:{X:u,Y:l,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:c},position:{x:n,y:i},pagePosition:{x:n+u,y:i+l},type:"hover"}}}return{start:function(){e.active||(document.addEventListener("mousemove",s),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("mousemove",s),o())}}}function x(t){const e=t.toUpperCase(),n=/HOVER\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;return`HOVER:${e.slice(i+1).trim()}`}function E(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r,_defaults:s,ev:c}=t,{currentContext:{name:u},shortcuts:l,ERROR_EVENT_NAME:a}=e;return null==u||(Object.entries(l[u]).forEach(([s,c])=>{if(r.test(s)){if("HOVER:SETUP"===s){i=!0;const n=c.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++}}),i||Object.assign(e.listenOptions,o)),n}function O(t,e){const{ev:n,resetState:i,extra:o}=t;let r=null,s=null;function c(t){t.clientX,t.clientY;const{lastPosition:i,lastDirection:c,listenOptions:u,currentContext:l}=e,{scrollWait:a,endScrollWait:p,minSpace:d}=u;if(!i)return;let f=null;const h=window.scrollX,m=window.scrollY,g=Math.abs(m-i.y),v=Math.abs(h-i.x);if(g<d&&v<d)return;const x=[];g>=d&&(m>i.y?x.push("down"):x.push("up")),v>=d&&(h>i.x?x.push("right"):x.push("left")),f=x[0]||null;const E=t=>({x:h,y:m,direction:t,context:l.name,note:l.note,dependencies:o,options:e.listenOptions,viewport:{X:h,Y:m,width:window.innerWidth,height:window.innerHeight},type:"scroll"});x.forEach(t=>{const e=`SCROLL:${t.toUpperCase()}`;n.emit(e,E(t))}),clearTimeout(r),clearTimeout(s);const O=x[x.length-1]||null;r=setTimeout(()=>{},a),s=setTimeout(()=>n.emit("SCROLL:END",E(O)),p),e.lastPosition={x:h,y:m},e.lastDirection=f}return{start:function(){e.active||(e.lastPosition={x:window.scrollX,y:window.scrollY},window.addEventListener("scroll",c),e.active=!0)},stop:function(){e.active&&(window.removeEventListener("scroll",c),i())}}}function y(t){const e=t.toUpperCase(),n=/SCROLL\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;return`SCROLL:${e.slice(i+1).trim()}`}function w(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r}=t,{currentContext:{name:s},shortcuts:c}=e;return null==s||(Object.entries(c[s]).forEach(([s,c])=>{if(r.test(s)){if("SCROLL:SETUP"===s){i=!0;const n=c.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++}}),i||Object.assign(e.listenOptions,o)),n}exports.pluginClick=function(t,e={}){const n={_findTarget:c,_readClickEvent:a,regex:/CLICK\s*\:/i},i={active:!1,maxLeftClicks:1,maxRightClicks:1,defaultOptions:{mouseWait:320,clickTarget:["data-click","href"]},listenOptions:{mouseWait:320,clickTarget:["data-click","href"]},streamKeys:!(!e.streamKeys||"function"!=typeof e.streamKeys)&&e.streamKeys};return n.resetState=function(){},t({prefix:"click",_normalizeShortcutName:l,_registerShortcutEvents:p,_listenDOM:u,pluginState:i,deps:n})},exports.pluginForm=function(t,e={}){const n={_defaults:m,regex:/FORM\s*\:/i},i={callbacks:{},typeFn:"",watchList:[],wait:{},defaultOptions:{},listenOptions:{}};return n.resetState=function(){i.callbacks={},i.typeFn="",i.watchList=[],i.wait={}},t({prefix:"form",_normalizeShortcutName:f,_registerShortcutEvents:h,_listenDOM:d,pluginState:i,deps:n})},exports.pluginHover=function(t,e={}){const n={_findTarget:g,regex:/HOVER\s*\:/i},i={active:!1,hovered:!1,hoverRectangle:null,hoverTimer:null,leaveTimer:null,lastEvent:"",lastHoverTarget:null,defaultOptions:{hoverTarget:["data-hover"],wait:320},listenOptions:{hoverTarget:["data-hover"],wait:320}};return n.resetState=function(){i.active=!1,i.hovered=!1,i.hoverRectangle=null,clearTimeout(i.hoverTimer),clearTimeout(i.leaveTimer),i.hoverTimer=null,i.leaveTimer=null,i.lastHoverTarget=null},t({prefix:"hover",_normalizeShortcutName:x,_registerShortcutEvents:E,_listenDOM:v,pluginState:i,deps:n})},exports.pluginKey=function(t,e={}){const c={_specialChars:s,_readKeyEvent:o,regex:/KEY\s*\:/i},u={active:!1,maxSequence:1,keyIgnore:null,defaultOptions:{keyWait:480},listenOptions:{keyWait:480},streamKeys:!(!e.streamKeys||"function"!=typeof e.streamKeys)&&e.streamKeys};return c.resetState=function(){u.active=!1,u.keyIgnore=null,u.maxSequence=1},t({prefix:"key",_normalizeShortcutName:i,_registerShortcutEvents:r,_listenDOM:n,pluginState:u,deps:c})},exports.pluginScroll=function(t,e={}){const n={regex:/SCROLL\s*\:/i},i={active:!1,lastPosition:null,lastDirection:null,defaultOptions:{scrollWait:50,endScrollWait:400,minSpace:40},listenOptions:{scrollWait:50,endScrollWait:400,minSpace:40}};return n.resetState=function(){i.active=!1},t({prefix:"scroll",_normalizeShortcutName:y,_registerShortcutEvents:w,_listenDOM:O,pluginState:i,deps:n})},exports.shortcuts=function(n={}){const i={},o={},r=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"},c={ev:r,inAPI:i,API:o,extra:{}};return o.enablePlugin=(t,e={})=>{if("function"!=typeof t)return;const n=t(i._setupPlugin,e),o=n.getPrefix(),r=i._systemAction(o,"none");-1===r?(s.plugins.push(n),n.unmute()):(n.destroy(),s.plugins[r].unmute())},o.disablePlugin=t=>{const e=i._systemAction(t,"destroy");-1!==e&&s.plugins.splice(e,1)},o.mutePlugin=t=>i._systemAction(t,"mute"),o.unmutePlugin=t=>i._systemAction(t,"unmute"),o.listPlugins=()=>s.plugins.map(t=>t.getPrefix()),o.getContext=()=>s.currentContext.name,o.getNote=()=>s.currentContext.note,o.setNote=(t=null)=>{"string"!=typeof t&&null!=t||(s.currentContext.note=t)},o.pause=(t="*")=>{const e=i._readShortcutWithPlugins(t);r.stop(e)},o.resume=(t="*")=>{const e=i._readShortcutWithPlugins(t);r.start(e)},o.emit=(t,...e)=>r.emit(i._readShortcutWithPlugins(t),...e),o.listContexts=()=>Object.keys(s.shortcuts),o.setDependencies=t=>Object.assign(c.extra,t),o.getDependencies=()=>c.extra,o.reset=function(){r.reset(),o.changeContext(),s.plugins.forEach(t=>t.destroy()),o.listContexts().map(t=>o.unload(t)),c.extra={},s.exposeShortcut=null},Object.entries(e).forEach(([t,e])=>{t.startsWith("_")?i[t]=e(c,s):o[t]=e(c,s)}),o};
|
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,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};
|
|
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(([i,o])=>{const r=t(i);r!==i&&(delete n[e][i],n[e][r]=o)})})}},_readShortcutWithPlugins:function(t,e){return function(n){const{inAPI:i}=t,o=n.split(":")[0].toLowerCase().trim(),r=i._systemAction(o,"none");let s=n;return-1!==r&&(s=e.plugins[r].shortcutName(n)),s}},_setupPlugin:function(t,e){const{inAPI:n}=t,{currentContext:i,shortcuts:o,exposeShortcut:r,ERROR_EVENT_NAME:s}=e;return function(e){const{prefix:c,_normalizeShortcutName:u,_registerShortcutEvents:l,_listenDOM:a,pluginState:d,deps:p}=e,{resetState:f}=p;d.currentContext=i,d.shortcuts=o,d.exposeShortcut=r,d.ERROR_EVENT_NAME=s;const h={ev:t.ev,extra:t.extra,...p};n._normalizeWithPlugins(u);let m=l(h,d);const g=a(h,d);m>0&&g.start();const v={getPrefix:()=>c,shortcutName:t=>u(t),contextChange:()=>{f(),m=l(h,d),m<1&&g.stop(),m>0&&g.start()},mute:()=>g.stop(),unmute:()=>g.start(),destroy:()=>{g.stop(),f()}};return Object.freeze(v),v}},_systemAction:function(t,e){return function(t,n,i=null){return e.plugins.findIndex(e=>e.getPrefix()===t&&(e[n]&&e[n](i),!0))}},changeContext:function(t,e){const{shortcuts:n,currentContext:i,ERROR_EVENT_NAME:o}=e,{ev:r}=t;return function(t=!1){const s=i.name;if(!t)return r.reset(),void(i.name=null);s!==t&&(n[t]?(n[s]&&r.reset(),i.name=t,e.plugins.forEach(e=>e.contextChange(t)),Object.entries(n[t]).forEach(([t,e])=>{t.includes(":SETUP")||e.forEach(e=>r.on(t,e))}),r.on("*",(...t)=>{e.exposeShortcut&&e.exposeShortcut(...t)})):r.emit(o,`Context '${t}' does not exist`))}},listShortcuts:function(t,e){const n=e.shortcuts;return function(t=null){if(null!=t){const e=n[t];return null==e?null:Object.entries(e).map(([t,e])=>t)}return Object.keys(n).map(t=>{const e={};return e.context=t,e.shortcuts=Object.entries(n[t]).map(([t,e])=>t),e})}},load:function(t,e){const{shortcuts:n,plugins:i}=e,{API:{changeContext:o,getContext:r}}=t;return function(t){const e=r(),s=i.map(t=>t.getPrefix().toUpperCase());let c=!1;Object.entries(t).forEach(([t,o])=>{t===e&&(c=!0),n[t]={},Object.entries(o).forEach(([e,o])=>{let r=e;const c=e.toUpperCase().trim(),u=s.map((t,e)=>c.startsWith(t)?e:null).filter(t=>null!==t);if(u.length){const t=u[0];r=i[t].shortcutName(e)}o instanceof Function&&(o=[o]),n[t][r]=o})}),c&&(o(),o(e))}},unload:function(t,e){const{currentContext:n,shortcuts:i,ERROR_EVENT_NAME:o}=e,{ev:r}=t;return function(t){n.name!==t?i[t]?delete i[t]:r.emit(o,`Context '${t}' does not exist`):r.emit(o,`Context '${t}' can't be removed during is current active context. Change the context first`)}}};function n(t,e){const{ev:n,_specialChars:i,_readKeyEvent:o,extra:r,resetState:s}=t,{currentContext:c,streamKeys:u,listenOptions:l}=e;let a=[],d=null,p=!0,f=!1;const h=()=>p=!1,m=()=>p=!0,g=()=>f=!0,v=()=>!1===p;function x(){const t=a.map(t=>[t.join("+")]),i={wait:h,end:m,ignore:g,isWaiting:v,note:c.note,context:c.name,dependencies:r,options:e.listenOptions,viewport:{X:window.scrollX,Y:window.scrollY,width:window.innerWidth,height:window.innerHeight},type:"key"};if(!p){const e=`KEY:${t.at(-1).join("+")}`;n.emit(e,i),f&&(a=a.slice(0,-1),f=!1)}if(p){const o=`KEY:${t.join(",")}`;n.emit(o,i),f&&(a=a.slice(0,-1),f=!1),a=[],clearTimeout(e.keyIgnore),e.keyIgnore=null,clearTimeout(d),d=null}}function E(n){clearTimeout(d);if(i().hasOwnProperty(n.code))return a.push(o(n,i)),u&&u({key:n.key,context:c.name,note:c.note,dependencies:t.extra}),e.keyIgnore?(clearTimeout(e.keyIgnore),e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait),void a.pop()):p&&a.length===e.maxSequence?(x(),void(e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait))):void(p?d=setTimeout(x,l.keyWait):x())}function O(n){if(!i().hasOwnProperty(n.code)){if(clearTimeout(d),u&&u({key:n.key,context:c.name,note:c.note,dependencies:t.extra}),e.keyIgnore)return clearTimeout(e.keyIgnore),void(e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait));if(a.push(o(n,i)),p&&a.length===e.maxSequence)return x(),void(e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait));p?d=setTimeout(x,l.keyWait):x()}}return{start:function(){e.active||(document.addEventListener("keydown",E),document.addEventListener("keypress",O),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("keydown",E),document.removeEventListener("keypress",O),e.active=!1,d&&(clearTimeout(d),d=null),e.keyIgnore&&(clearTimeout(e.keyIgnore),e.keyIgnore=null),a=[],p=!0,f=!1)}}}function i(t){const e=t.toUpperCase(),n=/KEY\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;if(e.includes("SETUP"))return"KEY:SETUP";return`KEY:${e.slice(i+1).split(",").map(t=>t.trim()).map(t=>t.split("+").map(t=>t.trim()).sort().join("+")).join(",")}`}function o(t,e){const{shiftKey:n,altKey:i,ctrlKey:o}=t,r=e(),s=t.code.replace("Key","").replace("Digit",""),c=[];return o&&c.push("CTRL"),n&&c.push("SHIFT"),i&&c.push("ALT"),r.hasOwnProperty(s)?c.push(r[s].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(s)||c.push(s.toUpperCase()),c.sort()}function r(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r}=t,{currentContext:{name:s},shortcuts:c}=e;return null==s?0:(Object.entries(c[s]).forEach(([s,c])=>{if(!r.test(s))return;if("KEY:SETUP"===s){i=!0;const n=c.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++;const u=s.slice(4).split(",").length;e.maxSequence<u&&(e.maxSequence=u)}),i||Object.assign(e.listenOptions,o),n)}function s(){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 c(t,e={}){const c={_specialChars:s,_readKeyEvent:o,regex:/KEY\s*\:/i},u={active:!1,maxSequence:1,keyIgnore:null,defaultOptions:{keyWait:480},listenOptions:{keyWait:480},streamKeys:!(!e.streamKeys||"function"!=typeof e.streamKeys)&&e.streamKeys};return c.resetState=function(){u.active=!1,u.keyIgnore=null,u.maxSequence=1},t({prefix:"key",_normalizeShortcutName:i,_registerShortcutEvents:r,_listenDOM:n,pluginState:u,deps:c})}function u(t,e,n){const{listenOptions:{clickTarget:i}}=e,o=n;if(o===document.body)return null;return i.some(t=>o.hasAttribute(t))?o:u(t,e,o.parentNode)}function l(t,e){const{ev:n,_findTarget:i,_readClickEvent:o,extra:r}=t,{listenOptions:s,currentContext:c}=e;let u=null,l=null,a=null,d=null,p=0;function f(){if(!u)return;const{left:t,top:i,width:s,height:f}=u.getBoundingClientRect(),h=window.scrollX,m=window.scrollY,g=o(l,p),v={target:u,x:l.clientX,y:l.clientY,context:c.name,note:c.note,options:e.listenOptions,event:l,dependencies:r,viewport:{X:h,Y:m,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:f},position:{x:t,y:i},pagePosition:{x:t+h,y:i+m},type:"click"};n.emit(g,v),a=null,d=null,u=null,l=null,p=0}function h(n){let o=e.maxLeftClicks;if(clearTimeout(a),d)return clearTimeout(d),void(d=setTimeout(()=>d=null,s.mouseWait));if(u=i(t,e,n.target),null!=u){if(u&&u.dataset.hasOwnProperty("quickClick")&&(o=1),u&&"A"===u.tagName&&(o=1),l=n,p++,p>=o)return f(),void(o>1&&(d=setTimeout(()=>d=null,s.mouseWait)));a=setTimeout(f,s.mouseWait)}}function m(n){let o=e.maxRightClicks;if(clearTimeout(a),d)return clearTimeout(d),void(d=setTimeout(()=>d=null,s.mouseWait));if(u=i(t,e,n.target),null!=u){if(u&&u.dataset.hasOwnProperty("quickClick")&&(o=1),u&&"A"===u.tagName&&(o=1),l=n,p++,p>=o)return f(),void(o>1&&(d=setTimeout(()=>d=null,s.mouseWait)));a=setTimeout(f,s.mouseWait)}}return{start:function(){e.active||(window.addEventListener("contextmenu",m),document.addEventListener("click",h),e.active=!0)},stop:function(){e.active&&(window.removeEventListener("contextmenu",m),document.removeEventListener("click",h),e.active=!1,d&&(clearTimeout(d),d=null),u=null,l=null,p=0)}}}function a(t){const e=t.toUpperCase(),n=/CLICK\s*\:/i.test(e),i=["LEFT","MIDDLE","RIGHT"],o=["ALT","SHIFT","CTRL"];let r=null,s=0;const c=[],u=e.indexOf(":");if(!n)return t;if(e.includes("SETUP"))return"CLICK:SETUP";return e.slice(u+1).trim().split("-").map(t=>t.trim()).forEach(t=>{i.includes(t)?r=t:o.includes(t)?c.push(t):isNaN(t)||(s=t)}),`CLICK:${r}-${s}${c.length>0?"-":""}${c.sort().join("-")}`}function d(t,e){const{shiftKey:n,altKey:i,ctrlKey:o,key:r,button:s}=t,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][s]}-${e}`,u=[];return o&&u.push("CTRL"),n&&u.push("SHIFT"),i&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function p(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r}=t,{listenOptions:s,currentContext:{name:c},shortcuts:u}=e;return null==c||(Object.entries(u[c]).forEach(([c,u])=>{if(!r.test(c))return;if("CLICK:SETUP"===c){i=!0;const n=u.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:s});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++;const[l,a]=c.slice(6).split("-");"LEFT"===l&&e.maxLeftClicks<a&&(e.maxLeftClicks=a),"RIGHT"===l&&e.maxRightClicks<a&&(e.maxRightClicks=a)}),i||Object.assign(e.listenOptions,o)),n}function f(t,e={}){const n={_findTarget:u,_readClickEvent:d,regex:/CLICK\s*\:/i},i={active:!1,maxLeftClicks:1,maxRightClicks:1,defaultOptions:{mouseWait:320,clickTarget:["data-click","href"]},listenOptions:{mouseWait:320,clickTarget:["data-click","href"]},streamKeys:!(!e.streamKeys||"function"!=typeof e.streamKeys)&&e.streamKeys};return n.resetState=function(){},t({prefix:"click",_normalizeShortcutName:a,_registerShortcutEvents:p,_listenDOM:l,pluginState:i,deps:n})}function h(t,e){const{ev:n}=t;let i=null;function o(t,e,n,i){const{left:o,top:r,width:s,height:c}=n.target.getBoundingClientRect(),u=window.scrollX,l=window.scrollY;return{target:n.target,context:e.currentContext.name,note:e.currentContext.note,event:n,dependencies:t.extra,options:e.listenOptions,viewport:{X:u,Y:l,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:c},position:{x:o,y:r},pagePosition:{x:o+u,y:r+l},type:i}}function r(i){const{callbacks:r,typeFn:s}=e;i.target;const c=o(t,e,i,"form-in"),u=`${s(c)}/in`;null!=r[u]&&n.emit(u,c,r[u])}function s(i){const{callbacks:r,typeFn:s}=e,c=o(t,e,i,"form-out"),u=`${s(c)}/out`;null!=r[u]&&n.emit(u,c,r[u])}function c(r){const{callbacks:s,typeFn:c}=e,u=o(t,e,r,"form-instant"),l=c(u),a=e.wait[`${l}`],d=`${l}/instant`;if(null==s[d])return;if(0===a)return void n.emit(d,u,s[d]);clearTimeout(i),i=setTimeout(()=>n.emit(d,u,s[d]),a)}return{start:function(){e.active||(document.addEventListener("focusin",r),document.addEventListener("focusout",s),document.addEventListener("input",c),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("focusin",r),document.removeEventListener("focusout",s),document.removeEventListener("input",c),e.active=!1,i&&(clearTimeout(i),i=null))}}}function m(t){const e=t.toUpperCase(),n=/FORM\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;return`FORM:${e.slice(i+1).trim()}`}function g(t,e){const{regex:n,_defaults:i,ev:o}=t,{currentContext:{name:r,note:s},shortcuts:c,callbacks:u,ERROR_EVENT_NAME:l,defaultOptions:a}=e;let d=[],p=[],f=[],h=0;if(null==r)return!1;if(Object.entries(c[r]).forEach(([i,o])=>{if(n.test(i)){if(i.includes("SETUP")){const n=o.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},a);return void Object.assign(e.listenOptions,n)}"FORM:WATCH"===i&&(d=o),"FORM:DEFINE"===i&&(p=o),"FORM:ACTION"===i&&(f=o)}}),0===f.length)return h;const m=new Set;0===p.length&&(p=[i.define]),0===d.length&&(d=[i.watch]);const g=d.map(n=>n({dependencies:t.extra,context:r,note:s,options:e.listenOptions})).reduce((t,e)=>(t.push(e),t),[]);return e.watchList=document.querySelectorAll(g),e.watchList.forEach(n=>{const{left:i,top:o,width:c,height:u}=n.getBoundingClientRect(),l=window.scrollX,a=window.scrollY;return m.add(p[0]({target:n,context:r,note:s,dependencies:t.extra,options:e.listenOptions,viewport:{X:l,Y:a,width:window.innerWidth,height:window.innerHeight},sizes:{width:c,height:u},position:{x:i,y:o},pagePosition:{x:i+l,y:o+a}}))}),e.typeFn=p[0]?p[0]:i.define,f.forEach(n=>{if(!(n instanceof Function))return o.emit(l,"The 'form:action' should be a function."),!1;const i=n({dependencies:t.extra,options:e.listenOptions});if(!(i instanceof Array))return o.emit(l,"Warning: The 'form:action' function should RETURN an array."),!1;i.forEach(({fn:t,type:n,timing:i,wait:r=0})=>{if(m.has(n)&&t instanceof Function){const e=`${n}/${i}`,r=u.hasOwnProperty(e);r?u[e].push(t):u[e]=[t],r||o.on(e,(t,e)=>{e.forEach(e=>{e instanceof Function&&e(t)})})}"instant"===i&&(e.wait[`${n}`]=r)})}),h=Object.keys(e.callbacks).length,h}const v={watch:()=>"input, select, textarea, button, a",define:({target:t})=>"checkbox"===t.type||"radio"===t.type?"checkbox":"button"==t.type||"submit"==t.type?"button":"input"};function x(t,e={}){const n={_defaults:v,regex:/FORM\s*\:/i},i={callbacks:{},typeFn:"",watchList:[],wait:{},defaultOptions:{},listenOptions:{}};return n.resetState=function(){i.callbacks={},i.typeFn="",i.watchList=[],i.wait={}},t({prefix:"form",_normalizeShortcutName:m,_registerShortcutEvents:g,_listenDOM:h,pluginState:i,deps:n})}function E(t,e,n){const{listenOptions:{hoverTarget:i}}=e,o=n;if(o===document.body)return!1;if(o===document)return!1;return i.some(t=>o.hasAttribute(t))?o:E(t,e,o.parentNode)}function O(t,e){const{ev:n,_findTarget:i,resetState:o,extra:r}=t;function s(o){const s=o.clientX,c=o.clientY,{hovered:u,hoverRectangle:l,listenOptions:a,hoverTimer:d,leaveTimer:p,lastEvent:f,lastHoverTarget:h}=e,m=i(t,e,o.target);if(!function(t,e,n){return!!t&&e>=t.left&&e<=t.right&&n>=t.top&&n<=t.bottom}(l,s,c)&&m!==u){if(u&&!m){if(e.hovered=!1,e.hoverRectangle=null,d&&(clearTimeout(d),e.hoverTimer=null),"off"===f)return;return void(e.leaveTimer=setTimeout(()=>{n.emit("HOVER:OFF",g(u)),e.leaveTimer=null,e.lastEvent="off"},a.wait))}u&&(n.emit("HOVER:OFF",g(u)),e.leaveTimer=null,e.lastEvent="off"),clearTimeout(p),clearTimeout(d),e.hovered=m,e.hoverRectangle=m.getBoundingClientRect(),e.hoverTimer=setTimeout(()=>{n.emit("HOVER:ON",g(m)),e.hoverTimer=null,e.lastHoverTarget=m,e.lastEvent="on"},a.wait)}function g(t){const{left:n,top:i,width:s,height:c}=t.getBoundingClientRect(),u=window.scrollX,l=window.scrollY;return{target:t,context:e.currentContext.name,note:e.currentContext.note,event:o,dependencies:r,options:e.listenOptions,viewport:{X:u,Y:l,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:c},position:{x:n,y:i},pagePosition:{x:n+u,y:i+l},type:"hover"}}}return{start:function(){e.active||(document.addEventListener("mousemove",s),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("mousemove",s),o())}}}function y(t){const e=t.toUpperCase(),n=/HOVER\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;return`HOVER:${e.slice(i+1).trim()}`}function w(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r,_defaults:s,ev:c}=t,{currentContext:{name:u},shortcuts:l,ERROR_EVENT_NAME:a}=e;return null==u||(Object.entries(l[u]).forEach(([s,c])=>{if(r.test(s)){if("HOVER:SETUP"===s){i=!0;const n=c.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++}}),i||Object.assign(e.listenOptions,o)),n}function T(t,e={}){const n={_findTarget:E,regex:/HOVER\s*\:/i},i={active:!1,hovered:!1,hoverRectangle:null,hoverTimer:null,leaveTimer:null,lastEvent:"",lastHoverTarget:null,defaultOptions:{hoverTarget:["data-hover"],wait:320},listenOptions:{hoverTarget:["data-hover"],wait:320}};return n.resetState=function(){i.active=!1,i.hovered=!1,i.hoverRectangle=null,clearTimeout(i.hoverTimer),clearTimeout(i.leaveTimer),i.hoverTimer=null,i.leaveTimer=null,i.lastHoverTarget=null},t({prefix:"hover",_normalizeShortcutName:y,_registerShortcutEvents:w,_listenDOM:O,pluginState:i,deps:n})}function C(t,e){const{ev:n,resetState:i,extra:o}=t;let r=null,s=null;function c(t){t.clientX,t.clientY;const{lastPosition:i,lastDirection:c,listenOptions:u,currentContext:l}=e,{scrollWait:a,endScrollWait:d,minSpace:p}=u;if(!i)return;let f=null;const h=window.scrollX,m=window.scrollY,g=Math.abs(m-i.y),v=Math.abs(h-i.x);if(g<p&&v<p)return;const x=[];g>=p&&(m>i.y?x.push("down"):x.push("up")),v>=p&&(h>i.x?x.push("right"):x.push("left")),f=x[0]||null;const E=t=>({x:h,y:m,direction:t,context:l.name,note:l.note,dependencies:o,options:e.listenOptions,viewport:{X:h,Y:m,width:window.innerWidth,height:window.innerHeight},type:"scroll"});x.forEach(t=>{const e=`SCROLL:${t.toUpperCase()}`;n.emit(e,E(t))}),clearTimeout(r),clearTimeout(s);const O=x[x.length-1]||null;r=setTimeout(()=>{},a),s=setTimeout(()=>n.emit("SCROLL:END",E(O)),d),e.lastPosition={x:h,y:m},e.lastDirection=f}return{start:function(){e.active||(e.lastPosition={x:window.scrollX,y:window.scrollY},window.addEventListener("scroll",c),e.active=!0)},stop:function(){e.active&&(window.removeEventListener("scroll",c),i())}}}function S(t){const e=t.toUpperCase(),n=/SCROLL\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;return`SCROLL:${e.slice(i+1).trim()}`}function k(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r}=t,{currentContext:{name:s},shortcuts:c}=e;return null==s||(Object.entries(c[s]).forEach(([s,c])=>{if(r.test(s)){if("SCROLL:SETUP"===s){i=!0;const n=c.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++}}),i||Object.assign(e.listenOptions,o)),n}function R(t,e={}){const n={regex:/SCROLL\s*\:/i},i={active:!1,lastPosition:null,lastDirection:null,defaultOptions:{scrollWait:50,endScrollWait:400,minSpace:40},listenOptions:{scrollWait:50,endScrollWait:400,minSpace:40}};return n.resetState=function(){i.active=!1},t({prefix:"scroll",_normalizeShortcutName:S,_registerShortcutEvents:k,_listenDOM:C,pluginState:i,deps:n})}function L(n={}){const i={},o={},r=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"},c={ev:r,inAPI:i,API:o,extra:{}};return o.enablePlugin=(t,e={})=>{if("function"!=typeof t)return;const n=t(i._setupPlugin,e),o=n.getPrefix(),r=i._systemAction(o,"none");-1===r?(s.plugins.push(n),n.unmute()):(n.destroy(),s.plugins[r].unmute())},o.disablePlugin=t=>{const e=i._systemAction(t,"destroy");-1!==e&&s.plugins.splice(e,1)},o.mutePlugin=t=>i._systemAction(t,"mute"),o.unmutePlugin=t=>i._systemAction(t,"unmute"),o.listPlugins=()=>s.plugins.map(t=>t.getPrefix()),o.getContext=()=>s.currentContext.name,o.getNote=()=>s.currentContext.note,o.setNote=(t=null)=>{"string"!=typeof t&&null!=t||(s.currentContext.note=t)},o.pause=(t="*")=>{const e=i._readShortcutWithPlugins(t);r.stop(e)},o.resume=(t="*")=>{const e=i._readShortcutWithPlugins(t);r.start(e)},o.emit=(t,...e)=>r.emit(i._readShortcutWithPlugins(t),...e),o.listContexts=()=>Object.keys(s.shortcuts),o.setDependencies=t=>Object.assign(c.extra,t),o.getDependencies=()=>c.extra,o.reset=function(){r.reset(),o.changeContext(),s.plugins.forEach(t=>t.destroy()),o.listContexts().map(t=>o.unload(t)),c.extra={},s.exposeShortcut=null},Object.entries(e).forEach(([t,e])=>{t.startsWith("_")?i[t]=e(c,s):o[t]=e(c,s)}),o}export{f as pluginClick,x as pluginForm,T as pluginHover,c as pluginKey,R as pluginScroll,L as shortcuts};
|
package/dist/shortcuts.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).shortcuts={})}(this,function(e){"use strict";var t={_normalizeWithPlugins:function(e,t){return function(e){const n=t.shortcuts;Object.keys(n).forEach(t=>{Object.entries(n[t]).forEach(([o,r])=>{const i=e(o);i!==o&&(delete n[t][o],n[t][i]=r)})})}},_readShortcutWithPlugins:function(e,t){return function(n){const{inAPI:o}=e,r=n.split(":")[0].toLowerCase().trim(),i=o._systemAction(r,"none");let s=n;return-1!==i&&(s=t.plugins[i].shortcutName(n)),s}},_systemAction:function(e,t){return function(e,n,o=null){return t.plugins.findIndex(t=>t.getPrefix()===e&&(t[n]&&t[n](o),!0))}},changeContext:function(e,t){const{shortcuts:n,currentContext:o,ERROR_EVENT_NAME:r}=t,{ev:i}=e;return function(e=!1){const s=o.name;if(!e)return i.reset(),void(o.name=null);s!==e&&(n[e]?(n[s]&&i.reset(),o.name=e,t.plugins.forEach(t=>t.contextChange(e)),Object.entries(n[e]).forEach(([e,t])=>{t.forEach(t=>i.on(e,t))}),i.on("*",(...e)=>{t.exposeShortcut&&t.exposeShortcut(...e)})):i.emit(r,`Context '${e}' does not exist`))}},listShortcuts:function(e,t){const n=t.shortcuts;return function(e=null){if(null!=e){let t=n[e];return null==t?null:Object.entries(t).map(([e,t])=>e)}return Object.keys(n).map(e=>{let t={};return t.context=e,t.shortcuts=Object.entries(n[e]).map(([e,t])=>e),t})}},load:function(e,t){const{shortcuts:n,plugins:o}=t,{API:{changeContext:r,getContext:i}}=e;return function(e){const t=i(),s=o.map(e=>e.getPrefix().toUpperCase());let c=!1;Object.entries(e).forEach(([e,r])=>{e===t&&(c=!0),n[e]={},Object.entries(r).forEach(([t,r])=>{let i=t,c=t.toUpperCase().trim(),u=s.map((e,t)=>c.startsWith(e)?t:null).filter(e=>null!==e);if(u.length){let e=u[0];i=o[e].shortcutName(t)}r instanceof Function&&(r=[r]),n[e][i]=r})}),c&&(r(),r(t))}},unload:function(e,t){const{currentContext:n,shortcuts:o,ERROR_EVENT_NAME:r}=t,{ev:i}=e;return function(e){n.name!==e?o[e]?delete o[e]:i.emit(r,`Context '${e}' does not exist`):i.emit(r,`Context '${e}' can't be removed during is current active context. Change the context first`)}}};function n(e){const t=e.toUpperCase(),n=/KEY\s*\:/i.test(t),o=t.indexOf(":");if(!n)return e;return`KEY:${t.slice(o+1).split(",").map(e=>e.trim()).map(e=>e.split("+").map(e=>e.trim()).sort().join("+")).join(",")}`}function o(e,t){let{shiftKey:n,altKey:o,ctrlKey:r}=e,i=t(),s=e.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(e,t){let n=0;const{regex:o}=e,{listenOptions:r,currentContext:{name:i},shortcuts:s}=t;return null==i?0:(Object.entries(s[i]).forEach(([e,t])=>{if(!o.test(e))return;n++;let i=e.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(e,t,n){const{listenOptions:{clickTarget:o}}=t;let r=n;return r===document||r===document.body?null:r.dataset[o]||"A"===r.nodeName?r:s(e,t,r.parentNode)}function c(e){const t=e.toUpperCase(),n=/CLICK\s*\:/i.test(t),o=["LEFT","MIDDLE","RIGHT"],r=["ALT","SHIFT","CTRL"];let i=null,s=[],c=0,u=t.indexOf(":");return n?(t.slice(u+1).trim().split("-").map(e=>e.trim()).forEach(e=>{o.includes(e)?i=e:r.includes(e)?s.push(e):isNaN(e)||(c=e)}),`CLICK:${i}-${c}${s.length>0?"-":""}${s.sort().join("-")}`):e}function u(e,t){let{shiftKey:n,altKey:o,ctrlKey:r,key:i,button:s}=e,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][s]}-${t}`,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(e,t){let n=0;const{regex:o}=e,{listenOptions:r,currentContext:{name:i},shortcuts:s}=t;return null==i?0:(Object.entries(s[i]).forEach(([e,t])=>{if(!o.test(e))return;n++;let[,i]=e.slice(6).split("-");r.maxClicks<i&&(r.maxClicks=i)}),n)}function a(e){const t=e.toUpperCase(),n=/FORM\s*\:/i.test(t),o=t.indexOf(":");if(!n)return e;return`FORM:${t.slice(o+1).trim()}`}function f(e,t){const{regex:n,_defaults:o,ev:r}=e,{currentContext:{name:i},shortcuts:s,callbacks:c}=t;let u=[],l=[],a=[];if(null==i)return!1;if(Object.entries(s[i]).forEach(([e,t])=>{n.test(e)&&("FORM:WATCH"===e&&(u=t),"FORM:DEFINE"===e&&(l=t),"FORM:ACTION"===e&&(a=t))}),0===a.length)return!1;let f=new Set;0===l.length&&(l=[o.define]),0===u.length&&(u=[o.watch]);let m=u.map(e=>e()).reduce((e,t)=>(e.push(t),e),[]);return t.watchList=document.querySelectorAll(m),t.watchList.forEach(e=>f.add(l[0](e))),t.typeFn=l[0]?l[0]:o.define,a.forEach(e=>{if(!(e instanceof Function))return console.warn("Warning: The 'form:action' should be a function."),!1;if(!(e()instanceof Array))return console.warn("Warning: The 'form:action' function should RETURN an array."),!1;e().forEach(({fn:e,type:n,timing:o,wait:i=0})=>{if(f.has(n)&&e instanceof Function){let t=`${n}/${o}`;const i=c.hasOwnProperty(t);i?c[t].push(e):c[t]=[e],i||r.on(t,(e,t)=>{t.forEach(t=>{t instanceof Function&&t(e)})})}"instant"===o&&(t.wait[`${n}`]=i)})}),Object.keys(t.callbacks).length>0}const m={watch:()=>"input, select, textarea, button, a",define:e=>"checkbox"===e.type||"radio"===e.type?"checkbox":"button"==e.type||"submit"==e.type?"button":"input"};e.pluginClick=function(e,t,n){let{currentContext:o,shortcuts:r}=t,{inAPI:i}=e,a={ev:e.ev,_findTarget:s,_readClickEvent:u,mainDependencies:e,regex:/CLICK\s*\:/i},f={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 m=function(e,t){const{ev:n,_findTarget:o,_readClickEvent:r,mainDependencies:i}=e,{listenOptions:s,currentContext:c}=t,{mouseWait:u}=s;let l=null,a=null,f=null,m=null,p=0;function h(){const e=r(a,p),t={target:l,targetProps:l?l.getBoundingClientRect():null,x:a.clientX,y:a.clientY,context:c.name,note:c.note,event:a,dependencies:i.extra,type:"click"};n.emit(e,t),f=null,m=null,l=null,a=null,p=0}function d(n){let r=s.maxClicks;return clearTimeout(f),m?(clearTimeout(m),void(m=setTimeout(()=>m=null,u))):(l=o(e,t,n.target),l&&l.dataset.hasOwnProperty("quickClick")&&(r=1),l&&"A"===l.tagName&&(r=1),a=n,p++,p>=r?(h(),void(r>1&&(m=setTimeout(()=>m=null,u)))):void(f=setTimeout(h,u)))}function g(n){let r=s.maxClicks;return clearTimeout(f),m?(clearTimeout(m),void(m=setTimeout(()=>m=null,u))):(l=o(e,t,n.target),l&&l.dataset.hasOwnProperty("quickClick")&&(r=1),l&&"A"===l.tagName&&(r=1),a=n,p++,p>=r?(h(),void(r>1&&(m=setTimeout(()=>m=null,u)))):void(f=setTimeout(h,u)))}return{start:function(){t.active||(window.addEventListener("contextmenu",g),document.addEventListener("click",d),t.active=!0)},stop:function(){t.active&&(window.removeEventListener("contextmenu",g),document.removeEventListener("click",d),t.active=!1,f&&(clearTimeout(f),f=null),m&&(clearTimeout(m),m=null),p=0)}}}(a,f),p=l(a,f);p>0&&m.start();let h={getPrefix:()=>"click",shortcutName:e=>c(e),contextChange:()=>{p=l(a,f),p<1&&m.stop(),p>0&&m.start()},mute:()=>{m.stop()},unmute:()=>m.start(),destroy:()=>m.stop()};return Object.freeze(h),h},e.pluginForm=function(e,t,n){let{currentContext:o,shortcuts:r}=t,{inAPI:i}=e,s={ev:e.ev,mainDependencies:e,regex:/FORM\s*\:/i,_defaults:m},c={currentContext:o,shortcuts:r,callbacks:{},typeFn:"",watchList:[],wait:{}};i._normalizeWithPlugins(a);let u=function(e,t){const{ev:n}=e;let o=null;function r(e,t,n,o){return{target:n.target,context:t.currentContext.name,note:t.currentContext.note,event:n,dependencies:e.mainDependencies.extra,type:o}}function i(o){const{callbacks:i,typeFn:s}=t,c=s(o.target),u=r(e,t,o,c),l=`${c}/in`;null!=i[l]&&n.emit(l,u,i[l])}function s(o){const{callbacks:i,typeFn:s}=t,c=r(e,t,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}=t,u=r(e,t,i,"form-instant"),l=c(i.target),a=t.wait[`${l}`],f=`${l}/instant`;null!=s[f]&&(0!==a?(clearTimeout(o),o=setTimeout(()=>n.emit(f,u,s[f]),a)):n.emit(f,u,s[f]))}return{start:function(){t.active||(document.addEventListener("focusin",i),document.addEventListener("focusout",s),document.addEventListener("input",c),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("focusin",i),document.removeEventListener("focusout",s),document.removeEventListener("input",c),t.active=!1)}}}(s,c);if(o.name){f(s,c)&&u.start()}let l={getPrefix:()=>"form",shortcutName:e=>a(e),contextChange:()=>{c.callbacks={},c.typeFn="",c.watchList=[],c.wait={},f(s,c)?u.start():u.stop()},mute:()=>u.stop(),unmute:()=>u.start(),destroy:()=>{u.stop()}};return Object.freeze(l),l},e.pluginKey=function(e,t,s={}){let{currentContext:c,shortcuts:u,exposeShortcut:l}=t,{inAPI:a}=e,f={ev:e.ev,_specialChars:i,_readKeyEvent:o,mainDependencies:e,regex:/KEY\s*\:/i},m={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};a._normalizeWithPlugins(n);let p=function(e,t){const{ev:n,_specialChars:o,_readKeyEvent:r,mainDependencies:i}=e,{currentContext:s,streamKeys:c,listenOptions:u}=t,{keyWait:l}=u;let a=[],f=null,m=!0,p=!1;const h=()=>m=!1,d=()=>m=!0,g=()=>p=!0,y=()=>!1===m;function x(){let e=a.map(e=>[e.join("+")]);const t={wait:h,end:d,ignore:g,isWaiting:y,note:s.note,context:s.name,dependencies:i.extra,type:"key"};if(!m){let o=e.at(-1);n.emit(o,t),p&&(e=e.slice(0,-1),p=!1)}if(m){const o=`KEY:${e.join(",")}`;n.emit(o,t),a=[],f=null}}function E(t){if(clearTimeout(f),o().hasOwnProperty(t.code))return a.push(r(t,o)),c&&c({key:t.key,context:s.name,note:s.note,dependencies:e.extra}),u.keyIgnore?(clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l))):m&&a.length===u.maxSequence?(x(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l))):void(m?f=setTimeout(x,l):x())}function v(t){if(!o().hasOwnProperty(t.code)){if(clearTimeout(f),c&&c({key:t.key,context:s.name,note:s.note,dependencies:e.extra}),u.keyIgnore)return clearTimeout(u.keyIgnore),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l));if(a.push(r(t,o)),m&&a.length===u.maxSequence)return x(),void(u.keyIgnore=setTimeout(()=>u.keyIgnore=null,l));m?f=setTimeout(x,l):x()}}return{start:function(){t.active||(document.addEventListener("keydown",E),document.addEventListener("keypress",v),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("keydown",E),document.removeEventListener("keypress",v),t.active=!1,f&&(clearTimeout(f),f=null),u.keyIgnore&&(clearTimeout(u.keyIgnore),u.keyIgnore=null),a=[],m=!0,p=!1)}}}(f,m),h=r(f,m);h>0&&p.start();let d={getPrefix:()=>"key",shortcutName:e=>n(e),contextChange:e=>{h=r(f,m),h<1&&p.stop(),h>0&&p.start()},mute:()=>p.stop(),unmute:()=>p.start(),destroy:()=>p.stop()};return Object.freeze(d),d},e.shortcuts=function(e={}){let n={},o={};const r=function(){let e={"*":[]},t={},n=new Set,o=!1,r="";return{on:function(t,n){e[t]||(e[t]=[]),e[t].push(n)},once:function(e,n){"*"!==e&&(t[e]||(t[e]=[]),t[e].push(n))},off:function(n,o){if(o)return e[n]&&(e[n]=e[n].filter(e=>e!==o)),t[n]&&(t[n]=t[n].filter(e=>e!==o)),e[n]&&0===e[n].length&&delete e[n],void(t[n]&&0===t[n].length&&delete e[n]);t[n]&&delete t[n],e[n]&&delete e[n]},reset:function(){e={"*":[]},t={},n=new Set},emit:function(){const[i,...s]=arguments;function c(t){let o=!1;"*"!==t&&(n.has(t)||(e[t].every(e=>{const t=e(...s);return"string"!=typeof t||"STOP"!==t.toUpperCase()||(o=!0,!1)}),o||e["*"].forEach(e=>e(i,...s))))}if(o&&(console.log(`${r} Event "${i}" was triggered.`),s.length>0&&(console.log("Arguments:"),console.log(...s),console.log("^----"))),"*"!==i){if(t[i]){if(n.has(i))return;t[i].forEach(e=>e(...s)),delete t[i]}e[i]&&c(i)}else Object.keys(e).forEach(e=>c(e))},stop:function(o){if("*"===o){const o=Object.keys(e),r=Object.keys(t);return void(n=new Set([...r,...o]))}n.add(o)},start:function(e){"*"!==e?n.delete(e):n.clear()},debug:function(e,t){o=!!e,t&&"string"==typeof t&&(r=t)}}}(),i={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!e.onShortcut||"function"!=typeof e.onShortcut)&&e.onShortcut,ERROR_EVENT_NAME:e.errorEventName?e.errorEventName:"@shortcuts-error"};let s={ev:r,inAPI:n,API:o,extra:{}};return o.enablePlugin=(e,t={})=>{if("function"!=typeof e)return;let o=e(s,i,t);const r=o.getPrefix();-1===n._systemAction(r,"none")?i.plugins.push(o):o.destroy()},o.disablePlugin=e=>{const t=n._systemAction(e,"destroy");-1!==t&&(i.plugins=i.plugins.filter((e,n)=>n!==t))},o.mutePlugin=e=>n._systemAction(e,"mute"),o.unmutePlugin=e=>n._systemAction(e,"unmute"),o.listPlugins=()=>i.plugins.map(e=>e.getPrefix()),o.getContext=()=>i.currentContext.name,o.getNote=()=>i.currentContext.note,o.setNote=(e=null)=>{"string"!=typeof e&&null!=e||(i.currentContext.note=e)},o.pause=(e="*")=>{let t=n._readShortcutWithPlugins(e);r.stop(t)},o.resume=(e="*")=>{const t=n._readShortcutWithPlugins(e);r.start(t)},o.emit=(e,...t)=>r.emit(n._readShortcutWithPlugins(e),...t),o.listContexts=()=>Object.keys(i.shortcuts),o.setDependencies=e=>s.extra={...s.extra,...e},o.getDependencies=()=>s.extra,o.reset=function(){r.reset(),o.changeContext(),i.plugins.forEach(e=>e.destroy()),o.listContexts().map(e=>o.unload(e)),s.extra={},i.exposeShortcut=null},Object.entries(t).forEach(([e,t])=>{e.startsWith("_")?n[e]=t(s,i):o[e]=t(s,i)}),o}});
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).shortcuts={})}(this,function(t){"use strict";var e={_normalizeWithPlugins:function(t,e){return function(t){const n=e.shortcuts;Object.keys(n).forEach(e=>{Object.entries(n[e]).forEach(([i,o])=>{const r=t(i);r!==i&&(delete n[e][i],n[e][r]=o)})})}},_readShortcutWithPlugins:function(t,e){return function(n){const{inAPI:i}=t,o=n.split(":")[0].toLowerCase().trim(),r=i._systemAction(o,"none");let s=n;return-1!==r&&(s=e.plugins[r].shortcutName(n)),s}},_setupPlugin:function(t,e){const{inAPI:n}=t,{currentContext:i,shortcuts:o,exposeShortcut:r,ERROR_EVENT_NAME:s}=e;return function(e){const{prefix:c,_normalizeShortcutName:u,_registerShortcutEvents:l,_listenDOM:a,pluginState:f,deps:d}=e,{resetState:p}=d;f.currentContext=i,f.shortcuts=o,f.exposeShortcut=r,f.ERROR_EVENT_NAME=s;const h={ev:t.ev,extra:t.extra,...d};n._normalizeWithPlugins(u);let m=l(h,f);const g=a(h,f);m>0&&g.start();const v={getPrefix:()=>c,shortcutName:t=>u(t),contextChange:()=>{p(),m=l(h,f),m<1&&g.stop(),m>0&&g.start()},mute:()=>g.stop(),unmute:()=>g.start(),destroy:()=>{g.stop(),p()}};return Object.freeze(v),v}},_systemAction:function(t,e){return function(t,n,i=null){return e.plugins.findIndex(e=>e.getPrefix()===t&&(e[n]&&e[n](i),!0))}},changeContext:function(t,e){const{shortcuts:n,currentContext:i,ERROR_EVENT_NAME:o}=e,{ev:r}=t;return function(t=!1){const s=i.name;if(!t)return r.reset(),void(i.name=null);s!==t&&(n[t]?(n[s]&&r.reset(),i.name=t,e.plugins.forEach(e=>e.contextChange(t)),Object.entries(n[t]).forEach(([t,e])=>{t.includes(":SETUP")||e.forEach(e=>r.on(t,e))}),r.on("*",(...t)=>{e.exposeShortcut&&e.exposeShortcut(...t)})):r.emit(o,`Context '${t}' does not exist`))}},listShortcuts:function(t,e){const n=e.shortcuts;return function(t=null){if(null!=t){const e=n[t];return null==e?null:Object.entries(e).map(([t,e])=>t)}return Object.keys(n).map(t=>{const e={};return e.context=t,e.shortcuts=Object.entries(n[t]).map(([t,e])=>t),e})}},load:function(t,e){const{shortcuts:n,plugins:i}=e,{API:{changeContext:o,getContext:r}}=t;return function(t){const e=r(),s=i.map(t=>t.getPrefix().toUpperCase());let c=!1;Object.entries(t).forEach(([t,o])=>{t===e&&(c=!0),n[t]={},Object.entries(o).forEach(([e,o])=>{let r=e;const c=e.toUpperCase().trim(),u=s.map((t,e)=>c.startsWith(t)?e:null).filter(t=>null!==t);if(u.length){const t=u[0];r=i[t].shortcutName(e)}o instanceof Function&&(o=[o]),n[t][r]=o})}),c&&(o(),o(e))}},unload:function(t,e){const{currentContext:n,shortcuts:i,ERROR_EVENT_NAME:o}=e,{ev:r}=t;return function(t){n.name!==t?i[t]?delete i[t]:r.emit(o,`Context '${t}' does not exist`):r.emit(o,`Context '${t}' can't be removed during is current active context. Change the context first`)}}};function n(t,e){const{ev:n,_specialChars:i,_readKeyEvent:o,extra:r,resetState:s}=t,{currentContext:c,streamKeys:u,listenOptions:l}=e;let a=[],f=null,d=!0,p=!1;const h=()=>d=!1,m=()=>d=!0,g=()=>p=!0,v=()=>!1===d;function x(){const t=a.map(t=>[t.join("+")]),i={wait:h,end:m,ignore:g,isWaiting:v,note:c.note,context:c.name,dependencies:r,options:e.listenOptions,viewport:{X:window.scrollX,Y:window.scrollY,width:window.innerWidth,height:window.innerHeight},type:"key"};if(!d){const e=`KEY:${t.at(-1).join("+")}`;n.emit(e,i),p&&(a=a.slice(0,-1),p=!1)}if(d){const o=`KEY:${t.join(",")}`;n.emit(o,i),p&&(a=a.slice(0,-1),p=!1),a=[],clearTimeout(e.keyIgnore),e.keyIgnore=null,clearTimeout(f),f=null}}function E(n){clearTimeout(f);if(i().hasOwnProperty(n.code))return a.push(o(n,i)),u&&u({key:n.key,context:c.name,note:c.note,dependencies:t.extra}),e.keyIgnore?(clearTimeout(e.keyIgnore),e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait),void a.pop()):d&&a.length===e.maxSequence?(x(),void(e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait))):void(d?f=setTimeout(x,l.keyWait):x())}function O(n){if(!i().hasOwnProperty(n.code)){if(clearTimeout(f),u&&u({key:n.key,context:c.name,note:c.note,dependencies:t.extra}),e.keyIgnore)return clearTimeout(e.keyIgnore),void(e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait));if(a.push(o(n,i)),d&&a.length===e.maxSequence)return x(),void(e.keyIgnore=setTimeout(()=>e.keyIgnore=null,l.keyWait));d?f=setTimeout(x,l.keyWait):x()}}return{start:function(){e.active||(document.addEventListener("keydown",E),document.addEventListener("keypress",O),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("keydown",E),document.removeEventListener("keypress",O),e.active=!1,f&&(clearTimeout(f),f=null),e.keyIgnore&&(clearTimeout(e.keyIgnore),e.keyIgnore=null),a=[],d=!0,p=!1)}}}function i(t){const e=t.toUpperCase(),n=/KEY\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;if(e.includes("SETUP"))return"KEY:SETUP";return`KEY:${e.slice(i+1).split(",").map(t=>t.trim()).map(t=>t.split("+").map(t=>t.trim()).sort().join("+")).join(",")}`}function o(t,e){const{shiftKey:n,altKey:i,ctrlKey:o}=t,r=e(),s=t.code.replace("Key","").replace("Digit",""),c=[];return o&&c.push("CTRL"),n&&c.push("SHIFT"),i&&c.push("ALT"),r.hasOwnProperty(s)?c.push(r[s].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(s)||c.push(s.toUpperCase()),c.sort()}function r(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r}=t,{currentContext:{name:s},shortcuts:c}=e;return null==s?0:(Object.entries(c[s]).forEach(([s,c])=>{if(!r.test(s))return;if("KEY:SETUP"===s){i=!0;const n=c.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++;const u=s.slice(4).split(",").length;e.maxSequence<u&&(e.maxSequence=u)}),i||Object.assign(e.listenOptions,o),n)}function s(){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 c(t,e,n){const{listenOptions:{clickTarget:i}}=e,o=n;if(o===document.body)return null;return i.some(t=>o.hasAttribute(t))?o:c(t,e,o.parentNode)}function u(t,e){const{ev:n,_findTarget:i,_readClickEvent:o,extra:r}=t,{listenOptions:s,currentContext:c}=e;let u=null,l=null,a=null,f=null,d=0;function p(){if(!u)return;const{left:t,top:i,width:s,height:p}=u.getBoundingClientRect(),h=window.scrollX,m=window.scrollY,g=o(l,d),v={target:u,x:l.clientX,y:l.clientY,context:c.name,note:c.note,options:e.listenOptions,event:l,dependencies:r,viewport:{X:h,Y:m,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:p},position:{x:t,y:i},pagePosition:{x:t+h,y:i+m},type:"click"};n.emit(g,v),a=null,f=null,u=null,l=null,d=0}function h(n){let o=e.maxLeftClicks;if(clearTimeout(a),f)return clearTimeout(f),void(f=setTimeout(()=>f=null,s.mouseWait));if(u=i(t,e,n.target),null!=u){if(u&&u.dataset.hasOwnProperty("quickClick")&&(o=1),u&&"A"===u.tagName&&(o=1),l=n,d++,d>=o)return p(),void(o>1&&(f=setTimeout(()=>f=null,s.mouseWait)));a=setTimeout(p,s.mouseWait)}}function m(n){let o=e.maxRightClicks;if(clearTimeout(a),f)return clearTimeout(f),void(f=setTimeout(()=>f=null,s.mouseWait));if(u=i(t,e,n.target),null!=u){if(u&&u.dataset.hasOwnProperty("quickClick")&&(o=1),u&&"A"===u.tagName&&(o=1),l=n,d++,d>=o)return p(),void(o>1&&(f=setTimeout(()=>f=null,s.mouseWait)));a=setTimeout(p,s.mouseWait)}}return{start:function(){e.active||(window.addEventListener("contextmenu",m),document.addEventListener("click",h),e.active=!0)},stop:function(){e.active&&(window.removeEventListener("contextmenu",m),document.removeEventListener("click",h),e.active=!1,f&&(clearTimeout(f),f=null),u=null,l=null,d=0)}}}function l(t){const e=t.toUpperCase(),n=/CLICK\s*\:/i.test(e),i=["LEFT","MIDDLE","RIGHT"],o=["ALT","SHIFT","CTRL"];let r=null,s=0;const c=[],u=e.indexOf(":");if(!n)return t;if(e.includes("SETUP"))return"CLICK:SETUP";return e.slice(u+1).trim().split("-").map(t=>t.trim()).forEach(t=>{i.includes(t)?r=t:o.includes(t)?c.push(t):isNaN(t)||(s=t)}),`CLICK:${r}-${s}${c.length>0?"-":""}${c.sort().join("-")}`}function a(t,e){const{shiftKey:n,altKey:i,ctrlKey:o,key:r,button:s}=t,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][s]}-${e}`,u=[];return o&&u.push("CTRL"),n&&u.push("SHIFT"),i&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function f(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r}=t,{listenOptions:s,currentContext:{name:c},shortcuts:u}=e;return null==c||(Object.entries(u[c]).forEach(([c,u])=>{if(!r.test(c))return;if("CLICK:SETUP"===c){i=!0;const n=u.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:s});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++;const[l,a]=c.slice(6).split("-");"LEFT"===l&&e.maxLeftClicks<a&&(e.maxLeftClicks=a),"RIGHT"===l&&e.maxRightClicks<a&&(e.maxRightClicks=a)}),i||Object.assign(e.listenOptions,o)),n}function d(t,e){const{ev:n}=t;let i=null;function o(t,e,n,i){const{left:o,top:r,width:s,height:c}=n.target.getBoundingClientRect(),u=window.scrollX,l=window.scrollY;return{target:n.target,context:e.currentContext.name,note:e.currentContext.note,event:n,dependencies:t.extra,options:e.listenOptions,viewport:{X:u,Y:l,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:c},position:{x:o,y:r},pagePosition:{x:o+u,y:r+l},type:i}}function r(i){const{callbacks:r,typeFn:s}=e;i.target;const c=o(t,e,i,"form-in"),u=`${s(c)}/in`;null!=r[u]&&n.emit(u,c,r[u])}function s(i){const{callbacks:r,typeFn:s}=e,c=o(t,e,i,"form-out"),u=`${s(c)}/out`;null!=r[u]&&n.emit(u,c,r[u])}function c(r){const{callbacks:s,typeFn:c}=e,u=o(t,e,r,"form-instant"),l=c(u),a=e.wait[`${l}`],f=`${l}/instant`;if(null==s[f])return;if(0===a)return void n.emit(f,u,s[f]);clearTimeout(i),i=setTimeout(()=>n.emit(f,u,s[f]),a)}return{start:function(){e.active||(document.addEventListener("focusin",r),document.addEventListener("focusout",s),document.addEventListener("input",c),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("focusin",r),document.removeEventListener("focusout",s),document.removeEventListener("input",c),e.active=!1,i&&(clearTimeout(i),i=null))}}}function p(t){const e=t.toUpperCase(),n=/FORM\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;return`FORM:${e.slice(i+1).trim()}`}function h(t,e){const{regex:n,_defaults:i,ev:o}=t,{currentContext:{name:r,note:s},shortcuts:c,callbacks:u,ERROR_EVENT_NAME:l,defaultOptions:a}=e;let f=[],d=[],p=[],h=0;if(null==r)return!1;if(Object.entries(c[r]).forEach(([i,o])=>{if(n.test(i)){if(i.includes("SETUP")){const n=o.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},a);return void Object.assign(e.listenOptions,n)}"FORM:WATCH"===i&&(f=o),"FORM:DEFINE"===i&&(d=o),"FORM:ACTION"===i&&(p=o)}}),0===p.length)return h;const m=new Set;0===d.length&&(d=[i.define]),0===f.length&&(f=[i.watch]);const g=f.map(n=>n({dependencies:t.extra,context:r,note:s,options:e.listenOptions})).reduce((t,e)=>(t.push(e),t),[]);return e.watchList=document.querySelectorAll(g),e.watchList.forEach(n=>{const{left:i,top:o,width:c,height:u}=n.getBoundingClientRect(),l=window.scrollX,a=window.scrollY;return m.add(d[0]({target:n,context:r,note:s,dependencies:t.extra,options:e.listenOptions,viewport:{X:l,Y:a,width:window.innerWidth,height:window.innerHeight},sizes:{width:c,height:u},position:{x:i,y:o},pagePosition:{x:i+l,y:o+a}}))}),e.typeFn=d[0]?d[0]:i.define,p.forEach(n=>{if(!(n instanceof Function))return o.emit(l,"The 'form:action' should be a function."),!1;const i=n({dependencies:t.extra,options:e.listenOptions});if(!(i instanceof Array))return o.emit(l,"Warning: The 'form:action' function should RETURN an array."),!1;i.forEach(({fn:t,type:n,timing:i,wait:r=0})=>{if(m.has(n)&&t instanceof Function){const e=`${n}/${i}`,r=u.hasOwnProperty(e);r?u[e].push(t):u[e]=[t],r||o.on(e,(t,e)=>{e.forEach(e=>{e instanceof Function&&e(t)})})}"instant"===i&&(e.wait[`${n}`]=r)})}),h=Object.keys(e.callbacks).length,h}const m={watch:()=>"input, select, textarea, button, a",define:({target:t})=>"checkbox"===t.type||"radio"===t.type?"checkbox":"button"==t.type||"submit"==t.type?"button":"input"};function g(t,e,n){const{listenOptions:{hoverTarget:i}}=e,o=n;if(o===document.body)return!1;if(o===document)return!1;return i.some(t=>o.hasAttribute(t))?o:g(t,e,o.parentNode)}function v(t,e){const{ev:n,_findTarget:i,resetState:o,extra:r}=t;function s(o){const s=o.clientX,c=o.clientY,{hovered:u,hoverRectangle:l,listenOptions:a,hoverTimer:f,leaveTimer:d,lastEvent:p,lastHoverTarget:h}=e,m=i(t,e,o.target);if(!function(t,e,n){return!!t&&e>=t.left&&e<=t.right&&n>=t.top&&n<=t.bottom}(l,s,c)&&m!==u){if(u&&!m){if(e.hovered=!1,e.hoverRectangle=null,f&&(clearTimeout(f),e.hoverTimer=null),"off"===p)return;return void(e.leaveTimer=setTimeout(()=>{n.emit("HOVER:OFF",g(u)),e.leaveTimer=null,e.lastEvent="off"},a.wait))}u&&(n.emit("HOVER:OFF",g(u)),e.leaveTimer=null,e.lastEvent="off"),clearTimeout(d),clearTimeout(f),e.hovered=m,e.hoverRectangle=m.getBoundingClientRect(),e.hoverTimer=setTimeout(()=>{n.emit("HOVER:ON",g(m)),e.hoverTimer=null,e.lastHoverTarget=m,e.lastEvent="on"},a.wait)}function g(t){const{left:n,top:i,width:s,height:c}=t.getBoundingClientRect(),u=window.scrollX,l=window.scrollY;return{target:t,context:e.currentContext.name,note:e.currentContext.note,event:o,dependencies:r,options:e.listenOptions,viewport:{X:u,Y:l,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:c},position:{x:n,y:i},pagePosition:{x:n+u,y:i+l},type:"hover"}}}return{start:function(){e.active||(document.addEventListener("mousemove",s),e.active=!0)},stop:function(){e.active&&(document.removeEventListener("mousemove",s),o())}}}function x(t){const e=t.toUpperCase(),n=/HOVER\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;return`HOVER:${e.slice(i+1).trim()}`}function E(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r,_defaults:s,ev:c}=t,{currentContext:{name:u},shortcuts:l,ERROR_EVENT_NAME:a}=e;return null==u||(Object.entries(l[u]).forEach(([s,c])=>{if(r.test(s)){if("HOVER:SETUP"===s){i=!0;const n=c.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++}}),i||Object.assign(e.listenOptions,o)),n}function O(t,e){const{ev:n,resetState:i,extra:o}=t;let r=null,s=null;function c(t){t.clientX,t.clientY;const{lastPosition:i,lastDirection:c,listenOptions:u,currentContext:l}=e,{scrollWait:a,endScrollWait:f,minSpace:d}=u;if(!i)return;let p=null;const h=window.scrollX,m=window.scrollY,g=Math.abs(m-i.y),v=Math.abs(h-i.x);if(g<d&&v<d)return;const x=[];g>=d&&(m>i.y?x.push("down"):x.push("up")),v>=d&&(h>i.x?x.push("right"):x.push("left")),p=x[0]||null;const E=t=>({x:h,y:m,direction:t,context:l.name,note:l.note,dependencies:o,options:e.listenOptions,viewport:{X:h,Y:m,width:window.innerWidth,height:window.innerHeight},type:"scroll"});x.forEach(t=>{const e=`SCROLL:${t.toUpperCase()}`;n.emit(e,E(t))}),clearTimeout(r),clearTimeout(s);const O=x[x.length-1]||null;r=setTimeout(()=>{},a),s=setTimeout(()=>n.emit("SCROLL:END",E(O)),f),e.lastPosition={x:h,y:m},e.lastDirection=p}return{start:function(){e.active||(e.lastPosition={x:window.scrollX,y:window.scrollY},window.addEventListener("scroll",c),e.active=!0)},stop:function(){e.active&&(window.removeEventListener("scroll",c),i())}}}function y(t){const e=t.toUpperCase(),n=/SCROLL\s*\:/i.test(e),i=e.indexOf(":");if(!n)return t;return`SCROLL:${e.slice(i+1).trim()}`}function w(t,e){let n=0,i=!1;const o=e.defaultOptions,{regex:r}=t,{currentContext:{name:s},shortcuts:c}=e;return null==s||(Object.entries(c[s]).forEach(([s,c])=>{if(r.test(s)){if("SCROLL:SETUP"===s){i=!0;const n=c.reduce((n,i)=>{const o=i({dependencies:t.extra,defaults:structuredClone(e.defaultOptions),options:e.listenOptions});return Object.assign(n,o)},o);return void Object.assign(e.listenOptions,n)}n++}}),i||Object.assign(e.listenOptions,o)),n}t.pluginClick=function(t,e={}){const n={_findTarget:c,_readClickEvent:a,regex:/CLICK\s*\:/i},i={active:!1,maxLeftClicks:1,maxRightClicks:1,defaultOptions:{mouseWait:320,clickTarget:["data-click","href"]},listenOptions:{mouseWait:320,clickTarget:["data-click","href"]},streamKeys:!(!e.streamKeys||"function"!=typeof e.streamKeys)&&e.streamKeys};return n.resetState=function(){},t({prefix:"click",_normalizeShortcutName:l,_registerShortcutEvents:f,_listenDOM:u,pluginState:i,deps:n})},t.pluginForm=function(t,e={}){const n={_defaults:m,regex:/FORM\s*\:/i},i={callbacks:{},typeFn:"",watchList:[],wait:{},defaultOptions:{},listenOptions:{}};return n.resetState=function(){i.callbacks={},i.typeFn="",i.watchList=[],i.wait={}},t({prefix:"form",_normalizeShortcutName:p,_registerShortcutEvents:h,_listenDOM:d,pluginState:i,deps:n})},t.pluginHover=function(t,e={}){const n={_findTarget:g,regex:/HOVER\s*\:/i},i={active:!1,hovered:!1,hoverRectangle:null,hoverTimer:null,leaveTimer:null,lastEvent:"",lastHoverTarget:null,defaultOptions:{hoverTarget:["data-hover"],wait:320},listenOptions:{hoverTarget:["data-hover"],wait:320}};return n.resetState=function(){i.active=!1,i.hovered=!1,i.hoverRectangle=null,clearTimeout(i.hoverTimer),clearTimeout(i.leaveTimer),i.hoverTimer=null,i.leaveTimer=null,i.lastHoverTarget=null},t({prefix:"hover",_normalizeShortcutName:x,_registerShortcutEvents:E,_listenDOM:v,pluginState:i,deps:n})},t.pluginKey=function(t,e={}){const c={_specialChars:s,_readKeyEvent:o,regex:/KEY\s*\:/i},u={active:!1,maxSequence:1,keyIgnore:null,defaultOptions:{keyWait:480},listenOptions:{keyWait:480},streamKeys:!(!e.streamKeys||"function"!=typeof e.streamKeys)&&e.streamKeys};return c.resetState=function(){u.active=!1,u.keyIgnore=null,u.maxSequence=1},t({prefix:"key",_normalizeShortcutName:i,_registerShortcutEvents:r,_listenDOM:n,pluginState:u,deps:c})},t.pluginScroll=function(t,e={}){const n={regex:/SCROLL\s*\:/i},i={active:!1,lastPosition:null,lastDirection:null,defaultOptions:{scrollWait:50,endScrollWait:400,minSpace:40},listenOptions:{scrollWait:50,endScrollWait:400,minSpace:40}};return n.resetState=function(){i.active=!1},t({prefix:"scroll",_normalizeShortcutName:y,_registerShortcutEvents:w,_listenDOM:O,pluginState:i,deps:n})},t.shortcuts=function(t={}){const n={},i={},o=function(){let t={"*":[]},e={},n=new Set,i=!1,o="";return{on:function(e,n){t[e]||(t[e]=[]),t[e].push(n)},once:function(t,n){"*"!==t&&(e[t]||(e[t]=[]),e[t].push(n))},off:function(n,i){if(i)return t[n]&&(t[n]=t[n].filter(t=>t!==i)),e[n]&&(e[n]=e[n].filter(t=>t!==i)),t[n]&&0===t[n].length&&delete t[n],void(e[n]&&0===e[n].length&&delete t[n]);e[n]&&delete e[n],t[n]&&delete t[n]},reset:function(){t={"*":[]},e={},n=new Set},emit:function(){const[r,...s]=arguments;function c(e){let i=!1;"*"!==e&&(n.has(e)||(t[e].every(t=>{const e=t(...s);return"string"!=typeof e||"STOP"!==e.toUpperCase()||(i=!0,!1)}),i||t["*"].forEach(t=>t(r,...s))))}if(i&&(console.log(`${o} Event "${r}" was triggered.`),s.length>0&&(console.log("Arguments:"),console.log(...s),console.log("^----"))),"*"!==r){if(e[r]){if(n.has(r))return;e[r].forEach(t=>t(...s)),delete e[r]}t[r]&&c(r)}else Object.keys(t).forEach(t=>c(t))},stop:function(i){if("*"===i){const i=Object.keys(t),o=Object.keys(e);return void(n=new Set([...o,...i]))}n.add(i)},start:function(t){"*"!==t?n.delete(t):n.clear()},debug:function(t,e){i=!!t,e&&"string"==typeof e&&(o=e)}}}(),r={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!t.onShortcut||"function"!=typeof t.onShortcut)&&t.onShortcut,ERROR_EVENT_NAME:t.errorEventName?t.errorEventName:"@shortcuts-error"},s={ev:o,inAPI:n,API:i,extra:{}};return i.enablePlugin=(t,e={})=>{if("function"!=typeof t)return;const i=t(n._setupPlugin,e),o=i.getPrefix(),s=n._systemAction(o,"none");-1===s?(r.plugins.push(i),i.unmute()):(i.destroy(),r.plugins[s].unmute())},i.disablePlugin=t=>{const e=n._systemAction(t,"destroy");-1!==e&&r.plugins.splice(e,1)},i.mutePlugin=t=>n._systemAction(t,"mute"),i.unmutePlugin=t=>n._systemAction(t,"unmute"),i.listPlugins=()=>r.plugins.map(t=>t.getPrefix()),i.getContext=()=>r.currentContext.name,i.getNote=()=>r.currentContext.note,i.setNote=(t=null)=>{"string"!=typeof t&&null!=t||(r.currentContext.note=t)},i.pause=(t="*")=>{const e=n._readShortcutWithPlugins(t);o.stop(e)},i.resume=(t="*")=>{const e=n._readShortcutWithPlugins(t);o.start(e)},i.emit=(t,...e)=>o.emit(n._readShortcutWithPlugins(t),...e),i.listContexts=()=>Object.keys(r.shortcuts),i.setDependencies=t=>Object.assign(s.extra,t),i.getDependencies=()=>s.extra,i.reset=function(){o.reset(),i.changeContext(),r.plugins.forEach(t=>t.destroy()),i.listContexts().map(t=>i.unload(t)),s.extra={},r.exposeShortcut=null},Object.entries(e).forEach(([t,e])=>{t.startsWith("_")?n[t]=e(s,r):i[t]=e(s,r)}),i}});
|