@peter.naydenov/shortcuts 3.3.0 → 3.4.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 +54 -2
- package/dist/shortcuts.cjs +1 -1
- package/dist/shortcuts.esm.mjs +1 -1
- package/dist/shortcuts.umd.js +1 -1
- package/index.html +1 -0
- package/jsconfig.json +10 -0
- package/package.json +16 -10
- package/src/main.js +26 -10
- package/src/methods/_readShortcutWithPlugins.js +2 -1
- package/src/methods/listShortcuts.js +2 -1
- package/src/methods/load.js +6 -4
- package/src/plugins/click/_listenDOM.js +12 -2
- package/src/plugins/click/index.js +6 -6
- package/src/plugins/form/index.js +4 -4
- package/src/plugins/key/_listenDOM.js +16 -2
- package/src/plugins/key/_readKeyEvent.js +4 -2
- package/src/plugins/key/index.js +1 -5
- package/test/01-general.test.js +97 -249
- package/test/02-key.test.js +174 -0
- package/test/03-click.test.js +320 -0
- package/test/04-form.test.js +90 -0
- package/test-helpers/setup.js +18 -0
- package/test-helpers/wait.js +8 -0
- package/vitest.config.js +21 -0
- package/vitest-example/HelloWorld.js +0 -9
- package/vitest-example/HelloWorld.test.js +0 -11
- package/vitest.workspace.js +0 -19
- /package/{test-components → test-helpers}/Block.jsx +0 -0
- /package/{test-components → test-helpers}/style.css +0 -0
|
@@ -4,6 +4,7 @@ function _readKeyEvent ( event, _specialChars ) {
|
|
|
4
4
|
let
|
|
5
5
|
{ shiftKey, altKey, ctrlKey } = event
|
|
6
6
|
, falseKeys = [ 'ControlLeft','ControlRight', 'ShiftLeft', 'ShiftRight', 'AltLeft', 'AltRight', 'Meta' ]
|
|
7
|
+
, _sp = _specialChars ()
|
|
7
8
|
, key = event.code
|
|
8
9
|
.replace ( 'Key', '' )
|
|
9
10
|
.replace('Digit','')
|
|
@@ -14,8 +15,9 @@ function _readKeyEvent ( event, _specialChars ) {
|
|
|
14
15
|
if ( shiftKey ) res.push ( 'SHIFT' )
|
|
15
16
|
if ( altKey ) res.push ( 'ALT' )
|
|
16
17
|
|
|
17
|
-
if (
|
|
18
|
-
else if (
|
|
18
|
+
if ( _sp.hasOwnProperty ( key ) ) res.push ( _sp[key].toUpperCase () )
|
|
19
|
+
else if ( !falseKeys.includes(key) ) res.push ( key.toUpperCase () )
|
|
20
|
+
|
|
19
21
|
return res.sort ()
|
|
20
22
|
} // _readKeyEvent func.
|
|
21
23
|
|
package/src/plugins/key/index.js
CHANGED
|
@@ -59,11 +59,7 @@ function pluginKey ( dependencies, state, options={} ) {
|
|
|
59
59
|
}
|
|
60
60
|
, mute : () => keysListener.stop ()
|
|
61
61
|
, unmute : () => keysListener.start ()
|
|
62
|
-
, destroy : () =>
|
|
63
|
-
keysListener.stop ()
|
|
64
|
-
pluginState = null
|
|
65
|
-
pluginAPI = null
|
|
66
|
-
}
|
|
62
|
+
, destroy : () => keysListener.stop ()
|
|
67
63
|
};
|
|
68
64
|
Object.freeze ( pluginAPI )
|
|
69
65
|
return pluginAPI
|
package/test/01-general.test.js
CHANGED
|
@@ -1,37 +1,51 @@
|
|
|
1
|
-
import { beforeEach, describe, it,
|
|
1
|
+
import { beforeEach, afterEach, describe, it, expect } from 'vitest'
|
|
2
2
|
import { userEvent } from '@vitest/browser/context'
|
|
3
|
+
import {
|
|
4
|
+
getByLabelText,
|
|
5
|
+
getByText,
|
|
6
|
+
getByTestId,
|
|
7
|
+
queryByTestId,
|
|
8
|
+
// Tip: all queries are also exposed on an object
|
|
9
|
+
// called "queries" which you could import here as well
|
|
10
|
+
waitFor
|
|
11
|
+
} from '@testing-library/dom'
|
|
12
|
+
|
|
3
13
|
|
|
4
|
-
import Block from '../test-components/Block.jsx'
|
|
5
|
-
import VisaulController from '@peter.naydenov/visual-controller-for-react'
|
|
6
|
-
import '../test-components/style.css'
|
|
7
14
|
|
|
15
|
+
import '../test-helpers/style.css'
|
|
16
|
+
import Block from '../test-helpers/Block.jsx'
|
|
17
|
+
import VisaulController from '@peter.naydenov/visual-controller-for-react'
|
|
18
|
+
import wait from '../test-helpers/wait.js'
|
|
8
19
|
import {
|
|
9
20
|
pluginClick,
|
|
10
21
|
pluginKey
|
|
11
22
|
, pluginForm
|
|
12
23
|
, shortcuts
|
|
13
24
|
} from '../src/main.js'
|
|
14
|
-
|
|
25
|
+
|
|
15
26
|
|
|
16
27
|
import askForPromise from 'ask-for-promise'
|
|
17
28
|
|
|
18
29
|
const html = new VisaulController ();
|
|
19
|
-
|
|
20
30
|
let
|
|
21
31
|
a = false
|
|
22
32
|
, b = false
|
|
33
|
+
, c = null
|
|
23
34
|
;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
function wait (ms) {
|
|
27
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const short = shortcuts ({onShortcut : ( shortcut, {context,note,type}) => console.log (shortcut, context, note, type) });
|
|
31
|
-
|
|
32
|
-
short.load ({
|
|
35
|
+
const contextDefinition = {
|
|
33
36
|
general : {
|
|
34
|
-
' key : shift+a': [
|
|
37
|
+
' key : shift+a': [
|
|
38
|
+
() => a = true,
|
|
39
|
+
() => c = 'triggered'
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
, touch : {
|
|
43
|
+
// Single click with left button
|
|
44
|
+
'click: left-1': () => b = true,
|
|
45
|
+
// Double click with left button
|
|
46
|
+
'click: left-2': () => b = true,
|
|
47
|
+
// Single click with right button
|
|
48
|
+
'click: right-1': () => b = true
|
|
35
49
|
}
|
|
36
50
|
, extra : {
|
|
37
51
|
'key : p,r,o,b,a': () => b = true
|
|
@@ -47,253 +61,87 @@ short.load ({
|
|
|
47
61
|
}
|
|
48
62
|
]
|
|
49
63
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
beforeEach ( () => {
|
|
53
|
-
let container = document.createElement ( 'div' )
|
|
54
|
-
container.id = 'app'
|
|
55
|
-
document.body.appendChild ( container )
|
|
56
|
-
html.publish ( Block, {}, 'app' )
|
|
57
|
-
a = false, b = false
|
|
58
|
-
}) // beforeEach
|
|
64
|
+
}
|
|
59
65
|
|
|
60
66
|
|
|
67
|
+
|
|
68
|
+
let short = shortcuts ();
|
|
61
69
|
|
|
62
70
|
|
|
63
71
|
|
|
64
72
|
describe ( "Shortcuts", () => {
|
|
65
73
|
|
|
74
|
+
beforeEach ( async () => {
|
|
75
|
+
short.load ( contextDefinition )
|
|
76
|
+
let container = document.createElement ( 'div' )
|
|
77
|
+
container.id = 'app'
|
|
78
|
+
document.body.appendChild ( container )
|
|
79
|
+
await html.publish ( Block, {}, 'app' )
|
|
80
|
+
a = false, b = false
|
|
81
|
+
}) // beforeEach
|
|
66
82
|
|
|
67
83
|
|
|
68
|
-
test ( 'Shortcut if no plugin installed', () => {
|
|
69
|
-
let res = new Promise ( (resolve,reject) => {
|
|
70
|
-
short.changeContext ( 'general' )
|
|
71
|
-
let r = short.listShortcuts ('general')
|
|
72
|
-
expect ( r[0]).to.equal ( ' key : shift+a' ) // Shortcut name is the same as it was set
|
|
73
|
-
resolve ('success')
|
|
74
|
-
})
|
|
75
|
-
return res
|
|
76
|
-
}) // test no plugin installed
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
test ( 'Key plugin, no context selected', () => {
|
|
81
|
-
const res = new Promise ( ( resolve ) => {
|
|
82
|
-
short.enablePlugin ( pluginKey )
|
|
83
|
-
const r = short.listShortcuts ( 'general' )
|
|
84
|
-
expect ( r[0] ).to.equal ( 'KEY:A+SHIFT' ) // Shortcut name is recognized by plugin and is normalized
|
|
85
|
-
resolve ('success')
|
|
86
|
-
})
|
|
87
|
-
return res
|
|
88
|
-
}) // test key plugin installed, no context selected
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
test ( 'Key plugin with context selected', () => {
|
|
93
|
-
const res = new Promise ( (resolve) => {
|
|
94
|
-
short.enablePlugin ( pluginKey )
|
|
95
|
-
short.changeContext ( 'general' )
|
|
96
|
-
const r = short.listShortcuts ('general')
|
|
97
|
-
expect ( r[0] ).to.equal ( 'KEY:A+SHIFT' ) // Shortcut name is recognized by plugin and is normalized
|
|
98
|
-
resolve ( 'success' )
|
|
99
|
-
})
|
|
100
|
-
return res
|
|
101
|
-
}) // test key plugin installed with context selected
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
test ( 'Simple shortcut', () => {
|
|
106
|
-
const res = new Promise ( (resolve) => {
|
|
107
|
-
short.enablePlugin ( pluginKey )
|
|
108
|
-
short.changeContext ()
|
|
109
|
-
short.changeContext ( 'general' )
|
|
110
|
-
userEvent.keyboard ( '{Shift>}a</Shift>' )
|
|
111
|
-
expect ( a ).to.be.false
|
|
112
|
-
wait ( 1000 )
|
|
113
|
-
.then ( () => { // Default wait sequence timeout is 480 ms, but maxSequence is 1, so we don't need to wait for timeout
|
|
114
|
-
expect ( a ).to.be.true
|
|
115
|
-
resolve ( 'success' )
|
|
116
|
-
})
|
|
117
|
-
})
|
|
118
|
-
return res
|
|
119
|
-
}) // test simple shortcut
|
|
120
84
|
|
|
85
|
+
afterEach ( async () => {
|
|
86
|
+
short.reset ()
|
|
87
|
+
a = false, b = false, c = null;
|
|
88
|
+
}) // afterEach
|
|
121
89
|
|
|
122
90
|
|
|
123
|
-
test ( 'Call sequence shortcut', async () => {
|
|
124
|
-
let res = new Promise ( async (resolve) => {
|
|
125
|
-
b = false
|
|
126
|
-
short.enablePlugin ( pluginKey )
|
|
127
|
-
short.changeContext ()
|
|
128
|
-
short.changeContext ( 'extra' )
|
|
129
|
-
await userEvent.keyboard ( 'proba' )
|
|
130
|
-
expect ( b ).to.be.true
|
|
131
|
-
resolve ( 'success' )
|
|
132
|
-
})
|
|
133
|
-
return res
|
|
134
|
-
}) // test call sequence shortcut
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
test ( 'Single mouse click', done => {
|
|
139
|
-
const res = new Promise ( async (resolve) => {
|
|
140
|
-
expect ( a ).to.be.false
|
|
141
|
-
expect ( b ).to.be.false
|
|
142
|
-
short.enablePlugin ( pluginClick )
|
|
143
|
-
|
|
144
|
-
short.load ({ 'extra' : {
|
|
145
|
-
' cLIck : left - 1 ' : () => a = true // Check if spaces, letter case can break the shortcut recognition
|
|
146
|
-
}
|
|
147
|
-
})
|
|
148
|
-
short.changeContext ()
|
|
149
|
-
short.changeContext ( 'extra' )
|
|
150
|
-
wait ( 100 )
|
|
151
|
-
.then ( async () => {
|
|
152
|
-
// Default wait mouse timeout is 320 ms, but maxClicks is 1, so we don't need to wait for timeout
|
|
153
|
-
let loc = document.querySelector('#rspan') || false
|
|
154
|
-
if ( loc ) await userEvent.click ( loc )
|
|
155
|
-
expect ( a ).to.be.true
|
|
156
|
-
resolve ( 'success' )
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
})
|
|
161
|
-
return res
|
|
162
|
-
}) // test single mouse click
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
test ( 'Double mouse click', () => {
|
|
167
|
-
let res = new Promise ( async (resolve) => {
|
|
168
|
-
expect ( a ).to.be.false
|
|
169
|
-
expect ( b ).to.be.false
|
|
170
|
-
|
|
171
|
-
short.enablePlugin ( pluginClick )
|
|
172
|
-
short.changeContext ( 'extra' )
|
|
173
|
-
short.load ({ // load will restart the selected context
|
|
174
|
-
'extra' : { // load will overwrite existing 'extra' context definition
|
|
175
|
-
'click: left-2' : () => a = true
|
|
176
|
-
}
|
|
177
|
-
})
|
|
178
|
-
wait ( 350 )
|
|
179
|
-
.then ( async () => { // Default wait mouse timeout is 320 ms
|
|
180
|
-
let loc = document.querySelector ( '#rspan' ) || false
|
|
181
|
-
// Third click is ignored. Max clicks according definition is 2.
|
|
182
|
-
if ( loc ) await userEvent.tripleClick ( loc )
|
|
183
|
-
expect ( a ).to.be.true
|
|
184
|
-
resolve ( 'success' )
|
|
185
|
-
})
|
|
186
|
-
})
|
|
187
|
-
return res
|
|
188
|
-
}) // test double mouse click
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
test ( 'Dependencies on shortcuts', () => {
|
|
193
|
-
const res = new Promise ( async (resolve) => {
|
|
194
|
-
const task = askForPromise ();
|
|
195
|
-
expect ( a ).to.be.false
|
|
196
|
-
expect ( b ).to.be.false
|
|
197
|
-
|
|
198
|
-
short.enablePlugin ( pluginClick )
|
|
199
|
-
short.setDependencies ({ task })
|
|
200
|
-
|
|
201
|
-
short.load ({
|
|
202
|
-
'extra' : { // load will overwrite existing 'extra' context definition
|
|
203
|
-
'click: left-1' : ({dependencies}) => {
|
|
204
|
-
const { task } = dependencies;
|
|
205
|
-
expect ( task ).to.have.property ( 'done' )
|
|
206
|
-
expect ( task ).to.have.property ( 'promise' )
|
|
207
|
-
a = true
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}) // load will restart the selected context
|
|
211
|
-
short.changeContext ( 'extra' )
|
|
212
|
-
wait ( 350 ) // Default wait mouse timeout is 320 ms
|
|
213
|
-
.then ( async () => {
|
|
214
|
-
let loc = document.querySelector ( '#rspan' ) || false
|
|
215
|
-
if ( loc ) await userEvent.click ( loc )
|
|
216
|
-
resolve ( 'success' )
|
|
217
|
-
})
|
|
218
|
-
}) // res promise
|
|
219
|
-
return res
|
|
220
|
-
}) // test dependencies on shortcuts
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
test ( 'Emit custom event', () => {
|
|
225
|
-
const res = new Promise ( async (resolve) => {
|
|
226
|
-
let result = null;
|
|
227
|
-
short.changeContext ()
|
|
228
|
-
short.enablePlugin ( pluginClick )
|
|
229
|
-
const myAllContext = {
|
|
230
|
-
myAll: {
|
|
231
|
-
'click : leff-1' : () => console.log ( 'nothing' )
|
|
232
|
-
, 'yo' : ({msg}) => result = msg
|
|
233
|
-
}}
|
|
234
|
-
short.load ( myAllContext )
|
|
235
|
-
short.changeContext ( 'myAll' )
|
|
236
|
-
short.emit ( 'yo', { context: short.getContext(), note: 'tt', type:'custom', msg:'hello' })
|
|
237
|
-
expect ( result ).to.be.equal ( 'hello' )
|
|
238
|
-
short.changeContext ( 'general' )
|
|
239
|
-
short.unload ( 'myAll' )
|
|
240
|
-
resolve ( 'success' )
|
|
241
|
-
})
|
|
242
|
-
return res
|
|
243
|
-
}) // test emit custom event
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
test ( 'List shortcuts', () => {
|
|
248
|
-
short.enablePlugin ( pluginKey )
|
|
249
|
-
let general = short.listShortcuts ('general');
|
|
250
|
-
expect ( general ).to.be.an ( 'array' )
|
|
251
|
-
expect ( general ).to.have.lengthOf ( 1 )
|
|
252
|
-
expect ( general[0] ).to.be.equal ( 'KEY:A+SHIFT' )
|
|
253
91
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
92
|
+
it ( 'Emit custom event', () => {
|
|
93
|
+
// TODO: Check arguments for the custom event handlers
|
|
94
|
+
let result = null;
|
|
95
|
+
short.enablePlugin ( pluginClick )
|
|
96
|
+
const myAllContext = {
|
|
97
|
+
myAll: {
|
|
98
|
+
'click : leff-1' : () => console.log ( 'nothing' )
|
|
99
|
+
, 'yo' : ({msg}) => result = msg
|
|
100
|
+
}}
|
|
101
|
+
short.load ( myAllContext )
|
|
102
|
+
short.changeContext ( 'myAll' )
|
|
103
|
+
short.emit ( 'yo', { context: short.getContext(), note: 'tt', type:'custom', msg:'hello' })
|
|
104
|
+
expect ( result ).to.be.equal ( 'hello' )
|
|
105
|
+
short.changeContext ( 'general' )
|
|
106
|
+
short.unload ( 'myAll' )
|
|
107
|
+
}) // it emit custom event
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
it ( 'List shortcuts', () => {
|
|
112
|
+
short.enablePlugin ( pluginKey )
|
|
113
|
+
|
|
114
|
+
let general = short.listShortcuts ('general');
|
|
115
|
+
expect ( general ).to.be.an ( 'array' )
|
|
116
|
+
expect ( general ).to.have.lengthOf ( 1 )
|
|
117
|
+
expect ( general[0] ).to.be.equal ( 'KEY:A+SHIFT' )
|
|
118
|
+
|
|
119
|
+
let fail = short.listShortcuts ( 'somethingNotExisting' );
|
|
120
|
+
expect ( fail ).to.be.null
|
|
121
|
+
|
|
122
|
+
let all = short.listShortcuts ();
|
|
123
|
+
expect ( all ).to.be.an ( 'array' )
|
|
124
|
+
|
|
125
|
+
expect ( all ).to.have.lengthOf ( 4 )
|
|
126
|
+
// Property 'context' is a context name - string
|
|
127
|
+
expect ( all[0] ).to.have.property ( 'context' )
|
|
128
|
+
expect ( all[0] ).to.have.property ( 'shortcuts' )
|
|
129
|
+
expect ( all[0].shortcuts ).to.be.an ( 'array' )
|
|
130
|
+
expect ( all[0].shortcuts ).to.have.lengthOf ( 1 )
|
|
131
|
+
expect ( all[0].shortcuts[0] ).to.be.equal ( 'KEY:A+SHIFT' )
|
|
132
|
+
expect ( all[0].context ).to.be.equal ( 'general' )
|
|
133
|
+
}) // it list shortcuts
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
it ( 'Reset', () => {
|
|
138
|
+
short.enablePlugin ( pluginKey )
|
|
139
|
+
short.reset ()
|
|
140
|
+
expect ( short.listShortcuts () ).to.have.lengthOf ( 0 )
|
|
141
|
+
expect ( short.listShortcuts () ).to.have.lengthOf ( 0 )
|
|
142
|
+
expect ( short.getContext () ).to.be.null
|
|
143
|
+
}) // it Reset
|
|
259
144
|
|
|
260
|
-
expect ( all ).to.have.lengthOf ( 3 )
|
|
261
|
-
expect ( all[0] ).to.have.property ( 'context' )
|
|
262
|
-
expect ( all[0] ).to.have.property ( 'shortcuts' )
|
|
263
|
-
expect ( all[0].shortcuts ).to.be.an('array')
|
|
264
|
-
expect ( all[0].shortcuts ).to.have.lengthOf ( 1 )
|
|
265
|
-
expect ( all[0].shortcuts[0] ).to.be.equal ( 'KEY:A+SHIFT' )
|
|
266
|
-
expect ( all[0].context ).to.be.equal ( 'general' )
|
|
267
|
-
}) // test list shortcuts
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
test ( 'Click on anchor', () => {
|
|
272
|
-
const res = new Promise ( async (resolve) => {
|
|
273
|
-
// Click on anchor that don't have click-data attribute.
|
|
274
|
-
let result = 'none';
|
|
275
|
-
short.enablePlugin ( pluginClick )
|
|
276
|
-
short.load ({ 'extra' : {
|
|
277
|
-
'click: 1 - left' : ({target, context, event }) => { // Order of button name and number of click is not important
|
|
278
|
-
event.preventDefault ()
|
|
279
|
-
expect ( context ).to.be.equal ( 'extra' )
|
|
280
|
-
expect ( target.nodeName ).to.be.equal ( 'A' )
|
|
281
|
-
result = target.nodeName
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
})
|
|
285
|
-
short.changeContext ( 'extra' )
|
|
286
|
-
wait ( 10 )
|
|
287
|
-
.then ( async () => {
|
|
288
|
-
let loc = document.querySelector ( '#anchor' ) || false;
|
|
289
|
-
if ( loc ) await userEvent.click ( loc )
|
|
290
|
-
expect ( result ).to.be.equal ( 'A' )
|
|
291
|
-
short.changeContext ( 'general' )
|
|
292
|
-
resolve ( 'success' )
|
|
293
|
-
})
|
|
294
|
-
})
|
|
295
|
-
return res
|
|
296
|
-
}) // test click on anchor
|
|
297
145
|
|
|
298
146
|
}) // describe
|
|
299
147
|
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { beforeEach, afterEach, describe, it, expect } from 'vitest'
|
|
2
|
+
import { userEvent } from '@vitest/browser/context'
|
|
3
|
+
import {
|
|
4
|
+
getByLabelText,
|
|
5
|
+
getByText,
|
|
6
|
+
getByTestId,
|
|
7
|
+
queryByTestId,
|
|
8
|
+
// Tip: all queries are also exposed on an object
|
|
9
|
+
// called "queries" which you could import here as well
|
|
10
|
+
waitFor
|
|
11
|
+
} from '@testing-library/dom'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
import '../test-helpers/style.css'
|
|
16
|
+
import Block from '../test-helpers/Block.jsx'
|
|
17
|
+
import VisaulController from '@peter.naydenov/visual-controller-for-react'
|
|
18
|
+
import wait from '../test-helpers/wait.js'
|
|
19
|
+
import {
|
|
20
|
+
shortcuts
|
|
21
|
+
, pluginKey
|
|
22
|
+
, pluginClick
|
|
23
|
+
, pluginForm
|
|
24
|
+
} from '../src/main.js'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
const html = new VisaulController ();
|
|
29
|
+
let
|
|
30
|
+
a = false
|
|
31
|
+
, b = false
|
|
32
|
+
, c = null
|
|
33
|
+
;
|
|
34
|
+
|
|
35
|
+
const contextDefinition = {
|
|
36
|
+
general : {
|
|
37
|
+
' key : shift+a': [
|
|
38
|
+
() => a = true,
|
|
39
|
+
() => c = 'triggered'
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
, touch : {
|
|
43
|
+
// Single click with left button
|
|
44
|
+
'click: left-1': () => b = true,
|
|
45
|
+
// Double click with left button
|
|
46
|
+
'click: left-2': () => b = true,
|
|
47
|
+
// Single click with right button
|
|
48
|
+
'click: right-1': () => b = true
|
|
49
|
+
}
|
|
50
|
+
, extra : {
|
|
51
|
+
'key : p,r,o,b,a': () => b = true
|
|
52
|
+
}
|
|
53
|
+
, extend : {
|
|
54
|
+
'form : watch' : () => 'input'
|
|
55
|
+
, 'form : define' : () => 'input'
|
|
56
|
+
, 'form : action' : () => [
|
|
57
|
+
{
|
|
58
|
+
fn : (e) => console.log ( e.target )
|
|
59
|
+
, type : 'input'
|
|
60
|
+
, mode : 'in'
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let short = shortcuts ();
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
describe ( 'Key plugin', () => {
|
|
73
|
+
|
|
74
|
+
beforeEach ( async () => {
|
|
75
|
+
short.load ( contextDefinition )
|
|
76
|
+
let container = document.createElement ( 'div' )
|
|
77
|
+
container.id = 'app'
|
|
78
|
+
document.body.appendChild ( container )
|
|
79
|
+
await html.publish ( Block, {}, 'app' )
|
|
80
|
+
a = false, b = false
|
|
81
|
+
}) // beforeEach
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
afterEach ( async () => {
|
|
86
|
+
short.reset ()
|
|
87
|
+
a = false, b = false, c = null;
|
|
88
|
+
}) // afterEach
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
it ( 'No "key" plugin installed', () => {
|
|
93
|
+
let r = short.listShortcuts ('general');
|
|
94
|
+
// Shortcut name is the same as it was set
|
|
95
|
+
expect ( r[0]).to.equal ( ' key : shift+a' )
|
|
96
|
+
}) // it no 'key' plugin installed
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
it ( 'Key plugin installed', () => {
|
|
101
|
+
short.enablePlugin ( pluginKey )
|
|
102
|
+
const r = short.listShortcuts ( 'general' )
|
|
103
|
+
// Shortcut name is recognized by plugin and is normalized
|
|
104
|
+
expect ( r[0] ).to.equal ( 'KEY:A+SHIFT' )
|
|
105
|
+
}) // it key plugin installed
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
it ( 'Execute a key shortcut: shift+a', async () => {
|
|
110
|
+
expect ( a ).to.equal ( false )
|
|
111
|
+
// Enable key plugin, normalize shortcuts related to the plugin
|
|
112
|
+
short.enablePlugin ( pluginKey )
|
|
113
|
+
short.changeContext ( 'general' )
|
|
114
|
+
await userEvent.keyboard ( '{Shift>}A{/Shift}' ) // Write 'a' with shift
|
|
115
|
+
await wait ( 12 )
|
|
116
|
+
await waitFor ( () => {
|
|
117
|
+
expect ( a ).to.equal ( true )
|
|
118
|
+
expect ( c ).to.equal ( 'triggered' )
|
|
119
|
+
}, { timeout: 1000, interval: 12 })
|
|
120
|
+
}) // it execute a key shortcut
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
it ( 'Key sequence', async () => {
|
|
125
|
+
// enable key plugin and normalize shortcuts related to the plugin 'key'
|
|
126
|
+
short.enablePlugin ( pluginKey )
|
|
127
|
+
short.changeContext ( 'extra' )
|
|
128
|
+
// Execute key sequence: 'p,r,o,b,a'
|
|
129
|
+
await userEvent.keyboard ( 'proba' )
|
|
130
|
+
await wait ( 12 )
|
|
131
|
+
await waitFor ( () => {
|
|
132
|
+
expect ( b ).to.equal ( true )
|
|
133
|
+
}, { timeout: 1000, interval: 12 })
|
|
134
|
+
}) // it key sequence
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
it ( 'Mute key plugin', async () => {
|
|
139
|
+
short.enablePlugin ( pluginKey )
|
|
140
|
+
const result = [];
|
|
141
|
+
let i = 0;
|
|
142
|
+
result.push ( 'init' )
|
|
143
|
+
|
|
144
|
+
short.setDependencies ({ result })
|
|
145
|
+
short.load ({
|
|
146
|
+
'local': {
|
|
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' )
|
|
156
|
+
await waitFor ( () => {
|
|
157
|
+
// We checking if the shortcut works
|
|
158
|
+
expect ( result ).to.have.lengthOf ( 2 )
|
|
159
|
+
expect ( i ).to.equal ( 1 )
|
|
160
|
+
}, { timeout: 1000, interval: 12 })
|
|
161
|
+
|
|
162
|
+
short.mutePlugin ( 'key' )
|
|
163
|
+
await userEvent.keyboard ( 'gti' )
|
|
164
|
+
await waitFor ( () => {
|
|
165
|
+
// Plugin is muted, so we don't expect any changes
|
|
166
|
+
expect ( result ).to.have.lengthOf ( 2 )
|
|
167
|
+
expect ( i ).to.equal ( 1 )
|
|
168
|
+
}, { timeout: 1000, interval: 12 })
|
|
169
|
+
}) // it mute key plugin
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
})
|