@peter.naydenov/shortcuts 3.5.1 → 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 +30 -1
- 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 -5
- 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 -3
- 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 -3
- 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 +34 -51
- 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 +26 -47
- 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 +35 -50
- 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/test/01-general.test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { beforeEach, afterEach, describe, it, expect } from 'vitest'
|
|
2
|
-
import { userEvent } from '
|
|
2
|
+
import { userEvent } from 'vitest/browser'
|
|
3
3
|
import {
|
|
4
4
|
getByLabelText,
|
|
5
5
|
getByText,
|
|
@@ -56,7 +56,7 @@ const contextDefinition = {
|
|
|
56
56
|
, 'form : define' : () => 'input'
|
|
57
57
|
, 'form : action' : () => [
|
|
58
58
|
{
|
|
59
|
-
fn : (e) =>
|
|
59
|
+
fn : (e) => e.target
|
|
60
60
|
, type : 'input'
|
|
61
61
|
, mode : 'in'
|
|
62
62
|
}
|
|
@@ -66,7 +66,7 @@ const contextDefinition = {
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
const short = shortcuts ();
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
|
|
@@ -74,7 +74,7 @@ describe ( "Shortcuts", () => {
|
|
|
74
74
|
|
|
75
75
|
beforeEach ( async () => {
|
|
76
76
|
short.load ( contextDefinition )
|
|
77
|
-
|
|
77
|
+
const container = document.createElement ( 'div' )
|
|
78
78
|
container.id = 'app'
|
|
79
79
|
document.body.appendChild ( container )
|
|
80
80
|
await html.publish ( Block, {}, 'app' )
|
|
@@ -119,42 +119,105 @@ describe ( "Shortcuts", () => {
|
|
|
119
119
|
it ( 'List enabled plugins. Disable and enable plugins', async () => {
|
|
120
120
|
expect ( short.listPlugins () ).to.be.deep.equal ( [] )
|
|
121
121
|
// Enable list of plugins
|
|
122
|
-
|
|
122
|
+
const myPlugins = [ pluginKey, pluginClick ]
|
|
123
123
|
myPlugins.forEach ( plugin => short.enablePlugin ( plugin ) )
|
|
124
124
|
expect ( short.listPlugins () ).to.be.deep.equal ( [ 'key', 'click' ] )
|
|
125
125
|
// Method disablePlugin require plugin name (prefix)
|
|
126
126
|
short.disablePlugin ( 'click' )
|
|
127
127
|
expect ( short.listPlugins () ).to.be.deep.equal ( [ 'key' ] )
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
128
|
+
// Method enablePlugin require the plugin as a function
|
|
129
|
+
short.enablePlugin ( pluginClick )
|
|
130
|
+
expect ( short.listPlugins () ).to.be.deep.equal ( [ 'key', 'click' ] )
|
|
131
|
+
|
|
132
|
+
// Try to enable non-function plugins - should do nothing
|
|
133
|
+
short.enablePlugin ( 'not a function' )
|
|
134
|
+
expect ( short.listPlugins () ).to.be.deep.equal ( [ 'key', 'click' ] )
|
|
135
|
+
short.enablePlugin ( 123 )
|
|
136
|
+
expect ( short.listPlugins () ).to.be.deep.equal ( [ 'key', 'click' ] )
|
|
137
|
+
short.enablePlugin ( {} )
|
|
138
|
+
expect ( short.listPlugins () ).to.be.deep.equal ( [ 'key', 'click' ] )
|
|
139
|
+
|
|
140
|
+
// Try to disable a plugin that is not enabled - should do nothing
|
|
141
|
+
short.disablePlugin ( 'scroll' )
|
|
142
|
+
expect ( short.listPlugins () ).to.be.deep.equal ( [ 'key', 'click' ] )
|
|
143
|
+
}) // it list enabled plugins
|
|
132
144
|
|
|
133
145
|
|
|
134
146
|
|
|
135
147
|
it ( 'Unload non existing context', () => {
|
|
136
148
|
let change = false;
|
|
137
|
-
|
|
149
|
+
const ls = short.listContexts ()
|
|
138
150
|
short.load ( {
|
|
139
151
|
local : {
|
|
140
|
-
'click : leff-1' : () =>
|
|
152
|
+
'click : leff-1' : () => 'nothing',
|
|
141
153
|
'@shortcuts-error': () => change = true
|
|
142
154
|
}
|
|
143
155
|
})
|
|
144
156
|
short.changeContext ( 'local' )
|
|
145
157
|
short.unload ( 'unknown' )
|
|
146
158
|
expect ( change ).to.be.true
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
159
|
+
}) // it unload non existing context
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
it ( 'Change to same context', () => {
|
|
164
|
+
short.changeContext ( 'general' )
|
|
165
|
+
expect ( short.getContext() ).to.be.equal ( 'general' )
|
|
166
|
+
// Changing to the same context should do nothing
|
|
167
|
+
short.changeContext ( 'general' )
|
|
168
|
+
expect ( short.getContext() ).to.be.equal ( 'general' )
|
|
169
|
+
// No error should be emitted
|
|
170
|
+
expect ( c ).to.be.null
|
|
171
|
+
}) // it change to same context
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
it ( 'Switch off all shortcuts', () => {
|
|
176
|
+
short.enablePlugin ( pluginKey )
|
|
177
|
+
short.changeContext ( 'general' )
|
|
178
|
+
expect ( short.getContext() ).to.be.equal ( 'general' )
|
|
179
|
+
|
|
180
|
+
// Switch off all shortcuts
|
|
181
|
+
short.changeContext ( false )
|
|
182
|
+
expect ( short.getContext() ).to.be.null
|
|
183
|
+
|
|
184
|
+
// Try to trigger a shortcut - should not work
|
|
185
|
+
// But since it's key plugin, hard to test without DOM events
|
|
186
|
+
// Just check context is null
|
|
187
|
+
expect ( short.getContext() ).to.be.null
|
|
188
|
+
}) // it switch off all shortcuts
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
it ( 'Set note with invalid types', () => {
|
|
193
|
+
short.changeContext ( 'general' )
|
|
194
|
+
// Set valid note
|
|
195
|
+
short.setNote ( 'valid note' )
|
|
196
|
+
expect ( short.getNote() ).to.be.equal ( 'valid note' )
|
|
197
|
+
|
|
198
|
+
// Try invalid types - should not change
|
|
199
|
+
short.setNote ( 123 )
|
|
200
|
+
expect ( short.getNote() ).to.be.equal ( 'valid note' )
|
|
201
|
+
|
|
202
|
+
short.setNote ( {} )
|
|
203
|
+
expect ( short.getNote() ).to.be.equal ( 'valid note' )
|
|
204
|
+
|
|
205
|
+
short.setNote ( [] )
|
|
206
|
+
expect ( short.getNote() ).to.be.equal ( 'valid note' )
|
|
207
|
+
|
|
208
|
+
// Valid null should work
|
|
209
|
+
short.setNote ( null )
|
|
210
|
+
expect ( short.getNote() ).to.be.null
|
|
211
|
+
}) // it set note with invalid types
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
it ( 'Emit custom event', () => {
|
|
153
216
|
let result = null;
|
|
154
217
|
short.enablePlugin ( pluginClick )
|
|
155
218
|
const myAllContext = {
|
|
156
219
|
myAll: {
|
|
157
|
-
'click : leff-1' : () =>
|
|
220
|
+
'click : leff-1' : () => 'nothing'
|
|
158
221
|
, 'yo' : ({msg}) => result = msg
|
|
159
222
|
}}
|
|
160
223
|
short.load ( myAllContext )
|
|
@@ -170,15 +233,21 @@ describe ( "Shortcuts", () => {
|
|
|
170
233
|
it ( 'List shortcuts', () => {
|
|
171
234
|
short.enablePlugin ( pluginKey )
|
|
172
235
|
|
|
173
|
-
|
|
236
|
+
const general = short.listShortcuts ('general');
|
|
174
237
|
expect ( general ).to.be.an ( 'array' )
|
|
175
238
|
expect ( general ).to.have.lengthOf ( 2 )
|
|
176
239
|
expect ( general ).to.include ( 'KEY:A+SHIFT' )
|
|
177
240
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
241
|
+
const fail = short.listShortcuts ( 'somethingNotExisting' );
|
|
242
|
+
expect ( fail ).to.be.null
|
|
243
|
+
|
|
244
|
+
// Edge cases for invalid context types
|
|
245
|
+
expect ( short.listShortcuts ( 123 ) ).to.be.null
|
|
246
|
+
expect ( short.listShortcuts ( {} ) ).to.be.null
|
|
247
|
+
expect ( short.listShortcuts ( [] ) ).to.be.null
|
|
248
|
+
expect ( short.listShortcuts ( undefined ) ).to.be.an ( 'array' ) // undefined == null, so lists all
|
|
249
|
+
|
|
250
|
+
const all = short.listShortcuts ();
|
|
182
251
|
expect ( all ).to.be.an ( 'array' )
|
|
183
252
|
|
|
184
253
|
expect ( all ).to.have.lengthOf ( 4 )
|
package/test/02-key.test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { beforeEach, afterEach, describe, it, expect } from 'vitest'
|
|
2
|
-
import { userEvent } from '
|
|
2
|
+
import { userEvent } from 'vitest/browser'
|
|
3
3
|
import {
|
|
4
4
|
getByLabelText,
|
|
5
5
|
getByText,
|
|
@@ -30,6 +30,7 @@ let
|
|
|
30
30
|
a = false
|
|
31
31
|
, b = false
|
|
32
32
|
, c = null
|
|
33
|
+
, container
|
|
33
34
|
;
|
|
34
35
|
|
|
35
36
|
const contextDefinition = {
|
|
@@ -55,7 +56,7 @@ const contextDefinition = {
|
|
|
55
56
|
, 'form : define' : () => 'input'
|
|
56
57
|
, 'form : action' : () => [
|
|
57
58
|
{
|
|
58
|
-
fn : (e) =>
|
|
59
|
+
fn : (e) => e.target
|
|
59
60
|
, type : 'input'
|
|
60
61
|
, mode : 'in'
|
|
61
62
|
}
|
|
@@ -63,7 +64,7 @@ const contextDefinition = {
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
const short = shortcuts ();
|
|
67
68
|
|
|
68
69
|
|
|
69
70
|
|
|
@@ -71,26 +72,30 @@ let short = shortcuts ();
|
|
|
71
72
|
|
|
72
73
|
describe ( 'Key plugin', () => {
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
75
|
+
beforeEach ( async () => {
|
|
76
|
+
short.load ( contextDefinition )
|
|
77
|
+
container = document.createElement ( 'div' )
|
|
78
|
+
container.id = 'app'
|
|
79
|
+
document.body.appendChild ( container )
|
|
80
|
+
await html.publish ( Block, {}, 'app' )
|
|
81
|
+
a = false, b = false
|
|
82
|
+
}) // beforeEach
|
|
82
83
|
|
|
83
84
|
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
afterEach ( async () => {
|
|
87
|
+
short.reset ()
|
|
88
|
+
short.disablePlugin ( 'key' )
|
|
89
|
+
if (container && document.body.contains(container)) {
|
|
90
|
+
document.body.removeChild(container);
|
|
91
|
+
}
|
|
92
|
+
a = false, b = false, c = null;
|
|
93
|
+
}) // afterEach
|
|
89
94
|
|
|
90
95
|
|
|
91
96
|
|
|
92
97
|
it ( 'No "key" plugin installed', () => {
|
|
93
|
-
|
|
98
|
+
const r = short.listShortcuts ('general');
|
|
94
99
|
// Shortcut name is the same as it was set
|
|
95
100
|
expect ( r[0]).to.equal ( ' key : shift+a' )
|
|
96
101
|
}) // it no 'key' plugin installed
|
|
@@ -146,7 +151,7 @@ describe ( 'Key plugin', () => {
|
|
|
146
151
|
short.load ({
|
|
147
152
|
'local': {
|
|
148
153
|
'key: x,y,z' : ({ dependencies }) => {
|
|
149
|
-
|
|
154
|
+
const { result } = dependencies;
|
|
150
155
|
result.push ( i++ )
|
|
151
156
|
}
|
|
152
157
|
}
|
|
@@ -156,6 +161,7 @@ describe ( 'Key plugin', () => {
|
|
|
156
161
|
|
|
157
162
|
// Test 1: Plugin should work normally
|
|
158
163
|
await userEvent.keyboard ( 'xyz' )
|
|
164
|
+
await wait ( 480 )
|
|
159
165
|
await waitFor ( () => {
|
|
160
166
|
// We checking if the shortcut works
|
|
161
167
|
expect ( result ).to.have.lengthOf ( 2 )
|
|
@@ -171,9 +177,11 @@ describe ( 'Key plugin', () => {
|
|
|
171
177
|
expect ( i ).to.equal ( 1 )
|
|
172
178
|
}, { timeout: 1000, interval: 12 })
|
|
173
179
|
|
|
180
|
+
|
|
174
181
|
// Test 3: Unmute plugin - should work again
|
|
175
182
|
short.unmutePlugin ( 'key' )
|
|
176
183
|
await userEvent.keyboard ( 'xyz' )
|
|
184
|
+
await wait ( 480 )
|
|
177
185
|
await waitFor ( () => {
|
|
178
186
|
// Plugin is unmuted, should work again
|
|
179
187
|
expect ( result ).to.have.lengthOf ( 3 )
|
|
@@ -199,7 +207,7 @@ describe ( 'Key plugin', () => {
|
|
|
199
207
|
* // Body of the handler. Do something...
|
|
200
208
|
* }
|
|
201
209
|
*/
|
|
202
|
-
|
|
210
|
+
const test = [];
|
|
203
211
|
let i = 0;
|
|
204
212
|
short.enablePlugin ( pluginKey )
|
|
205
213
|
short.setDependencies ({ test })
|
|
@@ -237,7 +245,7 @@ describe ( 'Key plugin', () => {
|
|
|
237
245
|
await wait ( 50 ) // Wait for key processing
|
|
238
246
|
await waitFor ( () => {
|
|
239
247
|
expect ( i ).to.be.equal ( 1 )
|
|
240
|
-
|
|
248
|
+
const result = test[0];
|
|
241
249
|
expect ( result.wait ).to.be.equal ( 'function' )
|
|
242
250
|
expect ( result.end ).to.be.equal ( 'function' )
|
|
243
251
|
expect ( result.ignore ).to.be.equal ( 'function' )
|
|
@@ -245,28 +253,221 @@ describe ( 'Key plugin', () => {
|
|
|
245
253
|
expect ( result.context ).to.be.equal ( 'local' )
|
|
246
254
|
expect ( result.type ).to.be.equal ( 'key' )
|
|
247
255
|
}, { timeout: 1000, interval: 12 })
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
256
|
+
}) // it arguments of key handler
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
it ( 'Pause and resume', async () => {
|
|
261
|
+
short.enablePlugin ( pluginKey )
|
|
262
|
+
expect ( b ).to.be.equal ( false )
|
|
263
|
+
short.changeContext ( 'extra' )
|
|
264
|
+
// Shortcut name will be normalized by the plugin
|
|
265
|
+
short.pause ( 'key : p,r,o,b,a' )
|
|
266
|
+
// Execute key sequence: 'p,r,o,b,a'
|
|
267
|
+
await userEvent.keyboard ( 'proba' )
|
|
268
|
+
await wait ( 500 )
|
|
269
|
+
await waitFor ( () => {
|
|
270
|
+
expect ( b ).to.be.equal ( false )
|
|
271
|
+
}, { timeout: 1000, interval: 30 })
|
|
272
|
+
|
|
273
|
+
short.resume ( 'key : p,r,o,b,a' )
|
|
274
|
+
await userEvent.keyboard ( 'proba' )
|
|
275
|
+
await wait ( 500 )
|
|
276
|
+
await waitFor ( () => {
|
|
277
|
+
expect ( b ).to.be.equal ( true )
|
|
262
278
|
}, { timeout: 1000, interval: 30 })
|
|
263
|
-
|
|
264
|
-
short.resume ( 'key : p,r,o,b,a' )
|
|
265
|
-
await userEvent.keyboard ( 'proba' )
|
|
266
|
-
await wait ( 500 )
|
|
267
|
-
await waitFor ( () => {
|
|
268
|
-
expect ( b ).to.be.equal ( true )
|
|
269
|
-
}, { timeout: 1000, interval: 30 })
|
|
270
279
|
}) // it pause and resume
|
|
271
280
|
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
it ( 'Wait and ignore in key sequence', async () => {
|
|
284
|
+
const emitted = [];
|
|
285
|
+
short.setDependencies ({ emitted })
|
|
286
|
+
short.load ({
|
|
287
|
+
'waittest' : {
|
|
288
|
+
'key: a' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
289
|
+
if ( !isWaiting () ) {
|
|
290
|
+
// Switch sequence timer off and wait for edit the sequence
|
|
291
|
+
wait ()
|
|
292
|
+
ignore ()
|
|
293
|
+
return
|
|
294
|
+
}
|
|
295
|
+
// Sequence was ended. Proceed
|
|
296
|
+
dependencies.emitted.push ( 'a' )
|
|
297
|
+
end ()
|
|
298
|
+
},
|
|
299
|
+
'key: b' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
300
|
+
dependencies.emitted.push ( 'b' )
|
|
301
|
+
},
|
|
302
|
+
'key: r' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
303
|
+
// Ignore 'r' in the sequence
|
|
304
|
+
ignore ()
|
|
305
|
+
},
|
|
306
|
+
'key: b,a' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
307
|
+
dependencies.emitted.push ( 'b,a' )
|
|
308
|
+
},
|
|
309
|
+
'key: esc' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
310
|
+
// Ignore 'escape in the sequence'
|
|
311
|
+
ignore ()
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
short.enablePlugin ( pluginKey )
|
|
317
|
+
short.changeContext ( 'waittest' )
|
|
318
|
+
// Press 'a' - should call handler, set wait and ignore
|
|
319
|
+
await userEvent.keyboard ( 'a' )
|
|
320
|
+
await wait ( 500 )
|
|
321
|
+
|
|
322
|
+
await userEvent.keyboard ('{Escape}')
|
|
323
|
+
// Then press 'b' - since waiting, should emit 'b'
|
|
324
|
+
await userEvent.keyboard ( 'b' )
|
|
325
|
+
// Then press 'r' - will ignore 'r' in sequence because of use of 'ignore' in a handler
|
|
326
|
+
await userEvent.keyboard ( 'r' )
|
|
327
|
+
await userEvent.keyboard ( 'a' )
|
|
328
|
+
await waitFor ( () => {
|
|
329
|
+
expect ( emitted ).to.deep.equal ( [ 'b', 'a', 'b,a'] )
|
|
330
|
+
}, { timeout: 1000, interval: 12 })
|
|
331
|
+
}) // it wait and ignore in key sequence
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
it ( 'Ignore keys after sequence', async () => {
|
|
336
|
+
const emitted = [];
|
|
337
|
+
short.setDependencies ({ emitted })
|
|
338
|
+
short.load ({
|
|
339
|
+
'waittest' : {
|
|
340
|
+
'key: a,b,esc' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
341
|
+
dependencies.emitted.push ( 'a,b,esc' )
|
|
342
|
+
},
|
|
343
|
+
'key: r' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
344
|
+
dependencies.emitted.push ( 'r' )
|
|
345
|
+
},
|
|
346
|
+
'key : s' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
347
|
+
dependencies.emitted.push ( 's' )
|
|
348
|
+
},
|
|
349
|
+
'key: esc' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
350
|
+
dependencies.emitted.push ( 'esc' )
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
short.enablePlugin ( pluginKey )
|
|
357
|
+
short.changeContext ( 'waittest' )
|
|
358
|
+
|
|
359
|
+
await userEvent.keyboard ( 'a' )
|
|
360
|
+
await userEvent.keyboard ( 'b' )
|
|
361
|
+
await userEvent.keyboard ( '{Escape}' )
|
|
362
|
+
|
|
363
|
+
// Will be ignored
|
|
364
|
+
await userEvent.keyboard ( 'r' )
|
|
365
|
+
await userEvent.keyboard ( 'r' )
|
|
366
|
+
await userEvent.keyboard ( '{Escape}' )
|
|
367
|
+
|
|
368
|
+
// Wait above keyWait time to activate sequence again
|
|
369
|
+
await wait ( 500 )
|
|
370
|
+
// New sequence - will emit 'key: s'
|
|
371
|
+
await userEvent.keyboard ( 's' )
|
|
372
|
+
await wait ( 500 )
|
|
373
|
+
await waitFor ( () => {
|
|
374
|
+
expect ( emitted ).to.deep.equal ( [ 'a,b,esc', 's' ] )
|
|
375
|
+
}, { timeout: 1000, interval: 12 })
|
|
376
|
+
}) // it ignore keys after sequence
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
it ( 'Stop a plugin durring a sequence', async () => {
|
|
381
|
+
const emitted = [];
|
|
382
|
+
short.setDependencies ({ emitted })
|
|
383
|
+
short.load ({
|
|
384
|
+
'waittest' : {
|
|
385
|
+
'key: a,b,esc' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
386
|
+
dependencies.emitted.push ( 'a,b,esc' )
|
|
387
|
+
},
|
|
388
|
+
'key: r' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
389
|
+
dependencies.emitted.push ( 'r' )
|
|
390
|
+
},
|
|
391
|
+
'key : s' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
392
|
+
dependencies.emitted.push ( 's' )
|
|
393
|
+
},
|
|
394
|
+
'key: esc' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
395
|
+
dependencies.emitted.push ( 'esc' )
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
})
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
short.enablePlugin ( pluginKey )
|
|
402
|
+
short.changeContext ( 'waittest' )
|
|
403
|
+
|
|
404
|
+
await userEvent.keyboard ( 'a' )
|
|
405
|
+
await userEvent.keyboard ( 'b' )
|
|
406
|
+
short.disablePlugin ( 'key' )
|
|
407
|
+
await userEvent.keyboard ( '{Escape}' )
|
|
408
|
+
expect ( emitted ).to.deep.equal ( [] )
|
|
409
|
+
}) // it stop a plugin durring a sequence
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
it ( 'Key setup event', async () => {
|
|
414
|
+
const emitted = [];
|
|
415
|
+
short.setDependencies ({ emitted })
|
|
416
|
+
short.load ({
|
|
417
|
+
'local' : {
|
|
418
|
+
'key: a' : ({ wait, ignore, dependencies, isWaiting, type, end }) => {
|
|
419
|
+
dependencies.emitted.push ( 'a' )
|
|
420
|
+
}
|
|
421
|
+
, 'key: setup' : ({ dependencies, defaults }) => {
|
|
422
|
+
dependencies.emitted.push ( 'setup' )
|
|
423
|
+
expect ( defaults.keyWait ).to.equal ( 480 )
|
|
424
|
+
// Setup should return an object with required param changes
|
|
425
|
+
// It's not possible to test...
|
|
426
|
+
return { keyWait: 100 }
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
})
|
|
430
|
+
|
|
431
|
+
short.enablePlugin ( pluginKey )
|
|
432
|
+
short.changeContext ( 'local' )
|
|
433
|
+
const start = performance.now ()
|
|
434
|
+
await userEvent.keyboard ( 'a' )
|
|
435
|
+
await wait ( 150 )
|
|
436
|
+
await userEvent.keyboard ( 'a' )
|
|
437
|
+
await waitFor ( () => {
|
|
438
|
+
const end = performance.now ()
|
|
439
|
+
expect ( end - start ).to.be.lessThan ( 200 )
|
|
440
|
+
expect ( emitted ).to.deep.equal ( [ 'setup', 'a', 'a' ] )
|
|
441
|
+
}, { timeout: 1000, interval: 12 })
|
|
442
|
+
}) // it key setup
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
it ( 'Extra parameters to plugin options', async () => {
|
|
447
|
+
short.enablePlugin ( pluginKey )
|
|
448
|
+
const emit = [];
|
|
449
|
+
const setupContext = {
|
|
450
|
+
'key:setup' : () => {
|
|
451
|
+
emit.push ( 'setup' )
|
|
452
|
+
return { keyWait: 100, emit }
|
|
453
|
+
},
|
|
454
|
+
'key:a' : ({options}) => {
|
|
455
|
+
expect ( options.keyWait ).to.equal ( 100 )
|
|
456
|
+
options.emit.push ( 'a' )
|
|
457
|
+
}
|
|
458
|
+
} // setupContext
|
|
459
|
+
|
|
460
|
+
short.load ({ setupContext })
|
|
461
|
+
short.changeContext ( 'setupContext' )
|
|
462
|
+
|
|
463
|
+
// Setup event execution is on change context:
|
|
464
|
+
expect ( emit[0] ).to.equal ( 'setup' )
|
|
465
|
+
|
|
466
|
+
// Click and measure time
|
|
467
|
+
await userEvent.keyboard ( 'a')
|
|
468
|
+
await waitFor ( () => {
|
|
469
|
+
expect ( emit ).to.deep.equal ( [ 'setup', 'a' ] )
|
|
470
|
+
}, { timeout: 1000, interval: 12 })
|
|
471
|
+
}) // it extra parameters to plugin options
|
|
472
|
+
|
|
272
473
|
})
|