@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
package/html/bg.png
ADDED
|
Binary file
|
package/html/favicon.ico
ADDED
|
Binary file
|
package/html/favicon.svg
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg width="165" height="165" viewBox="0 0 165 165" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M120.831 57.2543L84.693 109.505C84.3099 110.059 83.7558 110.474 83.1148 110.687C82.4738 110.9 81.7809 110.898 81.1412 110.684C80.5015 110.469 79.95 110.052 79.5702 109.497C79.1905 108.941 79.0032 108.277 79.037 107.606L80.4833 78.7582L57.1343 73.8064C56.6353 73.7007 56.1704 73.474 55.7807 73.1465C55.391 72.8191 55.0885 72.4009 54.9001 71.929C54.7117 71.4571 54.6432 70.9461 54.7006 70.4412C54.758 69.9364 54.9395 69.4532 55.2291 69.0345L91.3675 16.7837C91.7507 16.2294 92.3048 15.8145 92.9458 15.6018C93.5869 15.3891 94.2798 15.3902 94.9196 15.6051C95.5593 15.8199 96.1109 16.2367 96.4906 16.7923C96.8703 17.3478 97.0575 18.0117 97.0236 18.6833L95.5773 47.5314L118.926 52.4828C119.425 52.5885 119.89 52.8152 120.28 53.1426C120.67 53.4701 120.972 53.8883 121.16 54.3602C121.349 54.8321 121.417 55.3431 121.36 55.8479C121.303 56.3528 121.121 56.836 120.831 57.2547L120.831 57.2543Z" fill="#FCC72B"/>
|
|
3
|
+
<path d="M82.9866 153.343C82.0254 153.344 81.0735 153.156 80.1855 152.788C79.2975 152.42 78.4909 151.88 77.8122 151.2L43.6658 117.056C42.2998 115.683 41.5341 113.824 41.5366 111.887C41.5392 109.95 42.3098 108.092 43.6796 106.723C45.0493 105.353 46.9064 104.582 48.8435 104.579C50.7807 104.577 52.6399 105.342 54.0134 106.708L82.9866 135.678L146.105 72.5626C147.481 71.2088 149.336 70.4536 151.266 70.4615C153.197 70.4693 155.046 71.2396 156.41 72.6045C157.775 73.9695 158.546 75.8184 158.554 77.7487C158.561 79.679 157.806 81.5342 156.452 82.9101L88.1597 151.2C87.4811 151.881 86.6747 152.42 85.7869 152.788C84.8992 153.156 83.9475 153.344 82.9866 153.343Z" fill="#729B1B"/>
|
|
4
|
+
<path d="M82.9572 153.343C83.9184 153.344 84.8703 153.156 85.7583 152.788C86.6463 152.42 87.4528 151.88 88.1316 151.2L122.278 117.056C123.644 115.683 124.41 113.824 124.407 111.887C124.405 109.95 123.634 108.092 122.264 106.723C120.894 105.353 119.037 104.582 117.1 104.579C115.163 104.577 113.304 105.342 111.93 106.708L82.9572 135.678L19.8389 72.5626C18.4629 71.2088 16.6077 70.4536 14.6775 70.4615C12.7472 70.4693 10.8982 71.2396 9.53331 72.6045C8.16839 73.9695 7.39811 75.8184 7.39025 77.7487C7.38239 79.679 8.13759 81.5342 9.49135 82.9101L77.784 151.2C78.4627 151.881 79.2691 152.42 80.1568 152.788C81.0446 153.156 81.9963 153.344 82.9572 153.343Z" fill="#729B1B" fill-opacity="0.5"/>
|
|
5
|
+
</svg>
|
|
Binary file
|
package/html/index.html
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" href="./favicon.ico" sizes="48x48">
|
|
6
|
+
<link rel="icon" href="./favicon.svg" sizes="any" type="image/svg+xml">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
8
|
+
<title>Vitest</title>
|
|
9
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
10
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
11
|
+
<link
|
|
12
|
+
href="https://fonts.googleapis.com/css2?family=Readex+Pro:wght@300;400&display=swap"
|
|
13
|
+
rel="stylesheet"
|
|
14
|
+
/>
|
|
15
|
+
<script>
|
|
16
|
+
(function () {
|
|
17
|
+
const prefersDark =
|
|
18
|
+
window.matchMedia &&
|
|
19
|
+
window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
20
|
+
const setting = localStorage.getItem("vueuse-color-scheme") || "auto";
|
|
21
|
+
if (setting === "dark" || (prefersDark && setting !== "light"))
|
|
22
|
+
document.documentElement.classList.toggle("dark", true);
|
|
23
|
+
})();
|
|
24
|
+
</script>
|
|
25
|
+
<script>window.METADATA_PATH="html.meta.json.gz"</script>
|
|
26
|
+
<script type="module" src="./assets/index-DOkKC3NI.js"></script>
|
|
27
|
+
<link rel="stylesheet" href="./assets/index-COTh6lXR.css">
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<div id="app"></div>
|
|
31
|
+
</body>
|
|
32
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peter.naydenov/shortcuts",
|
|
3
3
|
"description": "Context control of shortcuts based on keyboard and mouse events",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Peter Naydenov",
|
|
7
|
-
"main": "./
|
|
7
|
+
"main": "./src/main.js",
|
|
8
8
|
"types": "./dist/main.d.ts",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"exports": {
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"test": "vitest",
|
|
25
25
|
"test:ui": "vitest --ui --open",
|
|
26
26
|
"cover": "vitest run --coverage",
|
|
27
|
-
"types": "tsc"
|
|
27
|
+
"types": "tsc",
|
|
28
|
+
"lint": "eslint src/ test/*.js"
|
|
28
29
|
},
|
|
29
30
|
"repository": {
|
|
30
31
|
"type": "git",
|
|
@@ -34,24 +35,27 @@
|
|
|
34
35
|
"@peter.naydenov/notice": "^2.4.1"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
|
-
"@peter.naydenov/visual-controller-for-react": "^3.0.
|
|
38
|
-
"@rollup/plugin-commonjs": "^
|
|
38
|
+
"@peter.naydenov/visual-controller-for-react": "^3.0.2",
|
|
39
|
+
"@rollup/plugin-commonjs": "^29.0.0",
|
|
39
40
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
40
41
|
"@rollup/plugin-terser": "^0.4.4",
|
|
41
42
|
"@testing-library/dom": "^10.4.1",
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
44
|
-
"@vitest/
|
|
45
|
-
"@vitest/
|
|
46
|
-
"
|
|
43
|
+
"@testing-library/user-event": "^14.6.1",
|
|
44
|
+
"@vitejs/plugin-react": "^5.1.0",
|
|
45
|
+
"@vitest/browser": "^4.0.8",
|
|
46
|
+
"@vitest/browser-playwright": "^4.0.8",
|
|
47
|
+
"@vitest/coverage-v8": "^4.0.8",
|
|
48
|
+
"@vitest/ui": "^4.0.8",
|
|
49
|
+
"ask-for-promise": "^3.1.0",
|
|
47
50
|
"chai": "^6.2.0",
|
|
51
|
+
"eslint": "^9.39.1",
|
|
48
52
|
"mocha": "^11.7.4",
|
|
49
53
|
"playwright": "^1.56.1",
|
|
50
54
|
"react": "^19.2.0",
|
|
51
55
|
"react-dom": "^19.2.0",
|
|
52
56
|
"typescript": "^5.9.3",
|
|
53
|
-
"vite": "^7.
|
|
54
|
-
"vitest": "^
|
|
57
|
+
"vite": "^7.2.2",
|
|
58
|
+
"vitest": "^4.0.8"
|
|
55
59
|
},
|
|
56
60
|
"keywords": [
|
|
57
61
|
"shortcut",
|
package/shortcuts.png
ADDED
|
Binary file
|
package/src/main.js
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {Object} dependencies
|
|
5
|
+
* @property {Object} ev - Event emitter instance
|
|
6
|
+
* @property {Object} inAPI - Internal API object
|
|
7
|
+
* @property {Object} API - Public API object
|
|
8
|
+
* @property {Object} extra - Extra dependencies object
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {Object} state
|
|
13
|
+
* @property {Object} currentContext - Current context data container with name and note properties
|
|
14
|
+
* @property {Object} shortcuts - Shortcuts object: { contextName : { shortcut : callback[] } }
|
|
15
|
+
* @property {Array} plugins - Array of active plugins
|
|
16
|
+
* @property {Function|null} exposeShortcut - Keyboard shortcut log function
|
|
17
|
+
* @property {string} ERROR_EVENT_NAME - Name for error events
|
|
18
|
+
*/
|
|
19
|
+
|
|
3
20
|
/**
|
|
4
21
|
* @typedef {Object} PluginAPI
|
|
5
22
|
* @property {function(): string} getPrefix - Get plugin prefix
|
|
@@ -10,9 +27,15 @@
|
|
|
10
27
|
* @property {function(): void} destroy - Destroy the plugin
|
|
11
28
|
*/
|
|
12
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {Object} contextShortcuts
|
|
32
|
+
* @property {string} context - Context name
|
|
33
|
+
* @property {string[]} shortcuts - List of shortcuts in a context
|
|
34
|
+
*/
|
|
35
|
+
|
|
13
36
|
/**
|
|
14
37
|
* @typedef {Object} ShortcutsAPI
|
|
15
|
-
* @property {function(
|
|
38
|
+
* @property {function(Function, Object): void} enablePlugin - Enable a plugin
|
|
16
39
|
* @property {function(string): void} disablePlugin - Disable a plugin
|
|
17
40
|
* @property {function(string): number} mutePlugin - Mute a plugin
|
|
18
41
|
* @property {function(string): number} unmutePlugin - Unmute a plugin
|
|
@@ -28,7 +51,7 @@
|
|
|
28
51
|
* @property {function(): Object} getDependencies - Get external dependencies
|
|
29
52
|
* @property {function(): void} reset - Reset the library instance
|
|
30
53
|
* @property {function(string|boolean): void} changeContext - Change current context
|
|
31
|
-
* @property {function(string|null): string[]|
|
|
54
|
+
* @property {function(string|null): string[]|contextShortcuts[]|null} listShortcuts - List shortcuts
|
|
32
55
|
* @property {function(Object): void} load - Load shortcuts into contexts
|
|
33
56
|
* @property {function(string): void} unload - Unload a context
|
|
34
57
|
*/
|
|
@@ -55,9 +78,11 @@ import notice from '@peter.naydenov/notice' // Docs: https://github.com/Peter
|
|
|
55
78
|
import methods from './methods/index.js'
|
|
56
79
|
|
|
57
80
|
// Plugins
|
|
58
|
-
import pluginKey
|
|
59
|
-
import pluginClick
|
|
60
|
-
import pluginForm
|
|
81
|
+
import pluginKey from './plugins/key/index.js'
|
|
82
|
+
import pluginClick from './plugins/click/index.js'
|
|
83
|
+
import pluginForm from './plugins/form/index.js'
|
|
84
|
+
import pluginHover from './plugins/hover/index.js'
|
|
85
|
+
import pluginScroll from './plugins/scroll/index.js'
|
|
61
86
|
|
|
62
87
|
|
|
63
88
|
|
|
@@ -72,12 +97,10 @@ import pluginForm from './plugins/form/index.js'
|
|
|
72
97
|
* @returns {ShortcutsAPI} The shortcuts API
|
|
73
98
|
*/
|
|
74
99
|
function main ( options = {} ) {
|
|
75
|
-
|
|
100
|
+
const
|
|
76
101
|
inAPI = {} // API for internal methods
|
|
77
102
|
, API = {} // API for public methods
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
ev = notice () // Event emitter instance
|
|
103
|
+
, ev = notice () // Event emitter instance
|
|
81
104
|
, state = {
|
|
82
105
|
currentContext : { name: null, note: null } // Context data container
|
|
83
106
|
, shortcuts : {} // shortcuts = { contextName : { shortcut : callback[] } }
|
|
@@ -86,35 +109,37 @@ function main ( options = {} ) {
|
|
|
86
109
|
, ERROR_EVENT_NAME : ( options.errorEventName ) ? options.errorEventName : '@shortcuts-error'
|
|
87
110
|
} // state
|
|
88
111
|
;
|
|
89
|
-
|
|
112
|
+
const dependencies = {
|
|
90
113
|
ev
|
|
91
114
|
, inAPI
|
|
92
115
|
, API
|
|
93
116
|
, extra : {}
|
|
94
117
|
};
|
|
95
118
|
|
|
96
|
-
|
|
97
|
-
|
|
98
119
|
// ---------------------- > PLUGIN METHODS < ---------------------- //
|
|
99
120
|
/**
|
|
100
121
|
* @function enablePlugin
|
|
101
122
|
* @description Enable a plugin
|
|
123
|
+
* @param {Function} plugin - Plugin function to enable
|
|
124
|
+
* @param {Object} [options={}] - Plugin configuration options
|
|
102
125
|
* @returns {void}
|
|
103
126
|
*/
|
|
104
127
|
API.enablePlugin = ( plugin, options={}) => {
|
|
105
128
|
if ( typeof plugin !== 'function' ) return
|
|
106
|
-
|
|
129
|
+
const setupPlugin = inAPI._setupPlugin
|
|
130
|
+
const plugApp = plugin ( setupPlugin, options )
|
|
107
131
|
const
|
|
108
132
|
name = plugApp.getPrefix ()
|
|
109
133
|
, ix = inAPI._systemAction ( name, 'none' )
|
|
110
134
|
;
|
|
111
|
-
|
|
112
135
|
if ( ix === -1 ) { // If plugin is not registered
|
|
113
136
|
// Started instance of the plugin
|
|
114
137
|
state.plugins.push ( plugApp )
|
|
138
|
+
plugApp.unmute ()
|
|
115
139
|
}
|
|
116
140
|
else {
|
|
117
141
|
plugApp.destroy ()
|
|
142
|
+
state.plugins[ix].unmute ()
|
|
118
143
|
}
|
|
119
144
|
} // enable func.
|
|
120
145
|
|
|
@@ -123,25 +148,28 @@ function main ( options = {} ) {
|
|
|
123
148
|
/**
|
|
124
149
|
* @function disablePlugin
|
|
125
150
|
* @description Disable a plugin
|
|
151
|
+
* @param {string} pluginName - Name of the plugin to disable
|
|
126
152
|
* @returns {void}
|
|
127
153
|
*/
|
|
128
154
|
API.disablePlugin = pluginName => {
|
|
129
155
|
const ix = inAPI._systemAction ( pluginName, 'destroy' );
|
|
130
|
-
if ( ix !== -1 ) state.plugins
|
|
156
|
+
if ( ix !== -1 ) state.plugins.splice ( ix, 1 )
|
|
131
157
|
} // disable func.
|
|
132
158
|
|
|
133
159
|
|
|
134
160
|
/**
|
|
135
161
|
* @function mutePlugin
|
|
136
162
|
* @description Mute a plugin
|
|
137
|
-
* @
|
|
163
|
+
* @param {string} pluginName - Name of the plugin to mute
|
|
164
|
+
* @returns {number} - Index of the plugin in the plugins array ( -1 if not found )
|
|
138
165
|
*/
|
|
139
166
|
API.mutePlugin = pluginName => inAPI._systemAction ( pluginName, 'mute' )
|
|
140
167
|
|
|
141
168
|
/**
|
|
142
|
-
* @function
|
|
169
|
+
* @function unmutePlugin
|
|
143
170
|
* @description Unmute a plugin
|
|
144
|
-
* @
|
|
171
|
+
* @param {string} pluginName - Name of the plugin to unmute
|
|
172
|
+
* @returns {number} - Index of the plugin in the plugins array ( -1 if not found )
|
|
145
173
|
*/
|
|
146
174
|
API.unmutePlugin = pluginName => inAPI._systemAction ( pluginName, 'unmute' )
|
|
147
175
|
|
|
@@ -185,7 +213,7 @@ function main ( options = {} ) {
|
|
|
185
213
|
* @returns {void}
|
|
186
214
|
*/
|
|
187
215
|
API.pause = (name='*') => {
|
|
188
|
-
|
|
216
|
+
const pausedEvent = inAPI._readShortcutWithPlugins ( name );
|
|
189
217
|
ev.stop ( pausedEvent )
|
|
190
218
|
}
|
|
191
219
|
|
|
@@ -222,15 +250,15 @@ function main ( options = {} ) {
|
|
|
222
250
|
/**
|
|
223
251
|
* @function setDependencies
|
|
224
252
|
* @description Set a dependency package that will be provided to each action function
|
|
225
|
-
* @param {
|
|
253
|
+
* @param {Object} deps - Enumerate external dependencies
|
|
226
254
|
* @returns {void}
|
|
227
255
|
*/
|
|
228
|
-
API.setDependencies = deps =>
|
|
256
|
+
API.setDependencies = deps => Object.assign ( dependencies.extra, deps )
|
|
229
257
|
|
|
230
258
|
/**
|
|
231
259
|
* @function getDependencies
|
|
232
260
|
* @description Get a dependency package that will be provided to each action function
|
|
233
|
-
* @returns {
|
|
261
|
+
* @returns {Object} - Enumerate external dependencies
|
|
234
262
|
**/
|
|
235
263
|
API.getDependencies = () => dependencies.extra
|
|
236
264
|
|
|
@@ -267,6 +295,8 @@ export {
|
|
|
267
295
|
pluginKey
|
|
268
296
|
, pluginClick
|
|
269
297
|
, pluginForm
|
|
298
|
+
, pluginHover
|
|
299
|
+
, pluginScroll
|
|
270
300
|
}
|
|
271
301
|
|
|
272
302
|
|
|
@@ -1,8 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} dependencies
|
|
3
|
+
* @property {Object} ev - Event emitter instance
|
|
4
|
+
* @property {Object} inAPI - Internal API object
|
|
5
|
+
* @property {Object} API - Public API object
|
|
6
|
+
* @property {Object} extra - Extra dependencies object
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} state
|
|
11
|
+
* @property {Object} currentContext - Current context data container
|
|
12
|
+
* @property {Object} shortcuts - Shortcuts object: { contextName : { shortcut : callback[] } }
|
|
13
|
+
* @property {Array} plugins - Array of active plugins
|
|
14
|
+
* @property {Function|null} exposeShortcut - Keyboard shortcut log function
|
|
15
|
+
* @property {string} ERROR_EVENT_NAME - Name for error events
|
|
16
|
+
*/
|
|
17
|
+
|
|
2
18
|
/**
|
|
3
19
|
* @function _normalizeWithPlugins
|
|
4
20
|
* @description Function used by plugins during the enable process to normalize the existing and related to the plugin shortcut names.
|
|
5
|
-
* @param {
|
|
21
|
+
* @param {dependencies} dependencies - Dependencies object containing inAPI
|
|
22
|
+
* @param {state} state - State object containing shortcuts
|
|
23
|
+
* @returns {function} - Returns a function that takes a normalize function
|
|
24
|
+
*/
|
|
25
|
+
function _normalizeWithPlugins ( dependencies, state ) {
|
|
26
|
+
/**
|
|
27
|
+
* @function _normalizeWithPlugins
|
|
28
|
+
* @description Normalize shortcut names across all contexts using plugin's normalize function
|
|
29
|
+
* @param {function} _normalizeShortcutName - Plugin internal 'normalize' function
|
|
6
30
|
* @returns {void}
|
|
7
31
|
*/
|
|
8
32
|
return function _normalizeWithPlugins ( _normalizeShortcutName ) {
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
/**
|
|
3
|
+
* @function _readShortcutWithPlugins
|
|
4
|
+
* @description Searches for belonging plugin and call the plugin method to normalize the shortcut name.
|
|
5
|
+
* @param {dependencies} dependencies - Dependencies object containing inAPI
|
|
6
|
+
* @param {state} state - State object containing plugins
|
|
7
|
+
* @returns {function} - Returns a function that processes shortcut names
|
|
8
|
+
*/
|
|
2
9
|
function _readShortcutWithPlugins ( dependencies, state ) {
|
|
3
10
|
/**
|
|
4
11
|
* @function _readShortcutWithPlugins
|
|
5
12
|
* @description Searches for belonging plugin and call the plugin method to normalize the shortcut name.
|
|
6
|
-
* @param {string} shortcut - The shortcut to read
|
|
7
|
-
* @returns {string} - The normalized shortcut name
|
|
13
|
+
* @param {string} shortcut - The shortcut to read
|
|
14
|
+
* @returns {string} - The normalized shortcut name
|
|
8
15
|
*/
|
|
9
16
|
return function _readShortcutWithPlugins ( shortcut ) {
|
|
10
17
|
const
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function _setupPlugin
|
|
3
|
+
* @description Setup a plugin with provided settings and dependencies
|
|
4
|
+
* @param {dependencies} dependencies - Dependencies object containing ev, extra, inAPI, API
|
|
5
|
+
* @param {state} state - State object containing currentContext, shortcuts, exposeShortcut, ERROR_EVENT_NAME
|
|
6
|
+
* @returns {function} - Returns a function that takes plugin settings and returns plugin API
|
|
7
|
+
*/
|
|
8
|
+
function _setupPlugin ( dependencies, state ) {
|
|
9
|
+
|
|
10
|
+
const { inAPI } = dependencies;
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
currentContext
|
|
14
|
+
, shortcuts
|
|
15
|
+
, exposeShortcut
|
|
16
|
+
, ERROR_EVENT_NAME
|
|
17
|
+
} = state
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @function _setupPlugin
|
|
21
|
+
* @description Setup a plugin with provided settings
|
|
22
|
+
* @param {Object} settings - Plugin configuration object
|
|
23
|
+
* @param {string} settings.prefix - Plugin prefix
|
|
24
|
+
* @param {function} settings._normalizeShortcutName - Normalize shortcut plugin method
|
|
25
|
+
* @param {function} settings._registerShortcutEvents - Register shortcut plugin method
|
|
26
|
+
* @param {function} settings._listenDOM - DOM listener plugin method
|
|
27
|
+
* @param {Object} settings.pluginState - Plugin state object
|
|
28
|
+
* @param {Object} settings.deps - Plugin dependencies object
|
|
29
|
+
* @returns {PluginAPI} - Plugin API object with methods
|
|
30
|
+
*/
|
|
31
|
+
return function _setupPlugin ( settings ) {
|
|
32
|
+
const {
|
|
33
|
+
prefix // Plugin prefix (string)
|
|
34
|
+
, _normalizeShortcutName // Normalize shortcut plugin method (function)
|
|
35
|
+
, _registerShortcutEvents // Register shortcut plugin method (function)
|
|
36
|
+
, _listenDOM // DOM listener plugin method (function)
|
|
37
|
+
|
|
38
|
+
, pluginState // Plugin state (object)
|
|
39
|
+
, deps // Plugin dependencies (object)
|
|
40
|
+
} = settings
|
|
41
|
+
, { resetState } = deps // Reset plugin state (function)
|
|
42
|
+
;
|
|
43
|
+
|
|
44
|
+
pluginState.currentContext = currentContext
|
|
45
|
+
pluginState.shortcuts = shortcuts
|
|
46
|
+
pluginState.exposeShortcut = exposeShortcut
|
|
47
|
+
pluginState.ERROR_EVENT_NAME = ERROR_EVENT_NAME
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
const plugDeps = {
|
|
52
|
+
ev: dependencies.ev
|
|
53
|
+
, extra: dependencies.extra
|
|
54
|
+
, ...deps
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Read shortcuts names from all context entities and normalize entries related to the plugin
|
|
58
|
+
inAPI._normalizeWithPlugins ( _normalizeShortcutName )
|
|
59
|
+
|
|
60
|
+
let countShortcuts = _registerShortcutEvents ( plugDeps, pluginState );
|
|
61
|
+
const listener = _listenDOM ( plugDeps, pluginState ) // DOM listener object with 'start' and 'stop' methods
|
|
62
|
+
if ( countShortcuts > 0 ) listener.start ()
|
|
63
|
+
|
|
64
|
+
const pluginAPI = {
|
|
65
|
+
getPrefix : () => prefix
|
|
66
|
+
, shortcutName : key => { // Format a key string according plugin needs
|
|
67
|
+
return _normalizeShortcutName ( key )
|
|
68
|
+
}
|
|
69
|
+
, contextChange : () => {
|
|
70
|
+
resetState ()
|
|
71
|
+
countShortcuts = _registerShortcutEvents ( plugDeps, pluginState )
|
|
72
|
+
if ( countShortcuts < 1 ) { // Remove DOM listener if there are no shortcuts in the current context
|
|
73
|
+
listener.stop ()
|
|
74
|
+
}
|
|
75
|
+
if ( countShortcuts > 0 ) { // Add DOM listener if there are shortcuts in the current context
|
|
76
|
+
listener.start ()
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
, mute : () => listener.stop ()
|
|
80
|
+
, unmute : () => listener.start ()
|
|
81
|
+
, destroy : () => {
|
|
82
|
+
listener.stop ()
|
|
83
|
+
resetState ()
|
|
84
|
+
}
|
|
85
|
+
}; // pluginAPI
|
|
86
|
+
Object.freeze ( pluginAPI )
|
|
87
|
+
return pluginAPI
|
|
88
|
+
}} // _setupPlugin
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
export default _setupPlugin
|
|
92
|
+
|
|
93
|
+
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @function _systemAction
|
|
5
|
+
* @description Call a specific plugin method.
|
|
6
|
+
* @param {dependencies} dependencies - Dependencies object containing inAPI
|
|
7
|
+
* @param {state} state - State object containing plugins array
|
|
8
|
+
* @returns {function} - Returns a function that executes plugin actions
|
|
9
|
+
*/
|
|
3
10
|
function _systemAction ( dependencies, state ) {
|
|
4
11
|
/**
|
|
5
12
|
* @function _systemAction
|
|
6
|
-
* @description Call a
|
|
7
|
-
* @param {string} pluginName - The name of the plugin
|
|
8
|
-
* @param {string} fn - The name of the method to call
|
|
9
|
-
* @param {any} params - The parameters to pass to the method
|
|
13
|
+
* @description Call a specific plugin method.
|
|
14
|
+
* @param {string} pluginName - The name of the plugin
|
|
15
|
+
* @param {string} fn - The name of the method to call
|
|
16
|
+
* @param {any} [params=null] - The parameters to pass to the method
|
|
17
|
+
* @returns {number} - Index of the plugin in the plugins array (-1 if not found)
|
|
10
18
|
*/
|
|
11
19
|
return function _systemAction ( pluginName, fn, params=null ) { // Specific plugin command: Mute, unmute, pause, resume, destroy
|
|
12
20
|
return state.plugins.findIndex ( plugin => {
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @function changeContext
|
|
5
|
+
* @description Change current context with shortcuts belonging to it
|
|
6
|
+
* @param {dependencies} dependencies - Dependencies object containing ev
|
|
7
|
+
* @param {state} state - State object containing shortcuts, currentContext, ERROR_EVENT_NAME
|
|
8
|
+
* @returns {function} - Returns a function that changes context
|
|
9
|
+
*/
|
|
3
10
|
function changeContext ( dependencies, state ) {
|
|
4
11
|
const
|
|
5
12
|
{
|
|
@@ -22,8 +29,8 @@ function expose () {
|
|
|
22
29
|
|
|
23
30
|
/**
|
|
24
31
|
* @function changeContext
|
|
25
|
-
* @description Change current context with shortcuts belonging to it
|
|
26
|
-
* @param {string} [contextName=false] - Name of context to change to. Default 'false' will switch off all shortcuts
|
|
32
|
+
* @description Change current context with shortcuts belonging to it
|
|
33
|
+
* @param {string|boolean} [contextName=false] - Name of context to change to. Default 'false' will switch off all shortcuts
|
|
27
34
|
* @returns {void}
|
|
28
35
|
*/
|
|
29
36
|
return function changeContext ( contextName = false ) {
|
|
@@ -45,9 +52,10 @@ return function changeContext ( contextName = false ) {
|
|
|
45
52
|
ev.reset () // Disable all shortcuts from current context
|
|
46
53
|
}
|
|
47
54
|
|
|
48
|
-
currentContext.name = contextName
|
|
55
|
+
currentContext.name = contextName
|
|
49
56
|
state.plugins.forEach ( plugin => plugin.contextChange ( contextName ) ) // Inform plugins for context change
|
|
50
57
|
Object.entries ( shortcuts[contextName] ).forEach ( ([shortcutName, list ]) => { // Enable new context shortcuts
|
|
58
|
+
if ( shortcutName.includes (':SETUP') ) return
|
|
51
59
|
list.forEach ( fn => ev.on ( shortcutName, fn ) )
|
|
52
60
|
})
|
|
53
61
|
expose ()
|
package/src/methods/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import load from './load.js'
|
|
|
6
6
|
import unload from './unload.js'
|
|
7
7
|
import changeContext from './changeContext.js'
|
|
8
8
|
import listShortcuts from './listShortcuts.js'
|
|
9
|
+
import _setupPlugin from './_setupPlugin.js'
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
|
|
@@ -13,6 +14,7 @@ export default {
|
|
|
13
14
|
// Internal methods
|
|
14
15
|
_normalizeWithPlugins
|
|
15
16
|
, _readShortcutWithPlugins
|
|
17
|
+
, _setupPlugin
|
|
16
18
|
, _systemAction
|
|
17
19
|
|
|
18
20
|
// Public methods
|
|
@@ -1,32 +1,25 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
/**
|
|
3
|
-
* @typedef {object} contextShortcuts
|
|
4
|
-
* @property {string} context - Context name
|
|
5
|
-
* @property {string[]} shortcuts - List of shortcuts in a context
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
2
|
|
|
10
3
|
function listShortcuts ( dependencies, state ) {
|
|
11
4
|
const shortcuts = state.shortcuts;
|
|
12
5
|
/**
|
|
13
6
|
* @function listShortcuts
|
|
14
|
-
* @description List all shortcuts in all contexts or in a specific context
|
|
15
|
-
* @param {string}[
|
|
16
|
-
* @returns {string[]|contextShortcuts[]} - List of shortcuts for a specified context
|
|
7
|
+
* @description List all shortcuts in all contexts or in a specific context
|
|
8
|
+
* @param {string|null} [contextName=null] - List of shortcuts for provided context name (optional)
|
|
9
|
+
* @returns {string[]|contextShortcuts[]|null} - List of shortcuts for a specified context, list of contextShortcuts for all contexts, or null if context doesn't exist
|
|
17
10
|
*/
|
|
18
11
|
return function listShortcuts ( contextName=null ) {
|
|
19
12
|
|
|
20
13
|
// Create a list of shortcuts for a specific context:
|
|
21
14
|
if ( contextName != null ) {
|
|
22
|
-
|
|
15
|
+
const context = shortcuts[contextName];
|
|
23
16
|
if ( context == null ) return null
|
|
24
17
|
return Object.entries ( context ).map ( ([shortcut, callbacks]) => shortcut )
|
|
25
18
|
}
|
|
26
19
|
|
|
27
20
|
// Create a list of allShortcuts for each context:
|
|
28
21
|
return Object.keys ( shortcuts ).map ( contextName => {
|
|
29
|
-
|
|
22
|
+
const result = {};
|
|
30
23
|
result['context'] = contextName
|
|
31
24
|
result['shortcuts'] = Object.entries ( shortcuts[contextName] ).map ( ([shortcut, callbacks]) => shortcut )
|
|
32
25
|
return result
|
package/src/methods/load.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @function load
|
|
5
|
+
* @description Load a context with shortcuts object
|
|
6
|
+
* @param {dependencies} dependencies - Dependencies object containing API with changeContext and getContext
|
|
7
|
+
* @param {state} state - State object containing shortcuts and plugins
|
|
8
|
+
* @returns {function} - Returns a function that loads shortcuts
|
|
9
|
+
*/
|
|
3
10
|
function load ( dependencies, state ) {
|
|
4
11
|
const
|
|
5
12
|
{ shortcuts, plugins } = state
|
|
@@ -27,11 +34,11 @@ return function load ( shortcutsUpdate ) {
|
|
|
27
34
|
Object.entries ( contextShortcuts ).forEach ( ([ title, payload ]) => {
|
|
28
35
|
let
|
|
29
36
|
name = title
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
; const test = title.toUpperCase().trim()
|
|
38
|
+
|
|
39
|
+
const pluginIndexList = pluginPrefixList.map ( (prefix,i) => test.startsWith ( prefix ) ? i : null ).filter ( i => i !== null );
|
|
33
40
|
if ( pluginIndexList.length ) {
|
|
34
|
-
|
|
41
|
+
const id = pluginIndexList[0];
|
|
35
42
|
name = plugins[id].shortcutName ( title )
|
|
36
43
|
}
|
|
37
44
|
if ( payload instanceof Function ) payload = [ payload ]
|
package/src/methods/unload.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @function unload
|
|
5
|
+
* @description Unload a non-active context with shortcuts
|
|
6
|
+
* @param {dependencies} dependencies - Dependencies object containing ev
|
|
7
|
+
* @param {state} state - State object containing currentContext, shortcuts, ERROR_EVENT_NAME
|
|
8
|
+
* @returns {function} - Returns a function that unloads contexts
|
|
9
|
+
*/
|
|
3
10
|
function unload ( dependencies, state ) {
|
|
4
11
|
const
|
|
5
12
|
{ currentContext, shortcuts, ERROR_EVENT_NAME } = state
|
|
@@ -7,7 +14,7 @@ const
|
|
|
7
14
|
;
|
|
8
15
|
/**
|
|
9
16
|
* @function unload
|
|
10
|
-
* @description Unload a non-active context with shortcuts
|
|
17
|
+
* @description Unload a non-active context with shortcuts
|
|
11
18
|
* @param {string} contextName - Context name to unload
|
|
12
19
|
* @returns {void}
|
|
13
20
|
*/
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @function _findTarget
|
|
5
|
+
* @description Find the appropriate click target element by checking if element has any of the target attributes
|
|
6
|
+
* @param {Object} dependencies - Dependencies object
|
|
7
|
+
* @param {Object} state - Plugin state containing listenOptions with clickTarget array
|
|
8
|
+
* @param {Element} target - DOM element to start searching from
|
|
9
|
+
* @returns {Element|null} - Target element or null if not found
|
|
10
|
+
*/
|
|
3
11
|
function _findTarget ( dependencies, state, target ) {
|
|
4
|
-
|
|
5
12
|
const { listenOptions : {clickTarget}} = state;
|
|
6
13
|
|
|
7
|
-
|
|
8
|
-
if ( t === document ) return null
|
|
14
|
+
const t = target;
|
|
9
15
|
if ( t === document.body ) return null
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
if (
|
|
17
|
+
const found = clickTarget.some ( attr => ( t.hasAttribute ( attr ) ) )
|
|
18
|
+
if ( found ) return t
|
|
13
19
|
return _findTarget ( dependencies, state, t.parentNode )
|
|
14
20
|
} // _findTarget func.
|
|
15
21
|
|