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