mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-12 00:47:29 +00:00
chore(web): Merge branch 'epic/web-core' into feat/web/keyboardDetails
This commit is contained in:
commit
16dcfaa0cc
9 changed files with 155 additions and 33 deletions
|
|
@ -18,7 +18,8 @@ Keyman configures two separate instances of this gesture engine - one for main k
|
|||
|
||||
----
|
||||
|
||||
For the main keyboard implementation of Keyman Engine for Web, the full set of Keyman gesture components is defined in `web/src/engine/osk/src/input/gestures/specsForLayout.ts`.
|
||||
For the main keyboard implementation of Keyman Engine for Web, the full set of Keyman gesture
|
||||
components is defined in `web/src/engine/src/osk/input/gestures/specsForLayout.ts`.
|
||||
|
||||
### Longpresses
|
||||
|
||||
|
|
@ -44,4 +45,4 @@ Components:
|
|||
|
||||
1. The user holds down on a modipress-friendly key
|
||||
2. Engine alt-state: a different set of initial gesture components is activated and used for newly-starting concurrent gestures
|
||||
3. Release of the modipressed key
|
||||
3. Release of the modipressed key
|
||||
|
|
|
|||
|
|
@ -474,8 +474,7 @@ export class KeymanEngine extends KeymanEngineBase<BrowserConfiguration, Context
|
|||
|
||||
const cache = this.keyboardRequisitioner.cache;
|
||||
const keyboardStubs = cache.getStubList()
|
||||
for (let i = 0; i < keyboardStubs.length; i++) {
|
||||
const stub = keyboardStubs[i];
|
||||
for (const stub of keyboardStubs) {
|
||||
const keyboard = cache.getKeyboardForStub(stub);
|
||||
const keyboardDetails = this.getKeyboardDetails(stub, keyboard);
|
||||
if (keyboardDetails) {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
/*
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*/
|
||||
import { KM_Core, km_core_option_item } from 'keyman/engine/core-adapter';
|
||||
import { KM_Core, km_core_option_item, KM_CORE_OPTION_SCOPE } from 'keyman/engine/core-adapter';
|
||||
import { KeyboardMinimalInterface, Keyboard, VariableStoreSerializer, KMXKeyboard } from 'keyman/engine/keyboard';
|
||||
import { toPrefixedKeyboardId } from 'keyman/engine/keyboard-storage';
|
||||
|
||||
export class CoreKeyboardInterface implements KeyboardMinimalInterface {
|
||||
private _activeKeyboard: Keyboard;
|
||||
|
||||
public constructor(public variableStoreSerializer: VariableStoreSerializer) {
|
||||
public constructor(public readonly variableStoreSerializer: VariableStoreSerializer) {
|
||||
if (!variableStoreSerializer) {
|
||||
throw new Error('variableStoreSerializer is required');
|
||||
}
|
||||
}
|
||||
|
||||
public get activeKeyboard(): Keyboard {
|
||||
|
|
@ -15,33 +19,36 @@ export class CoreKeyboardInterface implements KeyboardMinimalInterface {
|
|||
}
|
||||
public set activeKeyboard(keyboard: Keyboard) {
|
||||
this._activeKeyboard = keyboard;
|
||||
const options = this.loadSerializedOptions(keyboard);
|
||||
const options = this.loadSerializedOptions();
|
||||
|
||||
if (options.length > 0) {
|
||||
const kmxKeyboard = this._activeKeyboard as KMXKeyboard;
|
||||
KM_Core.instance.state_options_update(kmxKeyboard.state, options);
|
||||
KM_Core.instance.state_options_update(this.KmxKeyboard.state, options);
|
||||
}
|
||||
}
|
||||
|
||||
private get KmxKeyboard(): KMXKeyboard {
|
||||
return this._activeKeyboard as KMXKeyboard;
|
||||
}
|
||||
|
||||
private loadSerializedOptions(keyboard: Keyboard): km_core_option_item[] {
|
||||
// TODO-WEB-CORE: use km_core_keyboard_get_attrs to get list of all variable
|
||||
// store names and then iterate through those rather than reading from
|
||||
// cookie props
|
||||
private loadSerializedOptions(): km_core_option_item[] {
|
||||
const options: km_core_option_item[] = [];
|
||||
/*const stores = this.variableStoreSerializer.findStores(toPrefixedKeyboardId(keyboard.id));
|
||||
for (const store of stores) {
|
||||
for (const key in store) {
|
||||
if (store.hasOwnProperty(key)) {
|
||||
const attrs = KM_Core.instance.keyboard_get_attrs(this.KmxKeyboard.keyboard);
|
||||
const prefixedKeyboardId = toPrefixedKeyboardId(this.KmxKeyboard.id);
|
||||
const defaultOptions = attrs.object.default_options as km_core_option_item[];
|
||||
for (const defaultOption of defaultOptions) {
|
||||
if (defaultOption.scope == KM_CORE_OPTION_SCOPE.OPT_KEYBOARD) {
|
||||
const savedValue = this.variableStoreSerializer.loadStore(prefixedKeyboardId, defaultOption.key);
|
||||
if (savedValue !== undefined) {
|
||||
const item: km_core_option_item = {
|
||||
key: key,
|
||||
value: store[key],
|
||||
scope: KM_CORE_OPTION_SCOPE.OPT_KEYBOARD
|
||||
key: defaultOption.key,
|
||||
value: savedValue,
|
||||
scope: defaultOption.scope
|
||||
};
|
||||
options.push(item);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
attrs.delete();
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,10 @@
|
|||
import { CoreKeyboardInterface } from './coreKeyboardInterface.js';
|
||||
|
||||
export { CoreKeyboardProcessor } from './coreKeyboardProcessor.js';
|
||||
|
||||
/**
|
||||
* these are exported only for unit tests, do not use
|
||||
*/
|
||||
export const unitTestEndPoints = {
|
||||
CoreKeyboardInterface,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@
|
|||
export type VariableStores = { [name: string]: string; };
|
||||
|
||||
export interface VariableStoreSerializer {
|
||||
loadStore(keyboardID: string, storeName: string): string;
|
||||
loadStore(keyboardID: string, storeName: string): string | undefined;
|
||||
saveStore(keyboardID: string, storeName: string, storeValue: string): void;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ export class VariableStoreCookieSerializer implements VariableStoreSerializer {
|
|||
return `KeymanWeb_${keyboardID}_Option_${storeName}`;
|
||||
}
|
||||
|
||||
public loadStore(keyboardID: string, storeName: string): string {
|
||||
public loadStore(keyboardID: string, storeName: string): string | undefined {
|
||||
// Note, for historical reasons, we pass a VariableStores object into the
|
||||
// cookie serializer but expect only a single value to be loaded
|
||||
const storeCookieSerializer = new CookieSerializer<VariableStores>(this.getStoreCookieName(keyboardID, storeName));
|
||||
return storeCookieSerializer.load(decodeURIComponent)[storeName];
|
||||
return storeCookieSerializer.load(decodeURIComponent)[storeName] ?? undefined;
|
||||
}
|
||||
|
||||
public saveStore(keyboardID: string, storeName: string, storeValue: string) {
|
||||
|
|
|
|||
|
|
@ -47,13 +47,6 @@ const testsToFix = {
|
|||
'k_0202___alt.kmn',
|
||||
'k_0203___generic_ctrlalt.kmn',
|
||||
'k_0400___groups_and_virtual_keys.kmn', // kmx only
|
||||
'k_0501___options_with_preset.kmn', // variable stores initialization work to do with keyboard_attrs
|
||||
'k_0503___options_with_save_and_preset.kmn', // variable stores initialization work to do with keyboard_attrs
|
||||
'k_0504___options_with_reset.kmn', // variable stores initialization work to do with keyboard_attrs
|
||||
'k_0505___options_double_set_reset.kmn', // variable stores initialization work to do with keyboard_attrs
|
||||
'k_0506___options_double_set_staged.kmn', // variable stores initialization work to do with keyboard_attrs
|
||||
'k_0507___options___double_reset_staged.kmn', // variable stores initialization work to do with keyboard_attrs
|
||||
'k_0508___options___double_reset.kmn', // variable stores initialization work to do with keyboard_attrs
|
||||
'k_0600___system_stores.kmn',
|
||||
'k_0601___system_stores_2.kmn',
|
||||
'k_0700___caps_lock.kmn',
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ export class VariableStoreTestSerializer implements VariableStoreSerializer {
|
|||
return `KeymanWeb_${keyboardID}_Option_${storeName}`;
|
||||
}
|
||||
|
||||
loadStore(keyboardID: string, storeName: string): string {
|
||||
return this.stores[this.getStoreName(keyboardID, storeName)] ?? '';
|
||||
loadStore(keyboardID: string, storeName: string): string | undefined {
|
||||
return this.stores[this.getStoreName(keyboardID, storeName)] ?? undefined;
|
||||
}
|
||||
|
||||
saveStore(keyboardID: string, storeName: string, storeValue: string): void {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
import sinon from 'sinon';
|
||||
import { unitTestEndPoints } from 'keyman/engine/core-processor';
|
||||
import { VariableStoreTestSerializer } from 'keyman/test/headless-resources';
|
||||
import { KM_Core, KM_CORE_STATUS, KM_CORE_OPTION_SCOPE, type km_core_option_item } from 'keyman/engine/core-adapter';
|
||||
import { coreurl } from '../loadKeyboardHelper.js';
|
||||
|
||||
describe('CoreKeyboardInterface tests', function () {
|
||||
let sandbox: sinon.SinonSandbox;
|
||||
const mockKeyboard = {
|
||||
keyboard: {} as any,
|
||||
id: 'test_keyboard',
|
||||
state: {} as any
|
||||
};
|
||||
|
||||
beforeEach(async function () {
|
||||
sandbox = sinon.createSandbox();
|
||||
await KM_Core.createCoreProcessor(coreurl);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
describe('loadSerializedOptions', function () {
|
||||
it('returns empty array if there are no default options', function () {
|
||||
// Setup
|
||||
const mockAttrs = {
|
||||
object: {
|
||||
id: 'test_keyboard',
|
||||
version_string: '1.234',
|
||||
default_options: [] as km_core_option_item[],
|
||||
},
|
||||
status: KM_CORE_STATUS.OK,
|
||||
delete: sandbox.stub()
|
||||
};
|
||||
sandbox.stub(KM_Core.instance, 'keyboard_get_attrs').returns(mockAttrs as any);
|
||||
const keyboardInterface = new unitTestEndPoints.CoreKeyboardInterface(new VariableStoreTestSerializer());
|
||||
keyboardInterface['_activeKeyboard'] = mockKeyboard as any;
|
||||
|
||||
// Execute
|
||||
const options = keyboardInterface['loadSerializedOptions']();
|
||||
|
||||
// Verify
|
||||
assert.isArray(options);
|
||||
assert.lengthOf(options, 0);
|
||||
});
|
||||
|
||||
it('returns no options if no options serialized', function () {
|
||||
// Setup
|
||||
const mockAttrs = {
|
||||
object: {
|
||||
id: 'test_keyboard',
|
||||
version_string: '1.234',
|
||||
default_options: [
|
||||
{ key: 'opt1', value: 'val1', scope: KM_CORE_OPTION_SCOPE.OPT_KEYBOARD }
|
||||
],
|
||||
},
|
||||
status: KM_CORE_STATUS.OK,
|
||||
delete: sandbox.stub(),
|
||||
};
|
||||
sandbox.stub(KM_Core.instance, 'keyboard_get_attrs').returns(mockAttrs as any);
|
||||
const keyboardInterface = new unitTestEndPoints.CoreKeyboardInterface(new VariableStoreTestSerializer());
|
||||
keyboardInterface['_activeKeyboard'] = mockKeyboard as any;
|
||||
|
||||
// Execute
|
||||
const options = keyboardInterface['loadSerializedOptions']();
|
||||
|
||||
// Verify
|
||||
assert.isArray(options);
|
||||
assert.lengthOf(options, 0);
|
||||
});
|
||||
|
||||
it('returns serialized options from keyboard attrs', function () {
|
||||
// Setup
|
||||
const mockAttrs = {
|
||||
object: {
|
||||
id: 'test_keyboard',
|
||||
version_string: '1.234',
|
||||
default_options: [
|
||||
{ key: 'opt1', value: 'default1', scope: KM_CORE_OPTION_SCOPE.OPT_KEYBOARD },
|
||||
{ key: 'opt2', value: 'default2', scope: KM_CORE_OPTION_SCOPE.OPT_KEYBOARD }, // ignored because not serialized
|
||||
{ key: 'opt3', value: 'default3', scope: KM_CORE_OPTION_SCOPE.OPT_KEYBOARD },
|
||||
{ key: 'opt4', value: 'default4', scope: KM_CORE_OPTION_SCOPE.OPT_ENVIRONMENT },
|
||||
],
|
||||
},
|
||||
status: KM_CORE_STATUS.OK,
|
||||
delete: sandbox.stub(),
|
||||
};
|
||||
sandbox.stub(KM_Core.instance, 'keyboard_get_attrs').returns(mockAttrs as any);
|
||||
const serializer = new VariableStoreTestSerializer();
|
||||
serializer.saveStore('Keyboard_test_keyboard', 'opt1', 'val1');
|
||||
serializer.saveStore('Keyboard_test_keyboard', 'opt3', '');
|
||||
serializer.saveStore('Keyboard_test_keyboard', 'opt4', 'val4'); // ignored since not keyboard-scoped
|
||||
serializer.saveStore('Keyboard_test_keyboard', 'opt5', 'val5'); // ignored since not in default options
|
||||
const keyboardInterface = new unitTestEndPoints.CoreKeyboardInterface(serializer);
|
||||
keyboardInterface['_activeKeyboard'] = mockKeyboard as any;
|
||||
|
||||
// Execute
|
||||
const options = keyboardInterface['loadSerializedOptions']();
|
||||
|
||||
// Verify
|
||||
assert.isArray(options);
|
||||
assert.lengthOf(options,2);
|
||||
assert.deepEqual(options[0], { key: 'opt1', value: 'val1', scope: KM_CORE_OPTION_SCOPE.OPT_KEYBOARD });
|
||||
assert.deepEqual(options[1], { key: 'opt3', value: '', scope: KM_CORE_OPTION_SCOPE.OPT_KEYBOARD });
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue