@cxl/keyboard 1.0.0 → 1.1.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/LICENSE +674 -0
- package/README.md +5 -6
- package/index.bundle.js +1 -0
- package/index.d.ts +30 -16
- package/package.json +11 -14
- package/amd/index.d.ts +0 -92
- package/amd/index.js +0 -1
- package/index.js +0 -233
- package/index.min.js +0 -1
- package/mjs/index.d.ts +0 -91
- package/mjs/index.js +0 -1
- package/test.d.ts +0 -2
- package/test.js +0 -239
package/test.js
DELETED
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const spec_1 = require("@cxl/spec");
|
|
4
|
-
const index_js_1 = require("@cxl/keyboard");
|
|
5
|
-
exports.default = (0, spec_1.spec)('keyboard', s => {
|
|
6
|
-
s.test('normalize', it => {
|
|
7
|
-
it.should('handle empty and null inputs', a => {
|
|
8
|
-
a.equal((0, index_js_1.normalize)(''), '');
|
|
9
|
-
});
|
|
10
|
-
it.should('parse single keys', a => {
|
|
11
|
-
a.equal((0, index_js_1.normalize)(' x '), 'x');
|
|
12
|
-
a.equal((0, index_js_1.normalize)('ctrl+x'), 'ctrl+x');
|
|
13
|
-
});
|
|
14
|
-
it.should('parse multiple keys', a => {
|
|
15
|
-
a.equal((0, index_js_1.normalize)(' x y'), 'x y');
|
|
16
|
-
a.equal((0, index_js_1.normalize)('x y'), 'x y');
|
|
17
|
-
a.equal((0, index_js_1.normalize)('ctrl+shift+x'), 'ctrl+shift+x');
|
|
18
|
-
});
|
|
19
|
-
it.should('parse mod key', a => {
|
|
20
|
-
const layout = {
|
|
21
|
-
...index_js_1.KeyboardLayoutData['en-US'],
|
|
22
|
-
modKey: 'ctrlKey',
|
|
23
|
-
};
|
|
24
|
-
a.equal((0, index_js_1.normalize)('mod+x', layout), 'ctrl+x');
|
|
25
|
-
a.equal((0, index_js_1.normalize)('x+mod', layout), 'ctrl+x');
|
|
26
|
-
a.equal((0, index_js_1.normalize)('MOD+X', layout), 'ctrl+x');
|
|
27
|
-
layout.modKey = 'metaKey';
|
|
28
|
-
a.equal((0, index_js_1.normalize)('mod+x', layout), 'meta+x');
|
|
29
|
-
a.equal((0, index_js_1.normalize)('x+mod', layout), 'meta+x');
|
|
30
|
-
a.equal((0, index_js_1.normalize)('MOD+X', layout), 'meta+x');
|
|
31
|
-
});
|
|
32
|
-
it.should('normalize shifted keys', a => {
|
|
33
|
-
a.equal((0, index_js_1.normalize)('%'), 'shift+5');
|
|
34
|
-
a.equal((0, index_js_1.normalize)('shift+A'), 'shift+a');
|
|
35
|
-
a.equal((0, index_js_1.normalize)('shift+y'), 'shift+y');
|
|
36
|
-
a.equal((0, index_js_1.normalize)('shift+ctrl+5'), 'ctrl+shift+5');
|
|
37
|
-
a.equal((0, index_js_1.normalize)('ctrl+%'), 'ctrl+shift+5');
|
|
38
|
-
});
|
|
39
|
-
it.should('handle non character keys', a => {
|
|
40
|
-
a.equal((0, index_js_1.normalize)(':'), 'shift+;');
|
|
41
|
-
a.equal((0, index_js_1.normalize)('/'), '/');
|
|
42
|
-
a.equal((0, index_js_1.normalize)('.'), '.');
|
|
43
|
-
a.equal((0, index_js_1.normalize)('?'), 'shift+/');
|
|
44
|
-
a.equal((0, index_js_1.normalize)('shift+/'), 'shift+/');
|
|
45
|
-
//a.equal(normalize('shift++'), 'shift+=');
|
|
46
|
-
a.equal((0, index_js_1.normalize)('shift+?'), 'shift+/');
|
|
47
|
-
a.equal((0, index_js_1.normalize)('ctrl+:'), 'ctrl+shift+;');
|
|
48
|
-
a.equal((0, index_js_1.normalize)('ctrl+shift+?'), 'ctrl+shift+/');
|
|
49
|
-
a.equal((0, index_js_1.normalize)(';'), ';');
|
|
50
|
-
});
|
|
51
|
-
it.should('normalize special keys with modifiers', a => {
|
|
52
|
-
a.equal((0, index_js_1.normalize)('ctrl+alt+del'), 'ctrl+alt+del');
|
|
53
|
-
a.equal((0, index_js_1.normalize)('ctrl+shift+esc'), 'ctrl+shift+esc');
|
|
54
|
-
});
|
|
55
|
-
it.should('handle case sensitivity', a => {
|
|
56
|
-
a.equal((0, index_js_1.normalize)('CTRL+A'), 'ctrl+a');
|
|
57
|
-
a.equal((0, index_js_1.normalize)('Shift+Y'), 'shift+y');
|
|
58
|
-
});
|
|
59
|
-
/*it.should('handle complex sequences', a => {
|
|
60
|
-
a.equal(
|
|
61
|
-
normalize(' ctrl + shift + x ctrl+y'),
|
|
62
|
-
'ctrl+shift+x ctrl+y',
|
|
63
|
-
);
|
|
64
|
-
});*/
|
|
65
|
-
});
|
|
66
|
-
s.test('parseKey', it => {
|
|
67
|
-
it.should('correctly parse simple keys without modifiers', a => {
|
|
68
|
-
const result = (0, index_js_1.parseKey)('a');
|
|
69
|
-
a.equal(result.length, 1);
|
|
70
|
-
a.equal(result[0].key, 'a');
|
|
71
|
-
a.equal(result[0].shiftKey, false);
|
|
72
|
-
a.equal(result[0].ctrlKey, false);
|
|
73
|
-
a.equal(result[0].altKey, false);
|
|
74
|
-
a.equal(result[0].metaKey, false);
|
|
75
|
-
});
|
|
76
|
-
it.should('correctly parse modifier keys', a => {
|
|
77
|
-
const result = (0, index_js_1.parseKey)('shift+b');
|
|
78
|
-
a.equal(result.length, 1);
|
|
79
|
-
a.equal(result[0].key, 'b');
|
|
80
|
-
a.equal(result[0].shiftKey, true);
|
|
81
|
-
a.equal(result[0].ctrlKey, false);
|
|
82
|
-
a.equal(result[0].altKey, false);
|
|
83
|
-
a.equal(result[0].metaKey, false);
|
|
84
|
-
});
|
|
85
|
-
it.should('correctly parse multiple keys with modifiers', a => {
|
|
86
|
-
const result = (0, index_js_1.parseKey)('ctrl+alt+del');
|
|
87
|
-
a.equal(result.length, 1);
|
|
88
|
-
a.equal(result[0].key, 'del');
|
|
89
|
-
a.equal(result[0].shiftKey, false);
|
|
90
|
-
a.equal(result[0].ctrlKey, true);
|
|
91
|
-
a.equal(result[0].altKey, true);
|
|
92
|
-
a.equal(result[0].metaKey, false);
|
|
93
|
-
});
|
|
94
|
-
it.should('handle key sequences separated by spaces', a => {
|
|
95
|
-
const result = (0, index_js_1.parseKey)('ctrl+a ctrl+b');
|
|
96
|
-
a.equal(result.length, 2);
|
|
97
|
-
a.equal(result[0].key, 'a');
|
|
98
|
-
a.equal(result[0].ctrlKey, true);
|
|
99
|
-
a.equal(result[1].key, 'b');
|
|
100
|
-
a.equal(result[1].ctrlKey, true);
|
|
101
|
-
});
|
|
102
|
-
it.should('map mod key to the correct modifier', a => {
|
|
103
|
-
const layout = index_js_1.KeyboardLayoutData['en-US'];
|
|
104
|
-
const result = (0, index_js_1.parseKey)('mod+c', { ...layout, modKey: 'ctrlKey' });
|
|
105
|
-
a.equal(result.length, 1);
|
|
106
|
-
a.equal(result[0].key, 'c');
|
|
107
|
-
a.equal(result[0].ctrlKey, true);
|
|
108
|
-
const result2 = (0, index_js_1.parseKey)('mod+c', { ...layout, modKey: 'metaKey' });
|
|
109
|
-
a.equal(result2.length, 1);
|
|
110
|
-
a.equal(result2[0].key, 'c');
|
|
111
|
-
a.equal(result2[0].metaKey, true);
|
|
112
|
-
});
|
|
113
|
-
it.should('handle shifted characters correctly', a => {
|
|
114
|
-
const result = (0, index_js_1.parseKey)('shift+1');
|
|
115
|
-
a.equal(result.length, 1);
|
|
116
|
-
a.equal(result[0].key, '1'); // assuming shift+1 maps to '@' in shiftMap
|
|
117
|
-
a.equal(result[0].shiftKey, true);
|
|
118
|
-
});
|
|
119
|
-
it.should('handle keys with special characters', a => {
|
|
120
|
-
const result = (0, index_js_1.parseKey)('ctrl+shift+1');
|
|
121
|
-
a.equal(result.length, 1);
|
|
122
|
-
a.equal(result[0].key, '1');
|
|
123
|
-
a.equal(result[0].ctrlKey, true);
|
|
124
|
-
a.equal(result[0].shiftKey, true);
|
|
125
|
-
});
|
|
126
|
-
it.should('handle unsupported modifier combinations', a => {
|
|
127
|
-
const result = (0, index_js_1.parseKey)('ctrl+alt+meta+z');
|
|
128
|
-
a.equal(result.length, 1);
|
|
129
|
-
a.equal(result[0].key, 'z');
|
|
130
|
-
a.equal(result[0].ctrlKey, true);
|
|
131
|
-
a.equal(result[0].altKey, true);
|
|
132
|
-
a.equal(result[0].metaKey, true);
|
|
133
|
-
});
|
|
134
|
-
it.should('correctly parse special character keys', a => {
|
|
135
|
-
const result = (0, index_js_1.parseKey)('ctrl+alt+!');
|
|
136
|
-
a.equal(result.length, 1);
|
|
137
|
-
a.equal(result[0].key, '1');
|
|
138
|
-
a.equal(result[0].ctrlKey, true);
|
|
139
|
-
a.equal(result[0].altKey, true);
|
|
140
|
-
a.equal(result[0].shiftKey, true);
|
|
141
|
-
});
|
|
142
|
-
it.should('handle unsupported character sequences', a => {
|
|
143
|
-
const result = (0, index_js_1.parseKey)('ctrl+alt+ctrl+z');
|
|
144
|
-
a.equal(result.length, 1);
|
|
145
|
-
a.equal(result[0].key, 'z');
|
|
146
|
-
a.equal(result[0].ctrlKey, true);
|
|
147
|
-
a.equal(result[0].altKey, true);
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
s.test('handleKeyboard', it => {
|
|
151
|
-
it.should('call onKey with the correct sequence', (a) => {
|
|
152
|
-
// Setup a mock element
|
|
153
|
-
const elementMock = a.element('div');
|
|
154
|
-
const on = a.spyFn(elementMock, 'addEventListener');
|
|
155
|
-
const off = a.spyFn(elementMock, 'removeEventListener');
|
|
156
|
-
// Setup a mock callback
|
|
157
|
-
const onKeyMock = (0, spec_1.mockFn)(key => (key === 'a b' ? true : false));
|
|
158
|
-
// Register the handler
|
|
159
|
-
const dispose = (0, index_js_1.handleKeyboard)({
|
|
160
|
-
element: elementMock,
|
|
161
|
-
onKey: onKeyMock,
|
|
162
|
-
delay: 100,
|
|
163
|
-
layout: undefined,
|
|
164
|
-
capture: false,
|
|
165
|
-
});
|
|
166
|
-
// Simulate keydown events
|
|
167
|
-
const eventA = new KeyboardEvent('keydown', { key: 'a' });
|
|
168
|
-
const eventB = new KeyboardEvent('keydown', { key: 'b' });
|
|
169
|
-
// This will call the handler linked to the event
|
|
170
|
-
a.assert(typeof on.lastEvent?.arguments[1] === 'function');
|
|
171
|
-
on.lastEvent?.arguments[1](eventA);
|
|
172
|
-
a.equal(onKeyMock.lastArguments?.[0], 'a');
|
|
173
|
-
on.lastEvent?.arguments[1](eventB);
|
|
174
|
-
a.equal(onKeyMock.lastArguments?.[0], 'a b');
|
|
175
|
-
// Cleanup
|
|
176
|
-
dispose();
|
|
177
|
-
a.equal(off.lastEvent?.called, 1);
|
|
178
|
-
});
|
|
179
|
-
it.should('reset sequence after delay', async (a) => {
|
|
180
|
-
const elementMock = a.element('div');
|
|
181
|
-
const on = a.spyFn(elementMock, 'addEventListener');
|
|
182
|
-
const off = a.spyFn(elementMock, 'removeEventListener');
|
|
183
|
-
const onKeyMock = (0, spec_1.mockFn)(key => (key === 'a b' ? true : false));
|
|
184
|
-
const dispose = (0, index_js_1.handleKeyboard)({
|
|
185
|
-
element: elementMock,
|
|
186
|
-
onKey: onKeyMock,
|
|
187
|
-
delay: 100,
|
|
188
|
-
layout: undefined,
|
|
189
|
-
capture: false,
|
|
190
|
-
});
|
|
191
|
-
// Simulate keydown event
|
|
192
|
-
const eventA = new KeyboardEvent('keydown', { key: 'a' });
|
|
193
|
-
a.assert(typeof on.lastEvent?.arguments[1] === 'function');
|
|
194
|
-
on.lastEvent?.arguments[1](eventA);
|
|
195
|
-
// Advance time beyond delay
|
|
196
|
-
await new Promise(resolve => setTimeout(resolve, 200));
|
|
197
|
-
a.equal(onKeyMock.lastArguments?.[0], 'a');
|
|
198
|
-
// Simulate another keydown event
|
|
199
|
-
const eventC = new KeyboardEvent('keydown', { key: 'c' });
|
|
200
|
-
on.lastEvent?.arguments[1](eventC);
|
|
201
|
-
a.equal(onKeyMock.lastArguments?.[0], 'c');
|
|
202
|
-
// Cleanup
|
|
203
|
-
dispose();
|
|
204
|
-
a.equal(off.lastEvent?.called, 1);
|
|
205
|
-
});
|
|
206
|
-
it.should('handle rapid key presses correctly', (a) => {
|
|
207
|
-
const elementMock = a.element('div');
|
|
208
|
-
const on = a.spyFn(elementMock, 'addEventListener');
|
|
209
|
-
const onKeyMock = (0, spec_1.mockFn)(key => key === 'x y');
|
|
210
|
-
const dispose = (0, index_js_1.handleKeyboard)({
|
|
211
|
-
element: elementMock,
|
|
212
|
-
onKey: onKeyMock,
|
|
213
|
-
delay: 100,
|
|
214
|
-
layout: undefined,
|
|
215
|
-
capture: false,
|
|
216
|
-
});
|
|
217
|
-
const eventX = new KeyboardEvent('keydown', { key: 'x' });
|
|
218
|
-
const eventY = new KeyboardEvent('keydown', { key: 'y' });
|
|
219
|
-
a.assert(typeof on.lastEvent?.arguments[1] === 'function');
|
|
220
|
-
on.lastEvent?.arguments[1](eventX);
|
|
221
|
-
on.lastEvent?.arguments[1](eventY);
|
|
222
|
-
a.equal(onKeyMock.lastArguments?.[0], 'x y');
|
|
223
|
-
dispose();
|
|
224
|
-
});
|
|
225
|
-
it.should('verify event listener is removed on dispose', (a) => {
|
|
226
|
-
const elementMock = a.element('div');
|
|
227
|
-
const off = a.spyFn(elementMock, 'removeEventListener');
|
|
228
|
-
const dispose = (0, index_js_1.handleKeyboard)({
|
|
229
|
-
element: elementMock,
|
|
230
|
-
onKey: (0, spec_1.mockFn)(() => true),
|
|
231
|
-
delay: 100,
|
|
232
|
-
layout: undefined,
|
|
233
|
-
capture: false,
|
|
234
|
-
});
|
|
235
|
-
dispose();
|
|
236
|
-
a.equal(off.lastEvent?.called, 1);
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
});
|