mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-07 01:15:33 +00:00
chore(web): post-refactor fixes to keyboard-processor, input-processor unit tests
This commit is contained in:
parent
f94cd9f5dd
commit
ffb614f52c
6 changed files with 170 additions and 20 deletions
|
|
@ -96,7 +96,7 @@ describe('InputProcessor', function() {
|
|||
core.activeKeyboard = keyboard;
|
||||
let layout = keyboard.layout(utils.DeviceSpec.FormFactor.Phone);
|
||||
let key = layout.getLayer('default').getKey('K_A');
|
||||
let event = key.constructKeyEvent(core.keyboardProcessor, device);
|
||||
let event = keyboard.constructKeyEvent(key, device, core.keyboardProcessor.stateKeys);
|
||||
|
||||
let behavior = core.processKeyEvent(event, context);
|
||||
assert.isNotNull(behavior);
|
||||
|
|
@ -115,7 +115,7 @@ describe('InputProcessor', function() {
|
|||
core.activeKeyboard = keyboard;
|
||||
let layout = keyboard.layout(utils.DeviceSpec.FormFactor.Phone);
|
||||
let key = layout.getLayer('default').getKey('K_A');
|
||||
let event = key.constructKeyEvent(core.keyboardProcessor, device);
|
||||
let event = keyboard.constructKeyEvent(key, device, core.keyboardProcessor.stateKeys);
|
||||
|
||||
let behavior = core.processKeyEvent(event, context);
|
||||
assert.isNotNull(behavior);
|
||||
|
|
@ -132,7 +132,7 @@ describe('InputProcessor', function() {
|
|||
let layout = keyboard.layout(utils.DeviceSpec.FormFactor.Phone);
|
||||
let key = layout.getLayer('default').getKey('K_A');
|
||||
key.keyDistribution = testDistribution;
|
||||
let event = key.constructKeyEvent(core.keyboardProcessor, device);
|
||||
let event = keyboard.constructKeyEvent(key, device, core.keyboardProcessor.stateKeys);
|
||||
|
||||
let behavior = core.processKeyEvent(event, context);
|
||||
assert.isNotNull(behavior);
|
||||
|
|
@ -155,7 +155,7 @@ describe('InputProcessor', function() {
|
|||
let layout = keyboard.layout(utils.DeviceSpec.FormFactor.Phone);
|
||||
let key = layout.getLayer('default').getKey('K_A');
|
||||
key.keyDistribution = testDistribution;
|
||||
let event = key.constructKeyEvent(core.keyboardProcessor, device);
|
||||
let event = keyboard.constructKeyEvent(key, device, core.keyboardProcessor.stateKeys);
|
||||
|
||||
let behavior = core.processKeyEvent(event, context);
|
||||
assert.isNotNull(behavior);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import Codes from "../text/codes.js";
|
||||
import KeyEvent from "../text/keyEvent.js";
|
||||
import KeyEvent, { KeyEventSpec } from "../text/keyEvent.js";
|
||||
import KeyMapping from "../text/keyMapping.js";
|
||||
import type { KeyDistribution } from "../text/keyEvent.js";
|
||||
import type { LayoutKey, LayoutRow, LayoutLayer, LayoutFormFactor, ButtonClass } from "./defaultLayouts.js";
|
||||
|
|
@ -247,8 +247,7 @@ export class ActiveKey implements LayoutKey {
|
|||
// Start: mirrors _GetKeyEventProperties
|
||||
|
||||
// First check the virtual key, and process shift, control, alt or function keys
|
||||
let Lkc: KeyEvent = new KeyEvent();
|
||||
let props = {
|
||||
let props: KeyEventSpec = {
|
||||
// Override key shift state if specified for key in layout (corrected for popup keys KMEW-93)
|
||||
Lmodifiers: Codes.getModifierState(layer),
|
||||
Lstates: Codes.getStateFromLayer(layer),
|
||||
|
|
@ -263,9 +262,7 @@ export class ActiveKey implements LayoutKey {
|
|||
isSynthetic: true
|
||||
};
|
||||
|
||||
for(let key in props) {
|
||||
Lkc[key] = props[key];
|
||||
}
|
||||
let Lkc: KeyEvent = new KeyEvent(props);
|
||||
|
||||
if(layout.keyboard) {
|
||||
let keyboard = layout.keyboard;
|
||||
|
|
|
|||
|
|
@ -16,11 +16,50 @@ import DefaultOutput from './defaultOutput.js';
|
|||
// Defined here to avoid compilation issues.
|
||||
export type KeyDistribution = {keyId: string, p: number}[];
|
||||
|
||||
export interface KeyEventSpec {
|
||||
|
||||
Lcode: number;
|
||||
Lstates: number;
|
||||
LmodifierChange?: boolean;
|
||||
Lmodifiers: number;
|
||||
LisVirtualKey: boolean;
|
||||
vkCode: number;
|
||||
kName: string;
|
||||
kLayer?: string; // The key's layer property
|
||||
kbdLayer?: string; // The virtual keyboard's active layer
|
||||
kNextLayer?: string;
|
||||
|
||||
/**
|
||||
* Marks the active keyboard at the time that this KeyEvent was generated by the user.
|
||||
*
|
||||
* Note: this is NOT equivalent to the active keyboard at the time that the event handler begins
|
||||
* processing! It should be set via closure (or similar) on the event handler that can 100%
|
||||
* guarantee that the keyboard instance known to the handler has not changed during JS execution
|
||||
* since the user's interaction that raised the event.
|
||||
*/
|
||||
srcKeyboard?: Keyboard;
|
||||
|
||||
// Holds relevant event properties leading to construction of this KeyEvent.
|
||||
source?: any; // Technically, KeyEvent|MouseEvent|Touch - but those are DOM types that must be kept out of headless mode.
|
||||
// Holds a generated fat-finger distribution (when appropriate)
|
||||
keyDistribution?: KeyDistribution;
|
||||
|
||||
/**
|
||||
* The device model for web-core to follow when processing the keystroke.
|
||||
*/
|
||||
device: DeviceSpec;
|
||||
|
||||
/**
|
||||
* `true` if this event was produced by sources other than a DOM-based KeyboardEvent.
|
||||
*/
|
||||
isSynthetic?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is defined within its own file so that it can be loaded by code outside of KMW without
|
||||
* having to actually load the entirety of KMW.
|
||||
*/
|
||||
export default class KeyEvent {
|
||||
export default class KeyEvent implements KeyEventSpec {
|
||||
Lcode: number;
|
||||
Lstates: number;
|
||||
LmodifierChange?: boolean;
|
||||
|
|
@ -57,11 +96,24 @@ export default class KeyEvent {
|
|||
*/
|
||||
isSynthetic: boolean = true;
|
||||
|
||||
public constructor(keyEventSpec: KeyEventSpec) {
|
||||
for(let key in keyEventSpec) {
|
||||
if(keyEventSpec[key] !== undefined) {
|
||||
this[key] = keyEventSpec[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static constructNullKeyEvent(device: DeviceSpec): KeyEvent {
|
||||
const keyEvent = new KeyEvent();
|
||||
keyEvent.Lcode = 0;
|
||||
keyEvent.kName = '';
|
||||
keyEvent.device = device;
|
||||
const keyEvent = new KeyEvent({
|
||||
Lcode: 0,
|
||||
kName: '',
|
||||
device: device,
|
||||
Lstates: undefined,
|
||||
Lmodifiers: undefined,
|
||||
vkCode: undefined,
|
||||
LisVirtualKey: undefined
|
||||
});
|
||||
return keyEvent;
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +138,7 @@ export default class KeyEvent {
|
|||
if(this.Lcode != Codes.keyCodes['K_SPACE']) {
|
||||
// So long as the key name isn't prefixed with 'U_', we'll get a default mapping based on the Lcode value.
|
||||
// We need to determine the mnemonic base character - for example, SHIFT + K_PERIOD needs to map to '>'.
|
||||
let mappingEvent: KeyEvent = new KeyEvent();
|
||||
let mappingEvent: KeyEvent = new KeyEvent(this);
|
||||
for(let key in (this as KeyEvent)) {
|
||||
mappingEvent[key] = this[key];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
} from "./index.js";
|
||||
|
||||
import Keyboard from "@keymanapp/keyboard-processor/build/obj/keyboards/keyboard.js";
|
||||
import type KeyEvent from "@keymanapp/keyboard-processor/build/obj/text/keyEvent.js";
|
||||
import KeyEvent, { KeyEventSpec } from "@keymanapp/keyboard-processor/build/obj/text/keyEvent.js";
|
||||
import KeyboardProcessor from "@keymanapp/keyboard-processor/build/obj/text/keyboardProcessor.js";
|
||||
import type OutputTarget from "@keymanapp/keyboard-processor/build/obj/text/outputTarget.js";
|
||||
import { Mock } from "@keymanapp/keyboard-processor/build/obj/text/outputTarget.js";
|
||||
|
|
@ -64,7 +64,7 @@ export default class NodeProctor extends Proctor {
|
|||
|
||||
if(sequence instanceof RecordedKeystrokeSequence) {
|
||||
for(let keystroke of sequence.inputs) {
|
||||
let keyEvent: KeyEvent;
|
||||
let keyEvent: KeyEventSpec;
|
||||
if(keystroke instanceof RecordedPhysicalKeystroke) {
|
||||
// Use the keystroke's stored data to reconstruct the KeyEvent.
|
||||
keyEvent = {
|
||||
|
|
@ -80,7 +80,7 @@ export default class NodeProctor extends Proctor {
|
|||
}
|
||||
} else if(keystroke instanceof RecordedSyntheticKeystroke) {
|
||||
let key = this.keyboard.layout(this.device.formFactor).getLayer(keystroke.layer).getKey(keystroke.keyName);
|
||||
keyEvent = key.constructKeyEvent(processor, this.device);
|
||||
keyEvent = this.keyboard.constructKeyEvent(key, this.device, processor.stateKeys);
|
||||
}
|
||||
|
||||
// Fill in the final details of the KeyEvent...
|
||||
|
|
@ -90,7 +90,7 @@ export default class NodeProctor extends Proctor {
|
|||
// We don't care too much about particularities of per-keystroke behavior yet.
|
||||
// ... we _could_ if we wanted to, though. The framework is mostly in place;
|
||||
// it's a matter of actually adding the feature.
|
||||
let ruleBehavior = processor.processKeystroke(keyEvent, target);
|
||||
let ruleBehavior = processor.processKeystroke(new KeyEvent(keyEvent), target);
|
||||
|
||||
if(this.debugMode) {
|
||||
console.log(JSON.stringify(target, null, ' '));
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"module": "es6",
|
||||
"moduleResolution": "Node",
|
||||
"declaration": true,
|
||||
|
|
|
|||
100
package-lock.json
generated
100
package-lock.json
generated
|
|
@ -2247,6 +2247,33 @@
|
|||
"color-support": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/combine-source-map": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz",
|
||||
"integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"convert-source-map": "~1.1.0",
|
||||
"inline-source-map": "~0.6.0",
|
||||
"lodash.memoize": "~3.0.3",
|
||||
"source-map": "~0.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/combine-source-map/node_modules/convert-source-map": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
|
||||
"integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/combine-source-map/node_modules/source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
|
|
@ -3980,6 +4007,24 @@
|
|||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/inline-source-map": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz",
|
||||
"integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"source-map": "~0.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/inline-source-map/node_modules/source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
|
|
@ -4580,6 +4625,12 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
|
||||
},
|
||||
"node_modules/lodash.memoize": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
|
||||
"integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.set": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
|
||||
|
|
@ -9309,6 +9360,32 @@
|
|||
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
|
||||
"dev": true
|
||||
},
|
||||
"combine-source-map": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz",
|
||||
"integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"convert-source-map": "~1.1.0",
|
||||
"inline-source-map": "~0.6.0",
|
||||
"lodash.memoize": "~3.0.3",
|
||||
"source-map": "~0.5.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"convert-source-map": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
|
||||
"integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
|
|
@ -10556,6 +10633,23 @@
|
|||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"inline-source-map": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz",
|
||||
"integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"source-map": "~0.5.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
|
|
@ -11073,6 +11167,12 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
|
||||
},
|
||||
"lodash.memoize": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
|
||||
"integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.set": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue