@peter.naydenov/shortcuts 2.2.0 → 3.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/Changelog.md +16 -2
- package/How..to.make.plugins.md +41 -0
- package/Migration.guide.md +77 -0
- package/README-v.2.x.x.md +375 -0
- package/README.md +106 -58
- package/dist/shortcuts.cjs +1 -1
- package/dist/shortcuts.esm.mjs +1 -1
- package/dist/shortcuts.umd.js +1 -1
- package/package.json +5 -5
- package/src/main.js +81 -30
- package/src/methods/_normalizeWithPlugins.js +25 -0
- package/src/methods/_readShortcutWithPlugins.js +24 -0
- package/src/methods/_systemAction.js +25 -0
- package/src/methods/changeContext.js +20 -26
- package/src/methods/index.js +7 -13
- package/src/methods/load.js +21 -14
- package/src/plugins/click/_findTarget.js +20 -0
- package/src/plugins/click/_listenDOM.js +117 -0
- package/src/plugins/click/_normalizeShortcutName.js +44 -0
- package/src/plugins/click/_readClickEvent.js +24 -0
- package/src/plugins/click/_registerShortcutEvents.js +30 -0
- package/src/plugins/click/index.js +74 -0
- package/src/plugins/key/_listenDOM.js +138 -0
- package/src/plugins/key/_normalizeShortcutName.js +31 -0
- package/src/{methods → plugins/key}/_readKeyEvent.js +2 -3
- package/src/plugins/key/_registerShortcutEvents.js +28 -0
- package/src/plugins/key/index.js +76 -0
- package/test/01-general.cy.js +189 -154
- package/src/methods/_findTarget.js +0 -19
- package/src/methods/_listen.js +0 -210
- package/src/methods/_readMouseEvent.js +0 -24
- package/src/methods/_readShortcut.js +0 -17
- /package/src/{methods → plugins/key}/_specialChars.js +0 -0
package/test/01-general.cy.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
|
|
2
2
|
import Block from '../test-components/Block.jsx'
|
|
3
3
|
import '../test-components/style.css'
|
|
4
|
-
import
|
|
4
|
+
import {
|
|
5
|
+
pluginClick,
|
|
6
|
+
pluginKey
|
|
7
|
+
, shortcuts
|
|
8
|
+
} from '../src/main.js'
|
|
5
9
|
import { expect } from 'chai'
|
|
6
10
|
|
|
7
11
|
import askForPromise from 'ask-for-promise'
|
|
@@ -10,17 +14,20 @@ let
|
|
|
10
14
|
a = false
|
|
11
15
|
, b = false
|
|
12
16
|
;
|
|
13
|
-
|
|
17
|
+
|
|
18
|
+
const short = shortcuts ({onShortcut : ( shortcut, {context,note,type}) => console.log (shortcut, context, note, type) });
|
|
19
|
+
|
|
14
20
|
short.load ({
|
|
15
21
|
general : {
|
|
16
|
-
'shift+a': [ () => a = true ]
|
|
22
|
+
' key : shift+a': [ () => a = true ]
|
|
17
23
|
}
|
|
18
24
|
, extra : {
|
|
19
|
-
'shift+a,p,r,o,b,a,ctrl+m' : () => b = true
|
|
25
|
+
'key:shift+a,p,r,o,b,a,ctrl+m' : () => b = true
|
|
20
26
|
}
|
|
21
27
|
})
|
|
22
28
|
|
|
23
29
|
|
|
30
|
+
|
|
24
31
|
describe ( 'Shortcuts', () => {
|
|
25
32
|
|
|
26
33
|
beforeEach ( () => {
|
|
@@ -30,182 +37,210 @@ beforeEach ( () => {
|
|
|
30
37
|
|
|
31
38
|
|
|
32
39
|
|
|
33
|
-
it ( '
|
|
34
|
-
let res = false;
|
|
40
|
+
it ( 'Shortcut if no plugin installed', done => {
|
|
35
41
|
short.changeContext ( 'general' )
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
done ()
|
|
41
|
-
})
|
|
42
|
-
}) // it first test
|
|
42
|
+
let r = short.listShortcuts ('general')
|
|
43
|
+
expect ( r[0]).to.equal ( ' key : shift+a' ) // Shortcut name is the same as it was set
|
|
44
|
+
done ()
|
|
45
|
+
}) // it no plugin installed
|
|
43
46
|
|
|
44
47
|
|
|
45
48
|
|
|
46
|
-
it ( '
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
.then ( () => {
|
|
54
|
-
expect ( a ).to.be.false
|
|
55
|
-
|
|
56
|
-
cy.get('body')
|
|
57
|
-
.type ( '{shift}a' )
|
|
58
|
-
.type('proba')
|
|
59
|
-
.type('{ctrl}M')
|
|
60
|
-
return cy.wait ( 1 ) // Shortuct sequence is 7 keys - the maximum number of keys for this context. Don't need to wait for timeout
|
|
61
|
-
})
|
|
62
|
-
.then ( () => {
|
|
63
|
-
expect ( b ).to.be.true
|
|
49
|
+
it ( 'Key plugin, no context selected', done => {
|
|
50
|
+
short.enablePlugin ( pluginKey )
|
|
51
|
+
const r = short.listShortcuts ( 'general' )
|
|
52
|
+
expect ( r[0] ).to.equal ( 'KEY:A+SHIFT' ) // Shortcut name is recognized by plugin and is normalized
|
|
53
|
+
done ()
|
|
54
|
+
}) // it key plugin installed, no context selected
|
|
55
|
+
|
|
64
56
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}) // it
|
|
57
|
+
|
|
58
|
+
it ( 'Key plugin with context selected', done => {
|
|
59
|
+
short.enablePlugin ( pluginKey )
|
|
60
|
+
short.changeContext ( 'general' )
|
|
61
|
+
const r = short.listShortcuts ('general')
|
|
62
|
+
expect ( r[0] ).to.equal ( 'KEY:A+SHIFT' ) // Shortcut name is recognized by plugin and is normalized
|
|
63
|
+
cy.wait ( 1 )
|
|
64
|
+
.then ( () => done () )
|
|
65
|
+
}) // it key plugin installed with context selected
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
it ( 'Simple shortcut', done => {
|
|
70
|
+
short.enablePlugin ( pluginKey )
|
|
71
|
+
short.changeContext ( )
|
|
72
|
+
short.changeContext ( 'general' )
|
|
73
|
+
cy.get('body').type ( '{shift}a' )
|
|
74
|
+
cy.wait ( 1 ) // Default wait sequence timeout is 480 ms, but maxSequence is 1, so we don't need to wait for timeout
|
|
75
|
+
.then ( () => {
|
|
76
|
+
expect ( a ).to.be.true
|
|
77
|
+
done ()
|
|
78
|
+
})
|
|
79
|
+
}) // it simple shortcut
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
it ( 'Call sequence shortcut', done => {
|
|
84
|
+
b = false
|
|
85
|
+
short.enablePlugin ( pluginKey )
|
|
86
|
+
short.changeContext ( 'general' )
|
|
87
|
+
short.changeContext ( 'extra' )
|
|
88
|
+
|
|
89
|
+
cy.get('body')
|
|
90
|
+
.type ( '{shift}a' )
|
|
91
|
+
.type ( 'proba' )
|
|
92
|
+
.type ( '{ctrl}M' )
|
|
93
|
+
|
|
94
|
+
cy.wait ( 1 ) // Default wait sequence timeout is 480 ms, but maxSequence is 1, so we don't need to wait for timeout
|
|
95
|
+
.then ( () => {
|
|
96
|
+
expect ( b ).to.be.true
|
|
97
|
+
done ()
|
|
98
|
+
})
|
|
99
|
+
}) // it call sequence shortcut
|
|
74
100
|
|
|
75
101
|
|
|
76
102
|
|
|
77
103
|
it ( 'Single mouse click', done => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
104
|
+
expect ( a ).to.be.false
|
|
105
|
+
expect ( b ).to.be.false
|
|
106
|
+
short.enablePlugin ( pluginClick )
|
|
107
|
+
|
|
108
|
+
short.load ({ 'extra' : {
|
|
109
|
+
' cLIck : left - 1 ' : () => a = true // Check if spaces, letter case can break the shortcut recognition
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
short.changeContext ( 'extra' )
|
|
113
|
+
cy.get('#rspan').click ()
|
|
114
|
+
cy.wait ( 10 ) // Default wait mouse timeout is 320 ms, but maxClicks is 1, so we don't need to wait for timeout
|
|
115
|
+
.then ( () => {
|
|
116
|
+
expect ( a ).to.be.true
|
|
83
117
|
})
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
.then ( () => expect ( a ).to.be.true )
|
|
88
|
-
cy.wait ( 300 ) // ...but mouseIgnore still active, so we better wait to not interfere with next test
|
|
89
|
-
.then ( () => done() )
|
|
90
|
-
}) // it mouse click
|
|
118
|
+
cy.wait ( 1 ) // ...but mouseIgnore still active, so we better wait to not interfere with next test
|
|
119
|
+
.then ( () => done() )
|
|
120
|
+
}) // it mouse click
|
|
91
121
|
|
|
92
122
|
|
|
93
123
|
|
|
94
124
|
it ( 'Double mouse click', done => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
})
|
|
113
|
-
|
|
125
|
+
expect ( a ).to.be.false
|
|
126
|
+
expect ( b ).to.be.false
|
|
127
|
+
|
|
128
|
+
short.enablePlugin ( pluginClick )
|
|
129
|
+
short.changeContext ( 'extra' )
|
|
130
|
+
|
|
131
|
+
short.load ({
|
|
132
|
+
'extra' : { // load will overwrite existing 'extra' context definition
|
|
133
|
+
'click: left-2' : () => a = true
|
|
134
|
+
}
|
|
135
|
+
}) // load will restart the selected context
|
|
136
|
+
|
|
137
|
+
cy.get('#rspan').click().click ().click () // Third click is ignored. Max clicks according definition is 2.
|
|
138
|
+
cy.wait ( 1 ) // Default wait mouse timeout is 320 ms
|
|
139
|
+
.then ( () => {
|
|
140
|
+
expect ( a ).to.be.true
|
|
141
|
+
done ()
|
|
142
|
+
})
|
|
143
|
+
}) // it double mouse click
|
|
114
144
|
|
|
115
145
|
|
|
116
|
-
it ( 'Emit custom event', () => {
|
|
117
|
-
let result = null;
|
|
118
|
-
const myAllContext = {
|
|
119
|
-
myAll: {
|
|
120
|
-
'mouse-click-leff-1' : () => console.log ( 'nothing' )
|
|
121
|
-
, 'yo' : (dependencies,r) => result = r
|
|
122
|
-
}}
|
|
123
|
-
short.load ( myAllContext )
|
|
124
|
-
short.changeContext ( 'myAll' )
|
|
125
|
-
short.emit ( 'yo', 'hello' )
|
|
126
|
-
expect ( result ).to.be.equal ( 'hello' )
|
|
127
|
-
short.changeContext ( 'general' )
|
|
128
|
-
short.unload ( 'myAll' )
|
|
129
|
-
}) // it emit custom event
|
|
130
146
|
|
|
147
|
+
it ( 'Dependencies on shortcuts', done => {
|
|
148
|
+
const task = askForPromise ();
|
|
149
|
+
expect ( a ).to.be.false
|
|
150
|
+
expect ( b ).to.be.false
|
|
151
|
+
|
|
152
|
+
short.enablePlugin ( pluginClick )
|
|
153
|
+
short.setDependencies ({ task })
|
|
154
|
+
|
|
155
|
+
short.load ({
|
|
156
|
+
'extra' : { // load will overwrite existing 'extra' context definition
|
|
157
|
+
'click: left-1' : ({dependencies}) => {
|
|
158
|
+
const { task } = dependencies;
|
|
159
|
+
expect ( task ).to.have.property ( 'done' )
|
|
160
|
+
expect ( task ).to.have.property ( 'promise' )
|
|
161
|
+
a = true
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}) // load will restart the selected context
|
|
165
|
+
|
|
166
|
+
short.changeContext ( 'extra' )
|
|
167
|
+
cy.get('#rspan').click ()
|
|
168
|
+
cy.wait ( 350 ) // Default wait mouse timeout is 320 ms
|
|
169
|
+
.then ( () => {
|
|
170
|
+
expect ( a ).to.be.true
|
|
171
|
+
done ()
|
|
172
|
+
})
|
|
173
|
+
}) // it dependencies on shortcuts
|
|
131
174
|
|
|
132
175
|
|
|
133
|
-
it ( 'Dependencies on shortcuts', done => {
|
|
134
|
-
const task = askForPromise ();
|
|
135
|
-
expect ( a ).to.be.false
|
|
136
|
-
expect ( b ).to.be.false
|
|
137
176
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
expect ( a ).to.be.true
|
|
156
|
-
done ()
|
|
157
|
-
})
|
|
158
|
-
}) // it dependencies on shortcuts
|
|
177
|
+
it ( 'Emit custom event', done => {
|
|
178
|
+
let result = null;
|
|
179
|
+
short.changeContext ()
|
|
180
|
+
short.enablePlugin ( pluginClick )
|
|
181
|
+
const myAllContext = {
|
|
182
|
+
myAll: {
|
|
183
|
+
'click : leff-1' : () => console.log ( 'nothing' )
|
|
184
|
+
, 'yo' : ({msg}) => result = msg
|
|
185
|
+
}}
|
|
186
|
+
short.load ( myAllContext )
|
|
187
|
+
short.changeContext ( 'myAll' )
|
|
188
|
+
short.emit ( 'yo', { context: short.getContext(), note: 'tt', type:'custom', msg:'hello' })
|
|
189
|
+
expect ( result ).to.be.equal ( 'hello' )
|
|
190
|
+
short.changeContext ( 'general' )
|
|
191
|
+
short.unload ( 'myAll' )
|
|
192
|
+
done ()
|
|
193
|
+
}) // it emit custom event
|
|
159
194
|
|
|
160
195
|
|
|
161
196
|
|
|
162
197
|
it ( 'List shortcuts', () => {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
let all = short.listShortcuts ();
|
|
172
|
-
expect ( all ).to.be.an('array')
|
|
173
|
-
|
|
174
|
-
expect ( all ).to.have.lengthOf ( 2 )
|
|
175
|
-
expect ( all[0] ).to.have.property ( 'context' )
|
|
176
|
-
expect ( all[0] ).to.have.property ( 'shortcuts' )
|
|
177
|
-
expect ( all[0].shortcuts ).to.be.an('array')
|
|
178
|
-
expect ( all[0].shortcuts ).to.have.lengthOf ( 1 )
|
|
179
|
-
expect ( all[0].shortcuts[0] ).to.be.equal ( 'A+SHIFT' )
|
|
180
|
-
expect ( all[0].context ).to.be.equal ( 'general' )
|
|
198
|
+
let general = short.listShortcuts ('general');
|
|
199
|
+
expect ( general ).to.be.an('array')
|
|
200
|
+
expect ( general ).to.have.lengthOf ( 1 )
|
|
201
|
+
expect ( general[0] ).to.be.equal ( 'KEY:A+SHIFT' )
|
|
202
|
+
|
|
203
|
+
let fail = short.listShortcuts ('somethingNotExisting');
|
|
204
|
+
expect ( fail ).to.be.null
|
|
181
205
|
|
|
182
|
-
|
|
206
|
+
let all = short.listShortcuts ();
|
|
207
|
+
expect ( all ).to.be.an('array')
|
|
208
|
+
|
|
209
|
+
expect ( all ).to.have.lengthOf ( 2 )
|
|
210
|
+
expect ( all[0] ).to.have.property ( 'context' )
|
|
211
|
+
expect ( all[0] ).to.have.property ( 'shortcuts' )
|
|
212
|
+
expect ( all[0].shortcuts ).to.be.an('array')
|
|
213
|
+
expect ( all[0].shortcuts ).to.have.lengthOf ( 1 )
|
|
214
|
+
expect ( all[0].shortcuts[0] ).to.be.equal ( 'KEY:A+SHIFT' )
|
|
215
|
+
expect ( all[0].context ).to.be.equal ( 'general' )
|
|
216
|
+
}) // it list shortcuts
|
|
183
217
|
|
|
184
218
|
|
|
185
219
|
|
|
186
220
|
it ( 'Click on anchor', done => {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
221
|
+
// Click on anchor that don't have click-data attribute.
|
|
222
|
+
let result = 'none';
|
|
223
|
+
short.load ({ 'extra' : {
|
|
224
|
+
'click: 1 - left' : ({target, context, event }) => { // Order of button name and number of click is not important
|
|
225
|
+
event.preventDefault ()
|
|
226
|
+
expect ( context ).to.be.equal ( 'extra' )
|
|
227
|
+
expect ( target.nodeName ).to.be.equal ( 'A' )
|
|
228
|
+
result = target.nodeName
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
short.changeContext ( 'extra' )
|
|
233
|
+
cy.get ( '#anchor' ).click ()
|
|
234
|
+
cy.wait ( 3 ) // Consider mouse click has some latency
|
|
235
|
+
// According Cypress documentation:
|
|
236
|
+
// It is unsafe to chain further commands that rely on the subject after .click().
|
|
237
|
+
// source docs: https://docs.cypress.io/api/commands/click
|
|
238
|
+
.then ( () => {
|
|
239
|
+
short.changeContext ( 'general' )
|
|
240
|
+
expect ( result ).to.be.equal ( 'A' )
|
|
241
|
+
done ()
|
|
242
|
+
})
|
|
243
|
+
}) // it click on anchor
|
|
244
|
+
}) // describe
|
|
245
|
+
|
|
246
|
+
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
function _findTarget ( dependencies, state ) {
|
|
4
|
-
const { listenOptions : {clickTarget}} = state;
|
|
5
|
-
return function _findTarget ( target ) {
|
|
6
|
-
const t = target;
|
|
7
|
-
if ( t === document ) return null
|
|
8
|
-
if ( t === document.body ) return null
|
|
9
|
-
|
|
10
|
-
if ( t.dataset[clickTarget] ) return t
|
|
11
|
-
if ( t.nodeName === 'A' ) return t
|
|
12
|
-
return _findTarget ( t.parentNode )
|
|
13
|
-
}} // _findTarget func.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export default _findTarget
|
|
18
|
-
|
|
19
|
-
|
package/src/methods/_listen.js
DELETED
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function _listen ( dependencies, state ) {
|
|
6
|
-
// Listen for input signals and generate event titles
|
|
7
|
-
return function _listen () {
|
|
8
|
-
const {
|
|
9
|
-
ev
|
|
10
|
-
, inAPI : {
|
|
11
|
-
_findTarget
|
|
12
|
-
, _specialChars
|
|
13
|
-
, _readKeyEvent
|
|
14
|
-
, _readMouseEvent
|
|
15
|
-
}
|
|
16
|
-
} = dependencies
|
|
17
|
-
, {
|
|
18
|
-
exposeShortcut
|
|
19
|
-
, currentContext
|
|
20
|
-
, streamKeys
|
|
21
|
-
, listenOptions
|
|
22
|
-
} = state
|
|
23
|
-
, {
|
|
24
|
-
mouseWait
|
|
25
|
-
, keyWait
|
|
26
|
-
, clickTarget
|
|
27
|
-
, listenFor
|
|
28
|
-
} = listenOptions
|
|
29
|
-
;
|
|
30
|
-
|
|
31
|
-
let
|
|
32
|
-
r = []
|
|
33
|
-
, mouseTarget = null // Dom element or null
|
|
34
|
-
, mouseDomEvent = null
|
|
35
|
-
, keyTimer = null // Timer for key sequence or null
|
|
36
|
-
, mouseTimer = null // Timer for mouse sequence or null
|
|
37
|
-
, mouseIgnore = null // Timer for ignoring mouse clicks or null
|
|
38
|
-
, sequence = true
|
|
39
|
-
, ignore = false // Use to trigger a single callback without adding the key to the sequence.
|
|
40
|
-
, count = 0
|
|
41
|
-
;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
waitKeys = () => sequence = false
|
|
48
|
-
, endKeys = () => sequence = true
|
|
49
|
-
, ignoreKeys = () => ignore = true
|
|
50
|
-
, waitingKeys = () => sequence === false
|
|
51
|
-
;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
function keySequenceEnd () { // Execute when key sequence ends
|
|
56
|
-
let res = r.map ( x => ([x.join('+')]) );
|
|
57
|
-
if ( !sequence ) {
|
|
58
|
-
let signal = res.at(-1);
|
|
59
|
-
ev.emit ( signal, { wait:waitKeys, end:endKeys, ignore:ignoreKeys, isWaiting:waitingKeys, note: currentContext.note, context: currentContext.name })
|
|
60
|
-
if ( ignore ) {
|
|
61
|
-
res = res.slice ( 0, -1 )
|
|
62
|
-
ignore = false
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
const data = {
|
|
66
|
-
wait: waitKeys
|
|
67
|
-
, end:endKeys
|
|
68
|
-
, ignore:ignoreKeys
|
|
69
|
-
, isWaiting:waitingKeys
|
|
70
|
-
, note: currentContext.note
|
|
71
|
-
, context: currentContext.name
|
|
72
|
-
, dependencies : dependencies.extra
|
|
73
|
-
};
|
|
74
|
-
if ( sequence ) {
|
|
75
|
-
ev.emit ( res.join(','), data )
|
|
76
|
-
if ( exposeShortcut ) exposeShortcut ({ shortcut:res.join(','), context: currentContext.name, note:currentContext.note, dependencies:dependencies.extra })
|
|
77
|
-
// Reset:
|
|
78
|
-
r = []
|
|
79
|
-
keyTimer = null
|
|
80
|
-
}
|
|
81
|
-
} // keySequeceEnd func.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
function mouseSequenceEnd () { // Execute when mouse sequence ends
|
|
86
|
-
const
|
|
87
|
-
mouseEvent = _readMouseEvent ( mouseDomEvent, count )
|
|
88
|
-
, data = {
|
|
89
|
-
target : mouseTarget
|
|
90
|
-
, targetProps : mouseTarget ? mouseTarget.getBoundingClientRect() : null
|
|
91
|
-
, x : mouseDomEvent.clientX
|
|
92
|
-
, y : mouseDomEvent.clientY
|
|
93
|
-
, context : currentContext.name
|
|
94
|
-
, note : currentContext.note
|
|
95
|
-
, event : mouseDomEvent
|
|
96
|
-
, dependencies : dependencies.extra
|
|
97
|
-
}
|
|
98
|
-
;
|
|
99
|
-
ev.emit ( mouseEvent.join('+'), data )
|
|
100
|
-
if ( exposeShortcut ) exposeShortcut ({ shortcut: mouseEvent.join('+'), context:currentContext.name, note:currentContext.note, dependencies:dependencies.extra })
|
|
101
|
-
// Reset:
|
|
102
|
-
mouseTimer = null
|
|
103
|
-
mouseIgnore = null
|
|
104
|
-
mouseTarget = null
|
|
105
|
-
mouseDomEvent = null
|
|
106
|
-
count = 0
|
|
107
|
-
} // mouseSequenceEnd func.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
function listenMouse () {
|
|
112
|
-
window.addEventListener ( 'contextmenu', event => { // Listen for right mouse clicks
|
|
113
|
-
let targetMax = listenOptions.maxClicks; // Maximum number of clicks per target
|
|
114
|
-
event.preventDefault ()
|
|
115
|
-
clearTimeout ( mouseTimer )
|
|
116
|
-
if ( mouseIgnore ) {
|
|
117
|
-
clearTimeout ( mouseIgnore )
|
|
118
|
-
mouseIgnore = setTimeout ( () => mouseIgnore=null, mouseWait )
|
|
119
|
-
return
|
|
120
|
-
}
|
|
121
|
-
mouseTarget = _findTarget ( event.target )
|
|
122
|
-
if ( mouseTarget && mouseTarget.dataset.hasOwnProperty('quickClick')) targetMax = 1
|
|
123
|
-
if ( mouseTarget && mouseTarget.tagName === 'A' ) targetMax = 1
|
|
124
|
-
mouseDomEvent = event
|
|
125
|
-
count++
|
|
126
|
-
if ( count >= targetMax ) {
|
|
127
|
-
mouseSequenceEnd ()
|
|
128
|
-
if ( targetMax > 1 ) mouseIgnore = setTimeout ( () => mouseIgnore=null, mouseWait )
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
mouseTimer = setTimeout ( mouseSequenceEnd, mouseWait )
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
document.addEventListener ( 'click', event => { // Listen for left and middle mouse clicks
|
|
135
|
-
let targetMax = listenOptions.maxClicks; // Maximum number of clicks per target
|
|
136
|
-
event.preventDefault ()
|
|
137
|
-
clearTimeout ( mouseTimer )
|
|
138
|
-
if ( mouseIgnore ) {
|
|
139
|
-
clearTimeout ( mouseIgnore )
|
|
140
|
-
mouseIgnore = setTimeout ( () => mouseIgnore=null, mouseWait )
|
|
141
|
-
return
|
|
142
|
-
}
|
|
143
|
-
mouseTarget = _findTarget ( event.target )
|
|
144
|
-
if ( mouseTarget && mouseTarget.dataset.hasOwnProperty('quickClick')) targetMax = 1
|
|
145
|
-
if ( mouseTarget && mouseTarget.tagName === 'A' ) targetMax = 1
|
|
146
|
-
mouseDomEvent = event
|
|
147
|
-
count++
|
|
148
|
-
if ( count >= targetMax ) {
|
|
149
|
-
mouseSequenceEnd ()
|
|
150
|
-
if ( targetMax > 1 ) mouseIgnore = setTimeout ( () => mouseIgnore=null, mouseWait )
|
|
151
|
-
return
|
|
152
|
-
}
|
|
153
|
-
mouseTimer = setTimeout ( mouseSequenceEnd, mouseWait )
|
|
154
|
-
})
|
|
155
|
-
} // listenMouse func.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
function listenKeyboard () {
|
|
160
|
-
document.addEventListener ( 'keydown', event => { // Listen for special keyboard keys
|
|
161
|
-
clearTimeout ( keyTimer )
|
|
162
|
-
if ( _specialChars.hasOwnProperty(event.code) ) r.push ( _readKeyEvent ( event, _specialChars ))
|
|
163
|
-
else return
|
|
164
|
-
if ( streamKeys ) streamKeys ({ key:event.key, context:currentContext.name, note:currentContext.note, dependencies:dependencies.extra })
|
|
165
|
-
if ( listenOptions.keyIgnore ) {
|
|
166
|
-
clearTimeout ( listenOptions.keyIgnore )
|
|
167
|
-
listenOptions.keyIgnore = setTimeout ( () => listenOptions.keyIgnore=null, keyWait )
|
|
168
|
-
return
|
|
169
|
-
}
|
|
170
|
-
if ( sequence && r.length === listenOptions.maxSequence ) {
|
|
171
|
-
keySequenceEnd ()
|
|
172
|
-
listenOptions.keyIgnore = setTimeout ( () => listenOptions.keyIgnore=null, keyWait )
|
|
173
|
-
return
|
|
174
|
-
}
|
|
175
|
-
if ( sequence ) keyTimer = setTimeout ( keySequenceEnd, keyWait )
|
|
176
|
-
else keySequenceEnd ()
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
document.addEventListener ( 'keypress', event => { // Listen for regular keyboard keys
|
|
180
|
-
if ( _specialChars.hasOwnProperty(event.code) ) return
|
|
181
|
-
clearTimeout ( keyTimer )
|
|
182
|
-
if ( streamKeys ) streamKeys ({ key:event.key, context:currentContext.name, note:currentContext.note, dependencies:dependencies.extra })
|
|
183
|
-
if ( listenOptions.keyIgnore ) {
|
|
184
|
-
clearTimeout ( listenOptions.keyIgnore )
|
|
185
|
-
listenOptions.keyIgnore = setTimeout ( () => listenOptions.keyIgnore=null, keyWait )
|
|
186
|
-
return
|
|
187
|
-
}
|
|
188
|
-
r.push ( _readKeyEvent ( event, _specialChars ))
|
|
189
|
-
if ( sequence && r.length === listenOptions.maxSequence ) {
|
|
190
|
-
keySequenceEnd ()
|
|
191
|
-
listenOptions.keyIgnore = setTimeout ( () => listenOptions.keyIgnore=null, keyWait )
|
|
192
|
-
return
|
|
193
|
-
}
|
|
194
|
-
if ( sequence ) keyTimer = setTimeout ( keySequenceEnd, keyWait )
|
|
195
|
-
else keySequenceEnd ()
|
|
196
|
-
})
|
|
197
|
-
} // listenKeyboard func.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
if ( listenFor.includes('mouse') ) listenMouse ()
|
|
202
|
-
if ( listenFor.includes('keyboard') ) listenKeyboard ()
|
|
203
|
-
|
|
204
|
-
}} // _listen func.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
export default _listen
|
|
209
|
-
|
|
210
|
-
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
function _readMouseEvent () {
|
|
4
|
-
return function _readMouseEvent ( event, count ) {
|
|
5
|
-
let
|
|
6
|
-
{ shiftKey, altKey, ctrlKey, key, button } = event
|
|
7
|
-
, mouseNames = [ 'LEFT', 'MIDDLE', 'RIGHT' ]
|
|
8
|
-
, mouseEvent = `MOUSE-CLICK-${mouseNames[button]}-${count}`
|
|
9
|
-
, res = []
|
|
10
|
-
;
|
|
11
|
-
|
|
12
|
-
res.push ( mouseEvent )
|
|
13
|
-
if ( ctrlKey ) res.push ( 'CTRL' )
|
|
14
|
-
if ( shiftKey ) res.push ( 'SHIFT' )
|
|
15
|
-
if ( altKey ) res.push ( 'ALT' )
|
|
16
|
-
|
|
17
|
-
return res.sort ()
|
|
18
|
-
}} // _readMouseEvent func.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
export default _readMouseEvent
|
|
23
|
-
|
|
24
|
-
|