rx-hotkeys 2.1.1 → 2.2.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/dist/hotkeys.d.ts +20 -0
- package/dist/hotkeys.d.ts.map +1 -1
- package/dist/hotkeys.js +49 -10
- package/dist/hotkeys.test.js +142 -8
- package/package.json +1 -1
package/dist/hotkeys.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Observable } from "rxjs";
|
|
1
2
|
import { StandardKey } from "./keys.js";
|
|
2
3
|
export declare enum ShortcutTypes {
|
|
3
4
|
Combination = "combination",
|
|
@@ -96,6 +97,25 @@ export declare class Hotkeys {
|
|
|
96
97
|
* @param enable - True to enable debug logs, false to disable.
|
|
97
98
|
*/
|
|
98
99
|
setDebugMode(enable: boolean): void;
|
|
100
|
+
/**
|
|
101
|
+
* An Observable that emits the new context name (or null) whenever the active context changes.
|
|
102
|
+
* This allows external parts of the application to react to context transitions.
|
|
103
|
+
*
|
|
104
|
+
* Note: This observable benefits from the distinct check within the `setContext` method,
|
|
105
|
+
* meaning it will only emit when the context value actually changes.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* const hotkeys = new Hotkeys();
|
|
110
|
+
* const subscription = hotkeys.onContextChange$.subscribe(newContext => {
|
|
111
|
+
* console.log("Hotkey context changed to:", newContext);
|
|
112
|
+
* // Update UI or perform other actions
|
|
113
|
+
* });
|
|
114
|
+
* // To unsubscribe when no longer needed:
|
|
115
|
+
* // subscription.unsubscribe();
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
get onContextChange$(): Observable<string | null>;
|
|
99
119
|
/**
|
|
100
120
|
* Checks if a shortcut with the given ID is currently registered and active.
|
|
101
121
|
* @param id - The unique ID of the shortcut to check.
|
package/dist/hotkeys.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hotkeys.d.ts","sourceRoot":"","sources":["../src/hotkeys.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hotkeys.d.ts","sourceRoot":"","sources":["../src/hotkeys.ts"],"names":[],"mappings":"AAAA,OAAO,EACuC,UAAU,EAEvD,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAIxC,oBAAY,aAAa;IACrB,WAAW,gBAAgB;IAC3B,QAAQ,aAAa;CACxB;AAED,UAAU,kBAAkB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC5D;;;;;;;;;;OAUG;IACH,IAAI,EAAE;QACF;;;;;;;;;WASG;QACH,GAAG,EAAE,WAAW,CAAC;QACjB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;KACrB,GAAG,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IACzD;;;;;;;;OAQG;IACH,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAyCD;;;;GAIG;AACH,qBAAa,OAAO;IAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAa;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAc;IAEhD,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,cAAc,CAAiC;IACvD,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,SAAS,CAAU;IAE3B;;;;;OAKG;gBACS,cAAc,GAAE,MAAM,GAAG,IAAW,EAAE,SAAS,GAAE,OAAe;IAe5E;;;;;;OAMG;IACI,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAiBnD;;;OAGG;IACI,UAAU,IAAI,MAAM,GAAG,IAAI;IAIlC;;;;OAIG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAa1C;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAW,gBAAgB,IAAI,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,CAEvD;IAED;;;;OAIG;IACI,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIvC,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,iBAAiB;IAkBzB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACI,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,GAAG,SAAS;IAgFvE;;;;;;;;;;;;;;;;;;;OAmBG;IACI,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS;IAkHjE;;;;;;OAMG;IACI,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAYlC;;;;;;OAMG;IACI,kBAAkB,IAAI;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,aAAa,CAAA;KAAC,EAAE;IAa/G;;;;;OAKG;IACI,OAAO,IAAI,IAAI;CAOzB"}
|
package/dist/hotkeys.js
CHANGED
|
@@ -65,8 +65,17 @@ export class Hotkeys {
|
|
|
65
65
|
* Pass `null` to activate shortcuts with no context or to deactivate context-specific shortcuts.
|
|
66
66
|
*/
|
|
67
67
|
setContext(contextName) {
|
|
68
|
+
if (this.activeContext$.getValue() === contextName) {
|
|
69
|
+
if (this.debugMode) {
|
|
70
|
+
// Optional: Log that no change is happening, or simply do nothing.
|
|
71
|
+
console.log(`${Hotkeys.LOG_PREFIX} setContext called with the same context "${contextName}". No change made.`);
|
|
72
|
+
}
|
|
73
|
+
return; // Context is the same, so no further action is needed.
|
|
74
|
+
}
|
|
75
|
+
// If we reach here, the context is actually changing.
|
|
76
|
+
const oldContext = this.activeContext$.getValue(); // For more informative logging
|
|
68
77
|
if (this.debugMode) {
|
|
69
|
-
console.log(`${Hotkeys.LOG_PREFIX} Context changed to "${contextName}"
|
|
78
|
+
console.log(`${Hotkeys.LOG_PREFIX} Context changed from "${oldContext}" to "${contextName}".`);
|
|
70
79
|
}
|
|
71
80
|
this.activeContext$.next(contextName);
|
|
72
81
|
}
|
|
@@ -83,11 +92,38 @@ export class Hotkeys {
|
|
|
83
92
|
* @param enable - True to enable debug logs, false to disable.
|
|
84
93
|
*/
|
|
85
94
|
setDebugMode(enable) {
|
|
86
|
-
this.debugMode
|
|
87
|
-
|
|
88
|
-
|
|
95
|
+
if (this.debugMode === enable) { // Check if state is actually changing
|
|
96
|
+
return; // If no change, do nothing (no log)
|
|
97
|
+
}
|
|
98
|
+
this.debugMode = enable; // Set the new state
|
|
99
|
+
if (enable) { // Log based on the NEW state after a change
|
|
100
|
+
console.log(`${Hotkeys.LOG_PREFIX} Debug mode enabled.`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
console.log(`${Hotkeys.LOG_PREFIX} Debug mode disabled.`);
|
|
89
104
|
}
|
|
90
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* An Observable that emits the new context name (or null) whenever the active context changes.
|
|
108
|
+
* This allows external parts of the application to react to context transitions.
|
|
109
|
+
*
|
|
110
|
+
* Note: This observable benefits from the distinct check within the `setContext` method,
|
|
111
|
+
* meaning it will only emit when the context value actually changes.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* const hotkeys = new Hotkeys();
|
|
116
|
+
* const subscription = hotkeys.onContextChange$.subscribe(newContext => {
|
|
117
|
+
* console.log("Hotkey context changed to:", newContext);
|
|
118
|
+
* // Update UI or perform other actions
|
|
119
|
+
* });
|
|
120
|
+
* // To unsubscribe when no longer needed:
|
|
121
|
+
* // subscription.unsubscribe();
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
get onContextChange$() {
|
|
125
|
+
return this.activeContext$.asObservable();
|
|
126
|
+
}
|
|
91
127
|
/**
|
|
92
128
|
* Checks if a shortcut with the given ID is currently registered and active.
|
|
93
129
|
* @param id - The unique ID of the shortcut to check.
|
|
@@ -148,8 +184,9 @@ export class Hotkeys {
|
|
|
148
184
|
let keyDetailsForLog;
|
|
149
185
|
if (typeof keys === "string") {
|
|
150
186
|
// Shorthand: keys is StandardKey, implying no modifiers should be active
|
|
151
|
-
|
|
152
|
-
|
|
187
|
+
// Corrected validation: Check for actual empty string, not a string that trims to empty.
|
|
188
|
+
if (keys === "") { // StandardKey type should prevent this, but check for robustness.
|
|
189
|
+
console.warn(`${Hotkeys.LOG_PREFIX} Invalid "keys" (shorthand) for combination shortcut "${id}". Key must not be an empty string. Shortcut not added.`);
|
|
153
190
|
return undefined;
|
|
154
191
|
}
|
|
155
192
|
configuredMainKey = keys;
|
|
@@ -161,8 +198,9 @@ export class Hotkeys {
|
|
|
161
198
|
}
|
|
162
199
|
else {
|
|
163
200
|
// Object form
|
|
164
|
-
|
|
165
|
-
|
|
201
|
+
// Corrected validation for keys.key
|
|
202
|
+
if (!keys || !keys.key || typeof keys.key !== "string" || keys.key === "") { // StandardKey type should prevent empty string for key.key
|
|
203
|
+
console.warn(`${Hotkeys.LOG_PREFIX} Invalid "keys.key" for combination shortcut "${id}". Key must be a non-empty string value from Keys. Shortcut not added.`);
|
|
166
204
|
return undefined;
|
|
167
205
|
}
|
|
168
206
|
configuredMainKey = keys.key;
|
|
@@ -234,8 +272,9 @@ export class Hotkeys {
|
|
|
234
272
|
console.warn(`${Hotkeys.LOG_PREFIX} Sequence for shortcut "${id}" is empty or invalid. Shortcut not added.`);
|
|
235
273
|
return undefined;
|
|
236
274
|
}
|
|
237
|
-
|
|
238
|
-
|
|
275
|
+
// Corrected validation: Check for actual empty string, not a string that trims to empty.
|
|
276
|
+
if (sequence.some(key => typeof key !== "string" || key === "")) { // StandardKey type should prevent empty strings.
|
|
277
|
+
console.warn(`${Hotkeys.LOG_PREFIX} Invalid key in sequence for shortcut "${id}". All keys must be non-empty string values from Keys. Shortcut not added.`);
|
|
239
278
|
return undefined;
|
|
240
279
|
}
|
|
241
280
|
const configuredSequence = sequence;
|
package/dist/hotkeys.test.js
CHANGED
|
@@ -69,35 +69,134 @@ describe("Hotkeys Library (Node.js Test Runner)", () => {
|
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
// ... (Initialization and Basic Context tests remain the same) ...
|
|
72
|
-
describe("Initialization and
|
|
72
|
+
describe("Initialization and Context Management", () => {
|
|
73
73
|
it("should initialize without errors", () => {
|
|
74
74
|
assert(keyManager instanceof Hotkeys);
|
|
75
|
+
assert.strictEqual(keyManager.getContext(), null); // Default initial context
|
|
75
76
|
});
|
|
76
77
|
it("should initialize with a null context by default", () => {
|
|
77
78
|
assert.strictEqual(keyManager.getContext(), null);
|
|
78
79
|
});
|
|
79
|
-
it("should initialize with a given initial context", () => {
|
|
80
|
-
const manager = new Hotkeys("editor");
|
|
80
|
+
it("should initialize with a given initial context (debug off)", () => {
|
|
81
|
+
const manager = new Hotkeys("editor", false);
|
|
81
82
|
assert.strictEqual(manager.getContext(), "editor");
|
|
82
83
|
manager.destroy();
|
|
83
84
|
});
|
|
84
|
-
it("should
|
|
85
|
+
it("should log library initialization with context in debug mode", () => {
|
|
86
|
+
const consoleLogMock = mock.method(console, "log");
|
|
87
|
+
const manager = new Hotkeys("debugInitCtx", true);
|
|
88
|
+
const initLog = consoleLogMock.mock.calls.find(call => call.arguments[0].includes(`Library initialized. Initial context: "debugInitCtx"`));
|
|
89
|
+
assert.ok(initLog, "Library initialization log not found or incorrect.");
|
|
90
|
+
manager.destroy();
|
|
91
|
+
consoleLogMock.mock.restore();
|
|
92
|
+
});
|
|
93
|
+
it("should set and get context correctly", () => {
|
|
85
94
|
keyManager.setContext("modal");
|
|
86
95
|
assert.strictEqual(keyManager.getContext(), "modal");
|
|
87
96
|
keyManager.setContext(null);
|
|
88
97
|
assert.strictEqual(keyManager.getContext(), null);
|
|
89
98
|
});
|
|
90
|
-
it("should
|
|
99
|
+
it("should log context change correctly when context is different (debug mode on)", () => {
|
|
91
100
|
const consoleLogMock = mock.method(console, "log");
|
|
92
101
|
keyManager.setDebugMode(true);
|
|
102
|
+
// Initial context is null for keyManager
|
|
103
|
+
consoleLogMock.mock.resetCalls(); // Clear "Debug mode enabled" log
|
|
93
104
|
keyManager.setContext("debug_test");
|
|
94
|
-
assert.ok(consoleLogMock.mock.calls.some(call => call.arguments[0].includes(`Context changed to "debug_test"`)));
|
|
105
|
+
assert.ok(consoleLogMock.mock.calls.some(call => call.arguments[0].includes(`Context changed from "null" to "debug_test"`)), "Log for context change from null incorrect.");
|
|
106
|
+
assert.strictEqual(keyManager.getContext(), "debug_test");
|
|
107
|
+
consoleLogMock.mock.resetCalls();
|
|
108
|
+
keyManager.setContext("another_test");
|
|
109
|
+
assert.ok(consoleLogMock.mock.calls.some(call => call.arguments[0].includes(`Context changed from "debug_test" to "another_test"`)), "Log for context change between non-null incorrect.");
|
|
110
|
+
assert.strictEqual(keyManager.getContext(), "another_test");
|
|
111
|
+
consoleLogMock.mock.restore();
|
|
112
|
+
});
|
|
113
|
+
it("should log context change from non-null to null (debug mode on)", () => {
|
|
114
|
+
const consoleLogMock = mock.method(console, "log");
|
|
115
|
+
keyManager.setContext("fromCtx"); // Initial context
|
|
116
|
+
keyManager.setDebugMode(true);
|
|
117
|
+
consoleLogMock.mock.resetCalls();
|
|
118
|
+
keyManager.setContext(null);
|
|
119
|
+
const logCall = consoleLogMock.mock.calls.find(call => call.arguments[0].includes(`Context changed from "fromCtx" to "null"`));
|
|
120
|
+
assert.ok(logCall, "Context change to null log not found or incorrect.");
|
|
121
|
+
assert.strictEqual(keyManager.getContext(), null);
|
|
122
|
+
consoleLogMock.mock.restore();
|
|
123
|
+
});
|
|
124
|
+
it(`should not call activeContext$.next and log "no change" if context is set to the same value (debug mode on)`, () => {
|
|
125
|
+
keyManager.setContext("sameCtx"); // Set initial context
|
|
126
|
+
const consoleLogMock = mock.method(console, "log");
|
|
127
|
+
keyManager.setDebugMode(true); // Enable debug for this test
|
|
128
|
+
consoleLogMock.mock.resetCalls(); // Clear "Debug mode enabled" log
|
|
129
|
+
// @ts-ignore: Accessing private member for test
|
|
130
|
+
const activeContextNextSpy = mock.method(keyManager["activeContext$"], "next");
|
|
131
|
+
keyManager.setContext("sameCtx"); // Attempt to set the same context
|
|
132
|
+
const noChangeLogCall = consoleLogMock.mock.calls.find(call => call.arguments[0].includes(`setContext called with the same context "sameCtx". No change made.`));
|
|
133
|
+
assert.ok(noChangeLogCall, "No-change log not found or incorrect for same context.");
|
|
134
|
+
const changedLogCall = consoleLogMock.mock.calls.find(call => call.arguments[0].includes(`Context changed from`));
|
|
135
|
+
assert.strictEqual(changedLogCall, undefined, "Context changed log should not appear for same context.");
|
|
136
|
+
assert.strictEqual(keyManager.getContext(), "sameCtx");
|
|
137
|
+
assert.strictEqual(activeContextNextSpy.mock.callCount(), 0, "activeContext$.next should not have been called.");
|
|
138
|
+
activeContextNextSpy.mock.restore();
|
|
139
|
+
consoleLogMock.mock.restore();
|
|
140
|
+
});
|
|
141
|
+
it("should not log or call next if context is set to the same value (debug mode off)", () => {
|
|
142
|
+
keyManager.setContext("sameCtxNoDebug"); // Set initial context
|
|
143
|
+
keyManager.setDebugMode(false);
|
|
144
|
+
// Ensure debug is off
|
|
145
|
+
const consoleLogMock = mock.method(console, "log");
|
|
146
|
+
// @ts-ignore: Accessing private member for test
|
|
147
|
+
const activeContextNextSpy = mock.method(keyManager["activeContext$"], "next");
|
|
148
|
+
keyManager.setContext("sameCtxNoDebug"); // Attempt to set the same context
|
|
149
|
+
assert.strictEqual(consoleLogMock.mock.callCount(), 0, "Console.log should not have been called with debug mode off.");
|
|
150
|
+
assert.strictEqual(activeContextNextSpy.mock.callCount(), 0, "activeContext$.next should not have been called.");
|
|
151
|
+
assert.strictEqual(keyManager.getContext(), "sameCtxNoDebug");
|
|
152
|
+
activeContextNextSpy.mock.restore();
|
|
153
|
+
consoleLogMock.mock.restore();
|
|
154
|
+
});
|
|
155
|
+
it("should toggle debug mode and log its state", () => {
|
|
156
|
+
const consoleLogMock = mock.method(console, "log");
|
|
157
|
+
keyManager.setDebugMode(true);
|
|
158
|
+
assert.ok(consoleLogMock.mock.calls.some(call => call.arguments[0].includes("Debug mode enabled")));
|
|
95
159
|
consoleLogMock.mock.resetCalls();
|
|
96
160
|
keyManager.setDebugMode(false);
|
|
97
|
-
|
|
98
|
-
assert.ok(
|
|
161
|
+
console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>", consoleLogMock.mock.calls);
|
|
162
|
+
assert.ok(consoleLogMock.mock.calls.some(call => call.arguments[0].includes("Debug mode disabled")));
|
|
99
163
|
consoleLogMock.mock.restore();
|
|
100
164
|
});
|
|
165
|
+
describe("onContextChange$ observable", () => {
|
|
166
|
+
it("should emit initial context to new subscriber", () => {
|
|
167
|
+
const manager = new Hotkeys("initial", false);
|
|
168
|
+
const spy = createMockFn();
|
|
169
|
+
const sub = manager.onContextChange$.subscribe(spy);
|
|
170
|
+
assert.strictEqual(spy.calledCount, 1);
|
|
171
|
+
assert.strictEqual(spy.lastArgs[0], "initial");
|
|
172
|
+
sub.unsubscribe();
|
|
173
|
+
manager.destroy();
|
|
174
|
+
});
|
|
175
|
+
it("should emit when context changes", () => {
|
|
176
|
+
const spy = createMockFn();
|
|
177
|
+
const sub = keyManager.onContextChange$.subscribe(spy); // Subscribes, gets initial null
|
|
178
|
+
spy.mockClear(); // Clear initial emission
|
|
179
|
+
keyManager.setContext("newContext");
|
|
180
|
+
assert.strictEqual(spy.calledCount, 1);
|
|
181
|
+
assert.strictEqual(spy.lastArgs[0], "newContext");
|
|
182
|
+
keyManager.setContext("anotherContext");
|
|
183
|
+
assert.strictEqual(spy.calledCount, 2);
|
|
184
|
+
assert.strictEqual(spy.lastArgs[0], "anotherContext");
|
|
185
|
+
keyManager.setContext(null);
|
|
186
|
+
assert.strictEqual(spy.calledCount, 3);
|
|
187
|
+
assert.strictEqual(spy.lastArgs[0], null);
|
|
188
|
+
sub.unsubscribe();
|
|
189
|
+
});
|
|
190
|
+
it("should not emit if context is set to the same value", () => {
|
|
191
|
+
keyManager.setContext("testContext");
|
|
192
|
+
const spy = createMockFn();
|
|
193
|
+
const sub = keyManager.onContextChange$.subscribe(spy); // Subscribes, gets "testContext"
|
|
194
|
+
spy.mockClear(); // Clear initial emission
|
|
195
|
+
keyManager.setContext("testContext"); // Set same context
|
|
196
|
+
assert.strictEqual(spy.calledCount, 0, "Observable should not emit if context value is the same.");
|
|
197
|
+
sub.unsubscribe();
|
|
198
|
+
});
|
|
199
|
+
});
|
|
101
200
|
});
|
|
102
201
|
describe("addCombination", () => {
|
|
103
202
|
it("should trigger callback for a simple key combination (e.g., 'A')", () => {
|
|
@@ -241,6 +340,18 @@ describe("Hotkeys Library (Node.js Test Runner)", () => {
|
|
|
241
340
|
consoleLogMock.mock.restore();
|
|
242
341
|
keyManager.setDebugMode(false);
|
|
243
342
|
});
|
|
343
|
+
it("should trigger callback for Keys.Space using shorthand", () => {
|
|
344
|
+
const config = { id: "spaceShorthand", keys: Keys.Space, callback: mockCallback };
|
|
345
|
+
keyManager.addCombination(config);
|
|
346
|
+
dispatchKeyEvent(" "); // Event key for space is " "
|
|
347
|
+
assert.strictEqual(mockCallback.calledCount, 1, "Callback for Keys.Space (shorthand) not called");
|
|
348
|
+
});
|
|
349
|
+
it("should trigger callback for Keys.Space using object form", () => {
|
|
350
|
+
const config = { id: "spaceObject", keys: { key: Keys.Space }, callback: mockCallback };
|
|
351
|
+
keyManager.addCombination(config);
|
|
352
|
+
dispatchKeyEvent(" ");
|
|
353
|
+
assert.strictEqual(mockCallback.calledCount, 1, "Callback for Keys.Space (object form) not called");
|
|
354
|
+
});
|
|
244
355
|
});
|
|
245
356
|
});
|
|
246
357
|
describe("addSequence", () => {
|
|
@@ -303,6 +414,29 @@ describe("Hotkeys Library (Node.js Test Runner)", () => {
|
|
|
303
414
|
assert.strictEqual(consoleErrorMock.mock.calls.length, 1);
|
|
304
415
|
assert.ok(consoleErrorMock.mock.calls[0].arguments[0].includes(`Error in user callback for sequence shortcut "errorSeq"`));
|
|
305
416
|
});
|
|
417
|
+
it("should trigger callback for a sequence including Keys.Space", () => {
|
|
418
|
+
const config = {
|
|
419
|
+
id: "seqWithSpace",
|
|
420
|
+
sequence: [Keys.G, Keys.Space, Keys.I],
|
|
421
|
+
callback: mockCallback
|
|
422
|
+
};
|
|
423
|
+
keyManager.addSequence(config);
|
|
424
|
+
dispatchKeyEvent(Keys.G);
|
|
425
|
+
dispatchKeyEvent(Keys.Space); // Dispatch " " for space
|
|
426
|
+
dispatchKeyEvent(Keys.I);
|
|
427
|
+
assert.strictEqual(mockCallback.calledCount, 1, "Callback for sequence with Keys.Space not called");
|
|
428
|
+
});
|
|
429
|
+
it("should trigger callback for a sequence starting or ending with Keys.Space", () => {
|
|
430
|
+
const config = {
|
|
431
|
+
id: "seqStartSpace",
|
|
432
|
+
sequence: [Keys.Space, Keys.A],
|
|
433
|
+
callback: mockCallback
|
|
434
|
+
};
|
|
435
|
+
keyManager.addSequence(config);
|
|
436
|
+
dispatchKeyEvent(Keys.Space);
|
|
437
|
+
dispatchKeyEvent(Keys.A);
|
|
438
|
+
assert.strictEqual(mockCallback.calledCount, 1, "Callback for sequence starting with Keys.Space not called");
|
|
439
|
+
});
|
|
306
440
|
describe("Sequence Contextual Triggering", () => {
|
|
307
441
|
let editorSequenceConfig;
|
|
308
442
|
beforeEach(() => {
|