mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-25 09:07:40 +00:00
feat(web): mnemonic + legacy keystroke pre-proc unit tests
This commit is contained in:
parent
3c0adc38e4
commit
a404c20ddf
4 changed files with 586 additions and 16 deletions
|
|
@ -32,7 +32,9 @@ const Codes = {
|
|||
"ALT_GR_SIM": (0x0001 | 0x0004),
|
||||
"CHIRAL":0x001F, // The base bitmask for chiral keyboards. Includes SHIFT, which is non-chiral.
|
||||
"IS_CHIRAL":0x000F, // Used to test if a bitmask uses a chiral modifier.
|
||||
"NON_CHIRAL":0x0070 // The default bitmask, for non-chiral keyboards
|
||||
"NON_CHIRAL":0x0070, // The default bitmask, for non-chiral keyboards,
|
||||
// Represents all modifier codes not supported by KMW 1.0 legacy keyboards.
|
||||
"NON_LEGACY": 0x006F // ALL, but without the SHIFT bit
|
||||
},
|
||||
|
||||
stateBitmasks: {
|
||||
|
|
|
|||
|
|
@ -121,6 +121,10 @@ export function preprocessKeyboardEvent(e: KeyboardEvent, keyboardState: Keyboar
|
|||
|
||||
// Stage 3 - Set our modifier state tracking variable and perform basic AltGr-related management.
|
||||
const LmodifierChange = keyboardState.modStateFlags != curModState;
|
||||
|
||||
// KeyboardState update: save our known modifier/state analysis bits.
|
||||
// Note: `keyboardState` is typically the full-fledged KeyboardProcessor instance. As a result,
|
||||
// changes here persist across calls (as we only ever make the one instance).
|
||||
keyboardState.modStateFlags = curModState;
|
||||
|
||||
// For European keyboards, not all browsers properly send both key-up events for the AltGr combo.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@ export function processForMnemonicsAndLegacy(s: KeyEvent, activeKeyboard: Keyboa
|
|||
//
|
||||
// Third: DO, however, track direct presses of any main modifier key. The OSK should
|
||||
// reflect the current modifier state even for legacy keyboards.
|
||||
if(!activeKeyboard.definesPositionalOrMnemonic && !(s.Lmodifiers & 0x60) && !s.isModifier) {
|
||||
if(!activeKeyboard.definesPositionalOrMnemonic &&
|
||||
!(s.Lmodifiers & Codes.modifierBitmasks.NON_LEGACY) &&
|
||||
!s.isModifier) {
|
||||
// Support version 1.0 KeymanWeb keyboards that do not define positional vs mnemonic
|
||||
s = new KeyEvent({
|
||||
Lcode: KeyMapping._USKeyCodeToCharCode(s),
|
||||
|
|
|
|||
|
|
@ -5,24 +5,586 @@ import { preprocessKeyboardEvent } from 'keyman/app/browser';
|
|||
import { processForMnemonicsAndLegacy } from 'keyman/engine/main';
|
||||
import { PhysicalInputEventSpec } from '@keymanapp/recorder-core';
|
||||
import { DeviceSpec } from '@keymanapp/web-utils';
|
||||
import { Codes, Keyboard, KeyEvent } from '@keymanapp/keyboard-processor';
|
||||
|
||||
const ModifierCodes = Codes.modifierCodes;
|
||||
const KeyCodes = Codes.keyCodes;
|
||||
|
||||
const DUMMY_DEVICE = new DeviceSpec('chrome', 'desktop', 'windows', false);
|
||||
|
||||
// console.log(JSON.stringify(processedEvent));
|
||||
|
||||
describe("app/browser: hardware event processing", () => {
|
||||
describe('preprocessKeyboardEvent', () => {
|
||||
it('dummy', () => {
|
||||
let test = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: 20,
|
||||
modifierSet: PhysicalInputEventSpec.modifierCodes.Shift,
|
||||
location: 1
|
||||
}) as any as KeyboardEvent, {
|
||||
// Only needs to be non-null for chiral-keystroke detection and for mnemonic detection.
|
||||
activeKeyboard: null,
|
||||
modStateFlags: 0,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
new DeviceSpec('chrome', 'desktop', 'windows', false)
|
||||
);
|
||||
describe('positional keyboards', () => {
|
||||
it("simple shifted 'a'", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_A,
|
||||
modifierSet: PhysicalInputEventSpec.modifierCodes.Shift,
|
||||
location: 1
|
||||
}) as any as KeyboardEvent, {
|
||||
activeKeyboard: new Keyboard({ KM: 0 }),
|
||||
modStateFlags: 0,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
console.log(JSON.stringify(test));
|
||||
assert.isTrue(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, KeyCodes.K_A);
|
||||
assert.equal(processedEvent.Lmodifiers, ModifierCodes.SHIFT);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
|
||||
// Note: Codes.modifierCodes.VIRTUAL_KEY is NOT applied here. It's applied by the
|
||||
// compiler & filtered out directly within the `keyMatch` keyboard-API func. It's
|
||||
// never part of the actual processed event object within KMW.
|
||||
});
|
||||
|
||||
it("simple unshifted 'a'", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_A,
|
||||
modifierSet: 0
|
||||
}) as any as KeyboardEvent, {
|
||||
activeKeyboard: new Keyboard({ KM: 0 }),
|
||||
modStateFlags: 0,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
assert.isTrue(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, KeyCodes.K_A);
|
||||
assert.equal(processedEvent.Lmodifiers, 0);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
|
||||
it("left-alt press", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_ALT,
|
||||
modifierSet: PhysicalInputEventSpec.modifierCodes.Alt,
|
||||
location: 1
|
||||
}) as any as KeyboardEvent, {
|
||||
// KMBM: Keyman Modifier BitMask
|
||||
activeKeyboard: new Keyboard({KM: 0}),
|
||||
modStateFlags: 0,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
assert.isTrue(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, KeyCodes.K_ALT);
|
||||
assert.equal(processedEvent.Lmodifiers, ModifierCodes.ALT);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
|
||||
it("left-alt release", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_ALT,
|
||||
modifierSet: 0,
|
||||
location: 1
|
||||
}) as any as KeyboardEvent, {
|
||||
// KMBM: Keyman Modifier BitMask
|
||||
activeKeyboard: new Keyboard({KM: 0}),
|
||||
modStateFlags: ModifierCodes.ALT,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
assert.isTrue(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, KeyCodes.K_ALT);
|
||||
assert.equal(processedEvent.Lmodifiers, 0);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
});
|
||||
|
||||
describe('positional+chiral keyboards', () => {
|
||||
it("simple shifted 'a'", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_A,
|
||||
modifierSet: PhysicalInputEventSpec.modifierCodes.Shift,
|
||||
location: 1
|
||||
}) as any as KeyboardEvent, {
|
||||
// KMBM: Keyman Modifier BitMask
|
||||
activeKeyboard: new Keyboard({KM:0, KMBM: Codes.modifierBitmasks.CHIRAL}),
|
||||
modStateFlags: 0,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
assert.isTrue(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, KeyCodes.K_A);
|
||||
assert.equal(processedEvent.Lmodifiers, ModifierCodes.SHIFT);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
|
||||
it("simple unshifted 'a'", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_A,
|
||||
modifierSet: 0
|
||||
}) as any as KeyboardEvent, {
|
||||
// KMBM: Keyman Modifier BitMask
|
||||
activeKeyboard: new Keyboard({KM: 0, KMBM: Codes.modifierBitmasks.CHIRAL}),
|
||||
modStateFlags: 0,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
assert.isTrue(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, KeyCodes.K_A);
|
||||
assert.equal(processedEvent.Lmodifiers, 0);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
|
||||
it("left-alt press", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_ALT,
|
||||
modifierSet: PhysicalInputEventSpec.modifierCodes.Alt,
|
||||
location: 1
|
||||
}) as any as KeyboardEvent, {
|
||||
// KMBM: Keyman Modifier BitMask
|
||||
activeKeyboard: new Keyboard({KM: 0, KMBM: Codes.modifierBitmasks.CHIRAL}),
|
||||
modStateFlags: 0,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
assert.isTrue(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, KeyCodes.K_ALT);
|
||||
assert.equal(processedEvent.Lmodifiers, ModifierCodes.LALT);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
|
||||
it("left-alt release", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_ALT,
|
||||
modifierSet: 0,
|
||||
location: 1
|
||||
}) as any as KeyboardEvent, {
|
||||
// KMBM: Keyman Modifier BitMask
|
||||
activeKeyboard: new Keyboard({KM: 0, KMBM: Codes.modifierBitmasks.CHIRAL}),
|
||||
modStateFlags: ModifierCodes.LALT,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
assert.isTrue(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, KeyCodes.K_ALT);
|
||||
assert.equal(processedEvent.Lmodifiers, 0);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mnemonic keyboards', () => {
|
||||
it("simple shifted 'a'", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_A,
|
||||
modifierSet: PhysicalInputEventSpec.modifierCodes.Shift,
|
||||
location: 1
|
||||
}) as any as KeyboardEvent, {
|
||||
activeKeyboard: new Keyboard({ KM: 1 }),
|
||||
modStateFlags: 0,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
assert.isTrue(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, 'A'.charCodeAt(0));
|
||||
assert.equal(processedEvent.Lmodifiers, ModifierCodes.SHIFT);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
|
||||
it("simple unshifted 'a'", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_A,
|
||||
modifierSet: 0
|
||||
}) as any as KeyboardEvent, {
|
||||
activeKeyboard: new Keyboard({ KM: 1 }),
|
||||
modStateFlags: 0,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
assert.isTrue(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, 'a'.charCodeAt(0));
|
||||
assert.equal(processedEvent.Lmodifiers, 0);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
});
|
||||
|
||||
describe('legacy keyboards', () => {
|
||||
it("simple shifted 'a'", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_A,
|
||||
modifierSet: PhysicalInputEventSpec.modifierCodes.Shift,
|
||||
location: 1
|
||||
}) as any as KeyboardEvent, {
|
||||
activeKeyboard: new Keyboard({ KM: undefined }),
|
||||
modStateFlags: 0,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
assert.isFalse(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, 'A'.charCodeAt(0));
|
||||
assert.equal(processedEvent.Lmodifiers, 0);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
|
||||
it("simple unshifted 'a'", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_A,
|
||||
modifierSet: 0
|
||||
}) as any as KeyboardEvent, {
|
||||
activeKeyboard: new Keyboard({ KM: undefined }),
|
||||
modStateFlags: 0,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
assert.isFalse(processedEvent.LisVirtualKey);
|
||||
assert.equal(processedEvent.Lcode, 'a'.charCodeAt(0));
|
||||
assert.equal(processedEvent.Lmodifiers, 0);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
|
||||
it("'a' during left-alt", () => {
|
||||
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
|
||||
keyCode: KeyCodes.K_A,
|
||||
modifierSet: PhysicalInputEventSpec.modifierCodes.Alt,
|
||||
location: 0
|
||||
}) as any as KeyboardEvent, {
|
||||
activeKeyboard: new Keyboard({ KM: undefined }),
|
||||
// Internally assumes that the ALT-press event was previously handled, with this as
|
||||
// the resulting modifier state at the time of key-press.
|
||||
modStateFlags: ModifierCodes.LALT,
|
||||
baseLayout: 'us'
|
||||
},
|
||||
DUMMY_DEVICE
|
||||
);
|
||||
|
||||
// ... which is used to disable the key within the rule-processing `keyMatch` function, as
|
||||
// the keyboard's rules weren't compiled with the Codes.VIRTUAL_KEY bit set.
|
||||
assert.isTrue(processedEvent.LisVirtualKey);
|
||||
|
||||
assert.equal(processedEvent.Lcode, KeyCodes.K_A);
|
||||
assert.equal(processedEvent.Lmodifiers, ModifierCodes.ALT);
|
||||
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('processForMnemonicsAndLegacy', () => {
|
||||
describe('positional keyboards', () => {
|
||||
it("simple shifted 'a'", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_A,
|
||||
Lmodifiers: ModifierCodes.SHIFT,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM: 0}),
|
||||
'us'
|
||||
);
|
||||
|
||||
assert.strictEqual(finalKeyEvent, baseKeyEvent);
|
||||
});
|
||||
|
||||
it("simple unshifted 'a'", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_A,
|
||||
Lmodifiers: 0,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM: 0}),
|
||||
'us'
|
||||
);
|
||||
|
||||
assert.strictEqual(finalKeyEvent, baseKeyEvent);
|
||||
});
|
||||
|
||||
it("left-alt press", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_ALT,
|
||||
Lmodifiers: ModifierCodes.ALT,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_ALT"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM: 0}),
|
||||
'us'
|
||||
);
|
||||
|
||||
assert.strictEqual(finalKeyEvent, baseKeyEvent);
|
||||
});
|
||||
|
||||
it("left-alt release", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_ALT,
|
||||
Lmodifiers: 0,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM: 0}),
|
||||
'us'
|
||||
);
|
||||
|
||||
assert.strictEqual(finalKeyEvent, baseKeyEvent);
|
||||
});
|
||||
});
|
||||
|
||||
describe('positional+chiral keyboards', () => {
|
||||
it("simple shifted 'a'", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_A,
|
||||
Lmodifiers: ModifierCodes.SHIFT,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM:0, KMBM: Codes.modifierBitmasks.CHIRAL}),
|
||||
'us'
|
||||
);
|
||||
|
||||
assert.strictEqual(finalKeyEvent, baseKeyEvent);
|
||||
});
|
||||
|
||||
it("simple unshifted 'a'", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_A,
|
||||
Lmodifiers: 0,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM:0, KMBM: Codes.modifierBitmasks.CHIRAL}),
|
||||
'us'
|
||||
);
|
||||
|
||||
assert.strictEqual(finalKeyEvent, baseKeyEvent);
|
||||
});
|
||||
|
||||
it("left-alt press", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_ALT,
|
||||
Lmodifiers: ModifierCodes.LALT,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_ALT"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM:0, KMBM: Codes.modifierBitmasks.CHIRAL}),
|
||||
'us'
|
||||
);
|
||||
|
||||
assert.strictEqual(finalKeyEvent, baseKeyEvent);
|
||||
});
|
||||
|
||||
it("left-alt release", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_LALT,
|
||||
Lmodifiers: 0,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM:0, KMBM: Codes.modifierBitmasks.CHIRAL}),
|
||||
'us'
|
||||
);
|
||||
|
||||
assert.strictEqual(finalKeyEvent, baseKeyEvent);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mnemonic keyboards', () => {
|
||||
it("simple shifted 'a'", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_A,
|
||||
Lmodifiers: ModifierCodes.SHIFT,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM:1}),
|
||||
'us'
|
||||
);
|
||||
|
||||
// May be the same instance, but the instance gets mutated. Compare against literals
|
||||
// for expected values.
|
||||
assert.equal(finalKeyEvent.Lcode, 'A'.charCodeAt(0));
|
||||
assert.equal(finalKeyEvent.Lmodifiers, ModifierCodes.SHIFT);
|
||||
assert.isTrue(finalKeyEvent.LisVirtualKey);
|
||||
});
|
||||
|
||||
it("simple unshifted 'a'", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_A,
|
||||
Lmodifiers: 0,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM:1}),
|
||||
'us'
|
||||
);
|
||||
|
||||
// May be the same instance, but the instance gets mutated. Compare against literals
|
||||
// for expected values.
|
||||
assert.equal(finalKeyEvent.Lcode, 'a'.charCodeAt(0));
|
||||
assert.equal(finalKeyEvent.Lmodifiers, 0);
|
||||
assert.isTrue(finalKeyEvent.LisVirtualKey);
|
||||
});
|
||||
});
|
||||
|
||||
describe('legacy keyboards', () => {
|
||||
|
||||
it("simple shifted 'a'", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_A,
|
||||
Lmodifiers: ModifierCodes.SHIFT,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM:undefined}),
|
||||
'us'
|
||||
);
|
||||
|
||||
// The event object gets wholesale-replaced.
|
||||
assert.notStrictEqual(finalKeyEvent, baseKeyEvent);
|
||||
|
||||
assert.isFalse(finalKeyEvent.LisVirtualKey);
|
||||
assert.equal(finalKeyEvent.Lcode, 'A'.charCodeAt(0));
|
||||
assert.equal(finalKeyEvent.Lmodifiers, 0);
|
||||
});
|
||||
|
||||
it("simple unshifted 'a'", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_A,
|
||||
Lmodifiers: 0,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM:undefined}),
|
||||
'us'
|
||||
);
|
||||
|
||||
// The event object gets wholesale-replaced.
|
||||
assert.notStrictEqual(finalKeyEvent, baseKeyEvent);
|
||||
|
||||
assert.isFalse(finalKeyEvent.LisVirtualKey);
|
||||
assert.equal(finalKeyEvent.Lcode, 'a'.charCodeAt(0));
|
||||
assert.equal(finalKeyEvent.Lmodifiers, 0);
|
||||
});
|
||||
|
||||
it("'a' during alt", () => {
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_A,
|
||||
Lmodifiers: ModifierCodes.ALT,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM:undefined}),
|
||||
'us'
|
||||
);
|
||||
|
||||
// Legacy keyboards expect this to be false; this acts as a filter for legacy keyboards
|
||||
// to prevent key processing with held CTRL / ALT.
|
||||
assert.isTrue(finalKeyEvent.LisVirtualKey);
|
||||
assert.equal(finalKeyEvent.Lcode, KeyCodes.K_A);
|
||||
assert.equal(finalKeyEvent.Lmodifiers, ModifierCodes.ALT);
|
||||
});
|
||||
|
||||
it("'a' during left-alt (invalid state)", () => {
|
||||
// Not that such a state should ever occur, but if it did... we can ensure it's
|
||||
// handled robustly.
|
||||
const baseKeyEvent = new KeyEvent({
|
||||
Lcode: KeyCodes.K_A,
|
||||
Lmodifiers: ModifierCodes.LALT,
|
||||
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
|
||||
LisVirtualKey: true,
|
||||
device: DUMMY_DEVICE,
|
||||
kName: "K_A"
|
||||
});
|
||||
|
||||
const finalKeyEvent = processForMnemonicsAndLegacy(
|
||||
baseKeyEvent,
|
||||
new Keyboard({KM:undefined}),
|
||||
'us'
|
||||
);
|
||||
|
||||
// Legacy keyboards expect this to be false; this acts as a filter for legacy keyboards
|
||||
// to prevent key processing with held CTRL / ALT.
|
||||
assert.isTrue(finalKeyEvent.LisVirtualKey);
|
||||
assert.equal(finalKeyEvent.Lcode, KeyCodes.K_A);
|
||||
assert.equal(finalKeyEvent.Lmodifiers, ModifierCodes.LALT);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue