Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change(web): move KeyboardProcessor.Codes into common/web/types 🏗️ #11913

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions common/web/input-processor/src/correctionLayout.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ActiveKey, ActiveKeyBase, ActiveLayer, ActiveRow, Codes } from "@keymanapp/keyboard-processor";
import { ActiveKey, ActiveKeyBase, ActiveLayer, ActiveRow } from "@keymanapp/keyboard-processor";
import { Codes } from "@keymanapp/common-types";

/**
* Defines correction-layout mappings for keys to be considered by
Expand Down Expand Up @@ -108,4 +109,4 @@ export function buildCorrectiveLayout(layer: ActiveLayer, kbdScaleRatio: number)
.filter((entry) => correctionKeyFilter(entry.keySpec)),
kbdScaleRatio: kbdScaleRatio
};
}
}
4 changes: 2 additions & 2 deletions common/web/input-processor/src/text/inputProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import ContextWindow from "./contextWindow.js";
import LanguageProcessor from "./prediction/languageProcessor.js";
import type ModelSpec from "./prediction/modelSpec.js";
import { globalObject, DeviceSpec } from "@keymanapp/web-utils";
import { Codes } from "@keymanapp/common-types";

import {
type Alternate,
Codes,
isEmptyTransform,
type Keyboard,
KeyboardInterface,
Expand Down Expand Up @@ -385,4 +385,4 @@ export default class InputProcessor {
// With the layer now set, we trigger new predictions.
this.languageProcessor.invalidateContext(outputTarget, this.keyboardProcessor.layerId);
}
}
}
2 changes: 0 additions & 2 deletions common/web/keyboard-processor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ export {
export { default as SpacebarText } from "./keyboards/spacebarText.js";
export { default as StateKeyMap } from "./keyboards/stateKeyMap.js";

export { default as Codes } from "./text/codes.js";
export * from "./text/codes.js";
Comment on lines -27 to -28
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not great (double-exporting and flattening of exports like this) and I am glad it's gone ... but do we need to maintain the exports for compatibility? @jahorton

Also exported in web/src/engine/osk/src/index.ts (why?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, if it builds, I assume it's fine. Standard Web CI builds even build the development tools, which would be the only thing I'd worry about falling over. (They'd fail the build if they fell over.)

export * from "./text/deadkeys.js";
export { default as DefaultRules } from "./text/defaultRules.js";
export * from "./text/defaultRules.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Codes from "../text/codes.js";
import { Codes } from '@keymanapp/common-types';
import KeyEvent, { KeyEventSpec } from "../text/keyEvent.js";
import KeyMapping from "../text/keyMapping.js";
import { ButtonClasses, Layouts } from "./defaultLayouts.js";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
***/

import { Version, deepCopy } from "@keymanapp/web-utils";
import { TouchLayout } from "@keymanapp/common-types";
import { Codes, TouchLayout } from "@keymanapp/common-types";

import LayoutFormFactorSpec = TouchLayout.TouchLayoutPlatform;
import LayoutLayerBase = TouchLayout.TouchLayoutLayer;
Expand All @@ -16,7 +16,6 @@ import ButtonClasses = TouchLayout.TouchLayoutKeySp;

export { ButtonClasses };

import Codes from "../text/codes.js";
import type Keyboard from "./keyboard.js";

export interface EncodedVisualKeyboard {
Expand Down
2 changes: 1 addition & 1 deletion common/web/keyboard-processor/src/keyboards/keyboard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Codes from "../text/codes.js";
import { Codes } from '@keymanapp/common-types';
import { EncodedVisualKeyboard, LayoutSpec, Layouts } from "./defaultLayouts.js";
import { ActiveKey, ActiveLayout, ActiveSubKey } from "./activeLayout.js";
import KeyEvent from "../text/keyEvent.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Codes } from '@keymanapp/common-types';
import Keyboard from "./keyboard.js";
import Codes from "../text/codes.js";

/**
* Defines members of the top-level `keyman` global object necessary to guarantee
Expand Down
2 changes: 1 addition & 1 deletion common/web/keyboard-processor/src/text/defaultRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// We should start splitting off code needed by keyboards even without a KeyboardProcessor active.
// There's an upcoming `/common/web/types` package that 'codes' and 'keyboards' may fit well within.

import Codes from "./codes.js";
import { Codes } from '@keymanapp/common-types';
import type KeyEvent from "./keyEvent.js";
import type OutputTarget from "./outputTarget.js";

Expand Down
2 changes: 1 addition & 1 deletion common/web/keyboard-processor/src/text/kbdInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//#region Imports

import { type DeviceSpec } from "@keymanapp/web-utils";
import { Codes } from '@keymanapp/common-types';

import Codes from "./codes.js";
import type KeyEvent from "./keyEvent.js";
import type { Deadkey } from "./deadkeys.js";
import KeyMapping from "./keyMapping.js";
Expand Down
2 changes: 1 addition & 1 deletion common/web/keyboard-processor/src/text/keyEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

import type Keyboard from "../keyboards/keyboard.js";
import { type DeviceSpec } from "@keymanapp/web-utils";
import { Codes } from '@keymanapp/common-types';

import Codes from './codes.js';
import DefaultRules from './defaultRules.js';
import { ActiveKeyBase } from "../index.js";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// #region Big ol' list of imports

import { EventEmitter } from 'eventemitter3';
import { Codes } from '@keymanapp/common-types';

import Codes from "./codes.js";
import type Keyboard from "../keyboards/keyboard.js";
import { MinimalKeymanGlobal } from '../keyboards/keyboardHarness.js';
import KeyEvent from "./keyEvent.js";
Expand Down
5 changes: 3 additions & 2 deletions common/web/keyboard-processor/tests/node/chirality.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import fs from 'fs';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);

import { Codes, KeyboardInterface, MinimalKeymanGlobal } from '@keymanapp/keyboard-processor';
import { Codes } from "@keymanapp/common-types";
import { KeyboardInterface, MinimalKeymanGlobal } from '@keymanapp/keyboard-processor';
import { NodeKeyboardLoader } from '@keymanapp/keyboard-processor/node-keyboard-loader';
import { KeyboardTest, NodeProctor } from '@keymanapp/recorder-core';

Expand Down Expand Up @@ -249,4 +250,4 @@ describe('Engine - Chirality', function() {
assert.equal(modifierTarget, mappedModifiers);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import fs from 'fs';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);

import { Codes, KeyboardInterface, KeyEvent, MinimalKeymanGlobal, Mock } from '@keymanapp/keyboard-processor';
import { Codes } from "@keymanapp/common-types";
import { KeyboardInterface, KeyEvent, MinimalKeymanGlobal, Mock } from '@keymanapp/keyboard-processor';
import { NodeKeyboardLoader } from '@keymanapp/keyboard-processor/node-keyboard-loader';

// Compare and contrast the unit tests here with those for app/browser key-event unit testing
Expand Down Expand Up @@ -195,4 +196,4 @@ describe('Engine - rule processing', function() {
assert.isTrue(positionalResult.triggerKeyDefault);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import fs from 'fs';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);

import { Codes, KeyboardInterface, KeyboardProcessor, KeyEvent, MinimalKeymanGlobal, Mock } from '@keymanapp/keyboard-processor';
import { Codes } from "@keymanapp/common-types";
import { KeyboardInterface, KeyboardProcessor, KeyEvent, MinimalKeymanGlobal, Mock } from '@keymanapp/keyboard-processor';
import { NodeKeyboardLoader } from '@keymanapp/keyboard-processor/node-keyboard-loader';


Expand Down Expand Up @@ -346,4 +347,4 @@ describe('Engine - specialized backspace handling', function() {
assert.equal(transform.deleteLeft, 0);
assert.isNotOk(transform.deleteRight);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// TODO: Move to separate folder: 'codes'
// We should start splitting off code needed by keyboards even without a KeyboardProcessor active.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should be deleted; and we need a header.

Suggested change
// We should start splitting off code needed by keyboards even without a KeyboardProcessor active.
/*
* Keyman is copyright (C) SIL International. MIT License.
*
* Keyboard key codes and modifier bitmasks.
*/

// see also: common/web/types/src/kmx/kmx.ts

const Codes = {
export const Codes = {
// Define Keyman Developer modifier bit-flags (exposed for use by other modules)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a overly broad export name! Can we rename it? KeyCodes?

// Compare against /common/include/kmx_file.h. CTRL+F "#define LCTRLFLAG" to find the secton.
modifierCodes: {
Expand Down Expand Up @@ -115,13 +114,13 @@ const Codes = {
* @return {number} modifier key state (desktop keyboards)
*/
getModifierState(layerId: string): number {
var modifier=0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think any of the functions in this file should be moved over -- just the constants. These functions should stay in KeymanWeb's source, because they are not generic nor consistent enough to be put into common/types.

let modifier=0;
if(layerId.indexOf('shift') >= 0) {
Comment on lines -118 to +117
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason these were changed in this PR? I would prefer not to have even minimal changes like this in a refactor PR

modifier |= Codes.modifierCodes['SHIFT'];
}

// The chiral checks must not be directly exclusive due each other to visual OSK feedback.
var ctrlMatched=false;
let ctrlMatched=false;
if(layerId.indexOf('leftctrl') >= 0) {
modifier |= Codes.modifierCodes['LCTRL'];
ctrlMatched=true;
Expand All @@ -134,7 +133,7 @@ const Codes = {
modifier |= Codes.modifierCodes['CTRL'];
}

var altMatched=false;
let altMatched=false;
if(layerId.indexOf('leftalt') >= 0) {
modifier |= Codes.modifierCodes['LALT'];
altMatched=true;
Expand All @@ -157,7 +156,7 @@ const Codes = {
* @return {number} modifier key state (desktop keyboards)
*/
getStateFromLayer(layerId: string): number {
var modifier=0;
let modifier=0;

if(layerId.indexOf('caps') >= 0) {
modifier |= Codes.modifierCodes['CAPS'];
Expand All @@ -168,5 +167,3 @@ const Codes = {
return modifier;
}
}

export default Codes;
1 change: 1 addition & 0 deletions common/web/types/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export { UnicodeSetParser, UnicodeSet } from './ldml-keyboard/unicodeset-parser-
export { VariableParser, MarkerParser } from './ldml-keyboard/pattern-parser.js';
export { LDMLKeyboardXMLSourceFileReader, LDMLKeyboardXMLSourceFileReaderOptions } from './ldml-keyboard/ldml-keyboard-xml-reader.js';

export { Codes } from './consts/codes.js';
export * as Constants from './consts/virtual-key-constants.js';

export { defaultCompilerOptions, CompilerBaseOptions, CompilerCallbacks, CompilerOptions, CompilerEvent, CompilerErrorNamespace,
Expand Down
71 changes: 71 additions & 0 deletions common/web/types/test/types/consts/test-codes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import 'mocha';
import { assert } from 'chai';
import { Codes } from '../../../src/consts/codes.js';

describe('Codes', function () {
describe('test isFrameKey()', function () {
it('should properly identify frame keys', () => {
[
'K_SHIFT',
'K_LOPT',
'K_ROPT',
'K_NUMLOCK',
'K_CAPS',
'K_NUMERALS', // not explicitly listed, but included because > 50000
].forEach(keyId => assert.isTrue(Codes.isFrameKey(keyId), `isFrameKey(${keyId})`));

[
'K_ESC',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a frame key, shouldn't it? But a job for a future PR if so.

'K_OE2',
'K_ALT', // not currently included in isFrameKey
'K_CTRL', // not currently included in isFrameKey
Comment on lines +20 to +21
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These also should be frame keys, shouldn't they? But also a job for a future PR if so.

].forEach(keyId => assert.isFalse(Codes.isFrameKey(keyId), `!isFrameKey(${keyId})`));
});
});

describe('test getModifierState()', function () {
it('should properly identify modifiers from layer id', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think many of these layerIds are deprecated, and it would be good to split tests for deprecated layerIds out.

[
{ layerId: 'shift', expected: Codes.modifierCodes['SHIFT'] },
{ layerId: 'leftshift', expected: Codes.modifierCodes['SHIFT'] },
{ layerId: 'rightshift', expected: Codes.modifierCodes['SHIFT'] },
{ layerId: 'ctrlshift', expected: Codes.modifierCodes['CTRL'] | Codes.modifierCodes['SHIFT'] },
{ layerId: 'shiftctrl', expected: Codes.modifierCodes['CTRL'] | Codes.modifierCodes['SHIFT'] },
{ layerId: 'fooshift', expected: Codes.modifierCodes['SHIFT'] },

{ layerId: 'leftctrl', expected: Codes.modifierCodes['LCTRL'] },
{ layerId: 'rightctrl', expected: Codes.modifierCodes['RCTRL'] },
{ layerId: 'ctrl', expected: Codes.modifierCodes['CTRL'] },
{ layerId: 'right_ctrl', expected: Codes.modifierCodes['CTRL'] },
{ layerId: 'leftctrlrightctrlshift', expected: Codes.modifierCodes['LCTRL'] | Codes.modifierCodes['RCTRL'] | Codes.modifierCodes['SHIFT'] },
{ layerId: 'leftctrl-rightctrl-shift', expected: Codes.modifierCodes['LCTRL'] | Codes.modifierCodes['RCTRL'] | Codes.modifierCodes['SHIFT'] },
{ layerId: 'ctrl-rightctrl-shift', expected: Codes.modifierCodes['RCTRL'] | Codes.modifierCodes['SHIFT'] },

{ layerId: 'leftalt', expected: Codes.modifierCodes['LALT'] },
{ layerId: 'rightalt', expected: Codes.modifierCodes['RALT'] },
{ layerId: 'alt', expected: Codes.modifierCodes['ALT'] },
{ layerId: 'leftaltrightaltshift', expected: Codes.modifierCodes['LALT'] | Codes.modifierCodes['RALT'] | Codes.modifierCodes['SHIFT'] },
{ layerId: 'leftaltrightalt', expected: Codes.modifierCodes['LALT'] | Codes.modifierCodes['RALT'] },
{ layerId: 'shiftleftctrlrightctrlleftaltrightalt', expected: Codes.modifierCodes['LCTRL'] | Codes.modifierCodes['RCTRL'] | Codes.modifierCodes['SHIFT'] | Codes.modifierCodes['LALT'] | Codes.modifierCodes['RALT'] },
{ layerId: 'shiftctrlalt', expected: Codes.modifierCodes['SHIFT'] | Codes.modifierCodes['CTRL'] | Codes.modifierCodes['ALT'] },

{ layerId: 'foo', expected: 0 },

].forEach(testdata => assert.equal(Codes.getModifierState(testdata.layerId), testdata.expected, `getModifierState(${testdata.layerId})`));
});
});

describe('test getStateFromLayer()', function () {
it('should properly identify caps state from layer id', () => {
[
{ layerId: 'caps', expected: Codes.modifierCodes['CAPS'] },
{ layerId: 'altcaps', expected: Codes.modifierCodes['CAPS'] },
{ layerId: 'capsalt', expected: Codes.modifierCodes['CAPS'] },

{ layerId: 'shift', expected: Codes.modifierCodes['NO_CAPS'] },
{ layerId: 'foo', expected: Codes.modifierCodes['NO_CAPS'] },

].forEach(testdata => { assert.equal(Codes.getStateFromLayer(testdata.layerId), testdata.expected, `getStateFromLayer(${testdata.layerId})`); });
});
});
});
2 changes: 1 addition & 1 deletion web/src/app/browser/src/defaultBrowserRules.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Codes } from "@keymanapp/common-types";
import {
Codes,
DefaultRules,
type KeyEvent,
type OutputTarget
Expand Down
3 changes: 2 additions & 1 deletion web/src/app/browser/src/hardwareEventKeyboard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Codes, DeviceSpec, KeyEvent, KeyMapping, Keyboard, KeyboardProcessor } from '@keymanapp/keyboard-processor';
import { Codes } from "@keymanapp/common-types";
import { DeviceSpec, KeyEvent, KeyMapping, Keyboard, KeyboardProcessor } from '@keymanapp/keyboard-processor';

import { HardKeyboard, processForMnemonicsAndLegacy } from 'keyman/engine/main';
import { DomEventTracker } from 'keyman/engine/events';
Expand Down
3 changes: 2 additions & 1 deletion web/src/engine/main/src/hardKeyboard.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { EventEmitter } from "eventemitter3";
import { Keyboard, KeyMapping, KeyEvent, type RuleBehavior, Codes } from "@keymanapp/keyboard-processor";
import { Keyboard, KeyMapping, KeyEvent, type RuleBehavior } from "@keymanapp/keyboard-processor";
import { Codes } from "@keymanapp/common-types";
import { KeyEventSourceInterface } from 'keyman/engine/events';

interface EventMap {
Expand Down
2 changes: 1 addition & 1 deletion web/src/engine/osk/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { Codes, DeviceSpec, Keyboard, KeyboardProperties, SpacebarText } from '@keymanapp/keyboard-processor';
export { DeviceSpec, Keyboard, KeyboardProperties, SpacebarText } from '@keymanapp/keyboard-processor';

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should Codes be re-exported, given it was exported here before? I don't know how "public" these exports are... @jahorton? (And if we rename Codes then perhaps its name should be maintained here export { KeyCodes as Codes } from '@keymanapp/common-types';?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering that we only even modularized to this extent with Keyman 17, I severely doubt anyone external is relying upon Codes here. If everything is building fine, we're good.

I would be a touch worried about Web's test-sequence "recording" module... but that's built via ./web/build.sh tools, which is triggered during standard Web CI builds. As even that didn't fall over, in the absolute worst case, all that would be needed is to tidy up the relevant pages.

tl;dr: nah, no need to re-export.

export { default as OSKView } from './views/oskView.js';
export { default as FloatingOSKView, FloatingOSKViewConfiguration } from './views/floatingOskView.js';
Expand Down
3 changes: 2 additions & 1 deletion web/src/engine/osk/src/keyboard-layout/oskBaseKey.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ActiveKey, Codes } from '@keymanapp/keyboard-processor';
import { ActiveKey } from '@keymanapp/keyboard-processor';
import { Codes } from "@keymanapp/common-types";

import OSKKey, { KeyLayoutParams, renameSpecialKey } from './oskKey.js';
import { KeyData, KeyElement, link } from '../keyElement.js';
Expand Down
2 changes: 1 addition & 1 deletion web/src/engine/osk/src/views/oskView.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { EventEmitter } from 'eventemitter3';
import { Codes } from "@keymanapp/common-types";

import { BannerView } from '../banner/bannerView.js';
import { BannerController } from '../banner/bannerController.js';
Expand All @@ -11,7 +12,6 @@ import { LengthStyle, ParsedLengthStyle } from '../lengthStyle.js';
import { type KeyElement } from '../keyElement.js';

import {
Codes,
DeviceSpec,
Keyboard,
KeyboardProperties,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ 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';
import { Codes } from "@keymanapp/common-types";
import { Keyboard, KeyEvent } from '@keymanapp/keyboard-processor';

const ModifierCodes = Codes.modifierCodes;
const KeyCodes = Codes.keyCodes;
Expand Down
Loading