From e3134a1c0fee2ed80658f0835b8d0bb6c166a2ce Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Sun, 21 Jul 2024 13:22:33 +1000 Subject: [PATCH] feat(developer): handle automatic versioning of special key caps on normal keys Special key caps on normal keys in touch layout files are supported with Keyman 14.0 and later versions. Handle automatic determination of the version number if `store(&VERSION)` is not present. Add corresponding unit tests. Fixes: #11960 --- .../src/kmw-compiler/compiler-globals.ts | 15 +++++++ .../src/kmw-compiler/validate-layout-file.ts | 6 +-- ...rsion_special_key_caps.keyman-touch-layout | 45 +++++++++++++++++++ .../fixtures/kmw/version_special_key_caps.kmn | 9 ++++ .../kmw/version_special_key_caps_14.kmn | 12 +++++ .../src/kmc-kmn/test/kmw/test-kmw-compiler.ts | 26 +++++++++++ .../src/kmc-kmn/test/kmw/test-kmw-messages.ts | 9 +++- 7 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps.keyman-touch-layout create mode 100644 developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps.kmn create mode 100644 developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps_14.kmn diff --git a/developer/src/kmc-kmn/src/kmw-compiler/compiler-globals.ts b/developer/src/kmc-kmn/src/kmw-compiler/compiler-globals.ts index 13d4d687f5..fee9f234c0 100644 --- a/developer/src/kmc-kmn/src/kmw-compiler/compiler-globals.ts +++ b/developer/src/kmc-kmn/src/kmw-compiler/compiler-globals.ts @@ -76,6 +76,21 @@ export function verifyMinimumRequiredKeymanVersion10(): boolean { return verifyMinimumRequiredKeymanVersion(KMX.KMX_Version.VERSION_100); } +/** + * Verify that minimum supported Keyman version in the keyboard is version 14.0, + * and upgrade to that version if possible and necessary. + * + * Will upgrade the minimum version to 14.0 if `KF_AUTOMATICVERSION` flag is set + * for the keyboard, which correlates to having no `store(&version)` line in the + * .kmn source file. + * + * @returns `true` if the version is now 14.0 or higher, `false` if a lower + * version has been specified in the source file `store(&version)` line. + */ +export function verifyMinimumRequiredKeymanVersion14(): boolean { + return verifyMinimumRequiredKeymanVersion(KMX.KMX_Version.VERSION_140); +} + /** * Verify that minimum supported Keyman version in the keyboard is version 15.0, * and upgrade to that version if possible and necessary. diff --git a/developer/src/kmc-kmn/src/kmw-compiler/validate-layout-file.ts b/developer/src/kmc-kmn/src/kmw-compiler/validate-layout-file.ts index 82c05dc03f..c11199811c 100644 --- a/developer/src/kmc-kmn/src/kmw-compiler/validate-layout-file.ts +++ b/developer/src/kmc-kmn/src/kmw-compiler/validate-layout-file.ts @@ -1,6 +1,7 @@ import { KMX, TouchLayout, TouchLayoutFileReader, TouchLayoutFileWriter } from "@keymanapp/common-types"; import { callbacks, minimumKeymanVersion, verifyMinimumRequiredKeymanVersion15, - isKeyboardVersion14OrLater, isKeyboardVersion17OrLater } from "./compiler-globals.js"; + isKeyboardVersion14OrLater, isKeyboardVersion17OrLater, + verifyMinimumRequiredKeymanVersion14 } from "./compiler-globals.js"; import { JavaScript_Key } from "./javascript-strings.js"; import { TRequiredKey, CRequiredKeys, CSpecialText, CSpecialText14Map, CSpecialText17Map, CSpecialTextMinVer, CSpecialTextMaxVer } from "./constants.js"; @@ -149,8 +150,7 @@ function CheckKey( const mapVersion = Math.max(Math.min(minimumKeymanVersion(), CSpecialTextMaxVer), CSpecialTextMinVer); const specialText = CSpecialText.get(mapVersion); if(specialText.includes(FText) && - // TODO: automatic version upgrade - !isKeyboardVersion14OrLater() && + !verifyMinimumRequiredKeymanVersion14() && !([TouchLayout.TouchLayoutKeySp.special, TouchLayout.TouchLayoutKeySp.specialActive].includes(FKeyType))) { callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutSpecialLabelOnNormalKey({ keyId: FId, diff --git a/developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps.keyman-touch-layout b/developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps.keyman-touch-layout new file mode 100644 index 0000000000..10593d518f --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps.keyman-touch-layout @@ -0,0 +1,45 @@ +{ + "tablet": { + "font": "Tahoma", + "layer": [ + { + "id": "default", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_Q", + "text": "q" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": 90, + "sp": 1 + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": 120, + "sp": 1 + }, + { + "id": "K_SPACE", + "text": "", + "width": 630, + "sp": 0 + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": 140, + "sp": 0 + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps.kmn b/developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps.kmn new file mode 100644 index 0000000000..6024466630 --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps.kmn @@ -0,0 +1,9 @@ +store(&NAME) 'version_special_key_caps' +store(&TARGETS) 'mobile' +store(&LAYOUTFILE) 'version_special_key_caps.keyman-touch-layout' + +c Use of special key caps on nomral keys should make compiler select version 14 + +begin Unicode > use(main) + +group(main) using keys diff --git a/developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps_14.kmn b/developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps_14.kmn new file mode 100644 index 0000000000..0fad6a72f0 --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/kmw/version_special_key_caps_14.kmn @@ -0,0 +1,12 @@ +store(&NAME) 'version_special_key_caps_14' +store(&TARGETS) 'mobile' +store(&LAYOUTFILE) 'version_special_key_caps.keyman-touch-layout' +store(&VERSION) '10.0' + +c Use of special key caps on normal keys should make compiler +c generate warning WARN_TouchLayoutSpecialLabelOnNormalKey due +c to version < 14.0 + +begin Unicode > use(main) + +group(main) using keys diff --git a/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts b/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts index 3cd9cdb519..4ba3773aae 100644 --- a/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts +++ b/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts @@ -163,6 +163,32 @@ describe('KeymanWeb Compiler', function() { assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.ERROR_140FeatureOnlyContextAndNotAnyWeb)); }); + it('should determine the minimum version correctly with special key caps on normal keys', async function() { + const filenames = generateTestFilenames('version_special_key_caps'); + + let result = await kmnCompiler.run(filenames.source, null); + assert.isNotNull(result); + assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); + // The min version message from the .kmn compiler is generic 208A INFO_Info; + // we expect only 1 of the info messages -- for the .kmx target (not 2) + assert.equal(callbacks.messages.filter(item => item.code == KmnCompilerMessages.INFO_Info).length, 1); + + const data = new TextDecoder('utf-8').decode(result.artifacts.js.data); + assert.match(data, /KMINVER="14.0"/, `Could not find expected 'KMINVER="14.0"'`); + }); + + it('should give warning WARN_TouchLayoutSpecialLabelOnNormalKey if the minimum version specified in the keyboard does not support special key caps on normal keys', async function() { + // Note that the logic being tested here is in kmx compiler.cpp, not kmw compiler + const filenames = generateTestFilenames('version_special_key_caps_14'); + + let result = await kmnCompiler.run(filenames.source, null); + assert.isNotNull(result); + // The min version message from the .kmn compiler is generic 208A INFO_Info + assert.isFalse(callbacks.hasMessage(KmnCompilerMessages.INFO_Info)); + assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); + assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.WARN_TouchLayoutSpecialLabelOnNormalKey)); + }); + }); async function run_test_keyboard(kmnCompiler: KmnCompiler, id: string): diff --git a/developer/src/kmc-kmn/test/kmw/test-kmw-messages.ts b/developer/src/kmc-kmn/test/kmw/test-kmw-messages.ts index 79cbdcb179..ecd63ee73c 100644 --- a/developer/src/kmc-kmn/test/kmw/test-kmw-messages.ts +++ b/developer/src/kmc-kmn/test/kmw/test-kmw-messages.ts @@ -48,7 +48,14 @@ describe('KmwCompilerMessages', function () { // TODO: other messages // WARN_ExtendedShiftFlagsNotSupportedInKeymanWeb: - // * Implemented in test-kmw-compiler.ts: 'should give warning WARN_ExtendedShiftFlagsNotSupportedInKeymanWeb for v9 keyboards if ${mode} found' + // * Implemented in test-kmw-compiler.ts: 'should give warning + // WARN_ExtendedShiftFlagsNotSupportedInKeymanWeb for v9 keyboards if + // ${mode} found' + + // WARN_TouchLayoutSpecialLabelOnNormalKey + // * Implemented in test-kmw-compiler.ts: 'should give warning + // WARN_TouchLayoutSpecialLabelOnNormalKey if the minimum version specified + // in the keyboard does not support special key caps on normal keys' // ERROR_NotAnyRequiresVersion14