@peter.naydenov/shortcuts 3.4.0 → 3.5.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/Changelog.md +6 -0
- package/README.md +2 -0
- package/dist/main.d.ts +120 -0
- package/dist/methods/_normalizeWithPlugins.d.ts +2 -0
- package/dist/methods/_readShortcutWithPlugins.d.ts +2 -0
- package/dist/methods/_systemAction.d.ts +2 -0
- package/dist/methods/changeContext.d.ts +2 -0
- package/dist/methods/index.d.ts +17 -0
- package/dist/methods/listShortcuts.d.ts +17 -0
- package/dist/methods/load.d.ts +2 -0
- package/dist/methods/unload.d.ts +2 -0
- package/dist/plugins/click/_findTarget.d.ts +2 -0
- package/dist/plugins/click/_listenDOM.d.ts +5 -0
- package/dist/plugins/click/_normalizeShortcutName.d.ts +2 -0
- package/dist/plugins/click/_readClickEvent.d.ts +2 -0
- package/dist/plugins/click/_registerShortcutEvents.d.ts +2 -0
- package/dist/plugins/click/index.d.ts +15 -0
- package/dist/plugins/form/_defaults.d.ts +5 -0
- package/dist/plugins/form/_listenDOM.d.ts +5 -0
- package/dist/plugins/form/_normalizeShortcutName.d.ts +2 -0
- package/dist/plugins/form/_registerShortcutEvents.d.ts +2 -0
- package/dist/plugins/form/index.d.ts +10 -0
- package/dist/plugins/key/_listenDOM.d.ts +5 -0
- package/dist/plugins/key/_normalizeShortcutName.d.ts +2 -0
- package/dist/plugins/key/_readKeyEvent.d.ts +2 -0
- package/dist/plugins/key/_registerShortcutEvents.d.ts +2 -0
- package/dist/plugins/key/_specialChars.d.ts +32 -0
- package/dist/plugins/key/index.d.ts +15 -0
- package/dist/shortcuts.cjs +1 -1
- package/dist/shortcuts.esm.mjs +1 -1
- package/dist/shortcuts.umd.js +1 -1
- package/package.json +6 -3
- package/src/main.js +74 -20
- package/src/methods/changeContext.js +2 -1
- package/src/methods/load.js +4 -3
- package/src/methods/unload.js +3 -3
- package/src/plugins/click/_listenDOM.js +1 -1
- package/src/plugins/click/index.js +10 -0
- package/src/plugins/form/index.js +8 -13
- package/src/plugins/key/index.js +10 -0
- package/test/01-general.test.js +64 -5
- package/test/02-key.test.js +136 -38
- package/test/03-click.test.js +88 -56
- package/tsconfig.json +23 -0
package/src/main.js
CHANGED
|
@@ -1,19 +1,52 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
4
|
+
* @typedef {Object} PluginAPI
|
|
5
|
+
* @property {function(): string} getPrefix - Get plugin prefix
|
|
6
|
+
* @property {function(string): string} shortcutName - Format shortcut name
|
|
7
|
+
* @property {function(string): void} contextChange - Handle context change
|
|
8
|
+
* @property {function(): void} mute - Mute the plugin
|
|
9
|
+
* @property {function(): void} unmute - Unmute the plugin
|
|
10
|
+
* @property {function(): void} destroy - Destroy the plugin
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Object} ShortcutsAPI
|
|
15
|
+
* @property {function(function, Object): void} enablePlugin - Enable a plugin
|
|
16
|
+
* @property {function(string): void} disablePlugin - Disable a plugin
|
|
17
|
+
* @property {function(string): number} mutePlugin - Mute a plugin
|
|
18
|
+
* @property {function(string): number} unmutePlugin - Unmute a plugin
|
|
19
|
+
* @property {function(): string[]} listPlugins - List enabled plugins
|
|
20
|
+
* @property {function(): string|null} getContext - Get current context name
|
|
21
|
+
* @property {function(): string|null} getNote - Get current context note
|
|
22
|
+
* @property {function(string|null): void} setNote - Set current context note
|
|
23
|
+
* @property {function(string): void} pause - Pause shortcuts in current context
|
|
24
|
+
* @property {function(string): void} resume - Resume shortcuts in current context
|
|
25
|
+
* @property {function(string, ...any): void} emit - Emit event for shortcut
|
|
26
|
+
* @property {function(): string[]} listContexts - List all context names
|
|
27
|
+
* @property {function(Object): void} setDependencies - Set external dependencies
|
|
28
|
+
* @property {function(): Object} getDependencies - Get external dependencies
|
|
29
|
+
* @property {function(): void} reset - Reset the library instance
|
|
30
|
+
* @property {function(string|boolean): void} changeContext - Change current context
|
|
31
|
+
* @property {function(string|null): string[]|Object[]} listShortcuts - List shortcuts
|
|
32
|
+
* @property {function(Object): void} load - Load shortcuts into contexts
|
|
33
|
+
* @property {function(string): void} unload - Unload a context
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Shortcuts
|
|
38
|
+
* =========
|
|
39
|
+
*
|
|
40
|
+
* Create shortcuts for your web application based on keyboard and mouse and DOM events.
|
|
41
|
+
* Repository: https://github.com/PeterNaydenov/shortcuts
|
|
42
|
+
*
|
|
43
|
+
* History notes:
|
|
44
|
+
* - Development was started on June 21st, 2023
|
|
45
|
+
* - First version was published on August 14th, 2023
|
|
46
|
+
* - Method 'emit' was added on September 30st, 2023
|
|
47
|
+
* - Version 2.0.0 was published on October 16th, 2023
|
|
48
|
+
* - Version 3.0.0. Plugin system. Published on March 5th, 2024
|
|
49
|
+
* - Version 3.2.0. Added plugin 'form'. Published on August 15th, 2025
|
|
17
50
|
*/
|
|
18
51
|
|
|
19
52
|
|
|
@@ -30,6 +63,14 @@ import pluginForm from './plugins/form/index.js'
|
|
|
30
63
|
|
|
31
64
|
|
|
32
65
|
|
|
66
|
+
/**
|
|
67
|
+
* @function shortcuts
|
|
68
|
+
* @description Create a shortcuts instance
|
|
69
|
+
* @param {Object} [options={}] - Configuration options
|
|
70
|
+
* @param {function} [options.onShortcut] - Function to log shortcut events
|
|
71
|
+
* @param {string} [options.errorEventName='@shortcuts-error'] - Name for error events
|
|
72
|
+
* @returns {ShortcutsAPI} The shortcuts API
|
|
73
|
+
*/
|
|
33
74
|
function main ( options = {} ) {
|
|
34
75
|
let
|
|
35
76
|
inAPI = {} // API for internal methods
|
|
@@ -38,10 +79,11 @@ function main ( options = {} ) {
|
|
|
38
79
|
const
|
|
39
80
|
ev = notice () // Event emitter instance
|
|
40
81
|
, state = {
|
|
41
|
-
currentContext
|
|
42
|
-
, shortcuts
|
|
43
|
-
, plugins
|
|
44
|
-
, exposeShortcut
|
|
82
|
+
currentContext : { name: null, note: null } // Context data container
|
|
83
|
+
, shortcuts : {} // shortcuts = { contextName : { shortcut : callback[] } }
|
|
84
|
+
, plugins : [] // Array of active plugins
|
|
85
|
+
, exposeShortcut : (options.onShortcut && ( typeof options.onShortcut === 'function')) ? options.onShortcut : false // Keyboard shortcut log function
|
|
86
|
+
, ERROR_EVENT_NAME : ( options.errorEventName ) ? options.errorEventName : '@shortcuts-error'
|
|
45
87
|
} // state
|
|
46
88
|
;
|
|
47
89
|
let dependencies = {
|
|
@@ -60,16 +102,20 @@ function main ( options = {} ) {
|
|
|
60
102
|
* @returns {void}
|
|
61
103
|
*/
|
|
62
104
|
API.enablePlugin = ( plugin, options={}) => {
|
|
105
|
+
if ( typeof plugin !== 'function' ) return
|
|
106
|
+
let plugApp = plugin ( dependencies, state, options )
|
|
63
107
|
const
|
|
64
|
-
name =
|
|
108
|
+
name = plugApp.getPrefix ()
|
|
65
109
|
, ix = inAPI._systemAction ( name, 'none' )
|
|
66
110
|
;
|
|
67
111
|
|
|
68
112
|
if ( ix === -1 ) { // If plugin is not registered
|
|
69
113
|
// Started instance of the plugin
|
|
70
|
-
let plugApp = plugin ( dependencies, state, options )
|
|
71
114
|
state.plugins.push ( plugApp )
|
|
72
115
|
}
|
|
116
|
+
else {
|
|
117
|
+
plugApp.destroy ()
|
|
118
|
+
}
|
|
73
119
|
} // enable func.
|
|
74
120
|
|
|
75
121
|
|
|
@@ -100,8 +146,15 @@ function main ( options = {} ) {
|
|
|
100
146
|
API.unmutePlugin = pluginName => inAPI._systemAction ( pluginName, 'unmute' )
|
|
101
147
|
|
|
102
148
|
|
|
103
|
-
|
|
149
|
+
/**
|
|
150
|
+
* @function listPlugins
|
|
151
|
+
* @description List all enabled plugins
|
|
152
|
+
* @returns {string[]} - Array of plugin names
|
|
153
|
+
*/
|
|
154
|
+
API.listPlugins = () => state.plugins.map ( plugin => plugin.getPrefix() )
|
|
155
|
+
|
|
104
156
|
|
|
157
|
+
|
|
105
158
|
// ---------------------- > PUBLIC METHODS < ---------------------- //
|
|
106
159
|
/**
|
|
107
160
|
* @function getContext
|
|
@@ -208,6 +261,7 @@ function main ( options = {} ) {
|
|
|
208
261
|
|
|
209
262
|
|
|
210
263
|
|
|
264
|
+
/** @type {function} */
|
|
211
265
|
export { main as shortcuts }
|
|
212
266
|
export {
|
|
213
267
|
pluginKey
|
|
@@ -5,6 +5,7 @@ const
|
|
|
5
5
|
{
|
|
6
6
|
shortcuts
|
|
7
7
|
, currentContext
|
|
8
|
+
, ERROR_EVENT_NAME
|
|
8
9
|
} = state
|
|
9
10
|
, { ev } = dependencies
|
|
10
11
|
;
|
|
@@ -37,7 +38,7 @@ return function changeContext ( contextName = false ) {
|
|
|
37
38
|
}
|
|
38
39
|
if ( current === contextName ) return // Do nothing if contextName is the same as current
|
|
39
40
|
if ( !shortcuts [ contextName ] ) { // If contextName is not defined
|
|
40
|
-
ev.emit (
|
|
41
|
+
ev.emit ( ERROR_EVENT_NAME, `Context '${ contextName }' does not exist` )
|
|
41
42
|
return
|
|
42
43
|
}
|
|
43
44
|
if ( shortcuts[current] ) {
|
package/src/methods/load.js
CHANGED
|
@@ -7,9 +7,10 @@ const
|
|
|
7
7
|
API : { changeContext, getContext }
|
|
8
8
|
} = dependencies;
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* @function load
|
|
11
|
+
* @description Load a context with shortcuts object
|
|
12
|
+
* @param {Object} shortcutsUpdate - Context description object: { contextName : { shortcut : callback[] } }
|
|
13
|
+
* @returns {void}
|
|
13
14
|
*/
|
|
14
15
|
return function load ( shortcutsUpdate ) {
|
|
15
16
|
const
|
package/src/methods/unload.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
function unload ( dependencies, state ) {
|
|
4
4
|
const
|
|
5
|
-
{ currentContext, shortcuts } = state
|
|
5
|
+
{ currentContext, shortcuts, ERROR_EVENT_NAME } = state
|
|
6
6
|
, { ev } = dependencies
|
|
7
7
|
;
|
|
8
8
|
/**
|
|
@@ -14,11 +14,11 @@ const
|
|
|
14
14
|
return function unload ( contextName ) {
|
|
15
15
|
const current = currentContext.name;
|
|
16
16
|
if ( current === contextName ) {
|
|
17
|
-
ev.emit (
|
|
17
|
+
ev.emit ( ERROR_EVENT_NAME, `Context '${ contextName }' can't be removed during is current active context. Change the context first` )
|
|
18
18
|
return
|
|
19
19
|
}
|
|
20
20
|
if ( !shortcuts [ contextName ] ) {
|
|
21
|
-
ev.emit (
|
|
21
|
+
ev.emit ( ERROR_EVENT_NAME, `Context '${ contextName }' does not exist` )
|
|
22
22
|
return
|
|
23
23
|
}
|
|
24
24
|
delete shortcuts [ contextName ]
|
|
@@ -38,7 +38,7 @@ function _listenDOM ( dependencies, state ) {
|
|
|
38
38
|
ev.emit ( mouseEvent, data )
|
|
39
39
|
// Reset:
|
|
40
40
|
mouseTimer = null
|
|
41
|
-
mouseIgnore = null
|
|
41
|
+
mouseIgnore = null // Timeout timer or null. Ignore mouse clicks until timer expires
|
|
42
42
|
mouseTarget = null
|
|
43
43
|
mouseDomEvent = null
|
|
44
44
|
count = 0
|
|
@@ -9,6 +9,16 @@ import _registerShortcutEvents from "./_registerShortcutEvents"
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @function pluginClick
|
|
14
|
+
* @description Plugin for mouse click shortcuts
|
|
15
|
+
* @param {Object} dependencies - Internal dependencies
|
|
16
|
+
* @param {Object} state - Library state
|
|
17
|
+
* @param {Object} [options={}] - Plugin options
|
|
18
|
+
* @param {number} [options.mouseWait=320] - Time to wait for click sequence in ms
|
|
19
|
+
* @param {string} [options.clickTarget='click'] - Data attribute name for click targets
|
|
20
|
+
* @returns {PluginAPI} Plugin API
|
|
21
|
+
*/
|
|
12
22
|
function pluginClick ( dependencies, state, options ) {
|
|
13
23
|
let
|
|
14
24
|
{ currentContext, shortcuts } = state
|
|
@@ -8,20 +8,15 @@ import _defaults from './_defaults.js'
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* @function pluginForm
|
|
13
|
+
* @description Plugin for form element shortcuts
|
|
14
|
+
* @param {Object} dependencies - Internal dependencies
|
|
15
|
+
* @param {Object} state - Library state
|
|
16
|
+
* @param {Object} [options={}] - Plugin options
|
|
17
|
+
* @returns {PluginAPI} Plugin API
|
|
18
|
+
*/
|
|
11
19
|
function pluginForm ( dependencies, state, options ) {
|
|
12
|
-
/**
|
|
13
|
-
* 'form: watch' - A function. Should return a string. Define a selection that will be watched for changes. example: 'input, select.color, textarea, #name'
|
|
14
|
-
* 'form: define' - A function that receives every watched element. Should return text value that represents the type of the
|
|
15
|
-
* element according custom specification. Types could be specific for every single form.
|
|
16
|
-
* 'form:action' - List of Callback objects.
|
|
17
|
-
* Callback definition object:
|
|
18
|
-
* {
|
|
19
|
-
* fn: function to be called
|
|
20
|
-
* type: fn should be executed on type of the element
|
|
21
|
-
* timing: 'in' | 'out' | 'instant' - when to execute the function
|
|
22
|
-
* wait: time in milliseconds to wait before executing the function again. Works only with mode 'instant'.
|
|
23
|
-
* }
|
|
24
|
-
*/
|
|
25
20
|
|
|
26
21
|
let
|
|
27
22
|
{ currentContext, shortcuts } = state
|
package/src/plugins/key/index.js
CHANGED
|
@@ -9,6 +9,16 @@ import _specialChars from './_specialChars.js'
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @function pluginKey
|
|
14
|
+
* @description Plugin for keyboard shortcuts
|
|
15
|
+
* @param {Object} dependencies - Internal dependencies
|
|
16
|
+
* @param {Object} state - Library state
|
|
17
|
+
* @param {Object} [options={}] - Plugin options
|
|
18
|
+
* @param {number} [options.keyWait=480] - Time to wait for key sequence in ms
|
|
19
|
+
* @param {function} [options.streamKeys] - Function to stream key presses
|
|
20
|
+
* @returns {PluginAPI} Plugin API
|
|
21
|
+
*/
|
|
12
22
|
function pluginKey ( dependencies, state, options={} ) {
|
|
13
23
|
let
|
|
14
24
|
{ currentContext, shortcuts, exposeShortcut } = state
|
package/test/01-general.test.js
CHANGED
|
@@ -37,7 +37,8 @@ const contextDefinition = {
|
|
|
37
37
|
' key : shift+a': [
|
|
38
38
|
() => a = true,
|
|
39
39
|
() => c = 'triggered'
|
|
40
|
-
]
|
|
40
|
+
],
|
|
41
|
+
'@shortcuts-error' : ( m ) => c = m
|
|
41
42
|
}
|
|
42
43
|
, touch : {
|
|
43
44
|
// Single click with left button
|
|
@@ -88,6 +89,64 @@ describe ( "Shortcuts", () => {
|
|
|
88
89
|
}) // afterEach
|
|
89
90
|
|
|
90
91
|
|
|
92
|
+
|
|
93
|
+
it ( 'Load and unload context', async () => {
|
|
94
|
+
let ls = short.listContexts ()
|
|
95
|
+
expect ( ls ).to.includes ( 'general' )
|
|
96
|
+
|
|
97
|
+
short.changeContext ( 'general' )
|
|
98
|
+
// Can't not to unload current active context - sends an error on @shortcuts-error
|
|
99
|
+
// @shortcuts-error is a system error event used accross the library
|
|
100
|
+
short.unload ( 'general' )
|
|
101
|
+
expect ( c ).to.be.equal ( `Context 'general' can't be removed during is current active context. Change the context first` )
|
|
102
|
+
|
|
103
|
+
// Try to change context to non-existent one
|
|
104
|
+
// Message goes to @shortcuts-error
|
|
105
|
+
short.changeContext ( 'hhm' )
|
|
106
|
+
expect ( c ).to.be.equal ( `Context 'hhm' does not exist` )
|
|
107
|
+
|
|
108
|
+
// Change to something that exists
|
|
109
|
+
short.changeContext ( 'extra' )
|
|
110
|
+
// Free to unload 'general'
|
|
111
|
+
short.unload ( 'general' )
|
|
112
|
+
ls = short.listContexts ()
|
|
113
|
+
// Unload success
|
|
114
|
+
expect ( ls ).to.not.includes ( 'general' )
|
|
115
|
+
}) // it load and unload context
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
it ( 'List enabled plugins. Disable and enable plugins', async () => {
|
|
120
|
+
expect ( short.listPlugins () ).to.be.deep.equal ( [] )
|
|
121
|
+
// Enable list of plugins
|
|
122
|
+
let myPlugins = [ pluginKey, pluginClick ]
|
|
123
|
+
myPlugins.forEach ( plugin => short.enablePlugin ( plugin ) )
|
|
124
|
+
expect ( short.listPlugins () ).to.be.deep.equal ( [ 'key', 'click' ] )
|
|
125
|
+
// Method disablePlugin require plugin name (prefix)
|
|
126
|
+
short.disablePlugin ( 'click' )
|
|
127
|
+
expect ( short.listPlugins () ).to.be.deep.equal ( [ 'key' ] )
|
|
128
|
+
// Method enablePlugin require the plugin as a function
|
|
129
|
+
short.enablePlugin ( pluginClick )
|
|
130
|
+
expect ( short.listPlugins () ).to.be.deep.equal ( [ 'key', 'click' ] )
|
|
131
|
+
}) // it list enabled plugins
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
it ( 'Unload non existing context', () => {
|
|
136
|
+
let change = false;
|
|
137
|
+
let ls = short.listContexts ()
|
|
138
|
+
short.load ( {
|
|
139
|
+
local : {
|
|
140
|
+
'click : leff-1' : () => console.log ( 'nothing' ),
|
|
141
|
+
'@shortcuts-error': () => change = true
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
short.changeContext ( 'local' )
|
|
145
|
+
short.unload ( 'unknown' )
|
|
146
|
+
expect ( change ).to.be.true
|
|
147
|
+
}) // it unload non existing context
|
|
148
|
+
|
|
149
|
+
|
|
91
150
|
|
|
92
151
|
it ( 'Emit custom event', () => {
|
|
93
152
|
// TODO: Check arguments for the custom event handlers
|
|
@@ -113,8 +172,8 @@ describe ( "Shortcuts", () => {
|
|
|
113
172
|
|
|
114
173
|
let general = short.listShortcuts ('general');
|
|
115
174
|
expect ( general ).to.be.an ( 'array' )
|
|
116
|
-
expect ( general ).to.have.lengthOf (
|
|
117
|
-
expect ( general
|
|
175
|
+
expect ( general ).to.have.lengthOf ( 2 )
|
|
176
|
+
expect ( general ).to.include ( 'KEY:A+SHIFT' )
|
|
118
177
|
|
|
119
178
|
let fail = short.listShortcuts ( 'somethingNotExisting' );
|
|
120
179
|
expect ( fail ).to.be.null
|
|
@@ -127,8 +186,8 @@ describe ( "Shortcuts", () => {
|
|
|
127
186
|
expect ( all[0] ).to.have.property ( 'context' )
|
|
128
187
|
expect ( all[0] ).to.have.property ( 'shortcuts' )
|
|
129
188
|
expect ( all[0].shortcuts ).to.be.an ( 'array' )
|
|
130
|
-
expect ( all[0].shortcuts ).to.have.lengthOf (
|
|
131
|
-
expect ( all[0].shortcuts
|
|
189
|
+
expect ( all[0].shortcuts ).to.have.lengthOf ( 2 )
|
|
190
|
+
expect ( all[0].shortcuts ).to.include ( 'KEY:A+SHIFT' )
|
|
132
191
|
expect ( all[0].context ).to.be.equal ( 'general' )
|
|
133
192
|
}) // it list shortcuts
|
|
134
193
|
|
package/test/02-key.test.js
CHANGED
|
@@ -47,9 +47,9 @@ const contextDefinition = {
|
|
|
47
47
|
// Single click with right button
|
|
48
48
|
'click: right-1': () => b = true
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
, extra : {
|
|
51
|
+
'key : p,r,o,b,a': () => b = true
|
|
52
|
+
}
|
|
53
53
|
, extend : {
|
|
54
54
|
'form : watch' : () => 'input'
|
|
55
55
|
, 'form : define' : () => 'input'
|
|
@@ -121,54 +121,152 @@ describe ( 'Key plugin', () => {
|
|
|
121
121
|
|
|
122
122
|
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
it ( 'Key sequence', async () => {
|
|
125
|
+
// enable key plugin and normalize shortcuts related to the plugin 'key'
|
|
126
126
|
short.enablePlugin ( pluginKey )
|
|
127
127
|
short.changeContext ( 'extra' )
|
|
128
128
|
// Execute key sequence: 'p,r,o,b,a'
|
|
129
129
|
await userEvent.keyboard ( 'proba' )
|
|
130
|
-
await wait (
|
|
130
|
+
await wait ( 480 )
|
|
131
131
|
await waitFor ( () => {
|
|
132
132
|
expect ( b ).to.equal ( true )
|
|
133
133
|
}, { timeout: 1000, interval: 12 })
|
|
134
|
-
|
|
134
|
+
}) // it key sequence
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
it ( 'Mute and unmute key plugin', async () => {
|
|
140
|
+
const result = [];
|
|
141
|
+
let i = 0;
|
|
142
|
+
result.push ( 'init' )
|
|
135
143
|
|
|
144
|
+
short.enablePlugin ( pluginKey )
|
|
145
|
+
short.setDependencies ({ result })
|
|
146
|
+
short.load ({
|
|
147
|
+
'local': {
|
|
148
|
+
'key: x,y,z' : ({ dependencies }) => {
|
|
149
|
+
let { result } = dependencies;
|
|
150
|
+
result.push ( i++ )
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
short.changeContext ( 'local' )
|
|
156
|
+
|
|
157
|
+
// Test 1: Plugin should work normally
|
|
158
|
+
await userEvent.keyboard ( 'xyz' )
|
|
159
|
+
await waitFor ( () => {
|
|
160
|
+
// We checking if the shortcut works
|
|
161
|
+
expect ( result ).to.have.lengthOf ( 2 )
|
|
162
|
+
expect ( i ).to.equal ( 1 )
|
|
163
|
+
}, { timeout: 1000, interval: 12 })
|
|
164
|
+
|
|
165
|
+
// Test 2: Mute plugin - should not trigger
|
|
166
|
+
short.mutePlugin ( 'key' )
|
|
167
|
+
await userEvent.keyboard ( 'xyz' )
|
|
168
|
+
await waitFor ( () => {
|
|
169
|
+
// Plugin is muted, so we don't expect any changes
|
|
170
|
+
expect ( result ).to.have.lengthOf ( 2 )
|
|
171
|
+
expect ( i ).to.equal ( 1 )
|
|
172
|
+
}, { timeout: 1000, interval: 12 })
|
|
173
|
+
|
|
174
|
+
// Test 3: Unmute plugin - should work again
|
|
175
|
+
short.unmutePlugin ( 'key' )
|
|
176
|
+
await userEvent.keyboard ( 'xyz' )
|
|
177
|
+
await waitFor ( () => {
|
|
178
|
+
// Plugin is unmuted, should work again
|
|
179
|
+
expect ( result ).to.have.lengthOf ( 3 )
|
|
180
|
+
expect ( i ).to.equal ( 2 )
|
|
181
|
+
}, { timeout: 1000, interval: 12 })
|
|
182
|
+
}) // it mute and unmute key plugin
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
it ( 'Arguments of key handler', async () => {
|
|
187
|
+
/**
|
|
188
|
+
* Need to know arguments for 'key' handler
|
|
189
|
+
* function myKeyHandler ({
|
|
190
|
+
* wait // (function). Function to pause key sequence processing
|
|
191
|
+
* , end // (function). Function to end key sequence processing
|
|
192
|
+
* , ignore // (function). Function to ignore current key in sequence
|
|
193
|
+
* , isWaiting // (function). Check if sequence is waiting
|
|
194
|
+
* , note // (string). Current context note or null
|
|
195
|
+
* , context // (string). Current context name
|
|
196
|
+
* , dependencies // (object). External dependencies object
|
|
197
|
+
* , type // (string). Event type ('key')
|
|
198
|
+
* }) {
|
|
199
|
+
* // Body of the handler. Do something...
|
|
200
|
+
* }
|
|
201
|
+
*/
|
|
202
|
+
let test = [];
|
|
203
|
+
let i = 0;
|
|
204
|
+
short.enablePlugin ( pluginKey )
|
|
205
|
+
short.setDependencies ({ test })
|
|
206
|
+
short.load ({
|
|
207
|
+
'local' : {
|
|
208
|
+
'key: a' : ({
|
|
209
|
+
wait
|
|
210
|
+
, end
|
|
211
|
+
, ignore
|
|
212
|
+
, isWaiting
|
|
213
|
+
, note
|
|
214
|
+
, context
|
|
215
|
+
, dependencies
|
|
216
|
+
, type
|
|
217
|
+
}) => {
|
|
218
|
+
const
|
|
219
|
+
{ test } = dependencies
|
|
220
|
+
, result = {
|
|
221
|
+
wait: typeof wait
|
|
222
|
+
, end: typeof end
|
|
223
|
+
, ignore: typeof ignore
|
|
224
|
+
, isWaiting: typeof isWaiting
|
|
225
|
+
, note
|
|
226
|
+
, context
|
|
227
|
+
, type
|
|
228
|
+
}
|
|
229
|
+
;
|
|
230
|
+
test.push ( result )
|
|
231
|
+
i++
|
|
232
|
+
}
|
|
233
|
+
} // local
|
|
234
|
+
})
|
|
235
|
+
short.changeContext ( 'local' )
|
|
236
|
+
await userEvent.keyboard ( 'a' )
|
|
237
|
+
await wait ( 50 ) // Wait for key processing
|
|
238
|
+
await waitFor ( () => {
|
|
239
|
+
expect ( i ).to.be.equal ( 1 )
|
|
240
|
+
let result = test[0];
|
|
241
|
+
expect ( result.wait ).to.be.equal ( 'function' )
|
|
242
|
+
expect ( result.end ).to.be.equal ( 'function' )
|
|
243
|
+
expect ( result.ignore ).to.be.equal ( 'function' )
|
|
244
|
+
expect ( result.isWaiting ).to.be.equal ( 'function' )
|
|
245
|
+
expect ( result.context ).to.be.equal ( 'local' )
|
|
246
|
+
expect ( result.type ).to.be.equal ( 'key' )
|
|
247
|
+
}, { timeout: 1000, interval: 12 })
|
|
248
|
+
}) // it arguments of key handler
|
|
136
249
|
|
|
137
250
|
|
|
138
|
-
|
|
251
|
+
it ( 'Pause and resume', async () => {
|
|
139
252
|
short.enablePlugin ( pluginKey )
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
'key: g,t,i ' : ({dependencies}) => {
|
|
148
|
-
let { result } = dependencies;
|
|
149
|
-
result.push ( i++ )
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
short.changeContext ( 'local' )
|
|
155
|
-
await userEvent.keyboard ( 'gti' )
|
|
253
|
+
expect ( b ).to.be.equal ( false )
|
|
254
|
+
short.changeContext ( 'extra' )
|
|
255
|
+
// Shortcut name will be normalized by the plugin
|
|
256
|
+
short.pause ( 'key : p,r,o,b,a' )
|
|
257
|
+
// Execute key sequence: 'p,r,o,b,a'
|
|
258
|
+
await userEvent.keyboard ( 'proba' )
|
|
259
|
+
await wait ( 500 )
|
|
156
260
|
await waitFor ( () => {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
expect ( i ).to.equal ( 1 )
|
|
160
|
-
}, { timeout: 1000, interval: 12 })
|
|
261
|
+
expect ( b ).to.be.equal ( false )
|
|
262
|
+
}, { timeout: 1000, interval: 30 })
|
|
161
263
|
|
|
162
|
-
short.
|
|
163
|
-
await userEvent.keyboard ( '
|
|
264
|
+
short.resume ( 'key : p,r,o,b,a' )
|
|
265
|
+
await userEvent.keyboard ( 'proba' )
|
|
266
|
+
await wait ( 500 )
|
|
164
267
|
await waitFor ( () => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}, { timeout: 1000, interval: 12 })
|
|
169
|
-
}) // it mute key plugin
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
268
|
+
expect ( b ).to.be.equal ( true )
|
|
269
|
+
}, { timeout: 1000, interval: 30 })
|
|
270
|
+
}) // it pause and resume
|
|
173
271
|
|
|
174
272
|
})
|