@peter.naydenov/shortcuts 3.5.2 → 4.0.1
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 +32 -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/dist/src/main.d.ts +172 -0
- package/dist/src/methods/_normalizeWithPlugins.d.ts +64 -0
- package/dist/src/methods/_readShortcutWithPlugins.d.ts +9 -0
- package/dist/src/methods/_setupPlugin.d.ts +9 -0
- package/dist/src/methods/_systemAction.d.ts +9 -0
- package/dist/src/methods/changeContext.d.ts +9 -0
- package/dist/src/methods/index.d.ts +19 -0
- package/dist/src/methods/listShortcuts.d.ts +2 -0
- package/dist/src/methods/load.d.ts +9 -0
- package/dist/src/methods/unload.d.ts +9 -0
- package/dist/src/plugins/click/_findTarget.d.ts +10 -0
- package/dist/src/plugins/click/_listenDOM.d.ts +78 -0
- package/dist/src/plugins/click/_normalizeShortcutName.d.ts +8 -0
- package/dist/src/plugins/click/_readClickEvent.d.ts +2 -0
- package/dist/src/plugins/click/_registerShortcutEvents.d.ts +28 -0
- package/dist/src/plugins/click/index.d.ts +16 -0
- package/dist/src/plugins/form/_defaults.d.ts +17 -0
- package/dist/src/plugins/form/_listenDOM.d.ts +68 -0
- package/dist/src/plugins/form/_normalizeShortcutName.d.ts +2 -0
- package/dist/src/plugins/form/_registerShortcutEvents.d.ts +96 -0
- package/dist/src/plugins/form/index.d.ts +9 -0
- package/dist/src/plugins/hover/_findTarget.d.ts +10 -0
- package/dist/src/plugins/hover/_listenDOM.d.ts +68 -0
- package/dist/src/plugins/hover/_normalizeShortcutName.d.ts +2 -0
- package/dist/src/plugins/hover/_registerShortcutEvents.d.ts +28 -0
- package/dist/src/plugins/hover/index.d.ts +14 -0
- package/dist/src/plugins/key/_listenDOM.d.ts +63 -0
- package/dist/src/plugins/key/_normalizeShortcutName.d.ts +2 -0
- package/dist/src/plugins/key/_readKeyEvent.d.ts +2 -0
- package/dist/src/plugins/key/_registerShortcutEvents.d.ts +28 -0
- package/dist/src/plugins/key/_specialChars.d.ts +7 -0
- package/dist/src/plugins/key/index.d.ts +14 -0
- package/dist/src/plugins/scroll/_listenDOM.d.ts +58 -0
- package/dist/src/plugins/scroll/_normalizeShortcutName.d.ts +2 -0
- package/dist/src/plugins/scroll/_registerShortcutEvents.d.ts +28 -0
- package/dist/src/plugins/scroll/index.d.ts +16 -0
- 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 +24 -19
- 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/tsconfig.json +2 -1
- package/vitest.config.js +13 -11
- package/How..to.make.plugins.md +0 -41
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { beforeEach, afterEach, describe, it, expect } from 'vitest'
|
|
2
|
+
import { userEvent } from 'vitest/browser'
|
|
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
|
+
, pluginScroll
|
|
25
|
+
} from '../src/main.js'
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
const html = new VisaulController ();
|
|
31
|
+
let
|
|
32
|
+
a = false
|
|
33
|
+
, b = false
|
|
34
|
+
, c = null
|
|
35
|
+
;
|
|
36
|
+
|
|
37
|
+
const contextDefinition = {
|
|
38
|
+
general : {
|
|
39
|
+
' key : shift+a': [
|
|
40
|
+
() => a = true,
|
|
41
|
+
() => c = 'triggered'
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
, scroll : {
|
|
45
|
+
' scroll: up': () => b = true,
|
|
46
|
+
'scroll : down': () => c = 'down',
|
|
47
|
+
'scroll:left': () => c = 'left',
|
|
48
|
+
'scroll:right': () => c = 'right'
|
|
49
|
+
}
|
|
50
|
+
, extra : {
|
|
51
|
+
'key : p,r,o,b,a': () => b = true
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
const short = shortcuts ();
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
describe ( 'Scroll plugin', () => {
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
beforeEach ( async () => {
|
|
65
|
+
short.load ( contextDefinition )
|
|
66
|
+
const container = document.createElement ( 'div' );
|
|
67
|
+
container.id = 'app'
|
|
68
|
+
document.body.appendChild ( container )
|
|
69
|
+
// Make page scrollable both vertically and horizontally
|
|
70
|
+
document.body.style.height = '2000px'
|
|
71
|
+
document.body.style.width = '2000px'
|
|
72
|
+
document.body.style.margin = '0'
|
|
73
|
+
document.documentElement.style.height = '2000px'
|
|
74
|
+
document.documentElement.style.width = '2000px'
|
|
75
|
+
await html.publish ( Block, {}, 'app' )
|
|
76
|
+
a = false, b = false, c = null
|
|
77
|
+
}) // beforeEach
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
afterEach ( async () => {
|
|
82
|
+
short.reset ();
|
|
83
|
+
html.destroy ()
|
|
84
|
+
a = false, b = false, c = null;
|
|
85
|
+
document.body.querySelector ( '#app' ).remove ()
|
|
86
|
+
}) // afterEach
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
it ( 'No "scroll" plugin installed', async () => {
|
|
91
|
+
const r = short.listShortcuts ('scroll');
|
|
92
|
+
// Shortcuts are untouched if plugin is not installed
|
|
93
|
+
expect ( r[0]).to.equal ( ' scroll: up' )
|
|
94
|
+
expect ( r[1]).to.equal ( 'scroll : down' )
|
|
95
|
+
expect ( r[2]).to.equal ( 'scroll:left' )
|
|
96
|
+
expect ( r[3]).to.equal ( 'scroll:right' )
|
|
97
|
+
}) // it no 'scroll' plugin installed
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
it ( 'Enable plugin when context has no shortcuts for this plugin', () => {
|
|
102
|
+
short.changeContext ( 'general' ) // 'general' has no scroll shortcuts
|
|
103
|
+
short.enablePlugin ( pluginScroll )
|
|
104
|
+
expect ( short.listPlugins () ).to.include ( 'scroll' )
|
|
105
|
+
// Since no scroll shortcuts in 'general', listener should not start
|
|
106
|
+
}) // it enable plugin when context has no shortcuts
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
it ( 'Scroll plugin installed', async () => {
|
|
111
|
+
short.enablePlugin ( pluginScroll )
|
|
112
|
+
const r = short.listShortcuts ( 'scroll' );
|
|
113
|
+
// Shortcuts are normalized
|
|
114
|
+
expect ( r[0]).to.equal ( 'SCROLL:UP' )
|
|
115
|
+
expect ( r[1]).to.equal ( 'SCROLL:DOWN' )
|
|
116
|
+
expect ( r[2]).to.equal ( 'SCROLL:LEFT' )
|
|
117
|
+
expect ( r[3]).to.equal ( 'SCROLL:RIGHT' )
|
|
118
|
+
}) // it scroll plugin installed
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
it ( 'Scroll down event', async () => {
|
|
123
|
+
expect ( c ).to.equal ( null )
|
|
124
|
+
short.changeContext ( 'scroll' )
|
|
125
|
+
short.enablePlugin ( pluginScroll )
|
|
126
|
+
|
|
127
|
+
// Scroll down by setting scroll position
|
|
128
|
+
window.scrollTo ( 0, 100 )
|
|
129
|
+
await wait ( 50 )
|
|
130
|
+
await waitFor ( () => {
|
|
131
|
+
expect ( c ).to.equal ( 'down' )
|
|
132
|
+
}, { timeout: 1000, interval: 12 })
|
|
133
|
+
}) // it scroll down event
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
it ( 'Scroll up event', async () => {
|
|
138
|
+
expect ( b ).to.equal ( false )
|
|
139
|
+
short.changeContext ( 'scroll' )
|
|
140
|
+
short.enablePlugin ( pluginScroll )
|
|
141
|
+
|
|
142
|
+
// First scroll down to establish baseline
|
|
143
|
+
window.scrollTo ( 0, 100)
|
|
144
|
+
await wait ( 50 )
|
|
145
|
+
|
|
146
|
+
// Then scroll up
|
|
147
|
+
window.scrollTo ( 0, 50)
|
|
148
|
+
await wait ( 50 )
|
|
149
|
+
|
|
150
|
+
await waitFor ( () => {
|
|
151
|
+
expect ( b ).to.equal ( true )
|
|
152
|
+
}, { timeout: 1000, interval: 12 })
|
|
153
|
+
}) // it scroll up event
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
it ( 'Scroll left event', async () => {
|
|
158
|
+
expect ( c ).to.equal ( null )
|
|
159
|
+
short.changeContext ( 'scroll' )
|
|
160
|
+
short.enablePlugin ( pluginScroll )
|
|
161
|
+
|
|
162
|
+
// First scroll right to establish baseline
|
|
163
|
+
window.scrollTo ( 100, 0 )
|
|
164
|
+
await wait ( 50 )
|
|
165
|
+
|
|
166
|
+
// Then scroll left
|
|
167
|
+
window.scrollTo ( 50, 0 )
|
|
168
|
+
await wait ( 50 )
|
|
169
|
+
|
|
170
|
+
await waitFor ( () => {
|
|
171
|
+
expect ( c ).to.equal ( 'left' )
|
|
172
|
+
}, { timeout: 1000, interval: 12 })
|
|
173
|
+
}) // it scroll left event
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
it ( 'Scroll right event', async () => {
|
|
178
|
+
expect ( c ).to.equal ( null )
|
|
179
|
+
short.changeContext ( 'scroll' )
|
|
180
|
+
short.enablePlugin ( pluginScroll )
|
|
181
|
+
|
|
182
|
+
// Scroll right by setting scroll position
|
|
183
|
+
window.scrollTo ( 100, 0 )
|
|
184
|
+
await wait ( 50 )
|
|
185
|
+
|
|
186
|
+
await waitFor ( () => {
|
|
187
|
+
expect ( c ).to.equal ( 'right' )
|
|
188
|
+
}, { timeout: 1000, interval: 12 })
|
|
189
|
+
}) // it scroll right event
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
it ( 'Combined horizontal and vertical scroll', async () => {
|
|
194
|
+
const scrollEvents = []
|
|
195
|
+
short.setDependencies ({ scrollEvents })
|
|
196
|
+
short.changeContext ( 'scroll' )
|
|
197
|
+
short.enablePlugin ( pluginScroll )
|
|
198
|
+
|
|
199
|
+
// Reset scroll position to (0, 0) first
|
|
200
|
+
window.scrollTo ( 0, 0 )
|
|
201
|
+
await wait ( 200 ) // Wait longer for any pending scroll events
|
|
202
|
+
|
|
203
|
+
// Clear any events that might have been triggered by reset
|
|
204
|
+
scrollEvents.length = 0
|
|
205
|
+
|
|
206
|
+
// Create a temporary context to capture scroll events
|
|
207
|
+
short.load ({
|
|
208
|
+
'testScroll': {
|
|
209
|
+
'scroll:up': ({ direction }) => scrollEvents.push(direction),
|
|
210
|
+
'scroll:down': ({ direction }) => scrollEvents.push(direction),
|
|
211
|
+
'scroll:left': ({ direction }) => scrollEvents.push(direction),
|
|
212
|
+
'scroll:right': ({ direction }) => scrollEvents.push(direction)
|
|
213
|
+
}
|
|
214
|
+
})
|
|
215
|
+
short.changeContext ( 'testScroll' )
|
|
216
|
+
|
|
217
|
+
// Scroll diagonally (right and down)
|
|
218
|
+
window.scrollTo ( 100, 100 )
|
|
219
|
+
await wait ( 50 )
|
|
220
|
+
|
|
221
|
+
// Scroll left
|
|
222
|
+
window.scrollTo ( 50, 100 )
|
|
223
|
+
await wait ( 50 )
|
|
224
|
+
|
|
225
|
+
// Scroll up
|
|
226
|
+
window.scrollTo ( 50, 50 )
|
|
227
|
+
await wait ( 50 )
|
|
228
|
+
|
|
229
|
+
await waitFor ( () => {
|
|
230
|
+
expect ( scrollEvents ).to.include.members ( ['right', 'down', 'left', 'up'] )
|
|
231
|
+
expect ( scrollEvents ).to.have.length ( 4 )
|
|
232
|
+
}, { timeout: 1000, interval: 12 })
|
|
233
|
+
}) // it combined horizontal and vertical scroll
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
it ( 'Mute and unmute scroll plugin', async () => {
|
|
238
|
+
short.changeContext ( 'scroll' )
|
|
239
|
+
short.enablePlugin ( pluginScroll )
|
|
240
|
+
c = null // Reset c variable
|
|
241
|
+
|
|
242
|
+
// Mute the plugin
|
|
243
|
+
short.mutePlugin ( 'scroll' )
|
|
244
|
+
|
|
245
|
+
// Scroll should not trigger
|
|
246
|
+
window.scrollTo ( 0, 100)
|
|
247
|
+
await wait ( 50 )
|
|
248
|
+
expect ( c ).to.equal ( null )
|
|
249
|
+
|
|
250
|
+
// Unmute the plugin
|
|
251
|
+
short.unmutePlugin ( 'scroll' )
|
|
252
|
+
|
|
253
|
+
// Scroll should trigger now
|
|
254
|
+
window.scrollTo ( 0, 200)
|
|
255
|
+
await wait ( 50 )
|
|
256
|
+
|
|
257
|
+
await waitFor ( () => {
|
|
258
|
+
expect ( c ).to.equal ( 'down' )
|
|
259
|
+
}, { timeout: 1000, interval: 12 })
|
|
260
|
+
}) // it mute and unmute scroll plugin
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
it ( 'Pause and resume', async () => {
|
|
265
|
+
short.changeContext ( 'scroll' )
|
|
266
|
+
short.enablePlugin ( pluginScroll )
|
|
267
|
+
|
|
268
|
+
// Pause the shortcut
|
|
269
|
+
short.pause ( 'scroll : down' )
|
|
270
|
+
|
|
271
|
+
// Scroll should not trigger
|
|
272
|
+
window.scrollTo(0, 100)
|
|
273
|
+
await wait ( 50 )
|
|
274
|
+
expect ( c ).to.equal ( null )
|
|
275
|
+
|
|
276
|
+
// Resume the shortcut
|
|
277
|
+
short.resume ( ' scroll : down' )
|
|
278
|
+
|
|
279
|
+
// Scroll should trigger now
|
|
280
|
+
window.scrollTo(0, 200)
|
|
281
|
+
await wait ( 50 )
|
|
282
|
+
|
|
283
|
+
await waitFor ( () => {
|
|
284
|
+
expect ( c ).to.equal ( 'down' )
|
|
285
|
+
}, { timeout: 1000, interval: 12 })
|
|
286
|
+
}) // it pause and resume
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
it ( 'Enable already enabled plugin', () => {
|
|
291
|
+
// Enable plugin first time
|
|
292
|
+
short.enablePlugin ( pluginScroll )
|
|
293
|
+
let plugins = short.listPlugins ()
|
|
294
|
+
expect ( plugins ).to.include ( 'scroll' )
|
|
295
|
+
expect ( plugins ).to.have.lengthOf ( 1 )
|
|
296
|
+
|
|
297
|
+
// Try to enable the same plugin again
|
|
298
|
+
short.enablePlugin ( pluginScroll )
|
|
299
|
+
plugins = short.listPlugins ()
|
|
300
|
+
// Should still have only one instance
|
|
301
|
+
expect ( plugins ).to.include ( 'scroll' )
|
|
302
|
+
expect ( plugins ).to.have.lengthOf ( 1 )
|
|
303
|
+
}) // it enable already enabled plugin
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
it ( 'Disable a plugin', () => {
|
|
308
|
+
// Enable plugin
|
|
309
|
+
short.enablePlugin ( pluginScroll )
|
|
310
|
+
expect ( short.listPlugins () ).to.include ( 'scroll' )
|
|
311
|
+
|
|
312
|
+
// Disable plugin
|
|
313
|
+
short.disablePlugin ( 'scroll' )
|
|
314
|
+
expect ( short.listPlugins () ).to.not.include ( 'scroll' )
|
|
315
|
+
}) // it disable a plugin
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
it ( 'Extra parameters to plugin options', async () => {
|
|
319
|
+
short.enablePlugin ( pluginScroll )
|
|
320
|
+
const emit = [];
|
|
321
|
+
const setupContext = {
|
|
322
|
+
'scroll:setup' : () => {
|
|
323
|
+
emit.push ( 'setup' )
|
|
324
|
+
return { minSpace: 10, customParam: 'scroll-test', emit }
|
|
325
|
+
},
|
|
326
|
+
'scroll:down' : ({options}) => {
|
|
327
|
+
expect ( options.minSpace ).to.equal ( 10 )
|
|
328
|
+
expect ( options.customParam ).to.equal ( 'scroll-test' )
|
|
329
|
+
options.emit.push ( 'down' )
|
|
330
|
+
},
|
|
331
|
+
'scroll:up' : ({options}) => {
|
|
332
|
+
expect ( options.minSpace ).to.equal ( 10 )
|
|
333
|
+
expect ( options.customParam ).to.equal ( 'scroll-test' )
|
|
334
|
+
options.emit.push ( 'up' )
|
|
335
|
+
},
|
|
336
|
+
'scroll:right' : ({options}) => {
|
|
337
|
+
expect ( options.minSpace ).to.equal ( 10 )
|
|
338
|
+
expect ( options.customParam ).to.equal ( 'scroll-test' )
|
|
339
|
+
options.emit.push ( 'right' )
|
|
340
|
+
},
|
|
341
|
+
'scroll:left' : ({options}) => {
|
|
342
|
+
expect ( options.minSpace ).to.equal ( 10 )
|
|
343
|
+
expect ( options.customParam ).to.equal ( 'scroll-test' )
|
|
344
|
+
options.emit.push ( 'left' )
|
|
345
|
+
}
|
|
346
|
+
} // setupContext
|
|
347
|
+
|
|
348
|
+
short.load ({ setupContext })
|
|
349
|
+
short.changeContext ( 'setupContext' )
|
|
350
|
+
|
|
351
|
+
// Setup event execution is on change context:
|
|
352
|
+
expect ( emit[0] ).to.equal ( 'setup' )
|
|
353
|
+
|
|
354
|
+
// Reset scroll position to (0, 0) first
|
|
355
|
+
window.scrollTo ( 0, 0 )
|
|
356
|
+
await wait ( 200 ) // Wait for any pending scroll events
|
|
357
|
+
|
|
358
|
+
// Test scroll with modified minSpace (smaller movements should trigger)
|
|
359
|
+
// We just need to verify that the options are accessible and contain our custom parameters
|
|
360
|
+
// The exact scroll behavior may vary in test environment
|
|
361
|
+
window.scrollTo ( 0, 50 ) // 50px movement, should definitely trigger with minSpace=10
|
|
362
|
+
await wait ( 100 )
|
|
363
|
+
|
|
364
|
+
// At least one scroll event should have been triggered with our custom options
|
|
365
|
+
expect ( emit.length ).to.be.greaterThan ( 1 )
|
|
366
|
+
expect ( emit[0] ).to.equal ( 'setup' )
|
|
367
|
+
|
|
368
|
+
// Verify that the scroll events have access to the custom parameters
|
|
369
|
+
// We don't need to assert exact scroll directions since test environment may behave differently
|
|
370
|
+
const scrollEvents = emit.filter(e => e !== 'setup')
|
|
371
|
+
expect ( scrollEvents.length ).to.be.greaterThan ( 0 )
|
|
372
|
+
}) // it extra parameters to plugin options
|
|
373
|
+
|
|
374
|
+
}) // describe Scroll plugin
|
package/test-helpers/Block.jsx
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
function Block () {
|
|
2
2
|
return <>
|
|
3
|
-
<div className="block" data-click="red"><span id='rspan'>Red</span> </div>
|
|
4
|
-
<button className="big-btn" data-click="mega">Mega button</button>
|
|
3
|
+
<div className="block" data-click="red" data-hover="red"><span id='rspan'>Red</span> </div>
|
|
4
|
+
<button className="big-btn" data-click="mega" data-hover="blue">Mega button</button>
|
|
5
5
|
<p>Some text with <a href="#" target="_blank">link <span id="anchor">in</span></a> it</p>
|
|
6
6
|
<p><input id="name" type="text" /></p>
|
|
7
7
|
<p><input type="text" id="age" /></p>
|
|
8
|
+
<p><button id="hidden" className="hide" data-click="hidden">Hidden button</button></p>
|
|
8
9
|
</>
|
|
9
10
|
}
|
|
10
11
|
|
package/test-helpers/style.css
CHANGED
package/tsconfig.json
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
"declaration": true,
|
|
5
5
|
"emitDeclarationOnly": true,
|
|
6
6
|
"outDir": "dist",
|
|
7
|
+
"rootDir": "src",
|
|
7
8
|
"target": "ES2020",
|
|
8
9
|
"module": "ESNext",
|
|
9
|
-
"moduleResolution": "
|
|
10
|
+
"moduleResolution": "bundler",
|
|
10
11
|
"esModuleInterop": true,
|
|
11
12
|
"allowSyntheticDefaultImports": true,
|
|
12
13
|
"strict": false,
|
package/vitest.config.js
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { defineConfig } from 'vitest/config'
|
|
2
2
|
import react from '@vitejs/plugin-react'
|
|
3
|
+
import { playwright } from '@vitest/browser-playwright'
|
|
3
4
|
|
|
4
5
|
export default defineConfig ({
|
|
5
6
|
plugins: [react()],
|
|
6
7
|
test: {
|
|
7
8
|
coverage: {
|
|
8
|
-
|
|
9
|
+
provider: 'v8',
|
|
10
|
+
reporter: ['lcov', 'html', 'text-summary' ]
|
|
9
11
|
},
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
browser: {
|
|
13
|
+
enabled: true,
|
|
14
|
+
headless: true,
|
|
15
|
+
provider: playwright(),
|
|
16
|
+
instances: [
|
|
17
|
+
{
|
|
18
|
+
browser: 'chromium'
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
20
22
|
}
|
|
21
23
|
})
|
package/How..to.make.plugins.md
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# Shortcut plugins
|
|
2
|
-
|
|
3
|
-
Shortcut plugin should be a function that receives 3 arguments: dependencies, state and options. Shoud return an shortcut plugin API object.
|
|
4
|
-
|
|
5
|
-
```js
|
|
6
|
-
function plugin ( dependencies, state, options ) {
|
|
7
|
-
// Normalize all shortcuts related to this plugin
|
|
8
|
-
// Setup some internal state
|
|
9
|
-
// Start listening to DOM events if current context has shortcuts related to this plugin
|
|
10
|
-
// ...
|
|
11
|
-
return {
|
|
12
|
-
// API
|
|
13
|
-
getPrefix: function () {
|
|
14
|
-
// return a plugin prefix
|
|
15
|
-
},
|
|
16
|
-
shortcutName : function ( shortcutName ) {
|
|
17
|
-
// normalize shortcut name
|
|
18
|
-
// return normalized shortcut name
|
|
19
|
-
},
|
|
20
|
-
contextChange: function ( context ) {
|
|
21
|
-
// How plugin should react to context change
|
|
22
|
-
// return void
|
|
23
|
-
},
|
|
24
|
-
mute: function () {
|
|
25
|
-
// Function that will stop DOM events from being triggered
|
|
26
|
-
},
|
|
27
|
-
unmute: function () {
|
|
28
|
-
// Function that will resume DOM events
|
|
29
|
-
},
|
|
30
|
-
destroy: function () {
|
|
31
|
-
// Destroy plugin instance
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
} // plugin
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
State and dependencies are objects coming from the main library. **Dependencies** contains the library event emitter ( dependencies.ev). From state object you have access to the current context object state and loaded shortcuts contextes. Object **options** contains a plugin options provided by the user.
|
|
38
|
-
|
|
39
|
-
If you need see an example of a shortcut plugin, check the available plugins in the library: key and click.
|
|
40
|
-
|
|
41
|
-
|