From fea40e2689b8f185568a2b42f6575dcae846077f Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 9 Dec 2024 11:47:54 +0000 Subject: [PATCH 001/155] chore(common/web): initial test boilerplate --- .../kmx/kmx-plus/element-string.tests.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 common/web/types/tests/kmx/kmx-plus/element-string.tests.ts diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts new file mode 100644 index 0000000000..438c16bf4a --- /dev/null +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -0,0 +1,19 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + * + * Created by Dr Mark C. Sinclair on 2024-12-09 + * + * Test code for element-string.ts + */ + +import 'mocha'; +import { assert } from 'chai'; + +describe('Test of ElementString', () => { + describe('Test of ElemElement', () => { + describe('Test of isEqual()', () => { + assert.isTrue(true); + assert.isFalse(false); + }); + }); +}); From 13b463aedf8ef29cd1e6356662b34b6242116c49 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 9 Dec 2024 16:16:31 +0000 Subject: [PATCH 002/155] chore(common/web): add initElemElement and first true test case for isEqual() --- .../kmx/kmx-plus/element-string.tests.ts | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 438c16bf4a..2ced6327ca 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -8,12 +8,40 @@ import 'mocha'; import { assert } from 'chai'; +import { ElemElementFlags, ElemElement } from '../../../src/kmx/kmx-plus/element-string.js'; +import { StrsItem, UsetItem } from '../../../src/kmx/kmx-plus/kmx-plus.js'; +import { UnicodeSet } from '../../../src/ldml-keyboard/unicodeset-parser-api.js'; + +const GOTHIC_A = new StrsItem("𐌰", 0x10330); +const GOTHIC_A_SET = new UsetItem( + new UnicodeSet("[𐌰-𐍊]", [[0x10330,0x1034A]]), + GOTHIC_A +); describe('Test of ElementString', () => { describe('Test of ElemElement', () => { describe('Test of isEqual()', () => { - assert.isTrue(true); - assert.isFalse(false); + it('returns true when elems identical', () => { + const one = initElemElement(); + const two = initElemElement() + assert.isTrue(one.isEqual(two)); + }); }); }); }); + +function initElemElement( + value: StrsItem = GOTHIC_A, + uset: UsetItem = GOTHIC_A_SET, + order: number = 0, + tertiary: number = 1, + flags: ElemElementFlags = ElemElementFlags.none, +): ElemElement { + const ee = new ElemElement(); + ee.value = value; + ee.uset = uset; + ee.order = order; + ee.tertiary = tertiary; + ee.flags = flags; + return ee; +} From ee23da5647ad9c3b8faca036a85c94a3cae9ddef Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 16 Dec 2024 12:17:18 +0000 Subject: [PATCH 003/155] chore(common/web): add five test cases for ElemElement.isEqual() --- .../kmx/kmx-plus/element-string.tests.ts | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 2ced6327ca..f1a530efde 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -13,10 +13,16 @@ import { StrsItem, UsetItem } from '../../../src/kmx/kmx-plus/kmx-plus.js'; import { UnicodeSet } from '../../../src/ldml-keyboard/unicodeset-parser-api.js'; const GOTHIC_A = new StrsItem("𐌰", 0x10330); -const GOTHIC_A_SET = new UsetItem( +const GOTHIC_B = new StrsItem("𐌱", 0x10331); +const UGARITIC_A = new StrsItem("𐎀", 0x10380); +const GOTHIC_SET = new UsetItem( new UnicodeSet("[𐌰-𐍊]", [[0x10330,0x1034A]]), GOTHIC_A ); +const UGARITIC_SET = new UsetItem( + new UnicodeSet("[𐎀-𐎟]", [[0x10380,0x1039F]]), + UGARITIC_A +); describe('Test of ElementString', () => { describe('Test of ElemElement', () => { @@ -26,13 +32,38 @@ describe('Test of ElementString', () => { const two = initElemElement() assert.isTrue(one.isEqual(two)); }); + it('returns false when value differs', () => { + const one = initElemElement(GOTHIC_A); + const two = initElemElement(GOTHIC_B); + assert.isFalse(one.isEqual(two)); + }); + it('returns false when order differs', () => { + const one = initElemElement(GOTHIC_A, GOTHIC_SET, 0); + const two = initElemElement(GOTHIC_A, GOTHIC_SET, 1); + assert.isFalse(one.isEqual(two)); + }); + it('returns false when tertiary differs', () => { + const one = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 1); + const two = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 2); + assert.isFalse(one.isEqual(two)); + }); + it('returns false when flags differs', () => { + const one = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 1, ElemElementFlags.none); + const two = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 1, ElemElementFlags.type); + assert.isFalse(one.isEqual(two)); + }); + it('returns true even though uset differs', () => { + const one = initElemElement(GOTHIC_A, GOTHIC_SET); + const two = initElemElement(GOTHIC_A, UGARITIC_SET); + assert.isTrue(one.isEqual(two)); + }); }); }); }); function initElemElement( value: StrsItem = GOTHIC_A, - uset: UsetItem = GOTHIC_A_SET, + uset: UsetItem = GOTHIC_SET, order: number = 0, tertiary: number = 1, flags: ElemElementFlags = ElemElementFlags.none, From 77076eb9ed09157b66e8159cd83078f8b705e8c3 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 16 Dec 2024 12:43:53 +0000 Subject: [PATCH 004/155] chore(common/web): add first test case for ElementString() --- .../types/tests/kmx/kmx-plus/element-string.tests.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index f1a530efde..ce3db90fc3 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -8,7 +8,7 @@ import 'mocha'; import { assert } from 'chai'; -import { ElemElementFlags, ElemElement } from '../../../src/kmx/kmx-plus/element-string.js'; +import { ElemElementFlags, ElemElement, ElementString } from '../../../src/kmx/kmx-plus/element-string.js'; import { StrsItem, UsetItem } from '../../../src/kmx/kmx-plus/kmx-plus.js'; import { UnicodeSet } from '../../../src/ldml-keyboard/unicodeset-parser-api.js'; @@ -59,6 +59,14 @@ describe('Test of ElementString', () => { }); }); }); + describe('Test of ElementString', () => { + describe('Test of fromStrings()', () => { + it('returns an empty El;ementString if source is null', () => { + const es = ElementString.fromStrings({}, null); + assert.deepEqual(es, new ElementString()); + }); + }); + }); }); function initElemElement( From 703fd2cbe6ec2be2995d0c3bb6ae8be08ac480b9 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 16 Dec 2024 15:41:00 +0000 Subject: [PATCH 005/155] chore(common/web): add use case for string array --- .../kmx/kmx-plus/element-string.tests.ts | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index ce3db90fc3..7c187d9920 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -9,11 +9,12 @@ import 'mocha'; import { assert } from 'chai'; import { ElemElementFlags, ElemElement, ElementString } from '../../../src/kmx/kmx-plus/element-string.js'; -import { StrsItem, UsetItem } from '../../../src/kmx/kmx-plus/kmx-plus.js'; +import { StrsItem, UsetItem, DependencySections, Strs } from '../../../src/kmx/kmx-plus/kmx-plus.js'; import { UnicodeSet } from '../../../src/ldml-keyboard/unicodeset-parser-api.js'; const GOTHIC_A = new StrsItem("𐌰", 0x10330); const GOTHIC_B = new StrsItem("𐌱", 0x10331); +const GOTHIC_C = new StrsItem("𐌲", 0x10332); const UGARITIC_A = new StrsItem("𐎀", 0x10380); const GOTHIC_SET = new UsetItem( new UnicodeSet("[𐌰-𐍊]", [[0x10330,0x1034A]]), @@ -43,13 +44,13 @@ describe('Test of ElementString', () => { assert.isFalse(one.isEqual(two)); }); it('returns false when tertiary differs', () => { - const one = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 1); - const two = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 2); + const one = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 0); + const two = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 1); assert.isFalse(one.isEqual(two)); }); it('returns false when flags differs', () => { - const one = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 1, ElemElementFlags.none); - const two = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 1, ElemElementFlags.type); + const one = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 0, ElemElementFlags.none); + const two = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 0, ElemElementFlags.type); assert.isFalse(one.isEqual(two)); }); it('returns true even though uset differs', () => { @@ -61,19 +62,30 @@ describe('Test of ElementString', () => { }); describe('Test of ElementString', () => { describe('Test of fromStrings()', () => { - it('returns an empty El;ementString if source is null', () => { + it('returns an empty ElementString if source is null', () => { const es = ElementString.fromStrings({}, null); assert.deepEqual(es, new ElementString()); }); + it('can create an ElementString from a string array', () => { + const strs: Strs = new Strs(); + const sections: DependencySections = { strs: strs }; + const actual = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); + const expected = [ + initElemElement(GOTHIC_A), + initElemElement(GOTHIC_B), + initElemElement(GOTHIC_C), + ]; + assert.deepEqual(actual, expected); + }); }); }); }); function initElemElement( value: StrsItem = GOTHIC_A, - uset: UsetItem = GOTHIC_SET, + uset: UsetItem = undefined, order: number = 0, - tertiary: number = 1, + tertiary: number = 0, flags: ElemElementFlags = ElemElementFlags.none, ): ElemElement { const ee = new ElemElement(); From 76316f1661bda4dd41f842d2eb0fd67b2be53cca Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 16 Dec 2024 17:07:52 +0000 Subject: [PATCH 006/155] chore(common/web): add test case for fromStrings() from string --- .../kmx/kmx-plus/element-string.tests.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 7c187d9920..926fd8eff2 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -11,6 +11,7 @@ import { assert } from 'chai'; import { ElemElementFlags, ElemElement, ElementString } from '../../../src/kmx/kmx-plus/element-string.js'; import { StrsItem, UsetItem, DependencySections, Strs } from '../../../src/kmx/kmx-plus/kmx-plus.js'; import { UnicodeSet } from '../../../src/ldml-keyboard/unicodeset-parser-api.js'; +import { ElementParser, ElementSegment, ElementType } from '../../../src/ldml-keyboard/pattern-parser.js'; const GOTHIC_A = new StrsItem("𐌰", 0x10330); const GOTHIC_B = new StrsItem("𐌱", 0x10331); @@ -25,6 +26,8 @@ const UGARITIC_SET = new UsetItem( UGARITIC_A ); +let origElementParserSegment = ElementParser.segment; + describe('Test of ElementString', () => { describe('Test of ElemElement', () => { describe('Test of isEqual()', () => { @@ -62,6 +65,14 @@ describe('Test of ElementString', () => { }); describe('Test of ElementString', () => { describe('Test of fromStrings()', () => { + beforeEach(() => { + ElementParser.segment = (str: string): ElementSegment[] => { + return [...str].map(s => new ElementSegment(s, ElementType.codepoint)); + } + }); + afterEach(() => { + ElementParser.segment = origElementParserSegment; + }); it('returns an empty ElementString if source is null', () => { const es = ElementString.fromStrings({}, null); assert.deepEqual(es, new ElementString()); @@ -78,6 +89,17 @@ describe('Test of ElementString', () => { assert.deepEqual(actual, expected); }); }); + it('can create an ElementString from a string', () => { + const strs: Strs = new Strs(); + const sections: DependencySections = { strs: strs }; + const actual = ElementString.fromStrings(sections, "𐌰𐌱𐌲"); + const expected = [ + initElemElement(GOTHIC_A), + initElemElement(GOTHIC_B), + initElemElement(GOTHIC_C), + ]; + assert.deepEqual(actual, expected); + }); }); }); From 09168fc083875f2d16faeb749863a2430a322a35 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 16 Dec 2024 17:38:32 +0000 Subject: [PATCH 007/155] chore(common/web): remove unneeded local variables --- .../types/tests/kmx/kmx-plus/element-string.tests.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 926fd8eff2..74207775a7 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -9,7 +9,7 @@ import 'mocha'; import { assert } from 'chai'; import { ElemElementFlags, ElemElement, ElementString } from '../../../src/kmx/kmx-plus/element-string.js'; -import { StrsItem, UsetItem, DependencySections, Strs } from '../../../src/kmx/kmx-plus/kmx-plus.js'; +import { StrsItem, UsetItem, Strs } from '../../../src/kmx/kmx-plus/kmx-plus.js'; import { UnicodeSet } from '../../../src/ldml-keyboard/unicodeset-parser-api.js'; import { ElementParser, ElementSegment, ElementType } from '../../../src/ldml-keyboard/pattern-parser.js'; @@ -78,9 +78,7 @@ describe('Test of ElementString', () => { assert.deepEqual(es, new ElementString()); }); it('can create an ElementString from a string array', () => { - const strs: Strs = new Strs(); - const sections: DependencySections = { strs: strs }; - const actual = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); + const actual = ElementString.fromStrings({ strs: new Strs() }, ["𐌰", "𐌱", "𐌲"]); const expected = [ initElemElement(GOTHIC_A), initElemElement(GOTHIC_B), @@ -90,9 +88,7 @@ describe('Test of ElementString', () => { }); }); it('can create an ElementString from a string', () => { - const strs: Strs = new Strs(); - const sections: DependencySections = { strs: strs }; - const actual = ElementString.fromStrings(sections, "𐌰𐌱𐌲"); + const actual = ElementString.fromStrings({ strs: new Strs() }, "𐌰𐌱𐌲"); const expected = [ initElemElement(GOTHIC_A), initElemElement(GOTHIC_B), From 5e4d699a7258082311d70ce34ea6df75dd97440f Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 16 Dec 2024 17:51:29 +0000 Subject: [PATCH 008/155] chore(common/web): add four test cases for order andf tertiary arguments to fromStrings() --- .../kmx/kmx-plus/element-string.tests.ts | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 74207775a7..21914a0aa0 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -96,6 +96,60 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); + it('can apply order string', () => { + const actual = ElementString.fromStrings( + { strs: new Strs() }, + "𐌰𐌱𐌲", + "1 2 3", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 1), + initElemElement(GOTHIC_B, undefined, 2), + initElemElement(GOTHIC_C, undefined, 3), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply single order to all', () => { + const actual = ElementString.fromStrings( + { strs: new Strs() }, + "𐌰𐌱𐌲", + "1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 1), + initElemElement(GOTHIC_B, undefined, 1), + initElemElement(GOTHIC_C, undefined, 1), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply tertiary string', () => { + const actual = ElementString.fromStrings( + { strs: new Strs() }, + "𐌰𐌱𐌲", + null, + "1 2 3", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 1), + initElemElement(GOTHIC_B, undefined, 0, 2), + initElemElement(GOTHIC_C, undefined, 0, 3), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply single tertiary to all', () => { + const actual = ElementString.fromStrings( + { strs: new Strs() }, + "𐌰𐌱𐌲", + null, + "1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 1), + initElemElement(GOTHIC_B, undefined, 0, 1), + initElemElement(GOTHIC_C, undefined, 0, 1), + ]; + assert.deepEqual(actual, expected); + }); }); }); From aef4ef41f03bbd0087951a10af2bab82253ae07c Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 16 Dec 2024 18:04:43 +0000 Subject: [PATCH 009/155] chore(common/web): add four test cases for tertiary_base and prebase arguments to fromStrings() --- .../kmx/kmx-plus/element-string.tests.ts | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 21914a0aa0..a7ab25ee7a 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -150,6 +150,68 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); + it('can apply tertiary_base string', () => { + const actual = ElementString.fromStrings( + { strs: new Strs() }, + "𐌰𐌱𐌲", + null, + null, + "1 0 1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.tertiary_base), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.tertiary_base), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply single tertiary_base to all', () => { + const actual = ElementString.fromStrings( + { strs: new Strs() }, + "𐌰𐌱𐌲", + null, + null, + "1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.tertiary_base), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.tertiary_base), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.tertiary_base), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply prebase string', () => { + const actual = ElementString.fromStrings( + { strs: new Strs() }, + "𐌰𐌱𐌲", + null, + null, + null, + "1 0 1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.prebase), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.prebase), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply single prebase to all', () => { + const actual = ElementString.fromStrings( + { strs: new Strs() }, + "𐌰𐌱𐌲", + null, + null, + null, + "1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.prebase), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.prebase), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.prebase), + ]; + assert.deepEqual(actual, expected); + }); }); }); From 725bfa7974f96f73dc66e62487844a773b13b2d6 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 19 Dec 2024 13:59:46 +1000 Subject: [PATCH 010/155] fix(windows): bool return value of KeymanIsTextSelected --- windows/src/engine/kmtip/kmkey.cpp | 55 +++++++++++------------------- 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/windows/src/engine/kmtip/kmkey.cpp b/windows/src/engine/kmtip/kmkey.cpp index 72c8220fd6..210ced4c6c 100644 --- a/windows/src/engine/kmtip/kmkey.cpp +++ b/windows/src/engine/kmtip/kmkey.cpp @@ -69,7 +69,7 @@ public: * @param[in] n The size of the buffer. * @param[out] buf The buffer to store the context. * @param[out] isTextSelected A flag indicating whether text is selected. - * @return S_OK if successful, otherwise an HRESULT error code. + * @return BOOL if successful. */ HRESULT WINAPI KeymanGetContext(int n, PWSTR buf, BOOL* isTextSelected); // I3567 HRESULT GetResult() { return _hr; } @@ -88,10 +88,9 @@ private: * @param[in] hrGetSelection The result of a call to GetSelection selection. * @param[in] cFetched The number of selections fetched. * @param[in] tfSelection The selection details. - * @param[out] isTextSelected A flag indicating whether text is selected. * @return S_OK if successful, otherwise an HRESULT error code. */ - HRESULT KeymanIsTextSelected(HRESULT hrGetSelection, ULONG cFetched, TF_SELECTION tfSelection, BOOL *isTextSelected); + BOOL CKeymanEditSession::KeymanIsTextSelected(HRESULT hrGetSelection, ULONG cFetched, TF_SELECTION tfSelection); }; #define KEYEVENT_EXTRAINFO_KEYMAN 0xF00F0000 // I4370 @@ -275,47 +274,33 @@ HRESULT WINAPI CKeymanEditSession::KeymanGetContext(int n, PWSTR buf, BOOL* isTe } // now check for selected text - if (!SUCCEEDED(hr = KeymanIsTextSelected(hrGetSelection, cFetched, tfSelection, isTextSelected))) { - SendDebugMessage(L"Warning: KeymanIsTextSelected failed"); - // Continue to return S_OK, even though checking if a text selection exists has failed. - // Reaching this point means the context in 'buf' is valid and will be passed to the caller. - // isTextSelected will be false, which is better than returning E_FAIL at this point. + *isTextSelected = KeymanIsTextSelected(hrGetSelection, cFetched, tfSelection); + + if(tfSelection.range) { + tfSelection.range->Release(); } + return_SendDebugExit(S_OK); } -HRESULT -CKeymanEditSession::KeymanIsTextSelected(HRESULT hrGetSelection, ULONG cFetched, TF_SELECTION tfSelection, BOOL *isTextSelected) { - SendDebugEntry(); +BOOL +CKeymanEditSession::KeymanIsTextSelected(HRESULT hrGetSelection, ULONG cFetched, TF_SELECTION tfSelection) { + if (hrGetSelection == TF_E_NOSELECTION || cFetched == 0 || !SUCCEEDED(hrGetSelection) || !tfSelection.range) { + // No selection is present, or an error occurred trying to get the selection + return FALSE; + } + // check if the range is empty HRESULT hr; + BOOL isEmpty = TRUE; - *isTextSelected = FALSE; - - if (!SUCCEEDED(hrGetSelection)) { - return_SendDebugExit(E_FAIL); - } - if (hrGetSelection == TF_E_NOSELECTION) { - // No selection is present - return_SendDebugExit(S_OK); + // Compare the start and end of the range + if (!SUCCEEDED(hr = tfSelection.range->IsEmpty(_ec, &isEmpty))) { + SendDebugMessageFormat(L"KeymanIsTextSelected: Exit: Testing range->isEmpty failed with %x", hr); + return FALSE; } - if (cFetched > 0) { - // check if the range is empty - BOOL isEmpty = FALSE; - - // Compare the start and end of the range - if (!SUCCEEDED(hr = tfSelection.range->IsEmpty(_ec, &isEmpty))) { - SendDebugMessage(L"Exit: Testing range->isEmpty"); - return_SendDebugExit(hr); - } - - if (!isEmpty) { - *isTextSelected = TRUE; - } - tfSelection.range->Release(); - } - return_SendDebugExit(S_OK); + return !isEmpty; } BOOL CKMTipTextService::TIPNotifyActivate(GUID *guidProfile) // I3581 // I4274 From e6abbf027fce302e5923218a8d493f1e86524b4a Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 19 Dec 2024 12:00:33 +0000 Subject: [PATCH 011/155] chore(common/web): stub out strs.allocString() --- .../kmx/kmx-plus/element-string.tests.ts | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index a7ab25ee7a..dd0aae7a9b 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -9,7 +9,7 @@ import 'mocha'; import { assert } from 'chai'; import { ElemElementFlags, ElemElement, ElementString } from '../../../src/kmx/kmx-plus/element-string.js'; -import { StrsItem, UsetItem, Strs } from '../../../src/kmx/kmx-plus/kmx-plus.js'; +import { StrsItem, UsetItem, Strs, StrsOptions, DependencySections, CharStrsItem } from '../../../src/kmx/kmx-plus/kmx-plus.js'; import { UnicodeSet } from '../../../src/ldml-keyboard/unicodeset-parser-api.js'; import { ElementParser, ElementSegment, ElementType } from '../../../src/ldml-keyboard/pattern-parser.js'; @@ -78,7 +78,9 @@ describe('Test of ElementString', () => { assert.deepEqual(es, new ElementString()); }); it('can create an ElementString from a string array', () => { - const actual = ElementString.fromStrings({ strs: new Strs() }, ["𐌰", "𐌱", "𐌲"]); + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); const expected = [ initElemElement(GOTHIC_A), initElemElement(GOTHIC_B), @@ -88,7 +90,9 @@ describe('Test of ElementString', () => { }); }); it('can create an ElementString from a string', () => { - const actual = ElementString.fromStrings({ strs: new Strs() }, "𐌰𐌱𐌲"); + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings(sections, "𐌰𐌱𐌲"); const expected = [ initElemElement(GOTHIC_A), initElemElement(GOTHIC_B), @@ -97,8 +101,10 @@ describe('Test of ElementString', () => { assert.deepEqual(actual, expected); }); it('can apply order string', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( - { strs: new Strs() }, + sections, "𐌰𐌱𐌲", "1 2 3", ); @@ -110,8 +116,10 @@ describe('Test of ElementString', () => { assert.deepEqual(actual, expected); }); it('can apply single order to all', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( - { strs: new Strs() }, + sections, "𐌰𐌱𐌲", "1", ); @@ -123,8 +131,10 @@ describe('Test of ElementString', () => { assert.deepEqual(actual, expected); }); it('can apply tertiary string', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( - { strs: new Strs() }, + sections, "𐌰𐌱𐌲", null, "1 2 3", @@ -137,8 +147,10 @@ describe('Test of ElementString', () => { assert.deepEqual(actual, expected); }); it('can apply single tertiary to all', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( - { strs: new Strs() }, + sections, "𐌰𐌱𐌲", null, "1", @@ -151,8 +163,10 @@ describe('Test of ElementString', () => { assert.deepEqual(actual, expected); }); it('can apply tertiary_base string', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( - { strs: new Strs() }, + sections, "𐌰𐌱𐌲", null, null, @@ -166,8 +180,10 @@ describe('Test of ElementString', () => { assert.deepEqual(actual, expected); }); it('can apply single tertiary_base to all', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( - { strs: new Strs() }, + sections, "𐌰𐌱𐌲", null, null, @@ -181,8 +197,10 @@ describe('Test of ElementString', () => { assert.deepEqual(actual, expected); }); it('can apply prebase string', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( - { strs: new Strs() }, + sections, "𐌰𐌱𐌲", null, null, @@ -197,8 +215,10 @@ describe('Test of ElementString', () => { assert.deepEqual(actual, expected); }); it('can apply single prebase to all', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( - { strs: new Strs() }, + sections, "𐌰𐌱𐌲", null, null, @@ -229,4 +249,9 @@ function initElemElement( ee.tertiary = tertiary; ee.flags = flags; return ee; -} +}; + +function stubStrsAllocString_Char(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem { + return new CharStrsItem(s); +}; + From 0585b3f639af14e5e6b98555d6e74eaf42ccc78f Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 19 Dec 2024 12:13:46 +0000 Subject: [PATCH 012/155] chore(common/web): add four test cases for order etc strings that are too short --- .../kmx/kmx-plus/element-string.tests.ts | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index dd0aae7a9b..55e5f20e28 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -130,6 +130,21 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); + it.skip('can handle order string that is too short', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + "1 2", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 1), + initElemElement(GOTHIC_B, undefined, 2), + initElemElement(GOTHIC_C, undefined, 0), + ]; + assert.deepEqual(actual, expected); + }); it('can apply tertiary string', () => { const sections = { strs: new Strs() }; sections.strs.allocString = stubStrsAllocString_Char; @@ -162,6 +177,22 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); + it.skip('can handle tertiary string that is too short', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + "1 2", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 1), + initElemElement(GOTHIC_B, undefined, 0, 2), + initElemElement(GOTHIC_C, undefined, 0, 0), + ]; + assert.deepEqual(actual, expected); + }); it('can apply tertiary_base string', () => { const sections = { strs: new Strs() }; sections.strs.allocString = stubStrsAllocString_Char; @@ -196,6 +227,23 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); + it('can handle tertiary_base string that is too short', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + null, + "1 0", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.tertiary_base), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.none), + ]; + assert.deepEqual(actual, expected); + }); it('can apply prebase string', () => { const sections = { strs: new Strs() }; sections.strs.allocString = stubStrsAllocString_Char; @@ -232,6 +280,24 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); + it('can handle prebase string that is too short', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + null, + null, + "1 0", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.prebase), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.none), + ]; + assert.deepEqual(actual, expected); + }); }); }); From 1ae53a042bb8beb6f93db09e6f159120a710c2e2 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 19 Dec 2024 14:43:15 +0000 Subject: [PATCH 013/155] chore(common/web): add test cases for non-number in order and tertiary strings --- .../kmx/kmx-plus/element-string.tests.ts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 55e5f20e28..8df97fcc29 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -145,6 +145,21 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); + it.skip('can handle non-number in order string', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + "1 A 3", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 1), + initElemElement(GOTHIC_B, undefined, 0), + initElemElement(GOTHIC_C, undefined, 3), + ]; + assert.deepEqual(actual, expected); + }); it('can apply tertiary string', () => { const sections = { strs: new Strs() }; sections.strs.allocString = stubStrsAllocString_Char; @@ -193,6 +208,22 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); + it.skip('can handle non-number in tertiary string', () => { + const sections = { strs: new Strs() }; + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + "1 A 3", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 1), + initElemElement(GOTHIC_B, undefined, 0, 0), + initElemElement(GOTHIC_C, undefined, 0, 3), + ]; + assert.deepEqual(actual, expected); + }); it('can apply tertiary_base string', () => { const sections = { strs: new Strs() }; sections.strs.allocString = stubStrsAllocString_Char; From 7694623fc9f6cf283eaa04b0801e6b6aeab2b77c Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 19 Dec 2024 16:19:21 +0000 Subject: [PATCH 014/155] chore(common/web): add first uset test case with supporting stubs and TestUnicodeSetParser class --- .../kmx/kmx-plus/element-string.tests.ts | 84 ++++++++++++++----- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 8df97fcc29..b9a5987109 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -8,25 +8,36 @@ import 'mocha'; import { assert } from 'chai'; +import { constants } from '@keymanapp/ldml-keyboard-constants'; import { ElemElementFlags, ElemElement, ElementString } from '../../../src/kmx/kmx-plus/element-string.js'; -import { StrsItem, UsetItem, Strs, StrsOptions, DependencySections, CharStrsItem } from '../../../src/kmx/kmx-plus/kmx-plus.js'; -import { UnicodeSet } from '../../../src/ldml-keyboard/unicodeset-parser-api.js'; +import { StrsItem, UsetItem, Strs, StrsOptions, DependencySections, CharStrsItem, Uset } from '../../../src/kmx/kmx-plus/kmx-plus.js'; +import { UnicodeSet, UnicodeSetParser } from '../../../src/ldml-keyboard/unicodeset-parser-api.js'; import { ElementParser, ElementSegment, ElementType } from '../../../src/ldml-keyboard/pattern-parser.js'; const GOTHIC_A = new StrsItem("𐌰", 0x10330); const GOTHIC_B = new StrsItem("𐌱", 0x10331); const GOTHIC_C = new StrsItem("𐌲", 0x10332); -const UGARITIC_A = new StrsItem("𐎀", 0x10380); -const GOTHIC_SET = new UsetItem( - new UnicodeSet("[𐌰-𐍊]", [[0x10330,0x1034A]]), - GOTHIC_A +const GOTHIC_PATTERN = "[𐌰-𐍊]"; +const GOTHIC_STRSITEM = new StrsItem(GOTHIC_PATTERN); +const GOTHIC_USETITEM = new UsetItem( + new UnicodeSet(GOTHIC_PATTERN, [[0x10330,0x1034A]]), + GOTHIC_STRSITEM ); -const UGARITIC_SET = new UsetItem( - new UnicodeSet("[𐎀-𐎟]", [[0x10380,0x1039F]]), - UGARITIC_A +const UGARITIC_PATTERN = "[𐎀-𐎟]"; +const UGARITIC_STRSITEM = new StrsItem(UGARITIC_PATTERN); +const UGARITIC_USETITEM = new UsetItem( + new UnicodeSet(UGARITIC_PATTERN, [[0x10380,0x1039F]]), + UGARITIC_STRSITEM ); -let origElementParserSegment = ElementParser.segment; +class TestUnicodeSetParser implements UnicodeSetParser { + parseUnicodeSet = (pattern: string, rangeCount: number) : UnicodeSet | null => { + return new UnicodeSet("[𐌰-𐍊]", [[0x10330,0x1034A]]); + }; + sizeUnicodeSet = (pattern: string) : number => { return 1; } +}; + +const origElementParserSegment = ElementParser.segment; describe('Test of ElementString', () => { describe('Test of ElemElement', () => { @@ -42,23 +53,23 @@ describe('Test of ElementString', () => { assert.isFalse(one.isEqual(two)); }); it('returns false when order differs', () => { - const one = initElemElement(GOTHIC_A, GOTHIC_SET, 0); - const two = initElemElement(GOTHIC_A, GOTHIC_SET, 1); + const one = initElemElement(GOTHIC_A, GOTHIC_USETITEM, 0); + const two = initElemElement(GOTHIC_A, GOTHIC_USETITEM, 1); assert.isFalse(one.isEqual(two)); }); it('returns false when tertiary differs', () => { - const one = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 0); - const two = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 1); + const one = initElemElement(GOTHIC_A, GOTHIC_USETITEM, 0, 0); + const two = initElemElement(GOTHIC_A, GOTHIC_USETITEM, 0, 1); assert.isFalse(one.isEqual(two)); }); it('returns false when flags differs', () => { - const one = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 0, ElemElementFlags.none); - const two = initElemElement(GOTHIC_A, GOTHIC_SET, 0, 0, ElemElementFlags.type); + const one = initElemElement(GOTHIC_A, GOTHIC_USETITEM, 0, 0, ElemElementFlags.none); + const two = initElemElement(GOTHIC_A, GOTHIC_USETITEM, 0, 0, ElemElementFlags.type); assert.isFalse(one.isEqual(two)); }); it('returns true even though uset differs', () => { - const one = initElemElement(GOTHIC_A, GOTHIC_SET); - const two = initElemElement(GOTHIC_A, UGARITIC_SET); + const one = initElemElement(GOTHIC_A, GOTHIC_USETITEM); + const two = initElemElement(GOTHIC_A, UGARITIC_USETITEM); assert.isTrue(one.isEqual(two)); }); }); @@ -66,9 +77,7 @@ describe('Test of ElementString', () => { describe('Test of ElementString', () => { describe('Test of fromStrings()', () => { beforeEach(() => { - ElementParser.segment = (str: string): ElementSegment[] => { - return [...str].map(s => new ElementSegment(s, ElementType.codepoint)); - } + ElementParser.segment = stubElementParserSegment_CodePoint; }); afterEach(() => { ElementParser.segment = origElementParserSegment; @@ -329,6 +338,27 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); + it('can create an ElementString from a uset string', () => { + ElementParser.segment = origElementParserSegment; + const sections = { + strs: new Strs(), + uset: new Uset(), + usetparser: new TestUnicodeSetParser(), + }; + sections.strs.allocString = stubStrsAllocString_Str; + sections.uset.allocUset = stubUsetAllocUset; + const actual = ElementString.fromStrings(sections, "[𐌰-𐍊]"); + const expected = [ + initElemElement( + new StrsItem(''), + GOTHIC_USETITEM, + 0, + 0, + constants.elem_flags_type_uset, + ), + ]; + assert.deepEqual(actual, expected); + }); }); }); @@ -352,3 +382,15 @@ function stubStrsAllocString_Char(s?: string, opts?: StrsOptions, sections?: Dep return new CharStrsItem(s); }; +function stubStrsAllocString_Str(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem { + return new StrsItem(s); +}; + +function stubElementParserSegment_CodePoint(str: string): ElementSegment[] { + return [...str].map(s => new ElementSegment(s, ElementType.codepoint)); +}; + +function stubUsetAllocUset(set: UnicodeSet, sections: DependencySections) : UsetItem { + return new UsetItem(set, new StrsItem(set.pattern)); +}; + From 9569ef208c13cbd42688b420c534fc4db743ccb6 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 19 Dec 2024 17:11:15 +0000 Subject: [PATCH 015/155] chore(common/web): corrected nesting error, and moved more code into fixtures --- .../kmx/kmx-plus/element-string.tests.ts | 525 +++++++++--------- 1 file changed, 252 insertions(+), 273 deletions(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index b9a5987109..e5702ff072 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -19,25 +19,20 @@ const GOTHIC_B = new StrsItem("𐌱", 0x10331); const GOTHIC_C = new StrsItem("𐌲", 0x10332); const GOTHIC_PATTERN = "[𐌰-𐍊]"; const GOTHIC_STRSITEM = new StrsItem(GOTHIC_PATTERN); -const GOTHIC_USETITEM = new UsetItem( - new UnicodeSet(GOTHIC_PATTERN, [[0x10330,0x1034A]]), - GOTHIC_STRSITEM -); +const GOTHIC_SET = new UnicodeSet(GOTHIC_PATTERN, [[0x10330,0x1034A]]); +const GOTHIC_USETITEM = new UsetItem(GOTHIC_SET, GOTHIC_STRSITEM); const UGARITIC_PATTERN = "[𐎀-𐎟]"; const UGARITIC_STRSITEM = new StrsItem(UGARITIC_PATTERN); -const UGARITIC_USETITEM = new UsetItem( - new UnicodeSet(UGARITIC_PATTERN, [[0x10380,0x1039F]]), - UGARITIC_STRSITEM -); +const UGARITIC_SET = new UnicodeSet(UGARITIC_PATTERN, [[0x10380,0x1039F]]); +const UGARITIC_USETITEM = new UsetItem(UGARITIC_SET, UGARITIC_STRSITEM); class TestUnicodeSetParser implements UnicodeSetParser { - parseUnicodeSet = (pattern: string, rangeCount: number) : UnicodeSet | null => { - return new UnicodeSet("[𐌰-𐍊]", [[0x10330,0x1034A]]); - }; + parseUnicodeSet = (pattern: string, rangeCount: number) : UnicodeSet | null => { return GOTHIC_SET; }; sizeUnicodeSet = (pattern: string) : number => { return 1; } }; const origElementParserSegment = ElementParser.segment; +let sections: DependencySections = null; describe('Test of ElementString', () => { describe('Test of ElemElement', () => { @@ -77,6 +72,11 @@ describe('Test of ElementString', () => { describe('Test of ElementString', () => { describe('Test of fromStrings()', () => { beforeEach(() => { + sections = { + strs: new Strs(), + uset: new Uset(), + usetparser: new TestUnicodeSetParser(), + }; ElementParser.segment = stubElementParserSegment_CodePoint; }); afterEach(() => { @@ -87,7 +87,6 @@ describe('Test of ElementString', () => { assert.deepEqual(es, new ElementString()); }); it('can create an ElementString from a string array', () => { - const sections = { strs: new Strs() }; sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); const expected = [ @@ -97,267 +96,247 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); - }); - it('can create an ElementString from a string', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings(sections, "𐌰𐌱𐌲"); - const expected = [ - initElemElement(GOTHIC_A), - initElemElement(GOTHIC_B), - initElemElement(GOTHIC_C), - ]; - assert.deepEqual(actual, expected); - }); - it('can apply order string', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - "1 2 3", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 1), - initElemElement(GOTHIC_B, undefined, 2), - initElemElement(GOTHIC_C, undefined, 3), - ]; - assert.deepEqual(actual, expected); - }); - it('can apply single order to all', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - "1", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 1), - initElemElement(GOTHIC_B, undefined, 1), - initElemElement(GOTHIC_C, undefined, 1), - ]; - assert.deepEqual(actual, expected); - }); - it.skip('can handle order string that is too short', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - "1 2", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 1), - initElemElement(GOTHIC_B, undefined, 2), - initElemElement(GOTHIC_C, undefined, 0), - ]; - assert.deepEqual(actual, expected); - }); - it.skip('can handle non-number in order string', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - "1 A 3", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 1), - initElemElement(GOTHIC_B, undefined, 0), - initElemElement(GOTHIC_C, undefined, 3), - ]; - assert.deepEqual(actual, expected); - }); - it('can apply tertiary string', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - null, - "1 2 3", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 0, 1), - initElemElement(GOTHIC_B, undefined, 0, 2), - initElemElement(GOTHIC_C, undefined, 0, 3), - ]; - assert.deepEqual(actual, expected); - }); - it('can apply single tertiary to all', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - null, - "1", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 0, 1), - initElemElement(GOTHIC_B, undefined, 0, 1), - initElemElement(GOTHIC_C, undefined, 0, 1), - ]; - assert.deepEqual(actual, expected); - }); - it.skip('can handle tertiary string that is too short', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - null, - "1 2", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 0, 1), - initElemElement(GOTHIC_B, undefined, 0, 2), - initElemElement(GOTHIC_C, undefined, 0, 0), - ]; - assert.deepEqual(actual, expected); - }); - it.skip('can handle non-number in tertiary string', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - null, - "1 A 3", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 0, 1), - initElemElement(GOTHIC_B, undefined, 0, 0), - initElemElement(GOTHIC_C, undefined, 0, 3), - ]; - assert.deepEqual(actual, expected); - }); - it('can apply tertiary_base string', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - null, - null, - "1 0 1", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.tertiary_base), - initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), - initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.tertiary_base), - ]; - assert.deepEqual(actual, expected); - }); - it('can apply single tertiary_base to all', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - null, - null, - "1", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.tertiary_base), - initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.tertiary_base), - initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.tertiary_base), - ]; - assert.deepEqual(actual, expected); - }); - it('can handle tertiary_base string that is too short', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - null, - null, - "1 0", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.tertiary_base), - initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), - initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.none), - ]; - assert.deepEqual(actual, expected); - }); - it('can apply prebase string', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - null, - null, - null, - "1 0 1", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.prebase), - initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), - initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.prebase), - ]; - assert.deepEqual(actual, expected); - }); - it('can apply single prebase to all', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - null, - null, - null, - "1", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.prebase), - initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.prebase), - initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.prebase), - ]; - assert.deepEqual(actual, expected); - }); - it('can handle prebase string that is too short', () => { - const sections = { strs: new Strs() }; - sections.strs.allocString = stubStrsAllocString_Char; - const actual = ElementString.fromStrings( - sections, - "𐌰𐌱𐌲", - null, - null, - null, - "1 0", - ); - const expected = [ - initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.prebase), - initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), - initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.none), - ]; - assert.deepEqual(actual, expected); - }); - it('can create an ElementString from a uset string', () => { - ElementParser.segment = origElementParserSegment; - const sections = { - strs: new Strs(), - uset: new Uset(), - usetparser: new TestUnicodeSetParser(), - }; - sections.strs.allocString = stubStrsAllocString_Str; - sections.uset.allocUset = stubUsetAllocUset; - const actual = ElementString.fromStrings(sections, "[𐌰-𐍊]"); - const expected = [ - initElemElement( - new StrsItem(''), - GOTHIC_USETITEM, - 0, - 0, - constants.elem_flags_type_uset, - ), - ]; - assert.deepEqual(actual, expected); + it('can create an ElementString from a string', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings(sections, "𐌰𐌱𐌲"); + const expected = [ + initElemElement(GOTHIC_A), + initElemElement(GOTHIC_B), + initElemElement(GOTHIC_C), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply order string', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + "1 2 3", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 1), + initElemElement(GOTHIC_B, undefined, 2), + initElemElement(GOTHIC_C, undefined, 3), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply single order to all', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + "1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 1), + initElemElement(GOTHIC_B, undefined, 1), + initElemElement(GOTHIC_C, undefined, 1), + ]; + assert.deepEqual(actual, expected); + }); + it.skip('can handle order string that is too short', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + "1 2", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 1), + initElemElement(GOTHIC_B, undefined, 2), + initElemElement(GOTHIC_C, undefined, 0), + ]; + assert.deepEqual(actual, expected); + }); + it.skip('can handle non-number in order string', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + "1 A 3", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 1), + initElemElement(GOTHIC_B, undefined, 0), + initElemElement(GOTHIC_C, undefined, 3), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply tertiary string', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + "1 2 3", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 1), + initElemElement(GOTHIC_B, undefined, 0, 2), + initElemElement(GOTHIC_C, undefined, 0, 3), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply single tertiary to all', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + "1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 1), + initElemElement(GOTHIC_B, undefined, 0, 1), + initElemElement(GOTHIC_C, undefined, 0, 1), + ]; + assert.deepEqual(actual, expected); + }); + it.skip('can handle tertiary string that is too short', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + "1 2", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 1), + initElemElement(GOTHIC_B, undefined, 0, 2), + initElemElement(GOTHIC_C, undefined, 0, 0), + ]; + assert.deepEqual(actual, expected); + }); + it.skip('can handle non-number in tertiary string', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + "1 A 3", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 1), + initElemElement(GOTHIC_B, undefined, 0, 0), + initElemElement(GOTHIC_C, undefined, 0, 3), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply tertiary_base string', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + null, + "1 0 1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.tertiary_base), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.tertiary_base), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply single tertiary_base to all', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + null, + "1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.tertiary_base), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.tertiary_base), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.tertiary_base), + ]; + assert.deepEqual(actual, expected); + }); + it('can handle tertiary_base string that is too short', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + null, + "1 0", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.tertiary_base), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.none), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply prebase string', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + null, + null, + "1 0 1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.prebase), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.prebase), + ]; + assert.deepEqual(actual, expected); + }); + it('can apply single prebase to all', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + null, + null, + "1", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.prebase), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.prebase), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.prebase), + ]; + assert.deepEqual(actual, expected); + }); + it('can handle prebase string that is too short', () => { + sections.strs.allocString = stubStrsAllocString_Char; + const actual = ElementString.fromStrings( + sections, + "𐌰𐌱𐌲", + null, + null, + null, + "1 0", + ); + const expected = [ + initElemElement(GOTHIC_A, undefined, 0, 0, ElemElementFlags.prebase), + initElemElement(GOTHIC_B, undefined, 0, 0, ElemElementFlags.none), + initElemElement(GOTHIC_C, undefined, 0, 0, ElemElementFlags.none), + ]; + assert.deepEqual(actual, expected); + }); + it('can create an ElementString from a uset string', () => { + ElementParser.segment = origElementParserSegment; + sections.strs.allocString = stubStrsAllocString_Str; + sections.uset.allocUset = stubUsetAllocUset; + const actual = ElementString.fromStrings(sections, "[𐌰-𐍊]"); + const expected = [ + initElemElement( + new StrsItem(''), + GOTHIC_USETITEM, + 0, + 0, + constants.elem_flags_type_uset, + ), + ]; + assert.deepEqual(actual, expected); + }); }); }); }); From 58e5f0fe94c6f5d1bc0bc6369d82884514ae6fb8 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 19 Dec 2024 17:21:05 +0000 Subject: [PATCH 016/155] chore(common/web): stub the ElementParser.segment for uset --- common/web/types/tests/kmx/kmx-plus/element-string.tests.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index e5702ff072..62350510ea 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -322,7 +322,7 @@ describe('Test of ElementString', () => { assert.deepEqual(actual, expected); }); it('can create an ElementString from a uset string', () => { - ElementParser.segment = origElementParserSegment; + ElementParser.segment = stubElementParserSegment_Uset; sections.strs.allocString = stubStrsAllocString_Str; sections.uset.allocUset = stubUsetAllocUset; const actual = ElementString.fromStrings(sections, "[𐌰-𐍊]"); @@ -369,6 +369,10 @@ function stubElementParserSegment_CodePoint(str: string): ElementSegment[] { return [...str].map(s => new ElementSegment(s, ElementType.codepoint)); }; +function stubElementParserSegment_Uset(str: string): ElementSegment[] { + return [new ElementSegment(str, ElementType.uset)]; +}; + function stubUsetAllocUset(set: UnicodeSet, sections: DependencySections) : UsetItem { return new UsetItem(set, new StrsItem(set.pattern)); }; From e169ece9a374a2f2ae25b26bada64a103acd3872 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 19 Dec 2024 17:32:42 +0000 Subject: [PATCH 017/155] chore(common/web): add two test cases for uset parse failures --- .../tests/kmx/kmx-plus/element-string.tests.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 62350510ea..de18758578 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -27,8 +27,8 @@ const UGARITIC_SET = new UnicodeSet(UGARITIC_PATTERN, [[0x10380,0x1039F]]); const UGARITIC_USETITEM = new UsetItem(UGARITIC_SET, UGARITIC_STRSITEM); class TestUnicodeSetParser implements UnicodeSetParser { - parseUnicodeSet = (pattern: string, rangeCount: number) : UnicodeSet | null => { return GOTHIC_SET; }; - sizeUnicodeSet = (pattern: string) : number => { return 1; } + parseUnicodeSet = (pattern: string, rangeCount: number) : UnicodeSet | null => GOTHIC_SET; + sizeUnicodeSet = (pattern: string) : number => 1; }; const origElementParserSegment = ElementParser.segment; @@ -337,6 +337,16 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); + it('returns null for an invalid unicode set size', () => { + ElementParser.segment = stubElementParserSegment_Uset; + sections.usetparser.sizeUnicodeSet = (pattern: string) : number => -1; + assert.isNull(ElementString.fromStrings(sections, "[𐌰-𐍊]")); + }); + it('returns null if it cannot parse the unicode set', () => { + ElementParser.segment = stubElementParserSegment_Uset; + sections.usetparser.parseUnicodeSet = (pattern: string, rangeCount: number) : UnicodeSet | null => null; + assert.isNull(ElementString.fromStrings(sections, "[𐌰-𐍊]")); + }); }); }); }); From 80d2f498246d3274e338d6f43c9c15d518f12916 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 6 Jan 2025 15:50:07 +0000 Subject: [PATCH 018/155] chore(common/web): add test case for quad string in ElementString.fromStrings() --- .../tests/kmx/kmx-plus/element-string.tests.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index de18758578..3e53146989 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -17,6 +17,8 @@ import { ElementParser, ElementSegment, ElementType } from '../../../src/ldml-ke const GOTHIC_A = new StrsItem("𐌰", 0x10330); const GOTHIC_B = new StrsItem("𐌱", 0x10331); const GOTHIC_C = new StrsItem("𐌲", 0x10332); +const HI_GOTHIC_A = new StrsItem('\ud800', 0xd800); +const LO_GOTHIC_A = new StrsItem('\udf30', 0xdf30); const GOTHIC_PATTERN = "[𐌰-𐍊]"; const GOTHIC_STRSITEM = new StrsItem(GOTHIC_PATTERN); const GOTHIC_SET = new UnicodeSet(GOTHIC_PATTERN, [[0x10330,0x1034A]]); @@ -347,6 +349,16 @@ describe('Test of ElementString', () => { sections.usetparser.parseUnicodeSet = (pattern: string, rangeCount: number) : UnicodeSet | null => null; assert.isNull(ElementString.fromStrings(sections, "[𐌰-𐍊]")); }); + it('can handle quad strings', () => { + sections.strs.allocString = stubStrsAllocString_Char; + ElementParser.segment = stubElementParserSegment_Escaped; + const actual = ElementString.fromStrings(sections, "\\ud800\\udf30"); + const expected = [ + initElemElement(HI_GOTHIC_A), + initElemElement(LO_GOTHIC_A), + ]; + assert.deepEqual(actual, expected); + }); }); }); }); @@ -383,6 +395,11 @@ function stubElementParserSegment_Uset(str: string): ElementSegment[] { return [new ElementSegment(str, ElementType.uset)]; }; +function stubElementParserSegment_Escaped(str: string): ElementSegment[] { + const strs = str.match(/\\u[0-9a-fA-F]{4}/g); + return strs.map((s) => new ElementSegment(s, ElementType.escaped)); +}; + function stubUsetAllocUset(set: UnicodeSet, sections: DependencySections) : UsetItem { return new UsetItem(set, new StrsItem(set.pattern)); }; From c615f82db2d2dfcc817d03ad9ce34ba1fbb6ba32 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 6 Jan 2025 16:41:36 +0000 Subject: [PATCH 019/155] chore(common/web): add test cases for ElemElement.isEqual() and ElementStrings.isEqual() --- .../kmx/kmx-plus/element-string.tests.ts | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 3e53146989..db3fdcc535 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -41,7 +41,12 @@ describe('Test of ElementString', () => { describe('Test of isEqual()', () => { it('returns true when elems identical', () => { const one = initElemElement(); - const two = initElemElement() + const two = initElemElement(); + assert.isTrue(one.isEqual(two)); + }); + it.skip('returns true when elems are clones', () => { + const one = initElemElement(new StrsItem("𐌰", 0x10330)); + const two = initElemElement(new StrsItem("𐌰", 0x10330)); assert.isTrue(one.isEqual(two)); }); it('returns false when value differs', () => { @@ -72,18 +77,18 @@ describe('Test of ElementString', () => { }); }); describe('Test of ElementString', () => { + beforeEach(() => { + sections = { + strs: new Strs(), + uset: new Uset(), + usetparser: new TestUnicodeSetParser(), + }; + ElementParser.segment = stubElementParserSegment_CodePoint; + }); + afterEach(() => { + ElementParser.segment = origElementParserSegment; + }); describe('Test of fromStrings()', () => { - beforeEach(() => { - sections = { - strs: new Strs(), - uset: new Uset(), - usetparser: new TestUnicodeSetParser(), - }; - ElementParser.segment = stubElementParserSegment_CodePoint; - }); - afterEach(() => { - ElementParser.segment = origElementParserSegment; - }); it('returns an empty ElementString if source is null', () => { const es = ElementString.fromStrings({}, null); assert.deepEqual(es, new ElementString()); @@ -360,6 +365,17 @@ describe('Test of ElementString', () => { assert.deepEqual(actual, expected); }); }); + describe('Test of isEqual()', () => { + it('returns true when ElementStrings are identical', () => { + const es = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); + assert.isTrue(es.isEqual(es)); + }); + it.skip('returns true when ElementStrings are clones', () => { + const one = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); + const two = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); + assert.isTrue(one.isEqual(two)); + }); + }); }); }); From 704486ae2e91c7d2cf8aafd3198aa18c630bd241 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 9 Jan 2025 11:27:52 +0000 Subject: [PATCH 020/155] chore(common/web): add two more test cases for ElementString.isEqual() --- .../types/tests/kmx/kmx-plus/element-string.tests.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index db3fdcc535..5c8f5ce80b 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -375,6 +375,16 @@ describe('Test of ElementString', () => { const two = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); assert.isTrue(one.isEqual(two)); }); + it('returns false when ElementStrings are different lengths', () => { + const one = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); + const two = ElementString.fromStrings(sections, ["𐌰", "𐌱"]); + assert.isFalse(one.isEqual(two)); + }); + it('returns false when ElementStrings have different ElemElements', () => { + const one = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); + const two = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌳"]); + assert.isFalse(one.isEqual(two)); + }); }); }); }); From 86095d4b11493d038c794235118f67bec13803de Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 9 Jan 2025 12:03:51 +0000 Subject: [PATCH 021/155] chore(common/web): add test case for string ElemElement --- .../tests/kmx/kmx-plus/element-string.tests.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 5c8f5ce80b..3d20c7ea3d 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -364,6 +364,20 @@ describe('Test of ElementString', () => { ]; assert.deepEqual(actual, expected); }); + it('can handle ElemElement of string type', () => { + sections.strs.allocString = stubStrsAllocString_Str; + const actual = ElementString.fromStrings(sections, ["𐌰𐌱𐌲",]); + const expected = [ + initElemElement( + new StrsItem("𐌰𐌱𐌲"), + undefined, + 0, + 0, + constants.elem_flags_type_str, + ), + ]; + assert.deepEqual(actual, expected); + }); }); describe('Test of isEqual()', () => { it('returns true when ElementStrings are identical', () => { From 23b3de14d91ebfe19445cf2d3b8e1f3a6220fe6f Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 9 Jan 2025 12:08:15 +0000 Subject: [PATCH 022/155] chore(common/web): clarify describe strings --- common/web/types/tests/kmx/kmx-plus/element-string.tests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 3d20c7ea3d..6c6f8b8ec9 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -36,7 +36,7 @@ class TestUnicodeSetParser implements UnicodeSetParser { const origElementParserSegment = ElementParser.segment; let sections: DependencySections = null; -describe('Test of ElementString', () => { +describe('Test of ElementString file', () => { describe('Test of ElemElement', () => { describe('Test of isEqual()', () => { it('returns true when elems identical', () => { @@ -76,7 +76,7 @@ describe('Test of ElementString', () => { }); }); }); - describe('Test of ElementString', () => { + describe('Test of ElementString class', () => { beforeEach(() => { sections = { strs: new Strs(), From 9d555a0639c24cb12a76863426b788063f04b367 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 9 Jan 2025 14:12:56 +0000 Subject: [PATCH 023/155] chore(common/web): introduce initElementString() to remove dependency on fromStrings() in isEqual() tests --- .../kmx/kmx-plus/element-string.tests.ts | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 6c6f8b8ec9..054bb3d393 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -17,6 +17,7 @@ import { ElementParser, ElementSegment, ElementType } from '../../../src/ldml-ke const GOTHIC_A = new StrsItem("𐌰", 0x10330); const GOTHIC_B = new StrsItem("𐌱", 0x10331); const GOTHIC_C = new StrsItem("𐌲", 0x10332); +const GOTHIC_D = new StrsItem("𐌳", 0x10333); const HI_GOTHIC_A = new StrsItem('\ud800', 0xd800); const LO_GOTHIC_A = new StrsItem('\udf30', 0xdf30); const GOTHIC_PATTERN = "[𐌰-𐍊]"; @@ -381,22 +382,49 @@ describe('Test of ElementString file', () => { }); describe('Test of isEqual()', () => { it('returns true when ElementStrings are identical', () => { - const es = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); + const es = initElementString([ + initElemElement(GOTHIC_A), + initElemElement(GOTHIC_B), + initElemElement(GOTHIC_C), + ]); assert.isTrue(es.isEqual(es)); }); it.skip('returns true when ElementStrings are clones', () => { - const one = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); - const two = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); + const one = initElementString([ + initElemElement(GOTHIC_A), + initElemElement(GOTHIC_B), + initElemElement(GOTHIC_C), + ]); + const two = initElementString([ + initElemElement(GOTHIC_A), + initElemElement(GOTHIC_B), + initElemElement(GOTHIC_C), + ]); assert.isTrue(one.isEqual(two)); }); it('returns false when ElementStrings are different lengths', () => { - const one = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); - const two = ElementString.fromStrings(sections, ["𐌰", "𐌱"]); + const one = initElementString([ + initElemElement(GOTHIC_A), + initElemElement(GOTHIC_B), + initElemElement(GOTHIC_C), + ]); + const two = initElementString([ + initElemElement(GOTHIC_A), + initElemElement(GOTHIC_B), + ]); assert.isFalse(one.isEqual(two)); }); it('returns false when ElementStrings have different ElemElements', () => { - const one = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌲"]); - const two = ElementString.fromStrings(sections, ["𐌰", "𐌱", "𐌳"]); + const one = initElementString([ + initElemElement(GOTHIC_A), + initElemElement(GOTHIC_B), + initElemElement(GOTHIC_C), + ]); + const two = initElementString([ + initElemElement(GOTHIC_A), + initElemElement(GOTHIC_B), + initElemElement(GOTHIC_D), + ]); assert.isFalse(one.isEqual(two)); }); }); @@ -419,6 +447,12 @@ function initElemElement( return ee; }; +function initElementString(elemElements: ElemElement[]): ElementString { + const es: ElementString = new ElementString(); + elemElements.forEach((ee) => {es.push(ee)}); + return es; +}; + function stubStrsAllocString_Char(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem { return new CharStrsItem(s); }; From b9c7835fbf513b4e926146e81988a9e2f2df9f35 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 9 Jan 2025 14:45:35 +0000 Subject: [PATCH 024/155] fix(common/web): add isEqual() method to StrsItem and use it in ElemElement.isEqual() --- common/web/types/src/kmx/kmx-plus/element-string.ts | 4 ++-- common/web/types/src/kmx/kmx-plus/kmx-plus.ts | 4 ++++ common/web/types/tests/kmx/kmx-plus/element-string.tests.ts | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/common/web/types/src/kmx/kmx-plus/element-string.ts b/common/web/types/src/kmx/kmx-plus/element-string.ts index b389107cce..ad3eaf6084 100644 --- a/common/web/types/src/kmx/kmx-plus/element-string.ts +++ b/common/web/types/src/kmx/kmx-plus/element-string.ts @@ -19,8 +19,8 @@ export class ElemElement { order: number; // -128 to +127; used only by reorder element values tertiary: number; // -128 to +127; used only by reorder element values flags: ElemElementFlags; - isEqual(a: ElemElement) { - return a.value === this.value && + isEqual(a: ElemElement): boolean { + return a.value.isEqual(this.value) && a.order === this.order && a.tertiary === this.tertiary && a.flags === this.flags; diff --git a/common/web/types/src/kmx/kmx-plus/kmx-plus.ts b/common/web/types/src/kmx/kmx-plus/kmx-plus.ts index a88688f7ab..d0de2989d0 100644 --- a/common/web/types/src/kmx/kmx-plus/kmx-plus.ts +++ b/common/web/types/src/kmx/kmx-plus/kmx-plus.ts @@ -131,6 +131,10 @@ export class StrsItem { get isOneChar() { return this.char !== undefined; } + + isEqual(a: StrsItem): boolean { + return a.value === this.value && a.char === this.char; + } }; /** diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 054bb3d393..0dc21a49fe 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -45,7 +45,7 @@ describe('Test of ElementString file', () => { const two = initElemElement(); assert.isTrue(one.isEqual(two)); }); - it.skip('returns true when elems are clones', () => { + it('returns true when elems are clones', () => { const one = initElemElement(new StrsItem("𐌰", 0x10330)); const two = initElemElement(new StrsItem("𐌰", 0x10330)); assert.isTrue(one.isEqual(two)); @@ -389,7 +389,7 @@ describe('Test of ElementString file', () => { ]); assert.isTrue(es.isEqual(es)); }); - it.skip('returns true when ElementStrings are clones', () => { + it('returns true when ElementStrings are clones', () => { const one = initElementString([ initElemElement(GOTHIC_A), initElemElement(GOTHIC_B), From 8e833c8314be4b98503b22ba5f07de59d59573bc Mon Sep 17 00:00:00 2001 From: sgschantz Date: Mon, 13 Jan 2025 14:08:22 +0700 Subject: [PATCH 025/155] chore(mac): reworked sentry testing can now force crashes or send messages by typing a single character when sentry testing is enabled in the UserDefaults --- .../Keyman4MacIM/KMInputController.m | 4 +- .../Keyman4MacIM/KMInputMethodAppDelegate.h | 1 + .../Keyman4MacIM/KMInputMethodAppDelegate.m | 40 ++++++++++- .../Keyman4MacIM/KMInputMethodEventHandler.m | 67 ++++++++----------- .../Keyman4MacIM/KMInputMethodLifecycle.h | 3 +- .../Keyman4MacIM/KMInputMethodLifecycle.m | 5 +- 6 files changed, 74 insertions(+), 46 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m index e97be3e389..acefcc8417 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m @@ -25,7 +25,7 @@ KMInputMethodEventHandler* _eventHandler; - (id)initWithServer:(IMKServer *)server delegate:(id)delegate client:(id)inputClient { - os_log_debug([KMLogs lifecycleLog], "initWithServer, active app: '%{public}@'", [KMInputMethodLifecycle getClientApplicationId]); + os_log_debug([KMLogs lifecycleLog], "initWithServer, active app: '%{public}@'", [KMInputMethodLifecycle getRunningApplicationId]); self = [super initWithServer:server delegate:delegate client:inputClient]; if (self) { @@ -84,7 +84,7 @@ KMInputMethodEventHandler* _eventHandler; if (_eventHandler != nil) { [_eventHandler deactivate]; } - _eventHandler = [[KMInputMethodEventHandler alloc] initWithClient:[KMInputMethodLifecycle getClientApplicationId] client:self.client]; + _eventHandler = [[KMInputMethodEventHandler alloc] initWithClient:[KMInputMethodLifecycle getRunningApplicationId] client:self.client]; } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h index fe06fa603a..d41bf25899 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h @@ -124,6 +124,7 @@ static const int KEYMAN_FIRST_KEYBOARD_MENUITEM_INDEX = 0; - (void)postKeyboardEventWithSource: (CGEventSourceRef)source code:(CGKeyCode) virtualKey postCallback:(PostEventCallback)postEvent; - (KeymanVersionInfo)versionInfo; - (void)registerConfigurationWindow:(NSWindowController *)window; +- (BOOL)isSentryTestingEnabled; @end #endif /* KMInputMethodAppDelegate_h */ diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index b938279197..9a5a98de47 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -48,6 +48,7 @@ NSString *const kKeymanKeyboardDownloadCompletedNotification = @"kKeymanKeyboard @property (nonatomic, strong) KMPackageReader *packageReader; @property BOOL receivedKeyDownFromOsk; @property NSEventModifierFlags oskEventModifiers; +@property (nonatomic, assign) BOOL sentryTestingEnabled; @end @implementation KMInputMethodAppDelegate @@ -143,11 +144,18 @@ id _lastServerWithOSKShowing = nil; os_log_debug([KMLogs lifecycleLog], "***KMInputMethodAppDelegate inputMethodActivated, re-enabling event tap..."); CGEventTapEnable(self.lowLevelEventTap, YES); } - + if (_kvk != nil && ([KMInputMethodLifecycle.shared shouldShowOskOnActivate])) { os_log_debug([KMLogs oskLog], "***KMInputMethodAppDelegate inputMethodActivated, showing OSK"); [self showOSK]; } + + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; + crumb.level = kSentryLevelInfo; + crumb.category = @"startup"; + //crumb.message = [NSString stringWithFormat:@"Authenticated user %@", user.email]; + crumb.message = [NSString stringWithFormat:@"inputMethodActivated"]; + [SentrySDK addBreadcrumb:crumb]; } - (KeymanVersionInfo)versionInfo { @@ -181,6 +189,7 @@ id _lastServerWithOSKShowing = nil; [self setDefaultKeymanMenuItems]; [self updateKeyboardMenuItems]; [self setPostLaunchKeymanSentryTags]; + self.sentryTestingEnabled = [KMSettingsRepository.shared readForceSentryError]; // [SentrySDK captureMessage:@"Starting Keyman [test message]"]; } @@ -196,6 +205,29 @@ id _lastServerWithOSKShowing = nil; }]; } +/** + * Determine whether sentry testing is enabled. + * When it is enabled, then typing certain characters will cause Sentry events or crashes to occur. + * + * To enable, set the flag is UserDefaults + * `defaults write keyman.inputmethod.Keyman KMForceSentryError 1` + * Also, use the SIL Euro Latin keyboard and type in the Stickies app + */ +- (BOOL)isSentryTestingEnabled { + NSString* const testKeyboardName = @"sil_euro_latin.kmx"; + NSString* const testClientApplicationId = @"com.apple.Stickies"; + BOOL testingEnabled = NO; + + if (self.sentryTestingEnabled) { + NSString * kmxName = [[self.kmx filePath] lastPathComponent]; + NSString * applicationId = [KMInputMethodLifecycle.shared clientApplicationId]; + testingEnabled = [kmxName isEqualToString:testKeyboardName] && [applicationId isEqualToString:testClientApplicationId]; + os_log_info([KMLogs testLog], "isSentryTestingEnabled, self.sentryTestingEnabled: %{public}@ kmxName: %{public}@ applicationId: %{public}@ testingEnabled: %{public}@", self.sentryTestingEnabled?@"YES":@"NO", kmxName, applicationId, testingEnabled?@"YES":@"NO"); + } + + return testingEnabled; +} + - (void)setPostLaunchKeymanSentryTags { NSString *keyboardFileName = [self.kmx.filePath lastPathComponent]; os_log_info([KMLogs keyboardLog], "initial kmx set to %{public}@", keyboardFileName); @@ -825,6 +857,12 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef [self setSelectedKeyboard:keyboardName inMenuItem:menuItem]; [self setSelectedKeyboard:keyboardName]; [self setContextBuffer:nil]; + + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; + crumb.level = kSentryLevelInfo; + crumb.category = @"startup"; + crumb.message = [NSString stringWithFormat:@"setDefaultSelectedKeyboard: %@", keyboardName]; + [SentrySDK addBreadcrumb:crumb]; } - (void) addKeyboardPlaceholderMenuItem { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m index 2e38dd4bc3..91ebe13f33 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m @@ -22,6 +22,7 @@ @property (nonatomic, retain) NSString* clientApplicationId; @property NSString *queuedText; @property BOOL contextChanged; +@property BOOL sentryTestingEnabled; @end @implementation KMInputMethodEventHandler @@ -33,9 +34,6 @@ const NSTimeInterval kQueuedTextEventDelayInSeconds = 0.1; CGKeyCode _keyCodeOfOriginalEvent; CGEventSourceRef _sourceFromOriginalEvent = nil; CGEventSourceRef _sourceForGeneratedEvent = nil; -NSMutableString* _easterEggForSentry = nil; -NSString* const kEasterEggText = @"Sentry force now"; -NSString* const kEasterEggKmxName = @"EnglishSpanish.kmx"; // This is the public initializer. - (instancetype)initWithClient:(NSString *)clientAppId client:(id) sender { @@ -44,20 +42,7 @@ NSString* const kEasterEggKmxName = @"EnglishSpanish.kmx"; _generatedBackspaceCount = 0; _lowLevelBackspaceCount = 0; _queuedText = nil; - - BOOL forceSentryCrash = [KMSettingsRepository.shared readForceSentryError]; - - // In Xcode, if Keyman is the active IM and the settings include the - // forceSentryCrash flag and "English plus Spanish" is the current keyboard - // and you type "Sentry force now", it will force a simulated crash to - // test reporting to sentry.keyman.com - if (forceSentryCrash && [clientAppId isEqual: @"com.apple.dt.Xcode"]) { - os_log_debug([KMLogs testLog], "initWithClient, preparing to force Sentry crash."); - _easterEggForSentry = [[NSMutableString alloc] init]; - } - else - _easterEggForSentry = nil; - + [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { [scope setTagValue:clientAppId forKey:@"clientAppId"]; }]; @@ -110,9 +95,15 @@ NSString* const kEasterEggKmxName = @"EnglishSpanish.kmx"; - (BOOL) handleEventWithKeymanEngine:(NSEvent *)event in:(id) sender { CoreKeyOutput *output = nil; + if ([self.appDelegate isSentryTestingEnabled]) { + if ([self forceSentryEvent:event]) { + return NO; + } + } + output = [self processEventWithKeymanEngine:event in:sender]; + if (output == nil) { - [self checkEventForSentryEasterEgg:event]; return NO; } @@ -139,28 +130,26 @@ NSString* const kEasterEggKmxName = @"EnglishSpanish.kmx"; return coreKeyOutput; } -- (void)checkEventForSentryEasterEgg:(NSEvent *)event { - if (_easterEggForSentry != nil) { - NSString * kmxName = [[self.kme.kmx filePath] lastPathComponent]; - os_log_debug([KMLogs testLog], "Sentry - KMX name: %{public}@", kmxName); - if ([kmxName isEqualToString:kEasterEggKmxName]) { - NSUInteger len = [_easterEggForSentry length]; - os_log_debug([KMLogs testLog], "Sentry - Processing character(s): %{public}@", [event characters]); - if ([[event characters] characterAtIndex:0] == [kEasterEggText characterAtIndex:len]) { - NSString *characterToAdd = [kEasterEggText substringWithRange:NSMakeRange(len, 1)]; - os_log_debug([KMLogs testLog], "Sentry - Adding character to Easter Egg code string: %{public}@", characterToAdd); - [_easterEggForSentry appendString:characterToAdd]; - if ([_easterEggForSentry isEqualToString:kEasterEggText]) { - os_log_debug([KMLogs testLog], "Sentry - Forcing crash now"); - [SentrySDK crash]; - } - } - else if (len > 0) { - os_log_debug([KMLogs testLog], "Sentry - Clearing Easter Egg code string."); - [_easterEggForSentry setString:@""]; - } - } +/** + * When in the mode to test sentry, this method will force certain Sentry APIs to be called, + * such as forcing a crash or capturing a message, depending on the key being typed. + */ +- (BOOL)forceSentryEvent:(NSEvent *)event { + BOOL forcedEvent = YES; + + NSString *sentryCommand = event.characters; + if ([sentryCommand isEqualToString:@"{"]) { + os_log_debug([KMLogs testLog], "forceSentryEvent: forcing crash now"); + [SentrySDK crash]; + } else if ([sentryCommand isEqualToString:@"["]) { + os_log_debug([KMLogs testLog], "forceSentryEvent: forcing message now"); + [SentrySDK captureMessage:@"Forced test message"]; + } else { + os_log_debug([KMLogs testLog], "forceSentryEvent: unrecognized command"); + forcedEvent = NO; } + + return forcedEvent; } /** diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.h b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.h index 62a3aac35d..e467e645bd 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.h @@ -15,7 +15,8 @@ extern NSString *const kInputMethodClientChangeNotification; @interface KMInputMethodLifecycle : NSObject + (KMInputMethodLifecycle *)shared; -+ (NSString*)getClientApplicationId; ++ (NSString*)getRunningApplicationId; +@property NSString *clientApplicationId; - (void)startLifecycle; - (void)activateClient:(id)client; - (void)deactivateClient:(id)client; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m index 9b877a530e..0b82c83006 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m @@ -61,7 +61,6 @@ typedef enum { @property LifecycleState lifecycleState; @property NSString *inputSourceId; -@property NSString *clientApplicationId; @end @implementation KMInputMethodLifecycle @@ -106,7 +105,7 @@ typedef enum { /** * Get the bundle ID of the currently active text input client.. */ -+ (NSString*)getClientApplicationId { ++ (NSString*)getRunningApplicationId { NSRunningApplication *currentApp = [[NSWorkspace sharedWorkspace] frontmostApplication]; NSString *clientAppId = [currentApp bundleIdentifier]; return clientAppId; @@ -156,7 +155,7 @@ typedef enum { */ - (void)performTransition:(id)client { NSString *currentInputSource = [KMInputMethodLifecycle getCurrentInputSourceId]; - NSString *currentClientAppId = [KMInputMethodLifecycle getClientApplicationId]; + NSString *currentClientAppId = [KMInputMethodLifecycle getRunningApplicationId]; TransitionType transition = [self determineTransition:currentInputSource withAppId:currentClientAppId]; [self saveNewInputMethodState:currentInputSource withAppId:currentClientAppId]; From a279767accf20966288b6bca746ac78548c6bc70 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 13 Jan 2025 11:37:58 +0000 Subject: [PATCH 026/155] fix(common/web): add ElementString.parseIntOrZero() method to handle invalid order and tertiary params --- common/web/types/src/kmx/kmx-plus/element-string.ts | 8 ++++++-- .../web/types/tests/kmx/kmx-plus/element-string.tests.ts | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/common/web/types/src/kmx/kmx-plus/element-string.ts b/common/web/types/src/kmx/kmx-plus/element-string.ts index b389107cce..2b4321abda 100644 --- a/common/web/types/src/kmx/kmx-plus/element-string.ts +++ b/common/web/types/src/kmx/kmx-plus/element-string.ts @@ -104,8 +104,8 @@ export class ElementString extends Array { typeFlag |= constants.elem_flags_type_str; } } - elem.order = orders.length ? parseInt(orders[i], 10) : 0; - elem.tertiary = tertiaries.length ? parseInt(tertiaries[i], 10) : 0; + elem.order = orders.length ? this.parseIntOrZero(orders[i]) : 0; + elem.tertiary = tertiaries.length ? this.parseIntOrZero(tertiaries[i]) : 0; elem.flags = ElemElementFlags.none | (ElemElementFlags.type & typeFlag) | (tertiary_bases?.[i] == '1' /* TODO-LDML: or 'true'? */ ? ElemElementFlags.tertiary_base : 0) | @@ -125,5 +125,9 @@ export class ElementString extends Array { } return true; } + private static parseIntOrZero(str: string) { + const num = parseInt(str, 10); + return !Number.isNaN(num) ? num : 0; + } } ; diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index 054bb3d393..be8b56da2d 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -142,7 +142,7 @@ describe('Test of ElementString file', () => { ]; assert.deepEqual(actual, expected); }); - it.skip('can handle order string that is too short', () => { + it('can handle order string that is too short', () => { sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( sections, @@ -156,7 +156,7 @@ describe('Test of ElementString file', () => { ]; assert.deepEqual(actual, expected); }); - it.skip('can handle non-number in order string', () => { + it('can handle non-number in order string', () => { sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( sections, @@ -200,7 +200,7 @@ describe('Test of ElementString file', () => { ]; assert.deepEqual(actual, expected); }); - it.skip('can handle tertiary string that is too short', () => { + it('can handle tertiary string that is too short', () => { sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( sections, @@ -215,7 +215,7 @@ describe('Test of ElementString file', () => { ]; assert.deepEqual(actual, expected); }); - it.skip('can handle non-number in tertiary string', () => { + it('can handle non-number in tertiary string', () => { sections.strs.allocString = stubStrsAllocString_Char; const actual = ElementString.fromStrings( sections, From d48ccda140f1c011af1b5f4edc9889d2e5266ea6 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 13 Jan 2025 12:05:39 +0000 Subject: [PATCH 027/155] fix(common/web): add test cases for parseIntOrZero() --- .../types/src/kmx/kmx-plus/element-string.ts | 2 +- .../tests/kmx/kmx-plus/element-string.tests.ts | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/common/web/types/src/kmx/kmx-plus/element-string.ts b/common/web/types/src/kmx/kmx-plus/element-string.ts index 2b4321abda..7a65592c0b 100644 --- a/common/web/types/src/kmx/kmx-plus/element-string.ts +++ b/common/web/types/src/kmx/kmx-plus/element-string.ts @@ -125,7 +125,7 @@ export class ElementString extends Array { } return true; } - private static parseIntOrZero(str: string) { + private static parseIntOrZero(str: string): number { const num = parseInt(str, 10); return !Number.isNaN(num) ? num : 0; } diff --git a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts index be8b56da2d..5f5b53481b 100644 --- a/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts +++ b/common/web/types/tests/kmx/kmx-plus/element-string.tests.ts @@ -428,6 +428,24 @@ describe('Test of ElementString file', () => { assert.isFalse(one.isEqual(two)); }); }); + describe('Test of parseIntOrZero()', () => { + it('returns a number for a valid string', () => { + const num = ElementString['parseIntOrZero']('1'); + assert.equal(num, 1); + }); + it('returns zero for an invalid string', () => { + const num = ElementString['parseIntOrZero']('A'); + assert.equal(num, 0); + }); + it('returns zero for undefined', () => { + const num = ElementString['parseIntOrZero'](undefined); + assert.equal(num, 0); + }); + it('returns zero for a null string', () => { + const num = ElementString['parseIntOrZero'](null); + assert.equal(num, 0); + }); + }); }); }); From afd942f4a6d099955ae475387e06e949ed4b59e0 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Wed, 15 Jan 2025 15:20:13 +0700 Subject: [PATCH 028/155] docs(ios): document gestures within iOS app help --- ios/docs/help/context/gestures.md | 15 +++++++++++++++ ios/docs/help/context/index.md | 2 ++ ios/docs/help/index.md | 1 + ios/docs/help/ios_images/gesture-hint.png | Bin 0 -> 559 bytes 4 files changed, 18 insertions(+) create mode 100644 ios/docs/help/context/gestures.md create mode 100644 ios/docs/help/ios_images/gesture-hint.png diff --git a/ios/docs/help/context/gestures.md b/ios/docs/help/context/gestures.md new file mode 100644 index 0000000000..251de0f1ce --- /dev/null +++ b/ios/docs/help/context/gestures.md @@ -0,0 +1,15 @@ +--- +title: Gesture Hints and Tips +--- + +## Using Gestures on the Keyboard Keys +There are now several gestures available to interact with some keys on the keyboard. Keys which have gestures available will normally show them as a hint in the top right of the key: + +![](../ios_images/gesture-hint.png) + +* **Long press**: Press and hold a key, and after a moment a submenu will appear. Slide the finger to the submenu to select a key. Release the finger, and the highlighted key from the submenu will be output. + +* **Flick**: Press and hold a key, and then slide the finger in various directions on a key to reach alternate outputs. The key will animate to show the expected output when the finger gets released. A common flick is to slide down to reach numerals on the top row of the keyboard. + + An up-flick on keys that support longpresses but do not have a defined up-flick will skip the wait and immediately display their longpress submenu. +* **Multitap**: Some keys can be pressed repeatedly and rapidly to reach alternate outputs. Tapping rapidly twice on Shift will activate Caps Lock on many keyboards. \ No newline at end of file diff --git a/ios/docs/help/context/index.md b/ios/docs/help/context/index.md index 99e41dd65c..90cfbfd5f6 100644 --- a/ios/docs/help/context/index.md +++ b/ios/docs/help/context/index.md @@ -2,6 +2,8 @@ title: Keyman for iPhone and iPad Help --- +[Keyboard gestures](gestures) + | | Keyboard Keys
(Keyboard Present) | |---|---| | ![](../ios_images/globe.png) | Install or select another language/keyboard | diff --git a/ios/docs/help/index.md b/ios/docs/help/index.md index c71c703e72..994bbbda9e 100644 --- a/ios/docs/help/index.md +++ b/ios/docs/help/index.md @@ -18,6 +18,7 @@ title: Keyman for iPhone and iPad 18.0 Help * [Using the Banner on the Keyboard](basic/using-the-banner) * [Switching Between Keyboards](basic/switching-between-keyboards) * [Using a Keyboard](basic/keyboard-usage) +* [Keyboard Gestures](context/gestures) * [Using the Menu](context/) * [Using the Settings Screen](basic/config/) * [Language Settings](basic/language-settings) diff --git a/ios/docs/help/ios_images/gesture-hint.png b/ios/docs/help/ios_images/gesture-hint.png new file mode 100644 index 0000000000000000000000000000000000000000..155ba674185a2d57fbda35de07e3d2f7d39cbc32 GIT binary patch literal 559 zcmeAS@N?(olHy`uVBq!ia0vp^dO#e+!2~3iSQp*`QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0V%NV7srqc=eM^`dod+S9Q*iA;i$0OrH^Z- zES=%G)mc-*>!6NP*TtOphc3p+{){%wH-=5gT8XA_WGDEY4%)(Y+RcLN z+=}+SY?n$SyUt}Wm#@y!6`8i~bg)m>vL&D1{*K#!zxst(aP?&EhbNYm)TU|vd0ATj z Date: Thu, 16 Jan 2025 15:26:03 +0700 Subject: [PATCH 029/155] chore(mac): add KMSentryHelper class, and new tags and breadcrumbs --- .../Keyman4MacIM.xcodeproj/project.pbxproj | 18 ++++- .../KMConfigurationWindowController.m | 33 ++++++-- .../KMDownloadKBWindowController.m | 1 + .../Keyman4MacIM/KMInputController.m | 6 +- .../Keyman4MacIM/KMInputMethodAppDelegate.h | 2 +- .../Keyman4MacIM/KMInputMethodAppDelegate.m | 74 ++++++++++-------- .../Keyman4MacIM/KMInputMethodEventHandler.m | 7 +- .../Keyman4MacIM/KMInputMethodLifecycle.m | 8 +- .../Keyman4MacIM/{ => Logging}/KMLogs.h | 3 +- .../Keyman4MacIM/{ => Logging}/KMLogs.m | 2 +- .../Keyman4MacIM/Logging/KMSentryHelper.h | 25 ++++++ .../Keyman4MacIM/Logging/KMSentryHelper.m | 77 +++++++++++++++++++ .../OnScreenKeyboard/OSKWindowController.m | 2 + .../Keyman4MacIM/TextApiCompliance.m | 13 ++++ 14 files changed, 217 insertions(+), 54 deletions(-) rename mac/Keyman4MacIM/Keyman4MacIM/{ => Logging}/KMLogs.h (84%) rename mac/Keyman4MacIM/Keyman4MacIM/{ => Logging}/KMLogs.m (99%) create mode 100644 mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h create mode 100644 mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m diff --git a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj index 483998a16e..3436ed498a 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj +++ b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj @@ -35,6 +35,7 @@ 29BE9D872CA3C21900B67DE7 /* KMModifierMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 29BE9D862CA3C21900B67DE7 /* KMModifierMapping.m */; }; 29C1CDE22C5B2F8B003C23BB /* KMSettingsRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = D861B03E2C5747F70003675E /* KMSettingsRepository.m */; }; 29C1CDE32C5B2F8B003C23BB /* KMDataRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = 29015ABC2C58D86F00CCBB94 /* KMDataRepository.m */; }; + 29DBBF672D35053E00D8E33C /* KMSentryHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 29DBBF662D35053E00D8E33C /* KMSentryHelper.m */; }; 29DD5F442CFEF88000683388 /* SILAndikaV1RGB.png in Resources */ = {isa = PBXBuildFile; fileRef = 29DD5F432CFEF88000683388 /* SILAndikaV1RGB.png */; }; 37A245C12565DFA6000BBF92 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 37A245C02565DFA6000BBF92 /* Assets.xcassets */; }; 37AE5C9D239A7B770086CC7C /* qrcode.min.js in Resources */ = {isa = PBXBuildFile; fileRef = 37AE5C9C239A7B770086CC7C /* qrcode.min.js */; }; @@ -275,6 +276,8 @@ 29D470972C648D5200224B4F /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/KMKeyboardHelpWindowController.strings; sourceTree = ""; }; 29D470982C648D5200224B4F /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/MainMenu.strings; sourceTree = ""; }; 29D470992C648D7100224B4F /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Localizable.strings; sourceTree = ""; }; + 29DBBF652D35053E00D8E33C /* KMSentryHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KMSentryHelper.h; sourceTree = ""; }; + 29DBBF662D35053E00D8E33C /* KMSentryHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KMSentryHelper.m; sourceTree = ""; }; 29DD5F432CFEF88000683388 /* SILAndikaV1RGB.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = SILAndikaV1RGB.png; sourceTree = ""; }; 29DD8400276C49E20066A16E /* am */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = am; path = am.lproj/KMAboutWindowController.strings; sourceTree = ""; }; 29DD8401276C49E20066A16E /* am */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = am; path = am.lproj/preferences.strings; sourceTree = ""; }; @@ -433,6 +436,17 @@ path = Privacy; sourceTree = ""; }; + 29DBBF642D34FFE000D8E33C /* Logging */ = { + isa = PBXGroup; + children = ( + 29B4A0D42BF7675A00682049 /* KMLogs.h */, + 29B4A0D32BF7675A00682049 /* KMLogs.m */, + 29DBBF652D35053E00D8E33C /* KMSentryHelper.h */, + 29DBBF662D35053E00D8E33C /* KMSentryHelper.m */, + ); + path = Logging; + sourceTree = ""; + }; 2CDC487CDFFBB26D621D73BD /* Pods */ = { isa = PBXGroup; children = ( @@ -564,8 +578,6 @@ 989C9C0A1A7876DE00A20425 /* Keyman4MacIM */ = { isa = PBXGroup; children = ( - 29B4A0D42BF7675A00682049 /* KMLogs.h */, - 29B4A0D32BF7675A00682049 /* KMLogs.m */, 299ABD6F29ECE75B00AA5948 /* KeySender.m */, 299ABD7029ECE75B00AA5948 /* KeySender.h */, D861B03D2C5747F70003675E /* KMSettingsRepository.h */, @@ -575,6 +587,7 @@ 297A501128DF4D360074EB1B /* Privacy */, 98FE105B1B4DE86300525F54 /* Categories */, 98D6DA791A799EE700B09822 /* Frameworks */, + 29DBBF642D34FFE000D8E33C /* Logging */, 989C9C121A7876DE00A20425 /* Images.xcassets */, 98BDD3681BC3511200FAC7C4 /* Keyman4MacIM.entitlements */, 98BF92401BF01CBE0002126A /* KMAboutWindow */, @@ -1000,6 +1013,7 @@ 9A3D6C5D221531B0008785A3 /* KMOSVersion.m in Sources */, 989C9C111A7876DE00A20425 /* main.m in Sources */, 290BC680274B9DB1005CD1C3 /* KMPackageInfo.m in Sources */, + 29DBBF672D35053E00D8E33C /* KMSentryHelper.m in Sources */, 29B4A0D52BF7675A00682049 /* KMLogs.m in Sources */, 98BF924F1BF02DC20002126A /* KMBarView.m in Sources */, E240F599202DED740000067D /* KMPackage.m in Sources */, diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m index 202be65ef5..142606152f 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m @@ -10,6 +10,7 @@ #import "KMDownloadKBWindowController.h" #import "KMDataRepository.h" #import "KMLogs.h" +#import "KMSentryHelper.h" @interface KMConfigurationWindowController () @property (nonatomic, weak) IBOutlet NSTableView *tableView; @@ -363,18 +364,23 @@ NSString *partialPath = [KMDataRepository.shared trimToPartialPath:kmxFilePath]; os_log_debug([KMLogs uiLog], "checkBoxAction, kmxFilePath = %{public}@ for checkBox.tag %li, partialPath = %{public}@", kmxFilePath, checkBox.tag, partialPath); if (checkBox.state == NSOnState) { - os_log_debug([KMLogs uiLog], "Adding active keyboard: %{public}@", kmxFilePath); + os_log_debug([KMLogs uiLog], "enabling active keyboard: %{public}@", kmxFilePath); + NSString *message = [NSString stringWithFormat:@"enabling active keyboard: %@", kmxFilePath]; + [KMSentryHelper addUserBreadCrumb:@"config" message:message]; [self.activeKeyboards addObject:partialPath]; [self saveActiveKeyboards]; } else if (checkBox.state == NSOffState) { - os_log_debug([KMLogs uiLog], "Disabling active keyboard: %{public}@", kmxFilePath); + os_log_debug([KMLogs uiLog], "disabling active keyboard: %{public}@", kmxFilePath); + NSString *message = [NSString stringWithFormat:@"disabling active keyboard: %@", kmxFilePath]; + [KMSentryHelper addUserBreadCrumb:@"config" message:message]; [self.activeKeyboards removeObject:partialPath]; [self saveActiveKeyboards]; } } - (void)infoAction:(id)sender { + [KMSentryHelper addUserBreadCrumb:@"user" message:@"getting package information"]; NSButton *infoButton = (NSButton *)sender; NSString *packagePath = [self packagePathAtIndex:infoButton.tag]; if (packagePath != nil) { @@ -389,6 +395,7 @@ } - (void)helpAction:(id)sender { + [KMSentryHelper addUserBreadCrumb:@"user" message:@"displaying help"]; NSButton *helpButton = (NSButton *)sender; NSString *packagePath = [self packagePathAtIndex:helpButton.tag]; if (packagePath != nil) { @@ -406,16 +413,25 @@ NSButton *deleteButton = (NSButton *)sender; NSDictionary *info = [self.tableContents objectAtIndex:deleteButton.tag]; NSString *deleteKeyboardMessage = NSLocalizedString(@"message-confirm-delete-keyboard", nil); + NSString *keyboardName = nil; + + if ([info objectForKey:@"HeaderTitle"] != nil) { + keyboardName = [info objectForKey:@"HeaderTitle"]; + [self.deleteAlertView setMessageText:[NSString localizedStringWithFormat:deleteKeyboardMessage, keyboardName]]; + } else { + keyboardName = [info objectForKey:kKMKeyboardNameKey]; + [self.deleteAlertView setMessageText:[NSString localizedStringWithFormat:deleteKeyboardMessage, keyboardName]]; + } - if ([info objectForKey:@"HeaderTitle"] != nil) - [self.deleteAlertView setMessageText:[NSString localizedStringWithFormat:deleteKeyboardMessage, [info objectForKey:@"HeaderTitle"]]]; - else - [self.deleteAlertView setMessageText:[NSString localizedStringWithFormat:deleteKeyboardMessage, [info objectForKey:kKMKeyboardNameKey]]]; - + os_log_debug([KMLogs testLog], "entered removeAction for keyboardName: %{public}@", keyboardName); + [self.deleteAlertView beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) { if (returnCode == NSAlertFirstButtonReturn) { os_log_debug([KMLogs uiLog], "confirm delete keyboard alert dismissed"); [self deleteFileAtIndex:[NSNumber numberWithInteger:deleteButton.tag]]; + + os_log_debug([KMLogs testLog], "removeAction for keyboardName: %{public}@", keyboardName); + [KMSentryHelper addBreadCrumb:@"configure" message:[NSString stringWithFormat:@"remove keyboard: %@", keyboardName]]; } self.deleteAlertView = nil; }]; @@ -453,7 +469,8 @@ - (void)installPackageFile:(NSString *)kmpFile { // kmpFile could be a temp file (in fact, it always is!), so don't display the name. os_log_debug([KMLogs dataLog], "kmpFile - ready to unzip/install Package File: %{public}@", kmpFile); - + [KMSentryHelper addBreadCrumb:@"configure" message:@"install package file"]; + BOOL didUnzip = [self.AppDelegate unzipFile:kmpFile]; if (!didUnzip) { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDownloadKeyboard/KMDownloadKBWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDownloadKeyboard/KMDownloadKBWindowController.m index 4b5ce44dea..2fec9f8b32 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDownloadKeyboard/KMDownloadKBWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDownloadKeyboard/KMDownloadKBWindowController.m @@ -9,6 +9,7 @@ #import "KMDownloadKBWindowController.h" #import "KMInputMethodAppDelegate.h" #import "KMLogs.h" +#import "KMSentryHelper.h" @interface KMDownloadKBWindowController () @property (nonatomic, weak) IBOutlet WebView *webView; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m index acefcc8417..dd53b49622 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m @@ -13,7 +13,7 @@ #import "KMLogs.h" #import "InputMethodKit/InputMethodKit.h" #import "KMInputMethodLifecycle.h" - +#import "KMSentryHelper.h" @implementation KMInputController @@ -111,17 +111,21 @@ KMInputMethodEventHandler* _eventHandler; NSInteger itag = mItem.tag; os_log_debug([KMLogs uiLog], "Keyman menu clicked - tag: %lu", itag); if (itag == CONFIG_MENUITEM_TAG) { + [KMSentryHelper addUserBreadCrumb:@"menu" message:@"Configuration..."]; [self showConfigurationWindow:sender]; } else if (itag == OSK_MENUITEM_TAG) { + [KMSentryHelper addUserBreadCrumb:@"menu" message:@"On-screen Keyboard"]; [KMSettingsRepository.shared writeShowOskOnActivate:YES]; os_log_debug([KMLogs oskLog], "menuAction OSK_MENUITEM_TAG, updating settings writeShowOsk to YES"); [self.appDelegate showOSK]; } else if (itag == ABOUT_MENUITEM_TAG) { + [KMSentryHelper addUserBreadCrumb:@"menu" message:@"About"]; [self.appDelegate showAboutWindow]; } else if (itag >= KEYMAN_FIRST_KEYBOARD_MENUITEM_TAG) { + [KMSentryHelper addUserBreadCrumb:@"menu" message:@"Selected Keyboard"]; [self.appDelegate selectKeyboardFromMenu:itag]; } } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h index d41bf25899..eade3d6d2f 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h @@ -124,7 +124,7 @@ static const int KEYMAN_FIRST_KEYBOARD_MENUITEM_INDEX = 0; - (void)postKeyboardEventWithSource: (CGEventSourceRef)source code:(CGKeyCode) virtualKey postCallback:(PostEventCallback)postEvent; - (KeymanVersionInfo)versionInfo; - (void)registerConfigurationWindow:(NSWindowController *)window; -- (BOOL)isSentryTestingEnabled; +- (BOOL)canForceSentryEvents; @end #endif /* KMInputMethodAppDelegate_h */ diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 9a5a98de47..ad0249643c 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -17,6 +17,7 @@ #import "KMPackageInfo.h" #import "PrivacyConsent.h" #import "KMLogs.h" +#import "KMSentryHelper.h" @import Sentry; NSString *const kKeymanKeyboardDownloadCompletedNotification = @"kKeymanKeyboardDownloadCompletedNotification"; @@ -125,10 +126,12 @@ id _lastServerWithOSKShowing = nil; - (void)inputMethodDeactivated:(NSNotification *)notification { if ([self.oskWindow.window isVisible]) { os_log_debug([KMLogs oskLog], "***KMInputMethodAppDelegate inputMethodDeactivated, hiding OSK"); + [KMSentryHelper addBreadCrumb:@"lifecycle" message:@"hiding OSK on input method deactivation"]; [self.oskWindow.window setIsVisible:NO]; } else { os_log_debug([KMLogs oskLog], "***KMInputMethodAppDelegate inputMethodDeactivated, OSK already hidden"); } + [KMSentryHelper addOskVisibleTag:[self.oskWindow.window isVisible]?@"true":@"false"]; if (self.lowLevelEventTap) { os_log_debug([KMLogs lifecycleLog], "***inputMethodDeactivated, disabling event tap"); @@ -144,18 +147,14 @@ id _lastServerWithOSKShowing = nil; os_log_debug([KMLogs lifecycleLog], "***KMInputMethodAppDelegate inputMethodActivated, re-enabling event tap..."); CGEventTapEnable(self.lowLevelEventTap, YES); } - + + os_log_debug([KMLogs lifecycleLog], "--- inputMethodActivated, kvk is non-nil: %{public}@ showOskOnActivate: %{public}@", (_kvk!=nil)?@"true":@"false", [KMInputMethodLifecycle.shared shouldShowOskOnActivate]?@"true":@"false"); + if (_kvk != nil && ([KMInputMethodLifecycle.shared shouldShowOskOnActivate])) { os_log_debug([KMLogs oskLog], "***KMInputMethodAppDelegate inputMethodActivated, showing OSK"); + [KMSentryHelper addBreadCrumb:@"lifecycle" message:@"opening OSK on input method activation"]; [self showOSK]; } - - SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; - crumb.level = kSentryLevelInfo; - crumb.category = @"startup"; - //crumb.message = [NSString stringWithFormat:@"Authenticated user %@", user.email]; - crumb.message = [NSString stringWithFormat:@"inputMethodActivated"]; - [SentrySDK addBreadcrumb:crumb]; } - (KeymanVersionInfo)versionInfo { @@ -206,39 +205,45 @@ id _lastServerWithOSKShowing = nil; } /** - * Determine whether sentry testing is enabled. - * When it is enabled, then typing certain characters will cause Sentry events or crashes to occur. + * Determine whether to force sentry events. + * When true, then typing certain characters will cause Sentry events or crashes to occur. * - * To enable, set the flag is UserDefaults + * To enable, set the flag in UserDefaults * `defaults write keyman.inputmethod.Keyman KMForceSentryError 1` * Also, use the SIL Euro Latin keyboard and type in the Stickies app */ -- (BOOL)isSentryTestingEnabled { +- (BOOL)canForceSentryEvents { NSString* const testKeyboardName = @"sil_euro_latin.kmx"; NSString* const testClientApplicationId = @"com.apple.Stickies"; - BOOL testingEnabled = NO; + BOOL canForce = NO; if (self.sentryTestingEnabled) { NSString * kmxName = [[self.kmx filePath] lastPathComponent]; NSString * applicationId = [KMInputMethodLifecycle.shared clientApplicationId]; - testingEnabled = [kmxName isEqualToString:testKeyboardName] && [applicationId isEqualToString:testClientApplicationId]; - os_log_info([KMLogs testLog], "isSentryTestingEnabled, self.sentryTestingEnabled: %{public}@ kmxName: %{public}@ applicationId: %{public}@ testingEnabled: %{public}@", self.sentryTestingEnabled?@"YES":@"NO", kmxName, applicationId, testingEnabled?@"YES":@"NO"); + canForce = [[self getKmxFileName] isEqualToString:testKeyboardName] && [applicationId isEqualToString:testClientApplicationId]; + os_log_info([KMLogs testLog], "canForceSentryEvents, self.sentryTestingEnabled: %{public}@ kmxName: %{public}@ applicationId: %{public}@ testingEnabled: %{public}@", self.sentryTestingEnabled?@"YES":@"NO", kmxName, applicationId, canForce?@"YES":@"NO"); } - return testingEnabled; + return canForce; +} + +- (NSString*) getKmxFileName { + return [[self.kmx filePath] lastPathComponent]; } - (void)setPostLaunchKeymanSentryTags { NSString *keyboardFileName = [self.kmx.filePath lastPathComponent]; os_log_info([KMLogs keyboardLog], "initial kmx set to %{public}@", keyboardFileName); - NSString *hasAccessibility = [PrivacyConsent.shared checkAccessibility]?@"Yes":@"No"; + NSString *hasAccessibility = [PrivacyConsent.shared checkAccessibility]?@"true":@"false"; - // assign custom keyboard tag in Sentry to initial keyboard - [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { - [scope setTagValue:hasAccessibility forKey:@"accessibilityEnabled"]; - [scope setTagValue:keyboardFileName forKey:@"keyboard"]; - }]; + // assign custom keyboard tag in Sentry for accessibility and initial keyboard + [KMSentryHelper addKeyboardTag:keyboardFileName]; + [KMSentryHelper addHasAccessibilityTag:hasAccessibility]; +// [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { +// [scope setTagValue:hasAccessibility forKey:@"accessibilityEnabled"]; +// [scope setTagValue:keyboardFileName forKey:@"keyboard"]; +// }]; } #ifdef USE_ALERT_SHOW_HELP_TO_FORCE_EASTER_EGG_CRASH_FROM_ENGINE @@ -438,22 +443,28 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef _kmx = kmx; CoreKeyboardInfo *keyboardInfo = [self.kme loadKeyboardFromKmxFile:kmx]; - os_log_info([KMLogs keyboardLog], "setKmx loaded keyboard, keyboard info: %{public}@", keyboardInfo); - + os_log_info([KMLogs keyboardLog], "loadKeyboardFromKmxFile, keyboard info: %{public}@", keyboardInfo); + [KMSentryHelper addBreadCrumb:@"configure" message:[NSString stringWithFormat:@"loadKeyboardFromKmxFile: %@", [self getKmxFileName]]]; + _modifierMapping = [[KMModifierMapping alloc] init:keyboardInfo]; os_log_info([KMLogs keyboardLog], "modifierMapping bothOptionKeysGenerateRightAlt: %d", self.modifierMapping.bothOptionKeysGenerateRightAlt); // assign custom keyboard tag in Sentry to default keyboard - [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { - [scope setTagValue:keyboardInfo.keyboardId forKey:@"keyboard"]; - }]; + [KMSentryHelper addKeyboardTag:keyboardInfo.keyboardId]; } - (void)setKvk:(KVKFile *)kvk { + if (kvk != nil) { + os_log_info([KMLogs lifecycleLog], "*** setKvk, kvk.associatedKeyboard: %{public}@", kvk.associatedKeyboard); + } else { + os_log_info([KMLogs lifecycleLog], "*** setKvk, setting to nil"); + } _kvk = kvk; - if (_oskWindow != nil) + + if (_oskWindow != nil) { [_oskWindow resetOSK]; + } } - (void)setKeyboardName:(NSString *)keyboardName { @@ -858,11 +869,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef [self setSelectedKeyboard:keyboardName]; [self setContextBuffer:nil]; - SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; - crumb.level = kSentryLevelInfo; - crumb.category = @"startup"; - crumb.message = [NSString stringWithFormat:@"setDefaultSelectedKeyboard: %@", keyboardName]; - [SentrySDK addBreadcrumb:crumb]; + [KMSentryHelper addBreadCrumb:@"startup" message:[NSString stringWithFormat:@"setDefaultSelectedKeyboard: %@", keyboardName]]; } - (void) addKeyboardPlaceholderMenuItem { @@ -986,6 +993,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef [[self.oskWindow window] makeKeyAndOrderFront:nil]; [[self.oskWindow window] setLevel:NSStatusWindowLevel]; [[self.oskWindow window] setTitle:self.oskWindowTitle]; + [KMSentryHelper addOskVisibleTag:[self.oskWindow.window isVisible]?@"true":@"false"]; } - (void)showAboutWindow { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m index 91ebe13f33..340a06a04e 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m @@ -12,6 +12,7 @@ #import "TextApiCompliance.h" #import "KMSettingsRepository.h" #import "KMLogs.h" +#import "KMSentryHelper.h" @import Sentry; @interface KMInputMethodEventHandler () @@ -43,9 +44,7 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; _lowLevelBackspaceCount = 0; _queuedText = nil; - [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { - [scope setTagValue:clientAppId forKey:@"clientAppId"]; - }]; + [KMSentryHelper addClientAppIdTag:clientAppId]; return self; } @@ -95,7 +94,7 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; - (BOOL) handleEventWithKeymanEngine:(NSEvent *)event in:(id) sender { CoreKeyOutput *output = nil; - if ([self.appDelegate isSentryTestingEnabled]) { + if ([self.appDelegate canForceSentryEvents]) { if ([self forceSentryEvent:event]) { return NO; } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m index 0b82c83006..543d7fe4d8 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m @@ -10,7 +10,7 @@ */ /** - * This class is needed because many activateServer and deactivateServer messages sent from macOS + * This class is needed because many activateServer and deactivateServer messages are sent from macOS * to KMInputController, but they are not particularly reliable. Keyman receives some messages when it * is not active and should not become active. It also receives messages when it is active, but there is no * need to change state. For example, when a menu is clicked with Keyman active, macOS will send a @@ -36,6 +36,7 @@ #import #import "KMSettingsRepository.h" #import +#import "KMSentryHelper.h" NSString *const kInputMethodActivatedNotification = @"kInputMethodActivatedNotification"; NSString *const kInputMethodDeactivatedNotification = @"kInputMethodDeactivatedNotification"; @@ -165,7 +166,8 @@ typedef enum { os_log_info([KMLogs lifecycleLog], "performTransition: None, new InputSourceId: %{public}@, new application ID: %{public}@", currentInputSource, currentClientAppId); break; case Activate: - os_log_info([KMLogs lifecycleLog], "performTransition: Activate, new InputSourceId: %{public}@, new application ID: %{public}@", currentInputSource, currentClientAppId); + os_log_info([KMLogs lifecycleLog], "performTransition: Activate, new application ID: %{public}@", currentClientAppId); + [KMSentryHelper addBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"activated input method '%@' for application ID '%@'", currentInputSource, currentClientAppId]]; /** * Perform two actions when activating the input method. * Change the client first which prepares the event handler. @@ -176,10 +178,12 @@ typedef enum { break; case Deactivate: os_log_info([KMLogs lifecycleLog], "performTransition: Deactivate, new InputSourceId: %{public}@, new application ID: %{public}@", currentInputSource, currentClientAppId); + [KMSentryHelper addBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"deactivated input method '%@' for application ID '%@'", currentInputSource, currentClientAppId]]; [self deactivateInputMethod]; break; case ChangeClients: os_log_info([KMLogs lifecycleLog], "performTransition: ChangeClients, new InputSourceId: %{public}@, new application ID: %{public}@", currentInputSource, currentClientAppId); + [KMSentryHelper addBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"change clients for input method '%@' to application ID '%@'", currentInputSource, currentClientAppId]]; [self changeClient]; break; } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMLogs.h b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMLogs.h similarity index 84% rename from mac/Keyman4MacIM/Keyman4MacIM/KMLogs.h rename to mac/Keyman4MacIM/Keyman4MacIM/Logging/KMLogs.h index 002bc5023c..f7f83702ec 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMLogs.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMLogs.h @@ -1,4 +1,4 @@ -/** +/* * Keyman is copyright (C) SIL International. MIT License. * * KMLogs.h @@ -6,7 +6,6 @@ * * Created by Shawn Schantz on 2024-05-16. * - * Contains methods to get singleton logger objects and constants for subsystem and category names. */ #import diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMLogs.m b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMLogs.m similarity index 99% rename from mac/Keyman4MacIM/Keyman4MacIM/KMLogs.m rename to mac/Keyman4MacIM/Keyman4MacIM/Logging/KMLogs.m index f2d4dc4d53..6a8a5cd957 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMLogs.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMLogs.m @@ -1,4 +1,4 @@ -/** +/* * Keyman is copyright (C) SIL International. MIT License. * * KMLogs.m diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h new file mode 100644 index 0000000000..e9d6936c0e --- /dev/null +++ b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h @@ -0,0 +1,25 @@ +/* + * Keyman is copyright (C) SIL International. MIT License. + * + * Created by Shawn Schantz on 2025-01-13. + * + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface KMSentryHelper : NSObject + ++ (void)addApiComplianceTag: (NSString *)value; ++ (void)addOskVisibleTag:(NSString *)value; ++ (void)addClientAppIdTag:(NSString *)value; ++ (void)addKeyboardTag:(NSString *)value; ++ (void)addHasAccessibilityTag:(NSString *)value; ++ (void)addBreadCrumb:(NSString *)category message:(NSString *)messageText; ++ (void)addUserBreadCrumb:(NSString *)category message:(NSString *)messageText; ++ (void)addDetailedBreadCrumb:(NSString *)category message:(NSString *)messageText data:( NSDictionary *) map; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m new file mode 100644 index 0000000000..5278e36037 --- /dev/null +++ b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m @@ -0,0 +1,77 @@ +/* + * Keyman is copyright (C) SIL International. MIT License. + * + * Created by Shawn Schantz on 2025-01-13. + * + * Description + */ + +#import "KMSentryHelper.h" +@import Sentry; + +@implementation KMSentryHelper + +NSString * const kApiComplianceTagName = @"apiCompliance"; +NSString * const kOskVisibleTagName = @"oskVisible"; +NSString * const kClientAppIdTagName = @"clientAppId"; +NSString * const kKeyboardTagName = @"keyboard"; +NSString * const kHasAccessibilityTagName = @"accessibilityEnabled"; + ++ (void)addApiComplianceTag: (NSString *)value { + [self addCustomTag:kApiComplianceTagName withValue:value]; +} + ++ (void)addOskVisibleTag:(NSString *)value { + [self addCustomTag:kOskVisibleTagName withValue:value]; +} + ++ (void)addClientAppIdTag:(NSString *)value { + [self addCustomTag:kClientAppIdTagName withValue:value]; +} + ++ (void)addKeyboardTag:(NSString *)value { + [self addCustomTag:kKeyboardTagName withValue:value]; +} + ++ (void)addHasAccessibilityTag:(NSString *)value { + [self addCustomTag:kHasAccessibilityTagName withValue:value]; +} + +/** + *assign custom keyboard tag in Sentry to initial keyboard + */ ++ (void)addCustomTag:(NSString *)tagName withValue:(NSString *)value { + [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { + [scope setTagValue:value forKey:tagName]; + }]; +} + ++ (void)addBreadCrumb:(NSString *)category message:(NSString *)messageText { + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; + crumb.level = kSentryLevelInfo; + crumb.category = category; + crumb.message = messageText; + //crumb.message = [NSString stringWithFormat:@"setDefaultSelectedKeyboard: %@", keyboardName]; + [SentrySDK addBreadcrumb:crumb]; +} + ++ (void)addUserBreadCrumb:(NSString *)category message:(NSString *)messageText { + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; + crumb.type = @"user"; + crumb.level = kSentryLevelInfo; + crumb.category = category; + crumb.message = messageText; + //crumb.message = [NSString stringWithFormat:@"setDefaultSelectedKeyboard: %@", keyboardName]; + [SentrySDK addBreadcrumb:crumb]; +} + ++ (void)addDetailedBreadCrumb:(NSString *)category message:(NSString *)messageText data:( NSDictionary *) map { + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; + crumb.level = kSentryLevelInfo; + crumb.category = category; + crumb.message = messageText; + crumb.data = map; + [SentrySDK addBreadcrumb:crumb]; +} + +@end diff --git a/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.m index b3824fa897..df0e723534 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.m @@ -11,6 +11,7 @@ #import "KMInputMethodLifecycle.h" #import "KMSettingsRepository.h" #import "KMLogs.h" +#import "KMSentryHelper.h" @interface OSKWindowController () @property (nonatomic, strong) NSButton *helpButton; @@ -76,6 +77,7 @@ // whenever the OSK is closing clear all of its modifier keys [self.oskView clearOskModifiers]; + [KMSentryHelper addOskVisibleTag:@"false"]; } - (void)helpAction:(id)sender { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m index e83439794b..4d77bada0f 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m @@ -36,6 +36,7 @@ #import #import "KMInputMethodAppDelegate.h" #import "KMLogs.h" +#import "KMSentryHelper.h" // this is the user managed list of non-compliant apps persisted in User Defaults NSString *const kKMLegacyApps = @"KMLegacyApps"; @@ -76,6 +77,16 @@ NSString *const kKMLegacyApps = @"KMLegacyApps"; return [NSString stringWithFormat:@"complianceUncertain: %d, hasCompliantSelectionApi: %d, canReadText: %d, canReplaceText: %d, mustBackspaceUsingEvents: %d, clientApplicationId: %@, client: %@", self.complianceUncertain, self.hasCompliantSelectionApi, [self canReadText], [self canReplaceText], [self mustBackspaceUsingEvents], _clientApplicationId, _client]; } +/** + * For Sentry, create a short description as the tag value is limited to 200 characters. + * We don't know how long the clientAppId will be, but this should not be well below 200 characters. + * If the text were to exceed 200 characters, then Sentry would display an error rather than truncating. + */ +-(NSString *)shortSentryTagDescription +{ + return [NSString stringWithFormat:@"uncertain: %@, compliant: %@, clientAppId: %@, ", self.complianceUncertain?@"true":@"false", self.hasCompliantSelectionApi?@"true":@"false", _clientApplicationId]; +} + /** test to see if the API selectedRange functions properly for the text input client */ -(void) checkCompliance:(id) client { // confirm that the API actually exists (this always seems to return true) @@ -91,6 +102,7 @@ NSString *const kKMLegacyApps = @"KMLegacyApps"; [self checkComplianceUsingInitialSelection]; } os_log_debug([KMLogs complianceLog], "checkCompliance workingSelectionApi for app %{public}@: set to %{public}@", self.clientApplicationId, self.complianceUncertain?@"YES":@"NO"); + [KMSentryHelper addApiComplianceTag:self.shortSentryTagDescription]; } -(void) checkComplianceUsingInitialSelection { @@ -135,6 +147,7 @@ NSString *const kKMLegacyApps = @"KMLegacyApps"; } os_log_info([KMLogs complianceLog], "checkComplianceAfterInsert, self.hasWorkingSelectionApi = %{public}@ for app %{public}@", self.hasCompliantSelectionApi?@"YES":@"NO", self.clientApplicationId); + [KMSentryHelper addApiComplianceTag:self.shortSentryTagDescription]; } - (BOOL)validateNewLocation:(NSUInteger)location delete:(NSString *)textToDelete { From 4f4df94bb30a9920eab30ef6d67c7da22aaa3db8 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Thu, 16 Jan 2025 16:29:53 +0100 Subject: [PATCH 030/155] chore(linux): Update debian changelog (cherry picked from commit fdafd5879ec926b1f71a768f61fe17e71749602b) --- linux/debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/linux/debian/changelog b/linux/debian/changelog index 3a2dae55f3..22fd40caad 100644 --- a/linux/debian/changelog +++ b/linux/debian/changelog @@ -1,3 +1,9 @@ +keyman (17.0.333-1) unstable; urgency=medium + + * New upstream release. + + -- Eberhard Beilharz Thu, 16 Jan 2025 16:29:44 +0100 + keyman (17.0.332-1) unstable; urgency=medium * set environment variable for rendering of downloads dialog (#12617) From 7deb248c1eb7489e6f772bde0a02d9f1968090d3 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Fri, 17 Jan 2025 08:03:55 +1000 Subject: [PATCH 031/155] feat(windows): This is to provide a PR build for testing --- windows/src/desktop/kmshell/main/BackgroundUpdateStateDiagram.md | 1 + 1 file changed, 1 insertion(+) diff --git a/windows/src/desktop/kmshell/main/BackgroundUpdateStateDiagram.md b/windows/src/desktop/kmshell/main/BackgroundUpdateStateDiagram.md index 160d54b2c1..1ff6f91b9d 100644 --- a/windows/src/desktop/kmshell/main/BackgroundUpdateStateDiagram.md +++ b/windows/src/desktop/kmshell/main/BackgroundUpdateStateDiagram.md @@ -9,3 +9,4 @@ stateDiagram Installing --> PostInstall PostInstall --> Idle ``` +State Transition matrix From c0bfb541face0266cf64c07ae156dd121df93c0b Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Fri, 17 Jan 2025 10:28:32 +0700 Subject: [PATCH 032/155] chore(common): Add 17.0.333 to version history --- HISTORY.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 78352f95e5..7f830394da 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -953,7 +953,7 @@ ## 18.0.41 alpha 2024-05-22 * fix(developer): handle `KM_CORE_IT_INVALIDATE_CONTEXT` in debugger (#11488) -* chore(linux): Trigger GHA packaging for stable builds :cherries: (#11495) +* chore(linux): Trigger GHA packaging for stable builds (#11495) * chore(android,mac,windows): Update crowdin strings for DE (#11497) * feat(web): custom infrastructure for @web/test-runner use (#11403) * chore(web): conversion of lm-worker browser-test for @web/test-runner use (#11404) @@ -1149,6 +1149,17 @@ * chore(common): move to 18.0 alpha (#10713) * chore: move to 18.0 alpha +## 17.0.333 stable 2025-01-16 + +* fix(core): permanently disable logging (#12674) +* fix(linux): pushing of updated changelog branch (#12819) +* fix(linux): work around Lintian errors (#12817) +* fix(core): implement ldml_processor::get_key_list() (#12816) +* chore(linux): Update debian changelog (#12022) +* fix(android): use main looper to dispatch key events when OSK is hidden (#12875) +* chore: use GitHub PR titles when writing HISTORY.md (#12908) +* fix(developer): filter incorrect fonts out of .keyboard_info (#12913) + ## 17.0.332 stable 2024-11-06 * fix(developer): create Server config directory before options save (#12609) From 7cb6be6a97d06142085437904736367fa5d8dc86 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 17 Jan 2025 11:03:20 +0700 Subject: [PATCH 033/155] fix(developer): support `&displayMap` font in web debugger Adds a new design-time font property for when `&displayMap` is in use in a keyboard, so that the web debugger can use that font as appropriate. If the keyboard does not have a `&displayMap` store, then the DisplayMap font property is disabled, and the web debugger will use the OSK Font instead, as previously was the case. Note that the font for `&displayMap` has to be installed on the keyboard author's system in order for it to be served up. Fixes: #12123 --- .../delphi/keyboards/kmxfileconsts.pas | 6 +- .../common/delphi/general/KeyboardFonts.pas | 5 +- developer/src/tike/child/UfrmKeymanWizard.pas | 32 +++++++++++ .../src/tike/dialogs/UfrmKeyboardFonts.dfm | 56 +++++++++++++++++-- .../src/tike/dialogs/UfrmKeyboardFonts.pas | 8 +++ ....Developer.UI.Project.kmnProjectFileUI.pas | 15 +++-- 6 files changed, 107 insertions(+), 15 deletions(-) diff --git a/common/windows/delphi/keyboards/kmxfileconsts.pas b/common/windows/delphi/keyboards/kmxfileconsts.pas index e8f0e0d740..8e1955aaa6 100644 --- a/common/windows/delphi/keyboards/kmxfileconsts.pas +++ b/common/windows/delphi/keyboards/kmxfileconsts.pas @@ -230,7 +230,8 @@ type ssPlatform = 31, ssBaseLayout = 32, ssLayer = 33, ssVKDictionary = 34, ssLayoutFile = 35, // I3438 // I3483 ssKeyboardVersion = 36, ssKMW_EmbedCSS = 37, ssTargets = 38, ssCasedKeys = 39, - ssBegin_NewContext = 40, ssBegin_PostKeystroke = 41, ssNewLayer = 42, ssOldLayer = 43); // I4140 // I4368 // I4504 + ssBegin_NewContext = 40, ssBegin_PostKeystroke = 41, ssNewLayer = 42, ssOldLayer = 43, // I4140 // I4368 // I4504 + ssDisplayMap = 44); const SystemStoreNames: array[TSystemStore] of WideString = ( @@ -245,7 +246,8 @@ const '', '', '', '', 'LAYOUTFILE', 'KEYBOARDVERSION', 'KMW_EMBEDCSS', 'TARGETS', //9.0 // I3483 // I4140 // I4368 // I4504 'CASEDKEYS', //14.0, - '', '', 'NEWLAYER', 'OLDLAYER'); //15.0 + '', '', 'NEWLAYER', 'OLDLAYER', //15.0 + 'DISPLAYMAP'); //17.0 implementation diff --git a/developer/src/common/delphi/general/KeyboardFonts.pas b/developer/src/common/delphi/general/KeyboardFonts.pas index 5c80392521..f1a2bac2b9 100644 --- a/developer/src/common/delphi/general/KeyboardFonts.pas +++ b/developer/src/common/delphi/general/KeyboardFonts.pas @@ -21,7 +21,8 @@ unit KeyboardFonts; interface type - TKeyboardFont = (kfontCode, kfontChar, kfontOSK, kfontTouchLayoutPhone, kfontTouchLayoutTablet, kfontTouchLayoutDesktop); + TKeyboardFont = (kfontCode, kfontChar, kfontOSK, kfontTouchLayoutPhone, kfontTouchLayoutTablet, kfontTouchLayoutDesktop, + kfontDisplayMap); TKeyboardFontArray = array[TKeyboardFont] of string; // I4409 @@ -34,7 +35,7 @@ type const KeyboardFontId: array[TKeyboardFont] of string = ( - 'Code', 'Char', 'Osk', 'TouchLayoutPhone', 'TouchLayoutTablet', 'TouchLayoutDesktop' + 'Code', 'Char', 'Osk', 'TouchLayoutPhone', 'TouchLayoutTablet', 'TouchLayoutDesktop', 'DisplayMap' ); implementation diff --git a/developer/src/tike/child/UfrmKeymanWizard.pas b/developer/src/tike/child/UfrmKeymanWizard.pas index 59e0f8a341..afb1e715ed 100644 --- a/developer/src/tike/child/UfrmKeymanWizard.pas +++ b/developer/src/tike/child/UfrmKeymanWizard.pas @@ -369,6 +369,8 @@ type FLayoutSetup: Boolean; FCheckboxGridHelper: TCheckboxGridHelper; + FDisplayMapFont: TFont; + function GetCurrentRule: TKeyboardParser_LayoutRule; procedure EnableControls; @@ -475,6 +477,7 @@ type procedure OrderDetailsPanels; function ValidateFileHasNoUnicodeCharacters(sw: WideString): Boolean; procedure UpdateQRCode; + procedure SetDisplayMapFont(const Value: TFont); protected function GetHelpTopic: string; override; @@ -495,6 +498,8 @@ type function ShouldRememberFocus(Control: TWinControl): Boolean; override; // I4679 + property DisplayMapFont: TFont read FDisplayMapFont write SetDisplayMapFont; + public procedure StartDebugging(FStartTest: Boolean = False); procedure StopDebugging; @@ -630,6 +635,8 @@ procedure TfrmKeymanWizard.FormCreate(Sender: TObject); begin FLoading := True; + FDisplayMapFont := TFont.Create; + //SetWindowTheme(pages.Handle, 'Explorer', ''); cmdAddToProject.Caption := '&Add to Project'; @@ -681,6 +688,7 @@ begin FreeAndNil(FKeyboardParser); // I4557 FreeAndNil(FDebugForm); FreeAndNil(FCheckboxGridHelper); + FreeAndNil(FDisplayMapFont); UninitSystemKeyboard; end; @@ -1825,6 +1833,15 @@ begin Delete(Result.Size, Length(Result.Size)-1, 2); end; end; + kfontDisplayMap: + begin + Result.Enabled := FKeyboardParser.GetSystemStoreValue(ssDisplayMap) <> ''; + if Result.Enabled then + begin + Result.Name := DisplayMapFont.Name; + Result.Size := IntToStr(TFontUtils.FontSizeInPoints(DisplayMapFont.Name, DisplayMapFont.Size)); // I4872 + end; + end; end; end; @@ -2535,6 +2552,8 @@ begin FFont.Free; end; end; + + SetFontFromString(DisplayMapFont, ProjectFile.IDEState['DisplayMapFont']); end; procedure TfrmKeymanWizard.SaveSettings(SaveProject: Boolean); @@ -2548,6 +2567,7 @@ begin else ProjectFile.IDEState['DebugDefaultFont'] := '0'; // I4702 ProjectFile.IDEState['DebugFont'] := FontAsString(FDebugForm.memo.Font); // I4702 + ProjectFile.IDEState['DisplayMapFont'] := FontAsString(DisplayMapFont); inherited; end; @@ -2781,6 +2801,13 @@ begin TUtilExecute.URL(lbDebugHosts.Items[lbDebugHosts.ItemIndex]); end; +procedure TfrmKeymanWizard.SetDisplayMapFont(const Value: TFont); +begin + FDisplayMapFont.Assign(Value); + if ProjectFile <> nil then + ProjectFile.IDEState['DisplayMapFont'] := FontAsString(DisplayMapFont); +end; + procedure TfrmKeymanWizard.SetFontInfo(Index: TKeyboardFont; const Value: TKeyboardFontInfo); // I4057 var f: TFont; @@ -2814,6 +2841,11 @@ begin CharFont.Name := Value.Name; CharFont.Size := StrToIntDef(Value.Size, 12); end; + kfontDisplayMap: + begin + DisplayMapFont.Name := Value.Name; + DisplayMapFont.Size := StrToIntDef(Value.Size, 12); + end; kfontOSK: begin if FKeyboardParser.Features.ContainsKey(kfOSK) then // I4258 diff --git a/developer/src/tike/dialogs/UfrmKeyboardFonts.dfm b/developer/src/tike/dialogs/UfrmKeyboardFonts.dfm index bd8ba4de5b..b874db58a8 100644 --- a/developer/src/tike/dialogs/UfrmKeyboardFonts.dfm +++ b/developer/src/tike/dialogs/UfrmKeyboardFonts.dfm @@ -2,11 +2,11 @@ inherited frmKeyboardFonts: TfrmKeyboardFonts BorderIcons = [biSystemMenu] BorderStyle = bsDialog Caption = 'Keyboard Fonts' - ClientHeight = 291 + ClientHeight = 322 ClientWidth = 512 Position = poScreenCenter ExplicitWidth = 518 - ExplicitHeight = 320 + ExplicitHeight = 351 PixelsPerInch = 96 TextHeight = 13 object lblDevEnv: TLabel @@ -147,6 +147,20 @@ inherited frmKeyboardFonts: TfrmKeyboardFonts Height = 13 Caption = 'em' end + object lblDisplayMap: TLabel + Left = 32 + Top = 248 + Width = 109 + Height = 13 + Caption = '&displayMap target font' + end + object Label4: TLabel + Left = 463 + Top = 248 + Width = 14 + Height = 13 + Caption = 'em' + end object fcbCode: TscFontComboBox Left = 176 Top = 41 @@ -260,23 +274,23 @@ inherited frmKeyboardFonts: TfrmKeyboardFonts end object cmdOK: TButton Left = 162 - Top = 248 + Top = 280 Width = 91 Height = 25 Caption = 'OK' Default = True - TabOrder = 12 + TabOrder = 14 OnClick = cmdOKClick end object cmdCancel: TButton Left = 259 - Top = 248 + Top = 280 Width = 90 Height = 25 Cancel = True Caption = 'Cancel' ModalResult = 2 - TabOrder = 13 + TabOrder = 15 end object fcbTouchLayoutPhone: TscFontComboBox Left = 176 @@ -347,4 +361,34 @@ inherited frmKeyboardFonts: TfrmKeyboardFonts ShowPreviewFontName = False ShowPreviewInList = False end + object editDisplayMapSize: TEdit + Left = 391 + Top = 245 + Width = 66 + Height = 21 + TabOrder = 13 + end + object fcbDisplayMap: TscFontComboBox + Left = 176 + Top = 245 + Width = 209 + Height = 24 + DropDownCount = 12 + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -13 + Font.Name = 'Tahoma' + Font.Style = [] + ItemHeight = 18 + ParentFont = False + TabOrder = 12 + MoveUsedToTop = False + ColorUsed = clWindow + PreviewWidth = 240 + PreviewHeight = 60 + FontTypes = [ftTrueTypeAnsi, ftTrueTypeSymbol] + ShowPreview = False + ShowPreviewFontName = False + ShowPreviewInList = False + end end diff --git a/developer/src/tike/dialogs/UfrmKeyboardFonts.pas b/developer/src/tike/dialogs/UfrmKeyboardFonts.pas index 8c5bc103c2..7f5d4546bd 100644 --- a/developer/src/tike/dialogs/UfrmKeyboardFonts.pas +++ b/developer/src/tike/dialogs/UfrmKeyboardFonts.pas @@ -66,6 +66,10 @@ type fcbTouchLayoutPhone: TscFontComboBox; fcbTouchLayoutTablet: TscFontComboBox; fcbTouchLayoutDesktop: TscFontComboBox; + lblDisplayMap: TLabel; + editDisplayMapSize: TEdit; + fcbDisplayMap: TscFontComboBox; + Label4: TLabel; procedure FormCreate(Sender: TObject); procedure cmdOKClick(Sender: TObject); private @@ -120,6 +124,10 @@ begin FControls[kfontTouchLayoutDesktop].CaptionLabel := lblTouchLayoutDesktopFont; FControls[kfontTouchLayoutDesktop].NameCombo := fcbTouchLayoutDesktop; FControls[kfontTouchLayoutDesktop].SizeEdit := editTouchLayoutDesktopSize; + + FControls[kfontDisplayMap].CaptionLabel := lblDisplayMap; + FControls[kfontDisplayMap].NameCombo := fcbDisplayMap; + FControls[kfontDisplayMap].SizeEdit := editDisplayMapSize; end; function TfrmKeyboardFonts.GetFontInfo(Index: TKeyboardFont): TKeyboardFontInfo; diff --git a/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas b/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas index 863b737dc0..10e9dcdd3c 100644 --- a/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas +++ b/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas @@ -200,7 +200,7 @@ end; function TkmnProjectFileUI.TestKeymanWeb(FSilent: Boolean): Boolean; // I4409 var - FCompiledName: string; + FCompiledName, OSKFont: string; editor: TfrmTikeEditor; wizard: TfrmKeymanWizard; i: TKeyboardFont; @@ -250,7 +250,7 @@ begin // We register all fonts that are used by the layout, // but just once for each reference! - for i := kfontChar to kfontTouchLayoutDesktop do + for i := kfontChar to kfontDisplayMap do begin Found := False; for j := kfontChar to TKeyboardFont(Ord(i)-1) do @@ -265,13 +265,18 @@ begin if TServerUI.VerifyServerRunning then begin + if Wizard.FontInfo[kfontDisplayMap].Enabled then + begin + OSKFont := Wizard.FontInfo[kfontDisplayMap].Name + end + else + OSKFont := Wizard.FontInfo[kfontOSK].Name; + TServerDebugAPI.RegisterKeyboard( FCompiledName, ProjectFile.FileVersion, - // We only need to specify the char + osk fonts here - // as the others are referenced in the touch layout definition directly Wizard.FontInfo[kfontChar].Name, - Wizard.FontInfo[kfontOSK].Name + OSKFont ); wizard.NotifyStartedWebDebug; // I4021 From 2467e1dd1fb9749ea8cb8ef7d2dd23ca39fb521f Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Fri, 17 Jan 2025 17:20:10 +1000 Subject: [PATCH 034/155] feat(windows): check update use statemachine Also the first time remoteupdate check config runs it needs to return true if the 'last update time' registry entry does not exist. --- .../main/Keyman.System.RemoteUpdateCheck.pas | 5 ++--- windows/src/desktop/kmshell/main/UfrmMain.pas | 14 ++++++-------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.RemoteUpdateCheck.pas b/windows/src/desktop/kmshell/main/Keyman.System.RemoteUpdateCheck.pas index df892929f0..55dde4eb1a 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.RemoteUpdateCheck.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.RemoteUpdateCheck.pas @@ -239,9 +239,8 @@ begin begin Exit; end; - if Registry.ValueExists(SRegValue_LastUpdateCheckTime) and - (Now - Registry.ReadDateTime(SRegValue_LastUpdateCheckTime) > - CheckPeriod) then + if (not Registry.ValueExists(SRegValue_LastUpdateCheckTime)) or + ((Now - Registry.ReadDateTime(SRegValue_LastUpdateCheckTime)) > CheckPeriod) then begin Result := True; end; diff --git a/windows/src/desktop/kmshell/main/UfrmMain.pas b/windows/src/desktop/kmshell/main/UfrmMain.pas index 86df47ec70..394cb09377 100644 --- a/windows/src/desktop/kmshell/main/UfrmMain.pas +++ b/windows/src/desktop/kmshell/main/UfrmMain.pas @@ -188,7 +188,7 @@ uses MessageIdentifiers, Keyman.System.ExecutionHistory, Keyman.System.KeymanSentryClient, - Keyman.System.RemoteUpdateCheck, + Keyman.System.UpdateStateMachine, OptionsXMLRenderer, Keyman.Configuration.System.UmodWebHttpServer, Keyman.Configuration.System.HttpServer.App.ConfigMain, @@ -800,16 +800,14 @@ begin end; procedure TfrmMain.Update_CheckNow; -// TODO: epic-windows-update -// Get an instance to the state machine and call handle check so the state can change to update -// available. -var UpdateCheck : TRemoteUpdateCheck; +var + BUpdateSM : TUpdateStateMachine; begin - UpdateCheck := TRemoteUpdateCheck.Create(True); + BUpdateSM := TUpdateStateMachine.Create(False); try - UpdateCheck.Run; + BUpdateSM.HandleCheck; finally - UpdateCheck.Free; + BUpdateSM.Free; end; DoRefresh; end; From 8e24d8a89683f8d4f2d04cf7d14bd0d2247eac60 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Fri, 17 Jan 2025 21:09:49 +1000 Subject: [PATCH 035/155] feat(windows): compare class instead of string name --- .../desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index 80fbf08634..c77510af6c 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -567,7 +567,7 @@ function TUpdateStateMachine.ReadyToInstall: Boolean; begin if not IsCurrentStateAssigned then Exit(False); - if (CurrentState.ClassName = 'WaitingRestartState') and not HasKeymanRun then + if (CurrentState is WaitingRestartState) and not HasKeymanRun then Result := True else Result := False; From 1ed44014d96a7b9c3bf8354ff46d6000194aef7f Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 17 Jan 2025 13:01:57 -0500 Subject: [PATCH 036/155] auto: increment master version to 18.0.171 --- HISTORY.md | 7 +++++++ VERSION.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 78352f95e5..2940491b3a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,12 @@ # Keyman Version History +## 18.0.170 alpha 2025-01-17 + +* chore(linux): update copyright year (#12918) +* fix(web): patch unit test with execution dependent on autocorrect state (#12940) +* test(common/web): unit tests for element-string (#12811) +* chore(linux): Update debian changelog (#12917) + ## 18.0.169 alpha 2025-01-17 * chore(windows): remove `postinstall` state from mermaid diagram (#12923) diff --git a/VERSION.md b/VERSION.md index df7920cb67..d4aee009e5 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.170 \ No newline at end of file +18.0.171 \ No newline at end of file From 548866e1a519539b7fd5299ebd6d0b86dc3759fe Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Sat, 18 Jan 2025 13:01:28 -0500 Subject: [PATCH 037/155] auto: increment master version to 18.0.172 --- HISTORY.md | 5 +++++ VERSION.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 2940491b3a..6d02a97e26 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # Keyman Version History +## 18.0.171 alpha 2025-01-18 + +* fix(common/web): add StrsItem.isEqual() method (#12868) +* fix(common/web): handle invalid order and tertiary arguments to ElementString.fromString() (#12882) + ## 18.0.170 alpha 2025-01-17 * chore(linux): update copyright year (#12918) diff --git a/VERSION.md b/VERSION.md index d4aee009e5..02da667937 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.171 \ No newline at end of file +18.0.172 \ No newline at end of file From 5c1a15591adf28dfb3ec2b94195e20460a4fe575 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Sun, 19 Jan 2025 13:01:08 -0500 Subject: [PATCH 038/155] auto: increment master version to 18.0.173 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 71c44403a8..be484aee8b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 18.0.172 alpha 2025-01-19 + +* chore(common): Add 17.0.333 to version history (#12926) + ## 18.0.171 alpha 2025-01-18 * fix(common/web): add StrsItem.isEqual() method (#12868) diff --git a/VERSION.md b/VERSION.md index 02da667937..5f77e86146 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.172 \ No newline at end of file +18.0.173 \ No newline at end of file From f1f30b95ad11af4cc72b447083415066f9b36217 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 20 Jan 2025 11:45:11 +1000 Subject: [PATCH 039/155] fix(windows): handle keyboard package not downloaded If the keyboard package to be installed is not found. log to sentry and keep installing other packages. No longer crashes. --- .../kmshell/main/Keyman.System.UpdateStateMachine.pas | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index 80fbf08634..eeff4d2792 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -1021,9 +1021,16 @@ begin for i := 0 to High(Params.Packages) do begin PackageFullPath := SavePath + Params.Packages[i].FileName; + if not FileExists(PackageFullPath) then + begin + TKeymanSentryClient.Client.MessageEvent(Sentry.Client.SENTRY_LEVEL_ERROR, + 'File does not exist:"' + PackageFullPath + '"'); + Continue; + end; if not DoInstallPackage(PackageFullPath) then // I2742 begin - KL.Log('Installing Package failed' + PackageFullPath); + TKeymanSentryClient.Client.MessageEvent(Sentry.Client.SENTRY_LEVEL_ERROR, + 'Installing Package failed"' + PackageFullPath + '"'); end; end; Result := True; From 45a6291a3e34c43b51bd0563bdac8233c74200f9 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 20 Jan 2025 09:19:47 +0700 Subject: [PATCH 040/155] refactor(developer): move ttfInfo to developer-utils We will need ttfInfo in kmc-package, so move it to the shared module. --- .../web/utils}/src/font-family.ts | 27 +++++++++++++++++++ developer/src/common/web/utils/src/index.ts | 4 ++- .../web/utils}/src/ttfmeta/LICENSE | 0 .../web/utils}/src/ttfmeta/README.md | 0 .../web/utils}/src/ttfmeta/lib/index.js | 16 ++++++++++- .../web/utils}/src/ttfmeta/lib/main.js | 10 +++++++ .../web/utils}/src/ttfmeta/lib/meta.js | 0 .../web/utils}/src/ttfmeta/test/local.mjs | 0 .../utils}/src/ttfmeta/test/mocha-index.mjs | 0 developer/src/common/web/utils/tsconfig.json | 4 +++ .../src/keyboard-info-compiler.ts | 2 +- .../test/font-family.tests.ts | 2 +- developer/src/kmc-keyboard-info/tsconfig.json | 1 - 13 files changed, 61 insertions(+), 5 deletions(-) rename developer/src/{kmc-keyboard-info => common/web/utils}/src/font-family.ts (51%) rename developer/src/{kmc-keyboard-info => common/web/utils}/src/ttfmeta/LICENSE (100%) rename developer/src/{kmc-keyboard-info => common/web/utils}/src/ttfmeta/README.md (100%) rename developer/src/{kmc-keyboard-info => common/web/utils}/src/ttfmeta/lib/index.js (73%) rename developer/src/{kmc-keyboard-info => common/web/utils}/src/ttfmeta/lib/main.js (97%) rename developer/src/{kmc-keyboard-info => common/web/utils}/src/ttfmeta/lib/meta.js (100%) rename developer/src/{kmc-keyboard-info => common/web/utils}/src/ttfmeta/test/local.mjs (100%) rename developer/src/{kmc-keyboard-info => common/web/utils}/src/ttfmeta/test/mocha-index.mjs (100%) diff --git a/developer/src/kmc-keyboard-info/src/font-family.ts b/developer/src/common/web/utils/src/font-family.ts similarity index 51% rename from developer/src/kmc-keyboard-info/src/font-family.ts rename to developer/src/common/web/utils/src/font-family.ts index a78e341de7..d8fad53e37 100644 --- a/developer/src/kmc-keyboard-info/src/font-family.ts +++ b/developer/src/common/web/utils/src/font-family.ts @@ -24,5 +24,32 @@ export async function getFontFamily(source: Uint8Array) { return null; } + return font.meta.property.find(prop => prop.name == 'font-family')?.text ?? null; +} + +/** + * Extracts the font-family from an in-memory TTF or WOFF blob in `source` + * parameter. + * + * @param source In-memory TTF or WOFF font blob + * + * @throws Uncaught exceptions from ttfMeta.promise if the font file is invalid. + * + * @returns If the file is invalid or cannot be parsed, returns `null`, + * otherwise returns the font family as a string. + */ +export function getFontFamilySync(source: Uint8Array) { + /* c8 ignore next 3 */ + if(!source) { + return null; + } + + const buffer = Buffer.from(source); + const font = ttfMeta.ttfInfoSync(buffer); + /* c8 ignore next 3 */ + if(!font) { + return null; + } + return font.meta.property.find(prop => prop.name == 'font-family')?.text ?? null; } \ No newline at end of file diff --git a/developer/src/common/web/utils/src/index.ts b/developer/src/common/web/utils/src/index.ts index 290efd5fc7..19845f0e8f 100644 --- a/developer/src/common/web/utils/src/index.ts +++ b/developer/src/common/web/utils/src/index.ts @@ -68,4 +68,6 @@ export * as SourceFilenamePatterns from './source-filename-patterns.js'; export { KeymanXMLType, KeymanXMLWriter, KeymanXMLReader } from './xml-utils.js'; export * as GitHubUrls from './github-urls.js'; -export * as CloudUrls from './cloud-urls.js'; \ No newline at end of file +export * as CloudUrls from './cloud-urls.js'; + +export { getFontFamily, getFontFamilySync } from './font-family.js'; \ No newline at end of file diff --git a/developer/src/kmc-keyboard-info/src/ttfmeta/LICENSE b/developer/src/common/web/utils/src/ttfmeta/LICENSE similarity index 100% rename from developer/src/kmc-keyboard-info/src/ttfmeta/LICENSE rename to developer/src/common/web/utils/src/ttfmeta/LICENSE diff --git a/developer/src/kmc-keyboard-info/src/ttfmeta/README.md b/developer/src/common/web/utils/src/ttfmeta/README.md similarity index 100% rename from developer/src/kmc-keyboard-info/src/ttfmeta/README.md rename to developer/src/common/web/utils/src/ttfmeta/README.md diff --git a/developer/src/kmc-keyboard-info/src/ttfmeta/lib/index.js b/developer/src/common/web/utils/src/ttfmeta/lib/index.js similarity index 73% rename from developer/src/kmc-keyboard-info/src/ttfmeta/lib/index.js rename to developer/src/common/web/utils/src/ttfmeta/lib/index.js index eb94d53c1f..53972297f1 100644 --- a/developer/src/kmc-keyboard-info/src/ttfmeta/lib/index.js +++ b/developer/src/common/web/utils/src/ttfmeta/lib/index.js @@ -31,6 +31,20 @@ export function ttfInfo(pathOrData, callback) { } } +/** + * @namespace + * @param {string | number | Buffer | URL} pathOrData + * @returns {typeof ttf.result} + */ +export function ttfInfoSync(pathOrData) { + if (pathOrData instanceof Buffer) { + return ttf.ttfInfoSync(ttf.view(pathOrData)); + } else { + const data = fs.readFileSync(pathOrData); + return ttf.ttfInfoSync(ttf.view(data)); + } +} + /** * @param {string | number | Buffer | URL} pathOrData * @returns {Promise} @@ -48,5 +62,5 @@ export function promise(pathOrData) { } /** @namespace */ -export const ttfMeta = { ttfInfo, promise }; +export const ttfMeta = { ttfInfo, ttfInfoSync, promise }; export default ttfMeta; diff --git a/developer/src/kmc-keyboard-info/src/ttfmeta/lib/main.js b/developer/src/common/web/utils/src/ttfmeta/lib/main.js similarity index 97% rename from developer/src/kmc-keyboard-info/src/ttfmeta/lib/main.js rename to developer/src/common/web/utils/src/ttfmeta/lib/main.js index 239a6244dc..a952512f26 100644 --- a/developer/src/kmc-keyboard-info/src/ttfmeta/lib/main.js +++ b/developer/src/common/web/utils/src/ttfmeta/lib/main.js @@ -300,6 +300,16 @@ export function ttfInfo(data, callback) { } } +/** + * @namespace + * @param {*} data + * @returns {typeof result} + */ +export function ttfInfoSync(data) { + resultTables(data); + return result; +} + /** * @param {string | number | Buffer | URL | DataView} pathOrData * @returns {Promise} diff --git a/developer/src/kmc-keyboard-info/src/ttfmeta/lib/meta.js b/developer/src/common/web/utils/src/ttfmeta/lib/meta.js similarity index 100% rename from developer/src/kmc-keyboard-info/src/ttfmeta/lib/meta.js rename to developer/src/common/web/utils/src/ttfmeta/lib/meta.js diff --git a/developer/src/kmc-keyboard-info/src/ttfmeta/test/local.mjs b/developer/src/common/web/utils/src/ttfmeta/test/local.mjs similarity index 100% rename from developer/src/kmc-keyboard-info/src/ttfmeta/test/local.mjs rename to developer/src/common/web/utils/src/ttfmeta/test/local.mjs diff --git a/developer/src/kmc-keyboard-info/src/ttfmeta/test/mocha-index.mjs b/developer/src/common/web/utils/src/ttfmeta/test/mocha-index.mjs similarity index 100% rename from developer/src/kmc-keyboard-info/src/ttfmeta/test/mocha-index.mjs rename to developer/src/common/web/utils/src/ttfmeta/test/mocha-index.mjs diff --git a/developer/src/common/web/utils/tsconfig.json b/developer/src/common/web/utils/tsconfig.json index 6f96f75ee7..362ec3a972 100644 --- a/developer/src/common/web/utils/tsconfig.json +++ b/developer/src/common/web/utils/tsconfig.json @@ -5,8 +5,12 @@ "rootDir": ".", "outDir": "./build/", "baseUrl": ".", + + /** for ttfmeta */ + "allowJs": true, }, "include": [ "src/**/*.ts", + "src/ttfmeta/lib/*.js", ], } diff --git a/developer/src/kmc-keyboard-info/src/keyboard-info-compiler.ts b/developer/src/kmc-keyboard-info/src/keyboard-info-compiler.ts index ee784429b9..3e1db45aed 100644 --- a/developer/src/kmc-keyboard-info/src/keyboard-info-compiler.ts +++ b/developer/src/kmc-keyboard-info/src/keyboard-info-compiler.ts @@ -12,7 +12,7 @@ import { CompilerCallbacks, KeymanCompiler, CompilerOptions, KeymanCompilerResul import { KmpCompiler } from "@keymanapp/kmc-package"; import { SchemaValidators } from "@keymanapp/common-types"; -import { getFontFamily } from "./font-family.js"; +import { getFontFamily } from "@keymanapp/developer-utils"; const regionNames = new Intl.DisplayNames(['en'], { type: "region" }); const scriptNames = new Intl.DisplayNames(['en'], { type: "script" }); diff --git a/developer/src/kmc-keyboard-info/test/font-family.tests.ts b/developer/src/kmc-keyboard-info/test/font-family.tests.ts index b27fad8d74..d926e75c65 100644 --- a/developer/src/kmc-keyboard-info/test/font-family.tests.ts +++ b/developer/src/kmc-keyboard-info/test/font-family.tests.ts @@ -2,7 +2,7 @@ import * as fs from 'fs'; import { assert } from 'chai'; import 'mocha'; import { makePathToFixture } from './helpers/index.js'; -import { getFontFamily } from '../src/font-family.js'; +import { getFontFamily } from '@keymanapp/developer-utils'; const AFGHAN_TURKMEN_DISPLAY_FONT = makePathToFixture('afghan_turkmen', "Lateef-Regular.ttf"); const AFGHAN_TURKMEN_OSK_FONT = makePathToFixture('afghan_turkmen', "Lateef-Bold.ttf"); diff --git a/developer/src/kmc-keyboard-info/tsconfig.json b/developer/src/kmc-keyboard-info/tsconfig.json index d09b25c560..124c812ecf 100644 --- a/developer/src/kmc-keyboard-info/tsconfig.json +++ b/developer/src/kmc-keyboard-info/tsconfig.json @@ -13,7 +13,6 @@ }, "include": [ "src/**/*.ts", - "src/ttfmeta/lib/*.js", "src/imports/langtags.js", ], "references": [ From 0b749a5df2b9b3b7aca1d493cf93017ee0ca8af5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 20 Jan 2025 09:21:50 +0700 Subject: [PATCH 041/155] feat(developer): rewrite font data in .kvk from package metadata When compiling a package, rewrite the font data in embedded .kvk files to use the facename from the font referenced in OSKFont or DisplayFont. This also does some safety checking for cross-references of the .kvk, and the font data. Fixes: #12912 --- .../kmc-package/src/compiler/kmp-compiler.ts | 113 ++++++++++++++---- .../src/compiler/kvk-font-facename.ts | 16 +++ .../src/compiler/package-compiler-messages.ts | 20 ++++ 3 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 developer/src/kmc-package/src/compiler/kvk-font-facename.ts diff --git a/developer/src/kmc-package/src/compiler/kmp-compiler.ts b/developer/src/kmc-package/src/compiler/kmp-compiler.ts index 607823c7dd..ca15cae14d 100644 --- a/developer/src/kmc-package/src/compiler/kmp-compiler.ts +++ b/developer/src/kmc-package/src/compiler/kmp-compiler.ts @@ -18,6 +18,8 @@ import { PackageKeyboardTargetValidator } from './package-keyboard-target-valida import { PackageMetadataUpdater } from './package-metadata-updater.js'; import { markdownToHTML } from './markdown.js'; import { PackageValidation } from './package-validation.js'; +import { getFontFamilySync } from "@keymanapp/developer-utils"; +import { setKvkFontData } from './kvk-font-facename.js'; const KMP_JSON_FILENAME = 'kmp.json'; const KMP_INF_FILENAME = 'kmp.inf'; @@ -483,36 +485,35 @@ export class KmpCompiler implements KeymanCompiler { this.callbacks.reportMessage(PackageCompilerMessages.Warn_AbsolutePath({filename: filename})); } + let memberFileData = this.getMemberFileData(kpsFilename, filename); + if(!memberFileData) { + failed = true; + return; + } filename = this.callbacks.resolveFilename(kpsFilename, filename); const basename = this.callbacks.path.basename(filename); - if(!this.callbacks.fs.existsSync(filename)) { - this.callbacks.reportMessage(PackageCompilerMessages.Error_FileDoesNotExist({filename: filename})); - failed = true; - return; + if(KeymanFileTypes.filenameIs(filename, KeymanFileTypes.Binary.VisualKeyboard)) { + if(!this.isKvkFileBinary(memberFileData)) { + this.callbacks.reportMessage(PackageCompilerMessages.Warn_FileIsNotABinaryKvkFile({filename: filename})); + } else { + memberFileData = this.setKvkFontData(kpsFilename, data, filename, memberFileData); + } } - let memberFileData; - try { - memberFileData = this.callbacks.loadFile(filename); - } catch(e) { - this.callbacks.reportMessage(PackageCompilerMessages.Error_FileCouldNotBeRead({filename: filename, e: e})); - failed = true; - return; - } - - this.warnIfKvkFileIsNotBinary(filename, memberFileData); - zip.file(basename, memberFileData); - - // Remove path data from files before JSON save - value.name = basename; }); if(failed) { return null; } + data.files.forEach((value) => { + const basename = this.callbacks.path.basename(value.name); + // Remove path data from files before JSON save + value.name = basename; + }); + // TODO #9477: transform .md to .htm // Remove path data from file references in options @@ -557,26 +558,88 @@ export class KmpCompiler implements KeymanCompiler { return transcodeToCP1252(s); } + private getMemberFileData(kpsFilename: string, filename: string) { + filename = this.callbacks.resolveFilename(kpsFilename, filename); + + if(!this.callbacks.fs.existsSync(filename)) { + this.callbacks.reportMessage(PackageCompilerMessages.Error_FileDoesNotExist({filename: filename})); + return null; + } + + try { + return this.callbacks.loadFile(filename); + } catch(e) { + this.callbacks.reportMessage(PackageCompilerMessages.Error_FileCouldNotBeRead({filename: filename, e: e})); + return null; + } + } + + private setKvkFontData(kpsFilename: string, data: KmpJsonFile.KmpJsonFile, filename: string, kvk: Uint8Array) { + // find the appropriate font to set + const kvkId = this.callbacks.path.basename(filename.toLowerCase(), '.kvk'); + const kbd = data.keyboards.find(k => k.id == kvkId); + if(!kbd) { + // cannot find a matching keyboard + this.callbacks.reportMessage(PackageCompilerMessages.Warn_CannotFindMatchingKeyboardForVisualKeyboard({filename})); + return kvk; + } + const fontFilename = kbd.oskFont || kbd.displayFont; + if(!fontFilename) { + // no font data to set + return kvk; + } + + // Look up the full font filename + const fontFile = data.files.find(file => this.callbacks.path.basename(file.name.toLowerCase()) == fontFilename.toLowerCase()); + if(!fontFile) { + // font cannot be found + this.callbacks.reportMessage(PackageCompilerMessages.Warn_CannotFindFontForKeyboard({id: kbd.id, fontFilename})); + return kvk; + } + + // the font is a filename, included in the .kps + const fontData = this.getMemberFileData(kpsFilename, fontFile.name); + if(!fontData) { + // cannot find source font + this.callbacks.reportMessage(PackageCompilerMessages.Warn_CannotFindFontForKeyboard({id: kbd.id, fontFilename: fontFile.name})); + return kvk; + } + + const fontFacename = getFontFamilySync(fontData); + if(!fontFacename) { + // Font facename could not be extracted from ttf + this.callbacks.reportMessage(PackageCompilerMessages.Warn_CannotReadFont({fontFilename: fontFile.name})); + return kvk; + } + + const result = setKvkFontData(kvk, fontFacename); + if(!result) { + // KVK is invalid + this.callbacks.reportMessage(PackageCompilerMessages.Warn_VisualKeyboardFileIsInvalid({filename})); + return kvk; + } + + return result; + } + /** * Legacy .kmp compiler would transform xml-format .kvk files into a binary .kvk file; now * we want that to remain the responsibility of the keyboard compiler, so we'll warn the * few users who are still doing this */ - private warnIfKvkFileIsNotBinary(filename: string, data: Uint8Array) { - if(!KeymanFileTypes.filenameIs(filename, KeymanFileTypes.Binary.VisualKeyboard)) { - return; - } - + private isKvkFileBinary(data: Uint8Array) { if(data.byteLength < 4) { // TODO: Not a valid .kvk file; should we be reporting this? - return; + return false; } + // Must start with 'KVKF' if(data[0] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[0] || data[1] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[1] || data[2] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[2] || data[3] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[3]) { - this.callbacks.reportMessage(PackageCompilerMessages.Warn_FileIsNotABinaryKvkFile({filename: filename})); + return false; } + return true; } } diff --git a/developer/src/kmc-package/src/compiler/kvk-font-facename.ts b/developer/src/kmc-package/src/compiler/kvk-font-facename.ts new file mode 100644 index 0000000000..b7c69da8e8 --- /dev/null +++ b/developer/src/kmc-package/src/compiler/kvk-font-facename.ts @@ -0,0 +1,16 @@ +import { KvkFileReader, KvkFileWriter } from "@keymanapp/common-types"; + +export function setKvkFontData(fileData: Uint8Array, fontFacename: string) { + const reader = new KvkFileReader(); + const kvk = reader.read(fileData); + if(!kvk) { + // kvk is invalid + return null; + } + + kvk.header.ansiFont.name = fontFacename; + kvk.header.unicodeFont.name = fontFacename; + + const writer = new KvkFileWriter(); + return writer.write(kvk); +} \ No newline at end of file diff --git a/developer/src/kmc-package/src/compiler/package-compiler-messages.ts b/developer/src/kmc-package/src/compiler/package-compiler-messages.ts index 9a593a3a11..6545b7d963 100644 --- a/developer/src/kmc-package/src/compiler/package-compiler-messages.ts +++ b/developer/src/kmc-package/src/compiler/package-compiler-messages.ts @@ -164,5 +164,25 @@ export class PackageCompilerMessages { static Error_RequiredParameterMissing = (o:{param: string}) => m( this.ERROR_RequiredParameterMissing, `Source parameter '${def(o.param)}' is required.` ); + + static WARN_CannotFindMatchingKeyboardForVisualKeyboard = SevWarn | 0x0023; + static Warn_CannotFindMatchingKeyboardForVisualKeyboard = (o:{filename: string}) => m( + this.WARN_CannotFindMatchingKeyboardForVisualKeyboard, `Cannot find matching keyboard for visual keyboard file '${def(o.filename)}'.` + ); + + static WARN_CannotFindFontForKeyboard = SevWarn | 0x0024; + static Warn_CannotFindFontForKeyboard = (o:{id: string, fontFilename: string}) => m( + this.WARN_CannotFindFontForKeyboard, `Cannot find font file '${def(o.fontFilename)}' for keyboard '${def(o.id)}'.` + ); + + static WARN_CannotReadFont = SevWarn | 0x0025; + static Warn_CannotReadFont = (o:{fontFilename: string}) => m( + this.WARN_CannotReadFont, `Cannot parse font file '${def(o.fontFilename)}' to get facename.` + ); + + static WARN_VisualKeyboardFileIsInvalid = SevWarn | 0x0026; + static Warn_VisualKeyboardFileIsInvalid = (o:{filename: string}) => m( + this.WARN_VisualKeyboardFileIsInvalid, `Visual keyboard file '${def(o.filename)}' is invalid.` + ); } From d24f3477bd6fab8021b0ae613c32456cf43e0b4f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 20 Jan 2025 10:06:25 +0700 Subject: [PATCH 042/155] chore(developer): update binary_kvk_file test to make .kps more valid The test .kps for binary_kvk_file tests was not very coherent, which meant that it failed with the changes and additional consistency checking included in this PR. --- .../binary_kvk_file/source/binary_kvk_file.kmx | Bin 0 -> 352 bytes .../binary_kvk_file/source/binary_kvk_file.kps | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 developer/src/kmc-package/test/fixtures/binary_kvk_file/source/binary_kvk_file.kmx diff --git a/developer/src/kmc-package/test/fixtures/binary_kvk_file/source/binary_kvk_file.kmx b/developer/src/kmc-package/test/fixtures/binary_kvk_file/source/binary_kvk_file.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bd6b832cab772d03a45460e6c982d79772a9ab6e GIT binary patch literal 352 zcmZvYyAAdPzftU-(5_7TAk3e<2#yh{6J%lpJ>i; zp8cfbGTcz0i3ZwI$I5E289asBOpaP`wxny)?MPoMtp7qQ?)E9)e`0JAA>To*E2jVe literal 0 HcmV?d00001 diff --git a/developer/src/kmc-package/test/fixtures/binary_kvk_file/source/binary_kvk_file.kps b/developer/src/kmc-package/test/fixtures/binary_kvk_file/source/binary_kvk_file.kps index de17212a84..1a02984beb 100644 --- a/developer/src/kmc-package/test/fixtures/binary_kvk_file/source/binary_kvk_file.kps +++ b/developer/src/kmc-package/test/fixtures/binary_kvk_file/source/binary_kvk_file.kps @@ -27,7 +27,7 @@ .kvk - ../../invalid/basic.kmx + binary_kvk_file.kmx Keyboard Basic 0 .kmx @@ -36,7 +36,7 @@ Basic - basic + binary_kvk_file 1.0 Khmer From 11d92be941125981e79477b4fdc85b2f6af4f5b8 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 20 Jan 2025 10:25:56 +0700 Subject: [PATCH 043/155] chore: address review comments --- developer/src/kmc-package/src/compiler/kmp-compiler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/developer/src/kmc-package/src/compiler/kmp-compiler.ts b/developer/src/kmc-package/src/compiler/kmp-compiler.ts index ca15cae14d..cd6cf6df36 100644 --- a/developer/src/kmc-package/src/compiler/kmp-compiler.ts +++ b/developer/src/kmc-package/src/compiler/kmp-compiler.ts @@ -495,6 +495,7 @@ export class KmpCompiler implements KeymanCompiler { if(KeymanFileTypes.filenameIs(filename, KeymanFileTypes.Binary.VisualKeyboard)) { if(!this.isKvkFileBinary(memberFileData)) { + // warn the few users who are still doing this -- non-binary .kvk should not be included in package! this.callbacks.reportMessage(PackageCompilerMessages.Warn_FileIsNotABinaryKvkFile({filename: filename})); } else { memberFileData = this.setKvkFontData(kpsFilename, data, filename, memberFileData); @@ -624,8 +625,7 @@ export class KmpCompiler implements KeymanCompiler { /** * Legacy .kmp compiler would transform xml-format .kvk files into a binary .kvk file; now - * we want that to remain the responsibility of the keyboard compiler, so we'll warn the - * few users who are still doing this + * we want that to remain the responsibility of the keyboard compiler. */ private isKvkFileBinary(data: Uint8Array) { if(data.byteLength < 4) { From 7d1b71466d25620ceff6ae1220ba520a620f7ea9 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 20 Jan 2025 15:19:25 +1000 Subject: [PATCH 044/155] feat(windows): guard for keyboard package --- .../desktop/kmshell/main/BackgroundUpdateStateDiagram.md | 1 - .../kmshell/main/Keyman.System.UpdateStateMachine.pas | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/windows/src/desktop/kmshell/main/BackgroundUpdateStateDiagram.md b/windows/src/desktop/kmshell/main/BackgroundUpdateStateDiagram.md index 1ff6f91b9d..160d54b2c1 100644 --- a/windows/src/desktop/kmshell/main/BackgroundUpdateStateDiagram.md +++ b/windows/src/desktop/kmshell/main/BackgroundUpdateStateDiagram.md @@ -9,4 +9,3 @@ stateDiagram Installing --> PostInstall PostInstall --> Idle ``` -State Transition matrix diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index c77510af6c..725fae67e6 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -1021,9 +1021,16 @@ begin for i := 0 to High(Params.Packages) do begin PackageFullPath := SavePath + Params.Packages[i].FileName; + if not FileExists(PackageFullPath) then + begin + TKeymanSentryClient.Client.MessageEvent(Sentry.Client.SENTRY_LEVEL_ERROR, + 'File does not exist:"' + PackageFullPath + '"'); + Continue; + end; if not DoInstallPackage(PackageFullPath) then // I2742 begin - KL.Log('Installing Package failed' + PackageFullPath); + TKeymanSentryClient.Client.MessageEvent(Sentry.Client.SENTRY_LEVEL_ERROR, + 'Installing Package failed"' + PackageFullPath + '"'); end; end; Result := True; From 4477808b81582faa078d0297a239e5c9eea238bd Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 20 Jan 2025 15:52:12 +1000 Subject: [PATCH 045/155] fix(windows): remove select check boxes from update tab It doesn't make sense to have the update tab have check boxes for de-selecting keyboards to update, because the auto update will go ahead and update them anyway. --- windows/src/desktop/kmshell/xml/config.css | 4 ++-- windows/src/desktop/kmshell/xml/keyman_update.xsl | 13 ------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/windows/src/desktop/kmshell/xml/config.css b/windows/src/desktop/kmshell/xml/config.css index e452cca5b8..9dd12f7d06 100644 --- a/windows/src/desktop/kmshell/xml/config.css +++ b/windows/src/desktop/kmshell/xml/config.css @@ -502,8 +502,8 @@ table tr .grid_container_update { display: grid; position: relative; - grid-template-columns: 50px 1fr 1fr 1fr; - margin: 10px 50px 10px 64px; + grid-template-columns: 1fr 1fr 1fr; + margin: 15px 50px 15px 64px; /* From https://geary.co/internal-borders-css-grid/ */ overflow: hidden; gap: var(--gap); diff --git a/windows/src/desktop/kmshell/xml/keyman_update.xsl b/windows/src/desktop/kmshell/xml/keyman_update.xsl index 0daa6ace3b..1222fc5619 100644 --- a/windows/src/desktop/kmshell/xml/keyman_update.xsl +++ b/windows/src/desktop/kmshell/xml/keyman_update.xsl @@ -31,7 +31,6 @@
-
Select
@@ -74,18 +73,6 @@ - -
- - javascript:updateTick(""); - Update_ - checked - Update_ - - - Update__RequiresAdmin - -
From 31b7b542e1767060b1483b6794313778ae0320d7 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 20 Jan 2025 16:02:46 +1000 Subject: [PATCH 046/155] fix(windows): missed file in commit update layout --- windows/src/desktop/kmshell/xml/config.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/src/desktop/kmshell/xml/config.css b/windows/src/desktop/kmshell/xml/config.css index 9dd12f7d06..1c97ee3858 100644 --- a/windows/src/desktop/kmshell/xml/config.css +++ b/windows/src/desktop/kmshell/xml/config.css @@ -503,7 +503,7 @@ table tr display: grid; position: relative; grid-template-columns: 1fr 1fr 1fr; - margin: 15px 50px 15px 64px; + margin: 15px 50px 15px 59px; /* From https://geary.co/internal-borders-css-grid/ */ overflow: hidden; gap: var(--gap); From f407d9823d534d496ce8ddafd7bf8da237bd9192 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 20 Jan 2025 13:06:01 +0700 Subject: [PATCH 047/155] fix(developer): include developer-utils deps in server build Fixes: #12950 --- developer/src/server/build.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/developer/src/server/build.sh b/developer/src/server/build.sh index c73ed853f7..65f38dd8df 100755 --- a/developer/src/server/build.sh +++ b/developer/src/server/build.sh @@ -113,7 +113,17 @@ function installer_server() { # monorepo context cat package.json | "$JQ" \ '. | del(.devDependencies."@keymanapp/resources-gosh") | del(.devDependencies."@keymanapp/keyman-version") | del(.dependencies."@keymanapp/developer-utils")' \ + > "$PRODBUILDTEMP/package0.json" + + # #12950: Merge dependencies from @keymanapp/developer-utils and Server; this + # is a bit messy but will mean we don't lose the needed dependencies. + jq -s '.[0] + { dependencies: (.[1].dependencies * .[0].dependencies) }' "$PRODBUILDTEMP/package0.json" \ + "$KEYMAN_ROOT/developer/src/common/web/utils/package.json" > "$PRODBUILDTEMP/package1.json" + cat $PRODBUILDTEMP/package1.json | "$JQ" \ + '. | del(.dependencies."@keymanapp/common-types")' \ > "$PRODBUILDTEMP/package.json" + rm "$PRODBUILDTEMP/package0.json" + rm "$PRODBUILDTEMP/package1.json" pushd "$PRODBUILDTEMP" npm install --omit=dev --omit=optional From 357d1961819bf8d725f484e39cefe744d776d71e Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 20 Jan 2025 14:11:42 +0700 Subject: [PATCH 048/155] chore(developer): use JQ variable in script --- developer/src/server/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/src/server/build.sh b/developer/src/server/build.sh index 65f38dd8df..e0e82e3617 100755 --- a/developer/src/server/build.sh +++ b/developer/src/server/build.sh @@ -117,7 +117,7 @@ function installer_server() { # #12950: Merge dependencies from @keymanapp/developer-utils and Server; this # is a bit messy but will mean we don't lose the needed dependencies. - jq -s '.[0] + { dependencies: (.[1].dependencies * .[0].dependencies) }' "$PRODBUILDTEMP/package0.json" \ + "$JQ" -s '.[0] + { dependencies: (.[1].dependencies * .[0].dependencies) }' "$PRODBUILDTEMP/package0.json" \ "$KEYMAN_ROOT/developer/src/common/web/utils/package.json" > "$PRODBUILDTEMP/package1.json" cat $PRODBUILDTEMP/package1.json | "$JQ" \ '. | del(.dependencies."@keymanapp/common-types")' \ From 162dc40f2cea367c0ed298044c4292cc58318094 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Mon, 20 Jan 2025 14:17:15 +0700 Subject: [PATCH 049/155] chore(mac): added architecture tag, more breadcrumbs --- .../KMConfigurationWindowController.m | 17 +++++---- .../Keyman4MacIM/KMInputMethodAppDelegate.m | 38 +++++++++++-------- .../Keyman4MacIM/KMInputMethodEventHandler.m | 8 +++- .../Keyman4MacIM/Logging/KMSentryHelper.h | 6 ++- .../Keyman4MacIM/Logging/KMSentryHelper.m | 18 +++++++-- .../OnScreenKeyboard/OSKWindowController.m | 2 +- 6 files changed, 58 insertions(+), 31 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m index 142606152f..6f63bcfccf 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m @@ -361,18 +361,19 @@ - (void)checkBoxAction:(id)sender { NSButton *checkBox = (NSButton *)sender; NSString *kmxFilePath = [self kmxFilePathAtIndex:checkBox.tag]; + NSString * kmxFileName = [kmxFilePath lastPathComponent]; NSString *partialPath = [KMDataRepository.shared trimToPartialPath:kmxFilePath]; os_log_debug([KMLogs uiLog], "checkBoxAction, kmxFilePath = %{public}@ for checkBox.tag %li, partialPath = %{public}@", kmxFilePath, checkBox.tag, partialPath); if (checkBox.state == NSOnState) { - os_log_debug([KMLogs uiLog], "enabling active keyboard: %{public}@", kmxFilePath); - NSString *message = [NSString stringWithFormat:@"enabling active keyboard: %@", kmxFilePath]; + os_log_debug([KMLogs uiLog], "enabling active keyboard: %{public}@", kmxFileName); + NSString *message = [NSString stringWithFormat:@"enabling active keyboard: %@", kmxFileName]; [KMSentryHelper addUserBreadCrumb:@"config" message:message]; [self.activeKeyboards addObject:partialPath]; [self saveActiveKeyboards]; } else if (checkBox.state == NSOffState) { - os_log_debug([KMLogs uiLog], "disabling active keyboard: %{public}@", kmxFilePath); - NSString *message = [NSString stringWithFormat:@"disabling active keyboard: %@", kmxFilePath]; + os_log_debug([KMLogs uiLog], "disabling active keyboard: %{public}@", kmxFileName); + NSString *message = [NSString stringWithFormat:@"disabling active keyboard: %@", kmxFileName]; [KMSentryHelper addUserBreadCrumb:@"config" message:message]; [self.activeKeyboards removeObject:partialPath]; [self saveActiveKeyboards]; @@ -423,21 +424,23 @@ [self.deleteAlertView setMessageText:[NSString localizedStringWithFormat:deleteKeyboardMessage, keyboardName]]; } - os_log_debug([KMLogs testLog], "entered removeAction for keyboardName: %{public}@", keyboardName); + os_log_debug([KMLogs configLog], "entered removeAction for keyboardName: %{public}@", keyboardName); [self.deleteAlertView beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) { if (returnCode == NSAlertFirstButtonReturn) { os_log_debug([KMLogs uiLog], "confirm delete keyboard alert dismissed"); [self deleteFileAtIndex:[NSNumber numberWithInteger:deleteButton.tag]]; - os_log_debug([KMLogs testLog], "removeAction for keyboardName: %{public}@", keyboardName); - [KMSentryHelper addBreadCrumb:@"configure" message:[NSString stringWithFormat:@"remove keyboard: %@", keyboardName]]; + os_log_debug([KMLogs configLog], "removeAction for keyboardName: %{public}@", keyboardName); + [KMSentryHelper addUserBreadCrumb:@"configure" message:[NSString stringWithFormat:@"remove keyboard: %@", keyboardName]]; } self.deleteAlertView = nil; }]; } - (IBAction)downloadAction:(id)sender { + [KMSentryHelper addUserBreadCrumb:@"user" message:@"download keyboard"]; + if (self.AppDelegate.infoWindow_.window != nil) [self.AppDelegate.infoWindow_ close]; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index ad0249643c..66842926b3 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -18,8 +18,17 @@ #import "PrivacyConsent.h" #import "KMLogs.h" #import "KMSentryHelper.h" +//#include "TargetConditionals.h" @import Sentry; +#if TARGET_CPU_ARM64 +NSString *processorType = @"ARM"; +#elif TARGET_CPU_X86_64 +NSString *processorType = @"Intel"; +#elif +NSString *processorType = @"Unknown"; +#endif + NSString *const kKeymanKeyboardDownloadCompletedNotification = @"kKeymanKeyboardDownloadCompletedNotification"; @implementation NSString (VersionNumbers) @@ -131,7 +140,7 @@ id _lastServerWithOSKShowing = nil; } else { os_log_debug([KMLogs oskLog], "***KMInputMethodAppDelegate inputMethodDeactivated, OSK already hidden"); } - [KMSentryHelper addOskVisibleTag:[self.oskWindow.window isVisible]?@"true":@"false"]; + [KMSentryHelper addOskVisibleTag:[self.oskWindow.window isVisible]]; if (self.lowLevelEventTap) { os_log_debug([KMLogs lifecycleLog], "***inputMethodDeactivated, disabling event tap"); @@ -218,10 +227,10 @@ id _lastServerWithOSKShowing = nil; BOOL canForce = NO; if (self.sentryTestingEnabled) { - NSString * kmxName = [[self.kmx filePath] lastPathComponent]; NSString * applicationId = [KMInputMethodLifecycle.shared clientApplicationId]; - canForce = [[self getKmxFileName] isEqualToString:testKeyboardName] && [applicationId isEqualToString:testClientApplicationId]; - os_log_info([KMLogs testLog], "canForceSentryEvents, self.sentryTestingEnabled: %{public}@ kmxName: %{public}@ applicationId: %{public}@ testingEnabled: %{public}@", self.sentryTestingEnabled?@"YES":@"NO", kmxName, applicationId, canForce?@"YES":@"NO"); + NSString * kmxFileName = [self getKmxFileName]; + canForce = [kmxFileName isEqualToString:testKeyboardName] && [applicationId isEqualToString:testClientApplicationId]; + os_log_info([KMLogs testLog], "canForceSentryEvents, self.sentryTestingEnabled: %{public}@ kmxName: %{public}@ applicationId: %{public}@ testingEnabled: %{public}@", self.sentryTestingEnabled?@"YES":@"NO", kmxFileName, applicationId, canForce?@"YES":@"NO"); } return canForce; @@ -235,15 +244,12 @@ id _lastServerWithOSKShowing = nil; NSString *keyboardFileName = [self.kmx.filePath lastPathComponent]; os_log_info([KMLogs keyboardLog], "initial kmx set to %{public}@", keyboardFileName); - NSString *hasAccessibility = [PrivacyConsent.shared checkAccessibility]?@"true":@"false"; - // assign custom keyboard tag in Sentry for accessibility and initial keyboard [KMSentryHelper addKeyboardTag:keyboardFileName]; - [KMSentryHelper addHasAccessibilityTag:hasAccessibility]; -// [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { -// [scope setTagValue:hasAccessibility forKey:@"accessibilityEnabled"]; -// [scope setTagValue:keyboardFileName forKey:@"keyboard"]; -// }]; + [KMSentryHelper addHasAccessibilityTag:[PrivacyConsent.shared checkAccessibility]]; + [KMSentryHelper addOskVisibleTag:[self.oskWindow.window isVisible]]; + [KMSentryHelper addArchitectureTag:processorType]; + } #ifdef USE_ALERT_SHOW_HELP_TO_FORCE_EASTER_EGG_CRASH_FROM_ENGINE @@ -354,6 +360,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef os_log_debug([KMLogs eventsLog], "*** kKeymanEventKeyCode = 0xFF"); } else { if ([OSKView isOskKeyDownEvent:event]) { + [KMSentryHelper addBreadCrumb:@"event" message:@"processing OSK-generated keydown event"]; NSEventModifierFlags oskEventModifiers = [OSKView extractModifierFlagsFromOskEvent:event]; appDelegate.receivedKeyDownFromOsk = YES; appDelegate.oskEventModifiers = oskEventModifiers; @@ -445,13 +452,11 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef os_log_info([KMLogs keyboardLog], "loadKeyboardFromKmxFile, keyboard info: %{public}@", keyboardInfo); [KMSentryHelper addBreadCrumb:@"configure" message:[NSString stringWithFormat:@"loadKeyboardFromKmxFile: %@", [self getKmxFileName]]]; + [KMSentryHelper addKeyboardTag:[self getKmxFileName]]; _modifierMapping = [[KMModifierMapping alloc] init:keyboardInfo]; os_log_info([KMLogs keyboardLog], "modifierMapping bothOptionKeysGenerateRightAlt: %d", self.modifierMapping.bothOptionKeysGenerateRightAlt); - - // assign custom keyboard tag in Sentry to default keyboard - [KMSentryHelper addKeyboardTag:keyboardInfo.keyboardId]; } - (void)setKvk:(KVKFile *)kvk { @@ -659,6 +664,8 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef if (!_activeKeyboards) { os_log_debug([KMLogs dataLog], "initializing activeKeyboards"); _activeKeyboards = [[KMSettingsRepository.shared readActiveKeyboards] mutableCopy]; + + [KMSentryHelper addActiveKeyboardCountTag:_activeKeyboards.count]; } return _activeKeyboards; @@ -669,6 +676,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef [KMSettingsRepository.shared writeActiveKeyboards:_activeKeyboards]; [self resetActiveKeyboards]; [self updateKeyboardMenuItems]; + [KMSentryHelper addActiveKeyboardCountTag:self.activeKeyboards.count]; } - (void)clearActiveKeyboards { @@ -993,7 +1001,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef [[self.oskWindow window] makeKeyAndOrderFront:nil]; [[self.oskWindow window] setLevel:NSStatusWindowLevel]; [[self.oskWindow window] setTitle:self.oskWindowTitle]; - [KMSentryHelper addOskVisibleTag:[self.oskWindow.window isVisible]?@"true":@"false"]; + [KMSentryHelper addOskVisibleTag:[self.oskWindow.window isVisible]]; } - (void)showAboutWindow { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m index 340a06a04e..d900cf073a 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m @@ -45,7 +45,6 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; _queuedText = nil; [KMSentryHelper addClientAppIdTag:clientAppId]; - return self; } @@ -139,9 +138,11 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; NSString *sentryCommand = event.characters; if ([sentryCommand isEqualToString:@"{"]) { os_log_debug([KMLogs testLog], "forceSentryEvent: forcing crash now"); + NSBeep(); [SentrySDK crash]; } else if ([sentryCommand isEqualToString:@"["]) { os_log_debug([KMLogs testLog], "forceSentryEvent: forcing message now"); + NSBeep(); [SentrySDK captureMessage:@"Forced test message"]; } else { os_log_debug([KMLogs testLog], "forceSentryEvent: unrecognized command"); @@ -162,7 +163,8 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; */ - (void)handleBackspace:(NSEvent *)event { os_log_debug([KMLogs eventsLog], "KMInputMethodEventHandler handleBackspace, event = %{public}@", event); - + [KMSentryHelper addBreadCrumb:@"user" message:@"handle backspace for non-compliant app"]; + if (self.generatedBackspaceCount > 0) { self.generatedBackspaceCount--; self.lowLevelBackspaceCount++; @@ -218,6 +220,7 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; [self handleContextChangedByLowLevelEvent]; if (event.type == NSEventTypeKeyDown) { + [KMSentryHelper addBreadCrumb:@"event" message:@"handling keydown event"]; // indicates that our generated backspace event(s) are consumed // and we can insert text that followed the backspace(s) if (event.keyCode == kKeymanEventKeyCode) { @@ -410,6 +413,7 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; NSString *value = [options objectForKey:key]; if(key && value) { os_log_debug([KMLogs keyLog], "persistOptions, key: %{public}@, value: %{public}@", key, value); + [KMSentryHelper addBreadCrumb:@"event" message:@"persist options"]; [[KMSettingsRepository shared] writeOptionForSelectedKeyboard:key withValue:value]; } else { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h index e9d6936c0e..5699cef1d2 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h @@ -12,10 +12,12 @@ NS_ASSUME_NONNULL_BEGIN @interface KMSentryHelper : NSObject + (void)addApiComplianceTag: (NSString *)value; -+ (void)addOskVisibleTag:(NSString *)value; ++ (void)addArchitectureTag: (NSString *)value; ++ (void)addOskVisibleTag:(BOOL)value; + (void)addClientAppIdTag:(NSString *)value; + (void)addKeyboardTag:(NSString *)value; -+ (void)addHasAccessibilityTag:(NSString *)value; ++ (void)addHasAccessibilityTag:(BOOL)value; ++ (void)addActiveKeyboardCountTag:(NSUInteger)value; + (void)addBreadCrumb:(NSString *)category message:(NSString *)messageText; + (void)addUserBreadCrumb:(NSString *)category message:(NSString *)messageText; + (void)addDetailedBreadCrumb:(NSString *)category message:(NSString *)messageText data:( NSDictionary *) map; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m index 5278e36037..66656b24d5 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m @@ -12,17 +12,23 @@ @implementation KMSentryHelper NSString * const kApiComplianceTagName = @"apiCompliance"; +NSString * const kArchitectureTagName = @"architecture"; NSString * const kOskVisibleTagName = @"oskVisible"; NSString * const kClientAppIdTagName = @"clientAppId"; NSString * const kKeyboardTagName = @"keyboard"; NSString * const kHasAccessibilityTagName = @"accessibilityEnabled"; +NSString * const kActiveKeyboardCountTagName = @"activeKeyboardCount"; + (void)addApiComplianceTag: (NSString *)value { [self addCustomTag:kApiComplianceTagName withValue:value]; } -+ (void)addOskVisibleTag:(NSString *)value { - [self addCustomTag:kOskVisibleTagName withValue:value]; ++ (void)addArchitectureTag: (NSString *)value { + [self addCustomTag:kArchitectureTagName withValue:value]; +} + ++ (void)addOskVisibleTag:(BOOL)value { + [self addCustomTag:kOskVisibleTagName withValue:value?@"true":@"false"]; } + (void)addClientAppIdTag:(NSString *)value { @@ -33,8 +39,12 @@ NSString * const kHasAccessibilityTagName = @"accessibilityEnabled"; [self addCustomTag:kKeyboardTagName withValue:value]; } -+ (void)addHasAccessibilityTag:(NSString *)value { - [self addCustomTag:kHasAccessibilityTagName withValue:value]; ++ (void)addHasAccessibilityTag:(BOOL)value { + [self addCustomTag:kHasAccessibilityTagName withValue:value?@"true":@"false"]; +} + ++ (void)addActiveKeyboardCountTag:(NSUInteger)value { + [self addCustomTag:kActiveKeyboardCountTagName withValue:[[NSNumber numberWithUnsignedLong:value] stringValue]]; } /** diff --git a/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.m index df0e723534..d4f457c754 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.m @@ -77,7 +77,7 @@ // whenever the OSK is closing clear all of its modifier keys [self.oskView clearOskModifiers]; - [KMSentryHelper addOskVisibleTag:@"false"]; + [KMSentryHelper addOskVisibleTag:NO]; } - (void)helpAction:(id)sender { From 2b390274c87545b1221a263a9a38bd3772356184 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Mon, 20 Jan 2025 16:17:36 +0700 Subject: [PATCH 050/155] chore(mac): add KMSentryHelper to test project resolves link error when running unit tests --- mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj index 3436ed498a..87b005309c 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj +++ b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj @@ -37,6 +37,7 @@ 29C1CDE32C5B2F8B003C23BB /* KMDataRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = 29015ABC2C58D86F00CCBB94 /* KMDataRepository.m */; }; 29DBBF672D35053E00D8E33C /* KMSentryHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 29DBBF662D35053E00D8E33C /* KMSentryHelper.m */; }; 29DD5F442CFEF88000683388 /* SILAndikaV1RGB.png in Resources */ = {isa = PBXBuildFile; fileRef = 29DD5F432CFEF88000683388 /* SILAndikaV1RGB.png */; }; + 29E67D042D3E4A86003CDE8F /* KMSentryHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 29DBBF662D35053E00D8E33C /* KMSentryHelper.m */; }; 37A245C12565DFA6000BBF92 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 37A245C02565DFA6000BBF92 /* Assets.xcassets */; }; 37AE5C9D239A7B770086CC7C /* qrcode.min.js in Resources */ = {isa = PBXBuildFile; fileRef = 37AE5C9C239A7B770086CC7C /* qrcode.min.js */; }; 37C2B0CB25FF2C350092E16A /* Help in Resources */ = {isa = PBXBuildFile; fileRef = 37C2B0CA25FF2C340092E16A /* Help */; }; @@ -1052,6 +1053,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 29E67D042D3E4A86003CDE8F /* KMSentryHelper.m in Sources */, 29C1CDE22C5B2F8B003C23BB /* KMSettingsRepository.m in Sources */, 29C1CDE32C5B2F8B003C23BB /* KMDataRepository.m in Sources */, 2915DC512BFE35DB0051FC52 /* KMLogs.m in Sources */, From 9eb151c781c5831bc6dd7f3ce089c74380fa2571 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Mon, 20 Jan 2025 13:02:42 -0500 Subject: [PATCH 051/155] auto: increment master version to 18.0.174 --- HISTORY.md | 6 ++++++ VERSION.md | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index be484aee8b..62ad9f552c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,11 @@ # Keyman Version History +## 18.0.173 alpha 2025-01-20 + +* feat(developer): rewrite font data in .kvk from package metadata (#12949) +* docs(ios): document gestures within iOS app help (#12900) +* fix(developer): include developer-utils deps in server build (#12951) + ## 18.0.172 alpha 2025-01-19 * chore(common): Add 17.0.333 to version history (#12926) diff --git a/VERSION.md b/VERSION.md index 5f77e86146..736c025123 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.173 \ No newline at end of file +18.0.174 \ No newline at end of file From 5e6fd79ec6ff5b49d00860febc04b16fc9a1214b Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 21 Jan 2025 08:34:11 +1000 Subject: [PATCH 052/155] fix(windows): catch report file not found --- .../main/Keyman.System.UpdateStateMachine.pas | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index eeff4d2792..18207b6bf2 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -996,17 +996,28 @@ function InstallingState.DoInstallPackage(PackageFileName: String): Boolean; var FPackage: IKeymanPackageFile2; begin - Result := True; - FPackage := kmcom.Packages.GetPackageFromFile(PackageFileName) - as IKeymanPackageFile2; - FPackage.Install2(True); - // Force overwrites existing package and leaves most settings for it intact + Result := False; + try + FPackage := kmcom.Packages.GetPackageFromFile(PackageFileName) + as IKeymanPackageFile2; + // Force overwrites existing package and leaves most settings for it intact + FPackage.Install2(True); + Result := True; + except + on E: Exception do + begin + TKeymanSentryClient.ReportHandledException(E, + 'Failed to install keyboard package'); + end; + end; + FPackage := nil; - - kmcom.Refresh; - kmcom.Apply; - - System.SysUtils.DeleteFile(PackageFileName); + if Result then + begin + kmcom.Refresh; + kmcom.Apply; + System.SysUtils.DeleteFile(PackageFileName); + end; end; From bda60eb39f9c5560b3562d79fe68109a5529d72f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 21 Jan 2025 10:55:18 +0700 Subject: [PATCH 053/155] chore(developer): validate targets parameter in kmc-generate Fixes: #12954 --- .../src/kmc-generate/src/basic-generator.ts | 19 +++++++++- .../kmc-generate/src/generator-messages.ts | 37 ++++++++++++++----- .../src/keyman-keyboard-generator.ts | 5 ++- .../src/ldml-keyboard-generator.ts | 5 ++- .../src/lexical-model-generator.ts | 5 ++- .../src/kmc-generate/test/messages.tests.ts | 14 +++++++ 6 files changed, 71 insertions(+), 14 deletions(-) diff --git a/developer/src/kmc-generate/src/basic-generator.ts b/developer/src/kmc-generate/src/basic-generator.ts index cb69ef5fdd..fe5a5cd304 100644 --- a/developer/src/kmc-generate/src/basic-generator.ts +++ b/developer/src/kmc-generate/src/basic-generator.ts @@ -7,6 +7,7 @@ import { KeymanTargets } from "@keymanapp/common-types"; import KEYMAN_VERSION from "@keymanapp/keyman-version"; import { AbstractGenerator, GeneratorArtifacts } from "./abstract-generator.js"; +import { GeneratorMessages } from "./generator-messages.js"; /** * @internal @@ -28,7 +29,19 @@ export class BasicGenerator extends AbstractGenerator { this.languageTags = this.options.languageTags.length ? this.options.languageTags.map(tag => new Intl.Locale(tag).minimize().toString()) : [this.DEFAULT_LOCALE]; - //TODO-GENERATE: validate targets + + // Verify that targets passed in are valid + let failed = false; + for(const target of this.options.targets) { + if(!KeymanTargets.AllKeymanTargets.includes(target)) { + this.callbacks.reportMessage(GeneratorMessages.Error_InvalidTarget({target})); + failed = true; + } + } + if(failed) { + return false; + } + if(this.options.targets.includes(KeymanTargets.KeymanTarget.any) || this.options.targets.length == 0) { this.resolvedTargets = KeymanTargets.AllKeymanTargets.filter(target => target != KeymanTargets.KeymanTarget.any); } else { @@ -50,6 +63,8 @@ export class BasicGenerator extends AbstractGenerator { dt.getDate().toString().padStart(2, '0'); this.tokenMap['$PACKAGE_LANGUAGES'] = this.generateLanguageListForPackage(); this.tokenMap['$PLATFORMS_DOTLIST_README'] = this.getPlatformDotListForReadme(); + + return true; } protected generate(artifacts: GeneratorArtifacts): boolean { @@ -89,6 +104,8 @@ export class BasicGenerator extends AbstractGenerator { sourceFile = this.callbacks.path.join(this.templateBasePath, this.templatePath, sourceFile); const sourceData = this.callbacks.loadFile(sourceFile); + + /* c8 ignore next 4 */ if(sourceData == null) { // internal error -- source file should be readable throw new Error(`source file ${sourceFile} does not exist`); diff --git a/developer/src/kmc-generate/src/generator-messages.ts b/developer/src/kmc-generate/src/generator-messages.ts index cda0d82fd2..82e1a4bfa6 100644 --- a/developer/src/kmc-generate/src/generator-messages.ts +++ b/developer/src/kmc-generate/src/generator-messages.ts @@ -17,30 +17,47 @@ const SevFatal = CompilerErrorSeverity.Fatal | Namespace; * @internal */ export class GeneratorMessages { - static Fatal_UnexpectedException = (o:{e: any}) => m(this.FATAL_UnexpectedException, null, o.e ?? 'unknown error'); static FATAL_UnexpectedException = SevFatal | 0x0001; + static Fatal_UnexpectedException = (o:{e: any}) => m( + this.FATAL_UnexpectedException, null, o.e ?? 'unknown error' + ); - static Info_GeneratingProject = (o:{type: string, id: string}) => m(this.INFO_GeneratingProject, - `Generating project of type ${def(o.type)} with id ${def(o.id)}`); static INFO_GeneratingProject = SevInfo | 0x0002; + static Info_GeneratingProject = (o:{type: string, id: string}) => m( + this.INFO_GeneratingProject, + `Generating project of type ${def(o.type)} with id ${def(o.id)}` + ); static ERROR_CannotCreateFolder = SevError | 0x0003; - static Error_CannotCreateFolder = (o:{folderName:string, e: any}) => CompilerMessageSpecWithException(this.ERROR_CannotCreateFolder, null, - `Unable to create folder ${def(o.folderName)}: ${o.e ?? 'unknown error'}`); + static Error_CannotCreateFolder = (o:{folderName:string, e: any}) => CompilerMessageSpecWithException( + this.ERROR_CannotCreateFolder, null, + `Unable to create folder ${def(o.folderName)}: ${o.e ?? 'unknown error'}` + ); static ERROR_OutputPathAlreadyExists = SevError | 0x0004; static Error_OutputPathAlreadyExists = (o:{outPath:string}) => m( this.ERROR_OutputPathAlreadyExists, - `Output path ${def(o.outPath)} already exists, not overwriting`); + `Output path ${def(o.outPath)} already exists, not overwriting` + ); static ERROR_CannotWriteOutputFile = SevError | 0x0005; - static Error_CannotWriteOutputFile = (o:{filename:string, e: any}) => CompilerMessageSpecWithException(this.ERROR_CannotWriteOutputFile, null, - `Unable to write file ${def(o.filename)}: ${o.e ?? 'unknown error'}`); + static Error_CannotWriteOutputFile = (o:{filename:string, e: any}) => CompilerMessageSpecWithException( + this.ERROR_CannotWriteOutputFile, null, + `Unable to write file ${def(o.filename)}: ${o.e ?? 'unknown error'}` + ); // See also PackageCompilerMessages.WARN_PackageNameDoesNotFollowLexicalModelConventions static WARN_ModelIdDoesNotFollowLexicalModelConventions = SevWarn | 0x0006; - static Warn_ModelIdDoesNotFollowLexicalModelConventions = (o:{id: string}) => m(this.WARN_ModelIdDoesNotFollowLexicalModelConventions, + static Warn_ModelIdDoesNotFollowLexicalModelConventions = (o:{id: string}) => m( + this.WARN_ModelIdDoesNotFollowLexicalModelConventions, `The id ${def(o.id)} does not follow the recommended model id conventions. The id should be all lower case, `+ `include only alphanumeric characters and underscore (_), not start with a digit, and should have the structure `+ - `..`); + `..` + ); + + static ERROR_InvalidTarget = SevError | 0x0007; + static Error_InvalidTarget = (o:{target:string}) => m( + this.ERROR_InvalidTarget, + `The specified target platform '${def(o.target)}' is not a valid target.` + ); }; diff --git a/developer/src/kmc-generate/src/keyman-keyboard-generator.ts b/developer/src/kmc-generate/src/keyman-keyboard-generator.ts index c3d5c7665a..27d0adb99f 100644 --- a/developer/src/kmc-generate/src/keyman-keyboard-generator.ts +++ b/developer/src/kmc-generate/src/keyman-keyboard-generator.ts @@ -39,7 +39,10 @@ export class KeymanKeyboardGenerator extends BasicGenerator implements KeymanCom * @returns Binary artifacts on success, null on failure. */ async run(): Promise { - this.preGenerate(); + if(!this.preGenerate()) { + // errors will have been reported in preGenerate + return null; + } const artifacts: GeneratorArtifacts = this.defaultArtifacts(); diff --git a/developer/src/kmc-generate/src/ldml-keyboard-generator.ts b/developer/src/kmc-generate/src/ldml-keyboard-generator.ts index e9885e7fb3..3be00cb329 100644 --- a/developer/src/kmc-generate/src/ldml-keyboard-generator.ts +++ b/developer/src/kmc-generate/src/ldml-keyboard-generator.ts @@ -28,7 +28,10 @@ export class LdmlKeyboardGenerator extends BasicGenerator implements KeymanCompi * @returns Binary artifacts on success, null on failure. */ async run(): Promise { - this.preGenerate(); + if(!this.preGenerate()) { + // errors will have been reported in preGenerate + return null; + } const artifacts: GeneratorArtifacts = this.defaultArtifacts(); this.templatePath = 'ldml-keyboard'; diff --git a/developer/src/kmc-generate/src/lexical-model-generator.ts b/developer/src/kmc-generate/src/lexical-model-generator.ts index f78807798c..f0cff6558b 100644 --- a/developer/src/kmc-generate/src/lexical-model-generator.ts +++ b/developer/src/kmc-generate/src/lexical-model-generator.ts @@ -31,7 +31,10 @@ export class LexicalModelGenerator extends BasicGenerator implements KeymanCompi * @returns Binary artifacts on success, null on failure. */ async run(): Promise { - this.preGenerate(); + if(!this.preGenerate()) { + // errors will have been reported in preGenerate + return null; + } const artifacts: GeneratorArtifacts = this.defaultArtifacts(); diff --git a/developer/src/kmc-generate/test/messages.tests.ts b/developer/src/kmc-generate/test/messages.tests.ts index 68c7f741fa..eebb17cda5 100644 --- a/developer/src/kmc-generate/test/messages.tests.ts +++ b/developer/src/kmc-generate/test/messages.tests.ts @@ -11,6 +11,8 @@ import { GeneratorMessages } from '../src/generator-messages.js'; import { TestCompilerCallbacks, verifyCompilerMessagesObject } from '@keymanapp/developer-test-helpers'; import { CompilerErrorNamespace } from '@keymanapp/developer-utils'; import { AbstractGenerator, GeneratorOptions } from '../src/abstract-generator.js'; +import { BasicGenerator } from '../src/basic-generator.js'; +import { options } from './shared-options.js'; describe('GeneratorMessages', function () { const callbacks = new TestCompilerCallbacks(); @@ -62,4 +64,16 @@ describe('GeneratorMessages', function () { assert.isTrue(callbacks.hasMessage(GeneratorMessages.ERROR_CannotWriteOutputFile), `messageId ERROR_CannotWriteOutputFile not generated, instead got: `+JSON.stringify(callbacks.messages,null,2)); }); + + it('should generate ERROR_InvalidTarget if an invalid target is passed in', async function () { + const testOptions: GeneratorOptions = { ...options, + // @ts-ignore ('invalid' could be passed by a user, even if would be a compile error here) + targets: ['invalid'] + }; + const bg = new BasicGenerator(); + const callbacks = new TestCompilerCallbacks(); + assert(await bg.init(callbacks, testOptions)); + assert.isFalse(bg.test_preGenerate()); + assert.isTrue(callbacks.hasMessage(GeneratorMessages.ERROR_InvalidTarget)); + }); }); From 3ad0dec493e57f86461c0eb9f5be6a24d9c8fda5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 21 Jan 2025 12:41:52 +0700 Subject: [PATCH 054/155] chore(developer): validate keyboard and model IDs in kmc-generate Fixes: #12957 --- developer/src/common/web/utils/src/index.ts | 4 +- .../src/common/web/utils/src/valid-ids.ts | 38 ++++++++++ .../common/web/utils/test/valid-ids.tests.ts | 76 +++++++++++++++++++ developer/src/kmc-generate/package.json | 3 +- .../kmc-generate/src/generator-messages.ts | 18 +++++ .../src/keyman-keyboard-generator.ts | 8 +- .../src/ldml-keyboard-generator.ts | 8 +- .../src/lexical-model-generator.ts | 7 +- ...s.tests.ts => generator-messages.tests.ts} | 46 ++++++++++- 9 files changed, 200 insertions(+), 8 deletions(-) create mode 100644 developer/src/common/web/utils/src/valid-ids.ts create mode 100644 developer/src/common/web/utils/test/valid-ids.tests.ts rename developer/src/kmc-generate/test/{messages.tests.ts => generator-messages.tests.ts} (64%) diff --git a/developer/src/common/web/utils/src/index.ts b/developer/src/common/web/utils/src/index.ts index 19845f0e8f..f8ee6246da 100644 --- a/developer/src/common/web/utils/src/index.ts +++ b/developer/src/common/web/utils/src/index.ts @@ -70,4 +70,6 @@ export { KeymanXMLType, KeymanXMLWriter, KeymanXMLReader } from './xml-utils.js' export * as GitHubUrls from './github-urls.js'; export * as CloudUrls from './cloud-urls.js'; -export { getFontFamily, getFontFamilySync } from './font-family.js'; \ No newline at end of file +export { getFontFamily, getFontFamilySync } from './font-family.js'; + +export * as ValidIds from './valid-ids.js'; diff --git a/developer/src/common/web/utils/src/valid-ids.ts b/developer/src/common/web/utils/src/valid-ids.ts new file mode 100644 index 0000000000..717a173f5d --- /dev/null +++ b/developer/src/common/web/utils/src/valid-ids.ts @@ -0,0 +1,38 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + */ + + +/** + * Verifies that an id passed in is valid as an identifier for a Keyman .kmn + * keyboard: starts with alpha or underscore and remainder is alphanumeric + * @param id + * @returns + */ +export function isValidKeymanKeyboardId(id: string) { + return /^[a-z_][a-z0-9_]*$/.test(id); +} + +/** + * Verifies that an id passed in is valid as an identifier for an LDML xml + * keyboard: starts with alpha or underscore and remainder is alphanumeric. + * Note that this test is not the same as the CLDR test for valid LDML xml + * filename, as this test has a narrower validity policy to match the Keyman + * implementation requirements. + * @param id + * @returns + */ +export function isValidLdmlKeyboardId(id: string) { + return /^[a-z_][a-z0-9_]*$/.test(id); +} + +/** + * Verifies that an id passed in is valid as an identifier for a Keyman + * lexical model: starts with alpha or underscore and remainder is alphanumeric, + * in three components -- author.bcp47.uniq + * @param id + * @returns + */ +export function isValidLexicalModelId(id: string) { + return /^[a-z_][a-z0-9_]*\.[a-z][a-z0-9_]+\.[a-z_][a-z0-9_]*$/.test(id); +} diff --git a/developer/src/common/web/utils/test/valid-ids.tests.ts b/developer/src/common/web/utils/test/valid-ids.tests.ts new file mode 100644 index 0000000000..c285332b66 --- /dev/null +++ b/developer/src/common/web/utils/test/valid-ids.tests.ts @@ -0,0 +1,76 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + */ + +import { assert } from 'chai'; +import 'mocha'; +import { isValidKeymanKeyboardId, isValidLdmlKeyboardId, isValidLexicalModelId } from '../src/valid-ids.js'; + +describe('valid-ids', function () { + it('should accept a valid Keyman keyboard ID', function() { + [ + 'khmer_angkor', + 'm', + 'fancypants1_2', + 'keyboard___', + '_100', + ].forEach(id => assert.isTrue(isValidKeymanKeyboardId(id), `expected '${id}' to be valid`)); + }); + + it('should reject invalid Keyman keyboard IDs', function() { + [ + 'khmer_angkor@example.com', + 'keyboard ', + 'Khmer', + ' keyboard', + '111', + '?', + 'keyboard.version', + ].forEach(id => assert.isFalse(isValidKeymanKeyboardId(id), `expected '${id}' to be invalid`)); + }); + + it('should accept a valid LDML keyboard ID', function() { + [ + 'khmer_angkor', + 'm', + 'fancypants1_2', + 'keyboard___', + '_100', + ].forEach(id => assert.isTrue(isValidLdmlKeyboardId(id), `expected '${id}' to be valid`)); + }); + + it('should reject invalid LDML keyboard IDs', function() { + [ + 'khmer_angkor@example.com', + 'keyboard ', + ' keyboard', + 'Khmer', + '111', + '?', + 'keyboard.version', + ].forEach(id => assert.isFalse(isValidLdmlKeyboardId(id), `expected '${id}' to be invalid`)); + }); + + it('should accept a valid lexical model ID', function() { + [ + 'khmer.km.khmer_angkor', + 'nrc.en.mtnt', + ].forEach(id => assert.isTrue(isValidLexicalModelId(id), `expected '${id}' to be valid`)); + }); + + it('should reject invalid lexical model IDs', function() { + [ + 'khmer', + 'en-us', + 'khmer.km-KM.angkor', + 'Khmer.km_km.angkor', + 'model ', + ' model', + '111', + '?', + 'lexical.model', + 'lexical..model', + '.en.model', + ].forEach(id => assert.isFalse(isValidLexicalModelId(id), `expected '${id}' to be invalid`)); + }); +}); diff --git a/developer/src/kmc-generate/package.json b/developer/src/kmc-generate/package.json index a8e0810338..ba488ff575 100644 --- a/developer/src/kmc-generate/package.json +++ b/developer/src/kmc-generate/package.json @@ -54,7 +54,8 @@ "exclude-after-remap": true, "exclude": [ "test/", - "src/template/" + "src/template/", + "src/main.ts" ] }, "repository": { diff --git a/developer/src/kmc-generate/src/generator-messages.ts b/developer/src/kmc-generate/src/generator-messages.ts index 82e1a4bfa6..ad562dbd29 100644 --- a/developer/src/kmc-generate/src/generator-messages.ts +++ b/developer/src/kmc-generate/src/generator-messages.ts @@ -60,4 +60,22 @@ export class GeneratorMessages { this.ERROR_InvalidTarget, `The specified target platform '${def(o.target)}' is not a valid target.` ); + + static ERROR_InvalidKeymanKeyboardId = SevError | 0x0008; + static Error_InvalidKeymanKeyboardId = (o:{id:string}) => m( + this.ERROR_InvalidKeymanKeyboardId, + `The specified keyboard id '${def(o.id)}' contains characters that are not permitted for a .kmn keyboard id or filename.` + ); + + static ERROR_InvalidLdmlKeyboardId = SevError | 0x0009; + static Error_InvalidLdmlKeyboardId = (o:{id:string}) => m( + this.ERROR_InvalidLdmlKeyboardId, + `The specified keyboard id '${def(o.id)}' contains characters that are not permitted for an LDML .xml keyboard id or filename.` + ); + + static ERROR_InvalidLexicalModelId = SevError | 0x000A; + static Error_InvalidLexicalModelId = (o:{id:string}) => m( + this.ERROR_InvalidLexicalModelId, + `The specified lexical model id '${def(o.id)}' contains characters that are not permitted or does not match the required pattern of 'author.bcp47.uniq'.` + ); }; diff --git a/developer/src/kmc-generate/src/keyman-keyboard-generator.ts b/developer/src/kmc-generate/src/keyman-keyboard-generator.ts index 27d0adb99f..ec76beff65 100644 --- a/developer/src/kmc-generate/src/keyman-keyboard-generator.ts +++ b/developer/src/kmc-generate/src/keyman-keyboard-generator.ts @@ -5,9 +5,10 @@ */ import { KeymanFileTypes, KeymanTargets } from '@keymanapp/common-types'; -import { KeymanCompiler, } from '@keymanapp/developer-utils'; +import { KeymanCompiler, ValidIds, } from '@keymanapp/developer-utils'; import { GeneratorArtifacts, GeneratorResult } from './abstract-generator.js'; import { BasicGenerator } from './basic-generator.js'; +import { GeneratorMessages } from './generator-messages.js'; /** * @public @@ -39,6 +40,11 @@ export class KeymanKeyboardGenerator extends BasicGenerator implements KeymanCom * @returns Binary artifacts on success, null on failure. */ async run(): Promise { + if(!ValidIds.isValidKeymanKeyboardId(this.options.id)) { + this.callbacks.reportMessage(GeneratorMessages.Error_InvalidKeymanKeyboardId({id:this.options.id})); + return null; + } + if(!this.preGenerate()) { // errors will have been reported in preGenerate return null; diff --git a/developer/src/kmc-generate/src/ldml-keyboard-generator.ts b/developer/src/kmc-generate/src/ldml-keyboard-generator.ts index 3be00cb329..f8afb49013 100644 --- a/developer/src/kmc-generate/src/ldml-keyboard-generator.ts +++ b/developer/src/kmc-generate/src/ldml-keyboard-generator.ts @@ -5,9 +5,10 @@ */ import { KeymanFileTypes } from '@keymanapp/common-types'; -import { KeymanCompiler, } from '@keymanapp/developer-utils'; +import { KeymanCompiler, ValidIds, } from '@keymanapp/developer-utils'; import { GeneratorArtifacts, GeneratorResult } from './abstract-generator.js'; import { BasicGenerator } from './basic-generator.js'; +import { GeneratorMessages } from './generator-messages.js'; /** * @public @@ -28,6 +29,11 @@ export class LdmlKeyboardGenerator extends BasicGenerator implements KeymanCompi * @returns Binary artifacts on success, null on failure. */ async run(): Promise { + if(!ValidIds.isValidLdmlKeyboardId(this.options.id)) { + this.callbacks.reportMessage(GeneratorMessages.Error_InvalidLdmlKeyboardId({id:this.options.id})); + return null; + } + if(!this.preGenerate()) { // errors will have been reported in preGenerate return null; diff --git a/developer/src/kmc-generate/src/lexical-model-generator.ts b/developer/src/kmc-generate/src/lexical-model-generator.ts index f0cff6558b..86316549cf 100644 --- a/developer/src/kmc-generate/src/lexical-model-generator.ts +++ b/developer/src/kmc-generate/src/lexical-model-generator.ts @@ -5,7 +5,7 @@ */ import { KeymanFileTypes } from '@keymanapp/common-types'; -import { KeymanCompiler, SourceFilenamePatterns } from '@keymanapp/developer-utils'; +import { KeymanCompiler, SourceFilenamePatterns, ValidIds } from '@keymanapp/developer-utils'; import { GeneratorArtifacts, GeneratorResult } from './abstract-generator.js'; import { BasicGenerator } from './basic-generator.js'; import { GeneratorMessages } from './generator-messages.js'; @@ -31,6 +31,11 @@ export class LexicalModelGenerator extends BasicGenerator implements KeymanCompi * @returns Binary artifacts on success, null on failure. */ async run(): Promise { + if(!ValidIds.isValidLexicalModelId(this.options.id)) { + this.callbacks.reportMessage(GeneratorMessages.Error_InvalidLexicalModelId({id:this.options.id})); + return null; + } + if(!this.preGenerate()) { // errors will have been reported in preGenerate return null; diff --git a/developer/src/kmc-generate/test/messages.tests.ts b/developer/src/kmc-generate/test/generator-messages.tests.ts similarity index 64% rename from developer/src/kmc-generate/test/messages.tests.ts rename to developer/src/kmc-generate/test/generator-messages.tests.ts index eebb17cda5..b5d3a8837a 100644 --- a/developer/src/kmc-generate/test/messages.tests.ts +++ b/developer/src/kmc-generate/test/generator-messages.tests.ts @@ -2,16 +2,23 @@ * Keyman is copyright (C) SIL International. MIT License. */ +import * as path from 'node:path'; +import * as fs from 'node:fs'; + import 'mocha'; -import * as path from 'path'; -import * as fs from 'fs'; import { fileURLToPath } from 'url'; import { assert } from 'chai'; -import { GeneratorMessages } from '../src/generator-messages.js'; + import { TestCompilerCallbacks, verifyCompilerMessagesObject } from '@keymanapp/developer-test-helpers'; import { CompilerErrorNamespace } from '@keymanapp/developer-utils'; + +import { GeneratorMessages } from '../src/generator-messages.js'; import { AbstractGenerator, GeneratorOptions } from '../src/abstract-generator.js'; import { BasicGenerator } from '../src/basic-generator.js'; +import { KeymanKeyboardGenerator } from '../src/keyman-keyboard-generator.js'; +import { LdmlKeyboardGenerator } from '../src/ldml-keyboard-generator.js'; +import { LexicalModelGenerator } from '../src/lexical-model-generator.js'; + import { options } from './shared-options.js'; describe('GeneratorMessages', function () { @@ -76,4 +83,37 @@ describe('GeneratorMessages', function () { assert.isFalse(bg.test_preGenerate()); assert.isTrue(callbacks.hasMessage(GeneratorMessages.ERROR_InvalidTarget)); }); + + it('should generate ERROR_InvalidKeymanKeyboardId if an invalid keyboard id is passed in', async function () { + const testOptions: GeneratorOptions = { ...options, + id: '???invalid', + }; + const kkg = new KeymanKeyboardGenerator(); + const callbacks = new TestCompilerCallbacks(); + assert.isTrue(await kkg.init(callbacks, testOptions)); + assert.isNull(await kkg.run()); + assert.isTrue(callbacks.hasMessage(GeneratorMessages.ERROR_InvalidKeymanKeyboardId)); + }); + + it('should generate ERROR_InvalidLdmlKeyboardId if an invalid keyboard id is passed in', async function () { + const testOptions: GeneratorOptions = { ...options, + id: '???invalid', + }; + const lkg = new LdmlKeyboardGenerator(); + const callbacks = new TestCompilerCallbacks(); + assert.isTrue(await lkg.init(callbacks, testOptions)); + assert.isNull(await lkg.run()); + assert.isTrue(callbacks.hasMessage(GeneratorMessages.ERROR_InvalidLdmlKeyboardId)); + }); + + it('should generate ERROR_InvalidLexicalModelId if an invalid lexical model id is passed in', async function () { + const testOptions: GeneratorOptions = { ...options, + id: 'example.???.invalid', + }; + const lmg = new LexicalModelGenerator(); + const callbacks = new TestCompilerCallbacks(); + assert.isTrue(await lmg.init(callbacks, testOptions)); + assert.isNull(await lmg.run()); + assert.isTrue(callbacks.hasMessage(GeneratorMessages.ERROR_InvalidLexicalModelId)); + }); }); From 2dec427bd438392fa9293e4e7617be54d54b9dff Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 21 Jan 2025 13:55:48 +0700 Subject: [PATCH 055/155] fix(developer): use correct terms in kmc-generate lexical model help Fixes: #12959 --- developer/src/kmc/src/commands/generate.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/developer/src/kmc/src/commands/generate.ts b/developer/src/kmc/src/commands/generate.ts index bac724d9d4..54c0cffce6 100644 --- a/developer/src/kmc/src/commands/generate.ts +++ b/developer/src/kmc/src/commands/generate.ts @@ -59,12 +59,12 @@ function declareGenerateLexicalModel(command: Command) { modelSubCommand .description('Generate a wordlist lexical model project') .option('-o, --out-path ', 'Output path (may exist)') - .option('-n, --name ', 'Keyboard descriptive name') + .option('-n, --name ', 'Lexical model descriptive name') .option('-c, --copyright ', 'Copyright holder') /* © yyyy */ - .option('-v, --version ', 'Keyboard version', '1.0') + .option('-v, --version ', 'Lexical model version', '1.0') .option('-L, --language-tag ', 'BCP-47 language tag', (value, previous) => previous.concat([value]), []) - .option('-a, --author ', 'Name of keyboard author') + .option('-a, --author ', 'Name of lexical model author') .option('-d, --description ', 'Short description of the project, Markdown') .action(generateLexicalModel); From 6f6316e79bd59a47b2fa7c74c409f3065a06304f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 21 Jan 2025 13:58:37 +0700 Subject: [PATCH 056/155] fix(developer): use 1.0.0 as default for ldml keyboards in kmc-generate Fixes: #12961 --- developer/src/kmc/src/commands/generate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/src/kmc/src/commands/generate.ts b/developer/src/kmc/src/commands/generate.ts index 54c0cffce6..c9d8dde391 100644 --- a/developer/src/kmc/src/commands/generate.ts +++ b/developer/src/kmc/src/commands/generate.ts @@ -45,7 +45,7 @@ function declareGenerateLdmlKeyboard(command: Command) { .option('-o, --out-path ', 'Output path (may exist)') .option('-n, --name ', 'Keyboard descriptive name') .option('-c, --copyright ', 'Copyright holder') /* © yyyy */ - .option('-v, --version ', 'Keyboard version', '1.0') + .option('-v, --version ', 'Keyboard version', '1.0.0') .option('-L, --language-tag ', 'BCP-47 language tag', (value, previous) => previous.concat([value]), []) .option('-a, --author ', 'Name of keyboard author') From 44483be68898ab73a448c941fa05c7e4d6ba9110 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Tue, 21 Jan 2025 14:32:16 +0700 Subject: [PATCH 057/155] fix(web): prevents multitap warning that occurs multitapping longpressable modifier keys Fixes: #12963 --- .../src/input/gestures/browser/multitap.ts | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/web/src/engine/osk/src/input/gestures/browser/multitap.ts b/web/src/engine/osk/src/input/gestures/browser/multitap.ts index 99e50810f9..76280f63e7 100644 --- a/web/src/engine/osk/src/input/gestures/browser/multitap.ts +++ b/web/src/engine/osk/src/input/gestures/browser/multitap.ts @@ -8,6 +8,7 @@ import { distributionFromDistanceMaps } from '../../../corrections.js'; import Modipress from './modipress.js'; import { keySupportsModipress } from '../specsForLayout.js'; import { GesturePreviewHost } from '../../../keyboard-layout/gesturePreviewHost.js'; +import { correctionKeyFilter } from '../../../correctionLayout.js'; /** * Represents a potential multitap gesture's implementation within KeymanWeb. @@ -104,20 +105,33 @@ export default class Multitap implements GestureHandler { keyEvent.baseTranscriptionToken = this.baseContextToken; const coord = tap.sources[0].currentSample; - const baseDistances = vkbd.getSimpleTapCorrectionDistances(coord, this.baseKey.key.spec as ActiveKey); + + const baseSpec = this.baseKey.key.spec; + const baseDistances = vkbd.getSimpleTapCorrectionDistances(coord, baseSpec as ActiveKey); + // If the key is on a different layer than is shown, what if the user meant to hit a different key? + // (Bypass if the tap is part of a modipress gesture.) if(coord.stateToken != vkbd.layerId && !tap.matchedId.includes('modipress')) { const matchKey = vkbd.layerGroup.findNearestKey({...coord, stateToken: vkbd.layerId}); - // Replace the key at the current location for the current layer key - // with the multitap base key. - const p = baseDistances.get(matchKey.key.spec); - if(p == null) { - console.warn("Could not find current layer's key") + // That said, if they directly touched a non-output key, simplify and assume + // that they hit the intended key. + if(correctionKeyFilter(matchKey.key.spec)) { + // Replace the key at the current location for the current layer key + // with the multitap base key. + const p = baseDistances.get(matchKey.key.spec); + if(p == null) { + console.warn("Could not find current layer's key") + } else { + baseDistances.delete(matchKey.key.spec); + baseDistances.set(coord.item.key.spec, p); + } } - baseDistances.delete(matchKey.key.spec); - baseDistances.set(coord.item.key.spec, p); } - keyEvent.keyDistribution = this.currentStageKeyDistribution(baseDistances); + + // Will also bypass if the base key is modipress-compatible. + if(coord.item && correctionKeyFilter(coord.item.key.spec)) { + keyEvent.keyDistribution = this.currentStageKeyDistribution(baseDistances); + } // TODO for future: multitap previews. From 8459472f75fbef34f4ee00e5603cda3ba9df6b94 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Tue, 21 Jan 2025 15:57:54 +0700 Subject: [PATCH 058/155] chore: adds h1 tags --- web/docs/engine/guide/examples/__auto-control.html | 3 +++ web/docs/engine/guide/examples/__control-by-control.html | 2 ++ web/docs/engine/guide/examples/__first-example.html | 3 +++ web/docs/engine/guide/examples/__full-manual-control.html | 3 ++- web/docs/engine/guide/examples/__manual-control.html | 3 ++- 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/web/docs/engine/guide/examples/__auto-control.html b/web/docs/engine/guide/examples/__auto-control.html index 9e1786c6d7..e7fc2768c6 100644 --- a/web/docs/engine/guide/examples/__auto-control.html +++ b/web/docs/engine/guide/examples/__auto-control.html @@ -20,9 +20,12 @@ +

Automatic Mode Example

+ +Back to Document \ No newline at end of file diff --git a/web/docs/engine/guide/examples/__control-by-control.html b/web/docs/engine/guide/examples/__control-by-control.html index b1f7ac5e42..440a7862d0 100644 --- a/web/docs/engine/guide/examples/__control-by-control.html +++ b/web/docs/engine/guide/examples/__control-by-control.html @@ -33,6 +33,7 @@ +

Control-by-Control Example

Email to (KeymanWeb not enabled)

@@ -43,5 +44,6 @@
+Back to Document \ No newline at end of file diff --git a/web/docs/engine/guide/examples/__first-example.html b/web/docs/engine/guide/examples/__first-example.html index 3b46160f65..1657db9440 100644 --- a/web/docs/engine/guide/examples/__first-example.html +++ b/web/docs/engine/guide/examples/__first-example.html @@ -18,6 +18,9 @@ +

First Example

Click me and type:

+ +Back to Document \ No newline at end of file diff --git a/web/docs/engine/guide/examples/__full-manual-control.html b/web/docs/engine/guide/examples/__full-manual-control.html index c9d76d90fb..24b0d004a7 100644 --- a/web/docs/engine/guide/examples/__full-manual-control.html +++ b/web/docs/engine/guide/examples/__full-manual-control.html @@ -43,7 +43,7 @@ window.addEventListener( 'load' , SetupDocument ); - +

Manual Control - Custom Interface

Keyboard:

@@ -51,5 +51,6 @@ window.addEventListener( 'load' , SetupDocument );

+Back to Document diff --git a/web/docs/engine/guide/examples/__manual-control.html b/web/docs/engine/guide/examples/__manual-control.html index 37776a7850..e9f5f219ca 100644 --- a/web/docs/engine/guide/examples/__manual-control.html +++ b/web/docs/engine/guide/examples/__manual-control.html @@ -32,7 +32,7 @@ - +

Manual Mode Example

KeymanWeb

@@ -40,6 +40,7 @@

+Back to Document
\ No newline at end of file From e86ddc89a283f07f4dd45e2b8d6427b2dc31090e Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 21 Jan 2025 15:58:19 +0700 Subject: [PATCH 059/155] chore(developer): add test for basic transform to kmc-generate Fixes: #12965 --- .../test/basic-generator.tests.ts | 56 +++++++++++++++++-- .../test/fixtures/basic/welcome.htm | 26 +++++++++ 2 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 developer/src/kmc-generate/test/fixtures/basic/welcome.htm diff --git a/developer/src/kmc-generate/test/basic-generator.tests.ts b/developer/src/kmc-generate/test/basic-generator.tests.ts index b1eb1e420d..41b4e0d99f 100644 --- a/developer/src/kmc-generate/test/basic-generator.tests.ts +++ b/developer/src/kmc-generate/test/basic-generator.tests.ts @@ -2,22 +2,70 @@ * Keyman is copyright (C) SIL International. MIT License. */ +import * as fs from 'node:fs'; + import 'mocha'; import { assert } from 'chai'; -import { BasicGenerator } from '../src/basic-generator.js'; import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; +import { BasicGenerator } from '../src/basic-generator.js'; +import { AbstractGenerator, GeneratorArtifacts } from '../src/abstract-generator.js'; import { options } from './shared-options.js'; +import { makePathToFixture } from './helpers/index.js'; + +// this class is here to make it possible to access protected members +class BasicGeneratorTest extends BasicGenerator { + static files() { + return [ + 'sample/' + AbstractGenerator.SFile_WelcomeHTM, + 'sample/' + AbstractGenerator.SFile_ReadmeHTM, + 'sample/' + AbstractGenerator.SFile_HistoryMD, + 'sample/' + AbstractGenerator.SFile_LicenseMD, + 'sample/' + AbstractGenerator.SFile_ReadmeMD, + 'sample/' + AbstractGenerator.SFile_GitIgnore, + ]; + }; + + setup() { + this.templatePath = 'kmn-keyboard'; + } +} describe('BasicGenerator', function () { it('should configure default settings', async function() { const bg = new BasicGenerator(); const callbacks = new TestCompilerCallbacks(); - assert(await bg.init(callbacks, options)); - bg.test_preGenerate(); + assert.isTrue(await bg.init(callbacks, options)); + assert.isTrue(bg.test_preGenerate()); assert.equal(bg.test_tokenMap['$NAME'], 'Sample Project'); }); - // TODO-GENERATE: test transform + it('should successfully transform common project files', async function() { + const bg = new BasicGeneratorTest(); + bg.setup(); + + const callbacks = new TestCompilerCallbacks(); + assert.isTrue(await bg.init(callbacks, options)); + assert.isTrue(bg.test_preGenerate()); + + const artifacts: GeneratorArtifacts = { "kmc-generate:outputPath": { data: null, filename: '' } }; + assert.isTrue(bg.test_generate(artifacts)); + + // standard artifacts are listed in AbstractGenerator + const keys = [].concat( + 'kmc-generate:outputPath', + BasicGeneratorTest.files().map(f => f.replaceAll('/', '\\')) + ); + + assert.hasAllKeys(artifacts, keys); + + // pick one file and compare it + const filename = BasicGeneratorTest.files()[0].replaceAll('/', '\\'); // welcome.htm + assert.equal(artifacts[filename].filename, filename); + const fixturePath = makePathToFixture('basic', 'welcome.htm'); + const fixture = fs.readFileSync(fixturePath, 'utf-8').replace(/\r\n/g, '\n'); + const actual = new TextDecoder().decode(artifacts[filename].data); + assert.equal(actual, fixture); + }); }); diff --git a/developer/src/kmc-generate/test/fixtures/basic/welcome.htm b/developer/src/kmc-generate/test/fixtures/basic/welcome.htm new file mode 100644 index 0000000000..1454a604b6 --- /dev/null +++ b/developer/src/kmc-generate/test/fixtures/basic/welcome.htm @@ -0,0 +1,26 @@ + + + + + + Start Using Sample Project + + + + +

Start Using Sample Project

+ +

+ # A mighty description +

+ +

Keyboard Layout

+ + + + + \ No newline at end of file From 071a8fbde4c4d446ecb30c1621313213adea4796 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Tue, 21 Jan 2025 13:01:35 -0500 Subject: [PATCH 060/155] auto: increment master version to 18.0.175 --- HISTORY.md | 5 +++++ VERSION.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 62ad9f552c..6ffda9827b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # Keyman Version History +## 18.0.174 alpha 2025-01-21 + +* chore(developer): validate targets parameter in kmc-generate (#12955) +* fix(developer): support `&displayMap` font in web debugger (#12929) + ## 18.0.173 alpha 2025-01-20 * feat(developer): rewrite font data in .kvk from package metadata (#12949) diff --git a/VERSION.md b/VERSION.md index 736c025123..e1b3341dda 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.174 \ No newline at end of file +18.0.175 \ No newline at end of file From edc8d00caf60342d4e0f709f553a7866eb8e809a Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 22 Jan 2025 07:14:07 +0700 Subject: [PATCH 061/155] chore(developer): stub out icon support in kmc-generate As icon generation turns out to be challenging due to limitations or native dependencies in node.js libraries for image generation, icon options are now stubbed out to avoid confusion. --- .../docs/help/reference/kmc/cli/reference.md | 3 +++ .../kmc-generate/src/abstract-generator.ts | 7 +++-- .../src/keyman-keyboard-generator.ts | 27 ++++++++++--------- .../src/kmc-generate/test/shared-options.ts | 3 ++- developer/src/kmc/src/commands/generate.ts | 6 +++-- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/developer/docs/help/reference/kmc/cli/reference.md b/developer/docs/help/reference/kmc/cli/reference.md index 763d5ad71f..fdaed58faa 100644 --- a/developer/docs/help/reference/kmc/cli/reference.md +++ b/developer/docs/help/reference/kmc/cli/reference.md @@ -367,10 +367,13 @@ and the files in that folder will follow the : The name of keyboard author (default: blank) + `-d, --description ` diff --git a/developer/src/kmc-generate/src/abstract-generator.ts b/developer/src/kmc-generate/src/abstract-generator.ts index 6cb8b1e43e..5a6ed46cc0 100644 --- a/developer/src/kmc-generate/src/abstract-generator.ts +++ b/developer/src/kmc-generate/src/abstract-generator.ts @@ -53,11 +53,14 @@ export interface GeneratorOptions /* not inheriting from CompilerBaseOptions */ * name of the author of the keyboard */ author?: string; - /** + + // TODO-GENERATE: icon support + /* * * set to true to generate an icon for a Keyman keyboard with the first * characters of the first specified BCP 47 tag */ - icon?: boolean; + // icon?: boolean; + /** * description of the keyboard, Markdown permissible */ diff --git a/developer/src/kmc-generate/src/keyman-keyboard-generator.ts b/developer/src/kmc-generate/src/keyman-keyboard-generator.ts index ec76beff65..13591fb472 100644 --- a/developer/src/kmc-generate/src/keyman-keyboard-generator.ts +++ b/developer/src/kmc-generate/src/keyman-keyboard-generator.ts @@ -72,9 +72,10 @@ export class KeymanKeyboardGenerator extends BasicGenerator implements KeymanCom KeymanKeyboardGenerator.SPath_Source+this.options.id+KeymanFileTypes.Source.TouchLayout; } - if(this.hasIcon()) { - this.includedPrefixes.push('Icon'); - } + // TODO-GENERATE: icon support + // if(this.hasIcon()) { + // this.includedPrefixes.push('Icon'); + // } if(this.hasKMX()) { this.includedPrefixes.push('KMX'); @@ -91,9 +92,9 @@ export class KeymanKeyboardGenerator extends BasicGenerator implements KeymanCom // Special case for creating icon, run after successful creation of other // project bits and pieces - if(this.hasIcon()) { - this.writeIcon(artifacts); - } + // if(this.hasIcon()) { + // this.writeIcon(artifacts); + // } return {artifacts}; } @@ -107,13 +108,13 @@ export class KeymanKeyboardGenerator extends BasicGenerator implements KeymanCom private readonly hasKMX = () => this.targetIncludes(KeymanTargets.KMXKeymanTargets); private readonly hasTouchLayout = () => this.targetIncludes(KeymanTargets.TouchKeymanTargets); - // TODO-GENERATE, once writeIcon is implemented: + // TODO-GENERATE: icon support // hasIcon = () => this.options.icon && this.targetIncludes(KeymanTargets.KMXKeymanTargets); - private readonly hasIcon = () => false; + // private readonly hasIcon = () => false; - private writeIcon(artifacts: GeneratorArtifacts) { - // TODO-GENERATE: this will require some effort - // proposal: generate 16x16 icon with 2-3 letters. Following TKeyboardIconGenerator.GenerateIcon - // research for .ico writer in node - } + // TODO-GENERATE: icon support + // private writeIcon(artifacts: GeneratorArtifacts) { + // proposal: generate 16x16 icon with 2-3 letters. Following TKeyboardIconGenerator.GenerateIcon + // research for .ico writer in node + // } } diff --git a/developer/src/kmc-generate/test/shared-options.ts b/developer/src/kmc-generate/test/shared-options.ts index 1010c417b4..cc36789fe3 100644 --- a/developer/src/kmc-generate/test/shared-options.ts +++ b/developer/src/kmc-generate/test/shared-options.ts @@ -6,7 +6,8 @@ import { KeymanTargets } from "@keymanapp/common-types"; import { GeneratorOptions } from "../src/abstract-generator.js"; export const options: GeneratorOptions = { - icon: false, + // TODO-GENERATE: icon support + // icon: false, id: 'sample', languageTags: ['en'], name: 'Sample Project', diff --git a/developer/src/kmc/src/commands/generate.ts b/developer/src/kmc/src/commands/generate.ts index c9d8dde391..d5abcec989 100644 --- a/developer/src/kmc/src/commands/generate.ts +++ b/developer/src/kmc/src/commands/generate.ts @@ -30,7 +30,8 @@ function declareGenerateKmnKeyboard(command: Command) { .option('-L, --language-tag ', 'BCP-47 language tag', (value, previous) => previous.concat([value]), []) .option('-a, --author ', 'Name of keyboard author') - .option('-i, --icon', 'Include a generated icon', true) + // TODO-GENERATE: icon support + // .option('-i, --icon', 'Include a generated icon', true) .option('-d, --description ', 'Short description of the project, Markdown') .action(generateKmnKeyboard); } @@ -73,7 +74,8 @@ function declareGenerateLexicalModel(command: Command) { function commanderOptionsToGeneratorOptions(id: string, options: any): GeneratorOptions { const result: GeneratorOptions = { - icon: options.icon ?? true, + // TODO-GENERATE: icon support + // icon: options.icon ?? true, id, languageTags: options.languageTag ?? [], name: options.name ?? id, From 89813e11adfb777dafa69beb08a9c31bf5f0f356 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 22 Jan 2025 07:45:41 +0700 Subject: [PATCH 062/155] chore(developer): use path separator for non-Windows platforms in kmc-generate tests --- developer/src/kmc-generate/test/basic-generator.tests.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/developer/src/kmc-generate/test/basic-generator.tests.ts b/developer/src/kmc-generate/test/basic-generator.tests.ts index 41b4e0d99f..f5cff4044a 100644 --- a/developer/src/kmc-generate/test/basic-generator.tests.ts +++ b/developer/src/kmc-generate/test/basic-generator.tests.ts @@ -3,6 +3,7 @@ */ import * as fs from 'node:fs'; +import * as path from 'node:path'; import 'mocha'; import { assert } from 'chai'; @@ -54,13 +55,13 @@ describe('BasicGenerator', function () { // standard artifacts are listed in AbstractGenerator const keys = [].concat( 'kmc-generate:outputPath', - BasicGeneratorTest.files().map(f => f.replaceAll('/', '\\')) + BasicGeneratorTest.files().map(f => f.replaceAll('/', path.sep)) ); assert.hasAllKeys(artifacts, keys); // pick one file and compare it - const filename = BasicGeneratorTest.files()[0].replaceAll('/', '\\'); // welcome.htm + const filename = BasicGeneratorTest.files()[0].replaceAll('/', path.sep); // welcome.htm assert.equal(artifacts[filename].filename, filename); const fixturePath = makePathToFixture('basic', 'welcome.htm'); const fixture = fs.readFileSync(fixturePath, 'utf-8').replace(/\r\n/g, '\n'); From 439ea0e4d1de3d5471bf56c6321583dfd8be07fa Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 22 Jan 2025 08:12:54 +0700 Subject: [PATCH 063/155] chore(developer): remove '--rename' option from kmc-copy An in-place rename is dangerous and destructive, so we won't support it. --- developer/src/kmc-copy/src/KeymanProjectCopier.ts | 5 ----- developer/src/kmc-copy/test/copier.tests.ts | 3 --- developer/src/kmc/src/commands/copy.ts | 2 -- 3 files changed, 10 deletions(-) diff --git a/developer/src/kmc-copy/src/KeymanProjectCopier.ts b/developer/src/kmc-copy/src/KeymanProjectCopier.ts index 40f68fc1fc..255ba6d63c 100644 --- a/developer/src/kmc-copy/src/KeymanProjectCopier.ts +++ b/developer/src/kmc-copy/src/KeymanProjectCopier.ts @@ -29,11 +29,6 @@ export interface CopierOptions /* not inheriting from CompilerBaseOptions */ { * output path where project folder will be created */ outPath: string; - /* - * TODO-COPY rename: rename existing files rather than copy - - rename: boolean; - */ /** * dryRun: show what would happen */ diff --git a/developer/src/kmc-copy/test/copier.tests.ts b/developer/src/kmc-copy/test/copier.tests.ts index 6d583862ae..e468bbd79c 100644 --- a/developer/src/kmc-copy/test/copier.tests.ts +++ b/developer/src/kmc-copy/test/copier.tests.ts @@ -306,7 +306,6 @@ describe('KeymanProjectCopier', function() { assert.isTrue(await copier.init(callbacks, { dryRun: false, outPath, - // TODO-COPY rename: false, })); const result = await copier.run(fullSource); @@ -370,7 +369,6 @@ describe('KeymanProjectCopier', function() { assert.isTrue(await copier.init(callbacks, { dryRun: false, outPath, - // TODO-COPY rename: false, })); // armenian_mnemonic selected because (a) small, and (b) has v2.0 project, so @@ -400,7 +398,6 @@ describe('KeymanProjectCopier', function() { assert.isTrue(await copier.init(callbacks, { dryRun: false, outPath, - // TODO-COPY rename: false, })); const result = await copier.run('cloud:'+id); diff --git a/developer/src/kmc/src/commands/copy.ts b/developer/src/kmc/src/commands/copy.ts index 2f22b24a0a..1d4ab94dcf 100644 --- a/developer/src/kmc/src/commands/copy.ts +++ b/developer/src/kmc/src/commands/copy.ts @@ -19,7 +19,6 @@ export function declareCopy(program: Command) { command .description('Copy a Keyman keyboard or lexical model project') .option('-o, --out-path ', 'New name and path for project') - // TODO-COPY .option('-r, --rename', 'Rename instead of copying project') .option('-n, --dry-run', 'Show what would happen, without making changes') .action(copyProject) .addHelpText('before', ` @@ -36,7 +35,6 @@ export function declareCopy(program: Command) { function commanderOptionsToCopierOptions(options: any): CopierOptions { const result: CopierOptions = { outPath: options.outPath, - // TODO-COPY rename: options.rename ?? false, dryRun: options.dryRun ?? false, }; return result; From a08f1aca6e19ca3138e34570a68062b9cf1ee8c9 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 22 Jan 2025 08:58:13 +0700 Subject: [PATCH 064/155] feat(developer): add 'verbose' and 'debug' log levels to kmc Adds 'verbose' and 'debug' log levels and corresponding error severity levels. This means the internal error severity values have changed to match - 'info' is now 2 instead of 0. Fixes: #12975 --- .../src/common/include/kmn_compiler_errors.h | 12 ++++++---- .../web/utils/src/compiler-interfaces.ts | 24 ++++++++++++------- developer/src/kmc-copy/src/cloud.ts | 4 +++- developer/src/kmc-copy/src/copier-messages.ts | 13 ++++++++++ .../src/kmc/src/util/NodeCompilerCallbacks.ts | 2 ++ .../Keyman.Developer.System.KmcWrapper.pas | 2 +- 6 files changed, 42 insertions(+), 15 deletions(-) diff --git a/developer/src/common/include/kmn_compiler_errors.h b/developer/src/common/include/kmn_compiler_errors.h index f2410f03b0..5ca5c6acfd 100644 --- a/developer/src/common/include/kmn_compiler_errors.h +++ b/developer/src/common/include/kmn_compiler_errors.h @@ -28,11 +28,13 @@ namespace CompilerErrorSeverity { // We use a namespace to stop the enum names leaking out into global namespace scope enum { - Info = 0x000000, // Informational, not necessarily a problem - Hint = 0x100000, // Something the user might want to be aware of - Warn = 0x200000, // Warning: Not great, but we can keep going. - Error = 0x300000, // Severe error where we can't continue - Fatal = 0x400000, // OOM or should-not-happen internal problem + Debug = 0x000000, // log everything including internal debug + Verbose = 0x100000, // log everything, except debug + Info = 0x200000, // Informational, not necessarily a problem + Hint = 0x300000, // Something the user might want to be aware of + Warn = 0x400000, // Warning: Not great, but we can keep going. + Error = 0x500000, // Severe error where we can't continue + Fatal = 0x600000, // OOM or should-not-happen internal problem }; }; diff --git a/developer/src/common/web/utils/src/compiler-interfaces.ts b/developer/src/common/web/utils/src/compiler-interfaces.ts index 0ffc828f1d..4cb9ae3c22 100644 --- a/developer/src/common/web/utils/src/compiler-interfaces.ts +++ b/developer/src/common/web/utils/src/compiler-interfaces.ts @@ -21,14 +21,18 @@ export interface CompilerEvent { }; export enum CompilerErrorSeverity { - Info = 0x000000, // Informational, not necessarily a problem - Hint = 0x100000, // Something the user might want to be aware of - Warn = 0x200000, // Warning: Not great, but we can keep going. - Error = 0x300000, // Severe error where we can't continue - Fatal = 0x400000, // OOM or should-not-happen internal problem + Debug = 0x000000, // log everything including internal debug + Verbose = 0x100000, // log everything, except debug + Info = 0x200000, // Informational, not necessarily a problem + Hint = 0x300000, // Something the user might want to be aware of + Warn = 0x400000, // Warning: Not great, but we can keep going. + Error = 0x500000, // Severe error where we can't continue + Fatal = 0x600000, // OOM or should-not-happen internal problem }; export const CompilerErrorSeverityValues = [ + CompilerErrorSeverity.Debug, + CompilerErrorSeverity.Verbose, CompilerErrorSeverity.Info, CompilerErrorSeverity.Hint, CompilerErrorSeverity.Warn, @@ -48,6 +52,8 @@ export enum CompilerErrorMask { }; const errorSeverityName = { + [CompilerErrorSeverity.Debug]: 'debug', + [CompilerErrorSeverity.Verbose]: 'verbose', [CompilerErrorSeverity.Info]: 'info', [CompilerErrorSeverity.Hint]: 'hint', [CompilerErrorSeverity.Warn]: 'warn', @@ -415,8 +421,9 @@ export const ALL_COMPILER_LOG_LEVELS = [ 'error', /// Only errors emitted 'warn', /// Errors + warnings 'hint', /// Errors + warnings + hints - 'info', /// All messages: errors + warnings + hints + info - 'debug' /// All messages: errors + warnings + hints + info, plus debug logs + 'info', /// All normal messages: errors + warnings + hints + info + 'verbose', /// All messages + verbose logging + 'debug', /// All messages + verbose + internal debug ] as const; type CompilerLogLevelTuple = typeof ALL_COMPILER_LOG_LEVELS; @@ -428,7 +435,8 @@ export const compilerLogLevelToSeverity: {[index in CompilerLogLevel]: number} = 'warn': CompilerErrorSeverity.Warn, 'hint': CompilerErrorSeverity.Hint, 'info': CompilerErrorSeverity.Info, - 'debug': CompilerErrorSeverity.Info + 'verbose': CompilerErrorSeverity.Verbose, + 'debug': CompilerErrorSeverity.Debug, }; export const ALL_COMPILER_LOG_FORMATS = [ diff --git a/developer/src/kmc-copy/src/cloud.ts b/developer/src/kmc-copy/src/cloud.ts index 7b3ef1ff11..a65284933e 100644 --- a/developer/src/kmc-copy/src/cloud.ts +++ b/developer/src/kmc-copy/src/cloud.ts @@ -63,9 +63,10 @@ export class KeymanCloudSource { } public async downloadFolderFromGitHub(ref: GitHubRef): Promise<{filename:string,type:'dir'|'file'}[]> { - // this.callbacks.reportMessage(CopierMessages.Info_DownloadingFile({ref})); // TODO-COPY: verbose mode support const url = `https://api.github.com/repos/${ref.owner}/${ref.repo}/contents/${ref.path}?ref=${ref.branch}`; + this.callbacks.reportMessage(CopierMessages.Verbose_DownloadingFolder({path:ref.path, url})); + let folder: any; try { folder = await this.callbacks.net.fetchJSON(url); @@ -94,6 +95,7 @@ export class KeymanCloudSource { } const url = `https://raw.githubusercontent.com/${ref.owner}/${ref.repo}/refs/heads/${ref.branch}${ref.path}`; + this.callbacks.reportMessage(CopierMessages.Verbose_DownloadingFile({filename:this.callbacks.path.basename(ref.path), url})); try { return await this.callbacks.net.fetchBlob(url); diff --git a/developer/src/kmc-copy/src/copier-messages.ts b/developer/src/kmc-copy/src/copier-messages.ts index 78a948ec79..8b25f93b19 100644 --- a/developer/src/kmc-copy/src/copier-messages.ts +++ b/developer/src/kmc-copy/src/copier-messages.ts @@ -7,6 +7,7 @@ import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m, CompilerMessageDef as def, CompilerMessageSpecWithException } from "@keymanapp/developer-utils"; const Namespace = CompilerErrorNamespace.Copier; +const SevVerbose = CompilerErrorSeverity.Verbose | Namespace; const SevInfo = CompilerErrorSeverity.Info | Namespace; // const SevHint = CompilerErrorSeverity.Hint | Namespace; const SevWarn = CompilerErrorSeverity.Warn | Namespace; @@ -198,4 +199,16 @@ export class CopierMessages { the provided error details for more details.` ); + static VERBOSE_DownloadingFile = SevVerbose | 0x001C; + static Verbose_DownloadingFile = (o:{filename: string, url: string}) => m( + this.VERBOSE_DownloadingFile, + `Downloading '${def(o.filename)}' from '${def(o.url)}'`, + ); + + static VERBOSE_DownloadingFolder = SevVerbose | 0x001D; + static Verbose_DownloadingFolder = (o:{path: string, url: string}) => m( + this.VERBOSE_DownloadingFolder, + `Downloading folder '${def(o.path)}' from '${def(o.url)}'`, + ); + }; diff --git a/developer/src/kmc/src/util/NodeCompilerCallbacks.ts b/developer/src/kmc/src/util/NodeCompilerCallbacks.ts index fd5f29d212..f3cdf1e7b2 100644 --- a/developer/src/kmc/src/util/NodeCompilerCallbacks.ts +++ b/developer/src/kmc/src/util/NodeCompilerCallbacks.ts @@ -23,6 +23,8 @@ const severityColors: {[value in CompilerErrorSeverity]: chalk.Chalk} = { [CompilerErrorSeverity.Warn]: color.hex('FFA500'), // orange [CompilerErrorSeverity.Error]: color.redBright, [CompilerErrorSeverity.Fatal]: color.redBright, + [CompilerErrorSeverity.Verbose]: color.gray, + [CompilerErrorSeverity.Debug]: color.blueBright, }; /** diff --git a/developer/src/tike/compile/Keyman.Developer.System.KmcWrapper.pas b/developer/src/tike/compile/Keyman.Developer.System.KmcWrapper.pas index 9778119e9f..24c070a5e8 100644 --- a/developer/src/tike/compile/Keyman.Developer.System.KmcWrapper.pas +++ b/developer/src/tike/compile/Keyman.Developer.System.KmcWrapper.pas @@ -114,7 +114,7 @@ begin state := plsFatal; Result := False; end - else // assume msgType = 'info' + else // assume msgType = 'info' (fine also for 'verbose', 'debug') state := plsInfo; FGlobalProject.Log(state, msgFilename, msgText, msgCode, msgLine); end From 0097242f5e0030f20805f03d6e969c3fed315937 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Wed, 22 Jan 2025 09:07:19 +0700 Subject: [PATCH 065/155] feat(web): allow main manual-test page to load from KMP --- web/src/test/manual/web/kmpHeader.js | 89 ++++++++++++++++ web/src/test/manual/web/package-loader.html | 107 ++++++++++++++++++++ web/src/test/manual/web/unminified.html | 7 ++ 3 files changed, 203 insertions(+) create mode 100644 web/src/test/manual/web/kmpHeader.js create mode 100644 web/src/test/manual/web/package-loader.html diff --git a/web/src/test/manual/web/kmpHeader.js b/web/src/test/manual/web/kmpHeader.js new file mode 100644 index 0000000000..4cf3b20b11 --- /dev/null +++ b/web/src/test/manual/web/kmpHeader.js @@ -0,0 +1,89 @@ + +/* + This script allows its host page to add a keyboard via KMP file. + + Expectations for the host page: + - `

` + - +*/ + +window.addEventListener('load', () => { + const packageSelector = document.getElementById('package-file-select'); + packageSelector.addEventListener('change', async (ev) => { + let file = ev.target.files[0]; + + if(!file) { + // The user probably canceled file selection; abort. + return; + } + + // Load the package. + // https://gildas-lormeau.github.io/zip.js/api/classes/ZipReader.html + const packageReader = new zip.ZipReader(new zip.BlobReader(file)); + const packageEntries = await packageReader.getEntries(); + + if(packageEntries.length == 0) { + alert('Could not decompress the KMP; package loading failed.'); + return; + } else { + const metadataFile = packageEntries.find((entry) => entry.filename == 'kmp.json'); + if(!metadataFile) { + alert('Could not extract kmp.json; aborting'); + } + const rawMetadata = await metadataFile.getData(new zip.TextWriter()); + + // Full kmp.json load! + const packageMetadata = JSON.parse(rawMetadata); + const keyboards = packageMetadata.keyboards + + for(let keyboard of keyboards) { + const keyboardFile = `${keyboard.id}.js`; + const displayFont = keyboard.displayFont; + const oskFont = keyboard.oskFont; + + async function dataFor(filename, type) { + if(type == 'font') { + const ext = filename.substring(filename.lastIndexOf('.')+1); + type = type + '/' + ext; + } + const rawEntry = packageEntries.find((entry) => entry.filename == filename); + if(!rawEntry) { + alert(`Could not extract ${filename} from the keyboard package.`); + return null; + } + return await rawEntry.getData(new zip.Data64URIWriter(type)); + } + + const kbdData = await dataFor(keyboardFile, 'text/javascript'); + const dFontData = displayFont ? await dataFor(displayFont, 'font') : null; + const oFontData = oskFont ? await dataFor(oskFont, 'font') : null; + + keyboard.languages.forEach((language) => { + if(dFontData) { + language.font = { + family: keyboard.id, + source: [dFontData] + }; + } + + if(oFontData) { + language.oskFont = { + family: keyboard.id, + source: [oFontData] + }; + } + }) + + const stub = { + id: keyboard.id, + name: keyboard.name, + languages: keyboard.languages, + filename: kbdData + }; + + // Load 'er up! + keyman.addKeyboards(stub).then(() => document.getElementById('ta1').focus()); + } + } + }); +}); \ No newline at end of file diff --git a/web/src/test/manual/web/package-loader.html b/web/src/test/manual/web/package-loader.html new file mode 100644 index 0000000000..1e6b7496ef --- /dev/null +++ b/web/src/test/manual/web/package-loader.html @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + KeymanWeb Sample Page - Unminified Source + + + + + + + + + + + + + + + + + + + + +

KeymanWeb Sample Page - Unminified Source

+ +
+ +
+ +

Type in your language in this text area:

+ + +

or in this input field:

+ + + +

Add a keyboard by keyboard name:

+ + + +

Add a keyboard by BCP-47 language code:

+ + + +

Add a keyboard by language name(s):

+ + + +

Return to testing home page

+
+ + +
+

--End of Document--

+ + + + + diff --git a/web/src/test/manual/web/unminified.html b/web/src/test/manual/web/unminified.html index 1e6b7496ef..fdca35c8d7 100644 --- a/web/src/test/manual/web/unminified.html +++ b/web/src/test/manual/web/unminified.html @@ -46,6 +46,10 @@ + + + + @@ -80,6 +84,9 @@ +

Add a keyboard via local KMP:

+

+

Return to testing home page

From f9cb1927c964ac9915c065c98c38975d9643e098 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 22 Jan 2025 10:01:49 +0700 Subject: [PATCH 066/155] chore(developer): cleanup tests with new verbose messages --- .../src/common/web/test-helpers/TestCompilerCallbacks.ts | 7 ++++++- .../web/test-helpers/verifyCompilerMessagesObject.ts | 6 +++--- developer/src/kmc-copy/test/copier.tests.ts | 6 +++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/developer/src/common/web/test-helpers/TestCompilerCallbacks.ts b/developer/src/common/web/test-helpers/TestCompilerCallbacks.ts index a0b0464e21..fad1dd646f 100644 --- a/developer/src/common/web/test-helpers/TestCompilerCallbacks.ts +++ b/developer/src/common/web/test-helpers/TestCompilerCallbacks.ts @@ -2,7 +2,8 @@ import * as fs from 'fs'; import * as path from 'path'; import { CompilerEvent, CompilerCallbacks, CompilerPathCallbacks, CompilerFileSystemCallbacks, CompilerError, CompilerNetAsyncCallbacks, DefaultCompilerFileSystemAsyncCallbacks, - CompilerFileSystemAsyncCallbacks } from '@keymanapp/developer-utils'; + CompilerFileSystemAsyncCallbacks, + CompilerErrorSeverity} from '@keymanapp/developer-utils'; import { fileURLToPath } from 'url'; const { TEST_SAVE_FIXTURES } = process.env; @@ -27,6 +28,10 @@ export class TestCompilerCallbacks implements CompilerCallbacks { this.messages = []; } + filteredMessages(severity: CompilerErrorSeverity = CompilerErrorSeverity.Info) { + return this.messages.filter(m => CompilerError.severity(m.code) >= severity); + } + printMessages() { if(this.messages.length) { process.stdout.write(CompilerError.formatEvent(this.messages)); diff --git a/developer/src/common/web/test-helpers/verifyCompilerMessagesObject.ts b/developer/src/common/web/test-helpers/verifyCompilerMessagesObject.ts index 7f0d9aee76..8a16de6bf1 100644 --- a/developer/src/common/web/test-helpers/verifyCompilerMessagesObject.ts +++ b/developer/src/common/web/test-helpers/verifyCompilerMessagesObject.ts @@ -31,7 +31,7 @@ export function verifyCompilerMessagesObject(source: Record, namespa // Verify each object member matches the pattern we expect if(typeof m[key] == 'function') { - const o = /^(Info|Hint|Warn|Error|Fatal)_([A-Za-z0-9_]+)$/.exec(key); + const o = /^(Debug|Verbose|Info|Hint|Warn|Error|Fatal)_([A-Za-z0-9_]+)$/.exec(key); expect(o).to.be.instanceOf(Array, `Expected member ${key} to be a valid message function name`); const c = o[1].toUpperCase() + '_' + o[2]; @@ -41,7 +41,7 @@ export function verifyCompilerMessagesObject(source: Record, namespa expect(v.code).to.equal(m[c], `Function ${key} returns the wrong code`); } else if(typeof m[key] == 'number') { - const o = /^(INFO|HINT|WARN|ERROR|FATAL)_([A-Za-z0-9_]+)$/.exec(key); + const o = /^(DEBUG|VERBOSE|INFO|HINT|WARN|ERROR|FATAL)_([A-Za-z0-9_]+)$/.exec(key); expect(o).to.be.instanceOf(Array); const f = toTitleCase(o[1]) + '_' + o[2]; @@ -53,7 +53,7 @@ export function verifyCompilerMessagesObject(source: Record, namespa // Verify severify masks if(typeof m[key] == 'number') { - const o = /^(INFO|HINT|WARN|ERROR|FATAL)_([A-Za-z0-9_]+)$/.exec(key); + const o = /^(DEBUG|VERBOSE|INFO|HINT|WARN|ERROR|FATAL)_([A-Za-z0-9_]+)$/.exec(key); expect(o).to.be.instanceOf(Array); const mask = CompilerError.formatSeverity(m[key]).toUpperCase(); diff --git a/developer/src/kmc-copy/test/copier.tests.ts b/developer/src/kmc-copy/test/copier.tests.ts index e468bbd79c..7f4dccf535 100644 --- a/developer/src/kmc-copy/test/copier.tests.ts +++ b/developer/src/kmc-copy/test/copier.tests.ts @@ -315,7 +315,7 @@ describe('KeymanProjectCopier', function() { // assert.isOk(result); - assert.isEmpty(callbacks.messages); + assert.isEmpty(callbacks.filteredMessages()); if(TEST_SAVE_ARTIFACTS) { assert.isTrue(await copier.write(result.artifacts)); @@ -377,7 +377,7 @@ describe('KeymanProjectCopier', function() { // We should have no messages and a successful result assert.isOk(result); - assert.isEmpty(callbacks.messages); + assert.isEmpty(callbacks.filteredMessages()); // TODO-COPY: verify outcome using pattern above @@ -404,7 +404,7 @@ describe('KeymanProjectCopier', function() { // We should have no messages and a successful result assert.isOk(result); - assert.isEmpty(callbacks.messages); + assert.isEmpty(callbacks.filteredMessages()); // TODO-COPY: verify outcome using pattern above From 1118a062b17d2b6c7beb57ad58d3bec59122ac28 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Wed, 22 Jan 2025 13:26:57 +1000 Subject: [PATCH 067/155] fix(windows): del cached files when download fails When download fails it could leave files in the cached foler this change leans them up before returning to idle. --- .../desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas | 1 + 1 file changed, 1 insertion(+) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index 539100be9b..c35725e78a 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -767,6 +767,7 @@ begin // IdleState to wait 'CheckPeriod' before trying again TKeymanSentryClient.Client.MessageEvent(Sentry.Client.SENTRY_LEVEL_ERROR, 'Error Updates not downloaded after 3 attempts'); + bucStateContext.RemoveCachedFiles; ChangeState(IdleState); end else From e949637e60b22e25a45257602f070f1d7de3cc9a Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Wed, 22 Jan 2025 13:55:17 +1000 Subject: [PATCH 068/155] fix(windows): continue if keyboard package is not found --- .../desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index c35725e78a..407765d8fd 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -1035,10 +1035,9 @@ begin PackageFullPath := SavePath + Params.Packages[i].FileName; if not FileExists(PackageFullPath) then begin - TKeymanSentryClient.Client.MessageEvent(Sentry.Client.SENTRY_LEVEL_ERROR, - 'File does not exist:"' + PackageFullPath + '"'); Continue; end; + if not DoInstallPackage(PackageFullPath) then // I2742 begin TKeymanSentryClient.Client.MessageEvent(Sentry.Client.SENTRY_LEVEL_ERROR, From c6aa912655cef5b07013e8a325b9e6d13af014ee Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 22 Jan 2025 10:58:01 +0700 Subject: [PATCH 069/155] chore(developer): validate output folder name in kmc-copy Fixes: #12978 --- .../src/kmc-copy/src/KeymanProjectCopier.ts | 17 ++++++++-- developer/src/kmc-copy/src/copier-messages.ts | 14 ++++++++ developer/src/kmc-copy/test/messages.tests.ts | 34 +++++++++++++++++-- .../kmc-generate/src/generator-messages.ts | 2 ++ 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/developer/src/kmc-copy/src/KeymanProjectCopier.ts b/developer/src/kmc-copy/src/KeymanProjectCopier.ts index 255ba6d63c..7d39611f14 100644 --- a/developer/src/kmc-copy/src/KeymanProjectCopier.ts +++ b/developer/src/kmc-copy/src/KeymanProjectCopier.ts @@ -4,7 +4,7 @@ * Copy a keyboard or lexical model project */ -import { CloudUrls, GitHubUrls, CompilerCallbacks, CompilerLogLevel, KeymanCompiler, KeymanCompilerArtifact, KeymanCompilerArtifacts, KeymanCompilerResult, KeymanDeveloperProject, KeymanDeveloperProjectOptions, KPJFileReader, KPJFileWriter, KpsFileReader, KpsFileWriter } from "@keymanapp/developer-utils"; +import { CloudUrls, GitHubUrls, CompilerCallbacks, CompilerLogLevel, KeymanCompiler, KeymanCompilerArtifact, KeymanCompilerArtifacts, KeymanCompilerResult, KeymanDeveloperProject, KeymanDeveloperProjectOptions, KPJFileReader, KPJFileWriter, KpsFileReader, KpsFileWriter, ValidIds } from "@keymanapp/developer-utils"; import { KeymanFileTypes } from "@keymanapp/common-types"; import { CopierMessages } from "./copier-messages.js"; @@ -120,7 +120,6 @@ export class KeymanProjectCopier implements KeymanCompiler { this.asyncCallbacks = new CopierAsyncCallbacks(this.callbacks, this.githubRef); - // TODO-COPY: validate outputId is valid for the project type? this.outputId = this.callbacks.path.basename(this.outPath); this.sourceId = this.callbacks.path.basename(projectSource, KeymanFileTypes.Source.Project); @@ -131,6 +130,20 @@ export class KeymanProjectCopier implements KeymanCompiler { return null; } + if(project.isKeyboardProject()) { + // LDML and .kmn keyboards have the same id validity requirements, so + // we'll just test against .kmn + if(!ValidIds.isValidKeymanKeyboardId(this.outputId)) { + this.callbacks.reportMessage(CopierMessages.Error_InvalidKeyboardId({id: this.outputId})); + return null; + } + } else if(project.isLexicalModelProject()) { + if(!ValidIds.isValidLexicalModelId(this.outputId)) { + this.callbacks.reportMessage(CopierMessages.Error_InvalidLexicalModelId({id: this.outputId})); + return null; + } + } + const result: CopierResult = { artifacts: { 'kmc-copy:outputPath': { data: null, diff --git a/developer/src/kmc-copy/src/copier-messages.ts b/developer/src/kmc-copy/src/copier-messages.ts index 8b25f93b19..4102170730 100644 --- a/developer/src/kmc-copy/src/copier-messages.ts +++ b/developer/src/kmc-copy/src/copier-messages.ts @@ -211,4 +211,18 @@ export class CopierMessages { `Downloading folder '${def(o.path)}' from '${def(o.url)}'`, ); + // See also generator-messages.ERROR_InvalidKeymanKeyboardId + static ERROR_InvalidKeyboardId = SevError | 0x001E; + static Error_InvalidKeyboardId = (o:{id: string}) => m( + this.ERROR_InvalidKeyboardId, + `The specified keyboard id '${def(o.id)}' contains characters that are not permitted for a keyboard id or filename.`, + ); + + // See also generator-messages.ERROR_InvalidLexicalModelId + static ERROR_InvalidLexicalModelId = SevError | 0x001F; + static Error_InvalidLexicalModelId = (o:{id:string}) => m( + this.ERROR_InvalidLexicalModelId, + `The specified lexical model id '${def(o.id)}' contains characters that are not permitted or does not match the required pattern of 'author.bcp47.uniq'.`, + ); + }; diff --git a/developer/src/kmc-copy/test/messages.tests.ts b/developer/src/kmc-copy/test/messages.tests.ts index aca98c3ea7..0a35b8afde 100644 --- a/developer/src/kmc-copy/test/messages.tests.ts +++ b/developer/src/kmc-copy/test/messages.tests.ts @@ -6,16 +6,44 @@ import 'mocha'; // import * as path from 'path'; // import * as fs from 'fs'; // import { fileURLToPath } from 'url'; -// import { assert } from 'chai'; -import { CopierMessages } from '../src/copier-messages.js'; -import { verifyCompilerMessagesObject } from '@keymanapp/developer-test-helpers'; +import { assert } from 'chai'; +import { TestCompilerCallbacks, verifyCompilerMessagesObject } from '@keymanapp/developer-test-helpers'; import { CompilerErrorNamespace } from '@keymanapp/developer-utils'; +import { CopierMessages } from '../src/copier-messages.js'; +import { KeymanProjectCopier } from '../src/KeymanProjectCopier.js'; +import { makePathToFixture } from './helpers/index.js'; describe('CopierMessages', function () { + const callbacks = new TestCompilerCallbacks(makePathToFixture('online')); + + this.beforeEach(function() { + callbacks.clear(); + }); + + this.afterEach(function() { + if(this.currentTest?.isFailed()) { + callbacks.printMessages(); + } + }); + it('should have a valid CopierMessages object', function() { return verifyCompilerMessagesObject(CopierMessages, CompilerErrorNamespace.Copier); }); + it('should generate ERROR_InvalidKeyboardId if the output keyboard id is invalid', async function() { + const copier = new KeymanProjectCopier(); + assert.isTrue(await copier.init(callbacks, {dryRun: true, outPath: '0invalid'})) + assert.isNull(await copier.run('cloud:jawa')); + assert.isTrue(callbacks.hasMessage(CopierMessages.ERROR_InvalidKeyboardId)); + }); + + it('should generate ERROR_InvalidLexicalModelId if the output lexical model id is invalid', async function() { + const copier = new KeymanProjectCopier(); + assert.isTrue(await copier.init(callbacks, {dryRun: true, outPath: 'nrc.str-x-sencoten.sencoten'})) + assert.isNull(await copier.run('cloud:nrc.str.sencoten')); + assert.isTrue(callbacks.hasMessage(CopierMessages.ERROR_InvalidLexicalModelId)); + }); + // it('should generate ERROR_OutputPathAlreadyExists if output path already exists', async function () { // const ag = new AbstractGenerator(); // const callbacks = new TestCompilerCallbacks(); diff --git a/developer/src/kmc-generate/src/generator-messages.ts b/developer/src/kmc-generate/src/generator-messages.ts index ad562dbd29..6c9ccfa7d8 100644 --- a/developer/src/kmc-generate/src/generator-messages.ts +++ b/developer/src/kmc-generate/src/generator-messages.ts @@ -61,6 +61,7 @@ export class GeneratorMessages { `The specified target platform '${def(o.target)}' is not a valid target.` ); + // See also copier-messages.ERROR_InvalidKeyboardId static ERROR_InvalidKeymanKeyboardId = SevError | 0x0008; static Error_InvalidKeymanKeyboardId = (o:{id:string}) => m( this.ERROR_InvalidKeymanKeyboardId, @@ -73,6 +74,7 @@ export class GeneratorMessages { `The specified keyboard id '${def(o.id)}' contains characters that are not permitted for an LDML .xml keyboard id or filename.` ); + // See also copier-messages.ERROR_InvalidLexicalModelId static ERROR_InvalidLexicalModelId = SevError | 0x000A; static Error_InvalidLexicalModelId = (o:{id:string}) => m( this.ERROR_InvalidLexicalModelId, From 62a2608013dc14219b053fbf01038f6cd06d3312 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 22 Jan 2025 11:10:54 +0700 Subject: [PATCH 070/155] chore(developer): add new severity types to message command --- developer/src/kmc/src/commands/messageCommand.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/src/kmc/src/commands/messageCommand.ts b/developer/src/kmc/src/commands/messageCommand.ts index ee568dad9c..257eacc913 100644 --- a/developer/src/kmc/src/commands/messageCommand.ts +++ b/developer/src/kmc/src/commands/messageCommand.ts @@ -178,7 +178,7 @@ function allMessageDetails(): CompilerMessageDetail[] { const toTitleCase = (s: string) => s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); function getMessageDetail(cls: any, id: string, escapeMarkdown: boolean): CompilerEvent { - const o = /^(INFO|HINT|WARN|ERROR|FATAL)_([A-Za-z0-9_]+)$/.exec(id); + const o = /^(DEBUG|VERBOSE|INFO|HINT|WARN|ERROR|FATAL)_([A-Za-z0-9_]+)$/.exec(id); if(!o) { throw new Error(`Unexpected compiler message ${id}, does not match message error format`); } From d4513a1d512dc115ee2b5232c78f82a42e7da626 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 22 Jan 2025 11:10:54 +0700 Subject: [PATCH 071/155] chore(developer): add new severity types to message command --- developer/src/kmc/src/commands/messageCommand.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/src/kmc/src/commands/messageCommand.ts b/developer/src/kmc/src/commands/messageCommand.ts index ee568dad9c..257eacc913 100644 --- a/developer/src/kmc/src/commands/messageCommand.ts +++ b/developer/src/kmc/src/commands/messageCommand.ts @@ -178,7 +178,7 @@ function allMessageDetails(): CompilerMessageDetail[] { const toTitleCase = (s: string) => s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); function getMessageDetail(cls: any, id: string, escapeMarkdown: boolean): CompilerEvent { - const o = /^(INFO|HINT|WARN|ERROR|FATAL)_([A-Za-z0-9_]+)$/.exec(id); + const o = /^(DEBUG|VERBOSE|INFO|HINT|WARN|ERROR|FATAL)_([A-Za-z0-9_]+)$/.exec(id); if(!o) { throw new Error(`Unexpected compiler message ${id}, does not match message error format`); } From d6ce0af77e5bd07ccae568f3823cf1a473968573 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Wed, 22 Jan 2025 11:28:50 +0700 Subject: [PATCH 072/155] chore(mac): added tag for lifecycleState Fixes: #11623 --- .../Keyman4MacIM/KMInputMethodEventHandler.m | 40 ++++++++++++++++--- .../Keyman4MacIM/KMInputMethodLifecycle.m | 40 +++++++++++++++++-- .../Keyman4MacIM/Logging/KMSentryHelper.h | 2 + .../Keyman4MacIM/Logging/KMSentryHelper.m | 15 ++++++- .../Keyman4MacIM/TextApiCompliance.m | 4 ++ 5 files changed, 89 insertions(+), 12 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m index d900cf073a..fcb381013e 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m @@ -44,6 +44,10 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; _lowLevelBackspaceCount = 0; _queuedText = nil; + _apiCompliance = [[TextApiCompliance alloc]initWithClient:sender applicationId:clientAppId]; + os_log_info([KMLogs lifecycleLog], "KMInputMethodEventHandler initWithClient, clientAppId: %{public}@", clientAppId); + [KMSentryHelper addBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"KMInputMethodEventHandler initWithClient, clientAppId '%@'", clientAppId]]; + [KMSentryHelper addClientAppIdTag:clientAppId]; return self; } @@ -184,13 +188,10 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; //MARK: Core-related key processing - (void)checkTextApiCompliance:(id)client { - // If the TextApiCompliance object is nil or the app or the context has changed, - // then create a new object for the current application and context. + // If the TextApiCompliance object is stale, create a new one for the current application and context. // The text api compliance may vary from one text field to another of the same app. - if ((self.apiCompliance == nil) || - (![self.apiCompliance.clientApplicationId isEqualTo:self.clientApplicationId]) || - self.contextChanged) { + if ([self textApiComplianceIsStale]) { self.apiCompliance = [[TextApiCompliance alloc]initWithClient:client applicationId:self.clientApplicationId]; os_log_debug([KMLogs complianceLog], "KMInputMethodHandler initWithClient checkTextApiCompliance: %{public}@", _apiCompliance); } else if (self.apiCompliance.isComplianceUncertain) { @@ -199,6 +200,33 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; } } +- (BOOL)textApiComplianceIsStale { + BOOL stale = false; + NSString *complianceAppId = nil; + TextApiCompliance *currentApiCompliance = self.apiCompliance; + + // test for three scenarios in which the api compliance is stale + if (currentApiCompliance == nil) { // if we have no previous api compliance object + stale = true; + } else { // if we have one but for a different client + complianceAppId = self.apiCompliance.clientApplicationId; + if ([complianceAppId isNotEqualTo:self.clientApplicationId]) { + stale = true; + } else { + stale = false; + } + } + if (self.contextChanged) { // if the context has changed + stale = true; + } + + NSString *message = [NSString stringWithFormat:@"textApiComplianceIsStale = %@ for appId: %@, apiCompliance: %p, complianceAppId: %@", stale?@"true":@"false", self.clientApplicationId, currentApiCompliance, complianceAppId]; + [KMSentryHelper addDebugBreadCrumb:@"compliance" message:message]; + os_log_debug([KMLogs complianceLog], "%{public}@", message); + + return stale; +} + - (void) handleContextChangedByLowLevelEvent { if (self.appDelegate.contextChangedByLowLevelEvent) { if (!self.contextChanged) { @@ -220,7 +248,7 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; [self handleContextChangedByLowLevelEvent]; if (event.type == NSEventTypeKeyDown) { - [KMSentryHelper addBreadCrumb:@"event" message:@"handling keydown event"]; + [KMSentryHelper addDebugBreadCrumb:@"event" message:@"handling keydown event"]; // indicates that our generated backspace event(s) are consumed // and we can insert text that followed the backspace(s) if (event.keyCode == kKeymanEventKeyCode) { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m index 543d7fe4d8..6c98c17b3c 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m @@ -66,6 +66,8 @@ typedef enum { @implementation KMInputMethodLifecycle +@synthesize lifecycleState = _lifecycleState; + + (KMInputMethodLifecycle *)shared { static KMInputMethodLifecycle *shared = nil; static dispatch_once_t onceToken; @@ -86,11 +88,40 @@ typedef enum { return self; } +- (void)setLifecycleState:(LifecycleState)state { + _lifecycleState = state; + + // whenever the state is changed, update the Sentry tag + [self addLifecycleStateSentryTag]; +} + +- (void)addLifecycleStateSentryTag { + NSString *stateString = @"Unknown"; + switch (self.lifecycleState) { + case Started: + stateString = @"Started"; + break; + case Active: + stateString = @"Active"; + break; + case Inactive: + stateString = @"Inactive"; + break; + } + [KMSentryHelper addLifecycleStateTag:stateString]; + os_log_info([KMLogs lifecycleLog], "setLifecycleState: %{public}@", stateString); +} + + +- (LifecycleState)lifecycleState { + return _lifecycleState; +} + /** * called from Application Delgate during init */ - (void)startLifecycle { - _lifecycleState = Started; + self.lifecycleState = Started; } /** @@ -109,6 +140,7 @@ typedef enum { + (NSString*)getRunningApplicationId { NSRunningApplication *currentApp = [[NSWorkspace sharedWorkspace] frontmostApplication]; NSString *clientAppId = [currentApp bundleIdentifier]; + os_log_debug([KMLogs lifecycleLog], "getRunningApplicationId, frontmost: %{public}@", clientAppId); return clientAppId; } @@ -217,7 +249,7 @@ typedef enum { */ - (void)activateInputMethod { os_log_debug([KMLogs lifecycleLog], "activateInputMethod"); - _lifecycleState = Active; + self.lifecycleState = Active; [[NSNotificationCenter defaultCenter] postNotificationName:kInputMethodActivatedNotification object:self]; } @@ -226,7 +258,7 @@ typedef enum { */ - (void)deactivateInputMethod { os_log_debug([KMLogs lifecycleLog], "deactivateInputMethod"); - _lifecycleState = Inactive; + self.lifecycleState = Inactive; [[NSNotificationCenter defaultCenter] postNotificationName:kInputMethodDeactivatedNotification object:self]; } @@ -234,7 +266,7 @@ typedef enum { * Does not change lifecycleState, just fires notification so that InputController knows to change the event handler */ - (void)changeClient { - os_log_debug([KMLogs lifecycleLog], "changeClient"); + os_log_debug([KMLogs lifecycleLog], "changeClient, posting kInputMethodClientChangeNotification"); [[NSNotificationCenter defaultCenter] postNotificationName:kInputMethodClientChangeNotification object:self]; } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h index 5699cef1d2..adbce67a53 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h @@ -11,6 +11,7 @@ NS_ASSUME_NONNULL_BEGIN @interface KMSentryHelper : NSObject ++ (void)addLifecycleStateTag: (NSString *)value; + (void)addApiComplianceTag: (NSString *)value; + (void)addArchitectureTag: (NSString *)value; + (void)addOskVisibleTag:(BOOL)value; @@ -19,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN + (void)addHasAccessibilityTag:(BOOL)value; + (void)addActiveKeyboardCountTag:(NSUInteger)value; + (void)addBreadCrumb:(NSString *)category message:(NSString *)messageText; ++ (void)addDebugBreadCrumb:(NSString *)category message:(NSString *)messageText; + (void)addUserBreadCrumb:(NSString *)category message:(NSString *)messageText; + (void)addDetailedBreadCrumb:(NSString *)category message:(NSString *)messageText data:( NSDictionary *) map; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m index 66656b24d5..b28e0b5b76 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m @@ -18,6 +18,11 @@ NSString * const kClientAppIdTagName = @"clientAppId"; NSString * const kKeyboardTagName = @"keyboard"; NSString * const kHasAccessibilityTagName = @"accessibilityEnabled"; NSString * const kActiveKeyboardCountTagName = @"activeKeyboardCount"; +NSString * const kLifecycleStateTagName = @"lifecycleState"; + ++ (void)addLifecycleStateTag: (NSString *)value { + [self addCustomTag:kLifecycleStateTagName withValue:value]; +} + (void)addApiComplianceTag: (NSString *)value { [self addCustomTag:kApiComplianceTagName withValue:value]; @@ -61,7 +66,14 @@ NSString * const kActiveKeyboardCountTagName = @"activeKeyboardCount"; crumb.level = kSentryLevelInfo; crumb.category = category; crumb.message = messageText; - //crumb.message = [NSString stringWithFormat:@"setDefaultSelectedKeyboard: %@", keyboardName]; + [SentrySDK addBreadcrumb:crumb]; +} + ++ (void)addDebugBreadCrumb:(NSString *)category message:(NSString *)messageText { + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; + crumb.level = kSentryLevelDebug; + crumb.category = category; + crumb.message = messageText; [SentrySDK addBreadcrumb:crumb]; } @@ -71,7 +83,6 @@ NSString * const kActiveKeyboardCountTagName = @"activeKeyboardCount"; crumb.level = kSentryLevelInfo; crumb.category = category; crumb.message = messageText; - //crumb.message = [NSString stringWithFormat:@"setDefaultSelectedKeyboard: %@", keyboardName]; [SentrySDK addBreadcrumb:crumb]; } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m index 4d77bada0f..81f50c5edd 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m @@ -63,6 +63,10 @@ NSString *const kKMLegacyApps = @"KMLegacyApps"; _clientApplicationId = appId; _complianceUncertain = YES; _initialSelection = NSMakeRange(NSNotFound, NSNotFound); + + NSString *message = [NSString stringWithFormat:@"TextApiCompliance initWithClient, client: %p applicationId: %@", client, appId]; + [KMSentryHelper addDebugBreadCrumb:@"compliance" message:message]; + os_log_debug([KMLogs complianceLog], "%{public}@", message); // if we do not have hard-coded noncompliance, then test the app if (![self applyNoncompliantAppLists:appId]) { From ba8e5dc1525ebb1d2f2bb6c9372633eafc2a7cf5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 22 Jan 2025 12:32:33 +0700 Subject: [PATCH 073/155] chore(developer): report on filename collisions in kmc-copy Fixes: #12981 --- .../src/kmc-copy/src/KeymanProjectCopier.ts | 11 ++++- developer/src/kmc-copy/src/copier-messages.ts | 6 +++ ...ages.tests.ts => copier-messages.tests.ts} | 39 ++++-------------- .../fixtures/projects/collision/collision.kpj | 7 ++++ .../projects/collision/source/collided.ico | Bin 0 -> 1150 bytes .../projects/collision/source/collision.ico | Bin 0 -> 1150 bytes .../projects/collision/source/collision.kmn | 7 ++++ 7 files changed, 36 insertions(+), 34 deletions(-) rename developer/src/kmc-copy/test/{messages.tests.ts => copier-messages.tests.ts} (52%) create mode 100644 developer/src/kmc-copy/test/fixtures/projects/collision/collision.kpj create mode 100644 developer/src/kmc-copy/test/fixtures/projects/collision/source/collided.ico create mode 100644 developer/src/kmc-copy/test/fixtures/projects/collision/source/collision.ico create mode 100644 developer/src/kmc-copy/test/fixtures/projects/collision/source/collision.kmn diff --git a/developer/src/kmc-copy/src/KeymanProjectCopier.ts b/developer/src/kmc-copy/src/KeymanProjectCopier.ts index 7d39611f14..69eb723bfb 100644 --- a/developer/src/kmc-copy/src/KeymanProjectCopier.ts +++ b/developer/src/kmc-copy/src/KeymanProjectCopier.ts @@ -310,7 +310,6 @@ export class KeymanProjectCopier implements KeymanCompiler { }; private async copyFolder(inputPath: string, outputPath: string, ignorePatterns: (string | RegExp)[], result: CopierResult) { - // TODO-COPY: watch out for file collisions when copying project files -- after renames const files = await this.asyncCallbacks.fsAsync.readdir(inputPath); for(const {filename,type} of files) { const fullPath = this.normalizePath(this.callbacks.path.join(inputPath, filename)); @@ -320,9 +319,17 @@ export class KeymanProjectCopier implements KeymanCompiler { if(type == 'dir') { await this.copyFolder(fullPath, this.callbacks.path.join(outputPath, filename), ignorePatterns, result); } else if(!result.artifacts[fullPath]) { + const filename = this.generateNewFilename(fullPath, outputPath); + + for(const artifact of Object.keys(result.artifacts)) { + if(result.artifacts[artifact].filename == filename) { + this.callbacks.reportMessage(CopierMessages.Warn_FilenameCollides({filename})); + } + } + result.artifacts[fullPath] = { data: await this.asyncCallbacks.fsAsync.readFile(fullPath), - filename: this.generateNewFilename(fullPath, outputPath) + filename } } } diff --git a/developer/src/kmc-copy/src/copier-messages.ts b/developer/src/kmc-copy/src/copier-messages.ts index 4102170730..8afff79149 100644 --- a/developer/src/kmc-copy/src/copier-messages.ts +++ b/developer/src/kmc-copy/src/copier-messages.ts @@ -225,4 +225,10 @@ export class CopierMessages { `The specified lexical model id '${def(o.id)}' contains characters that are not permitted or does not match the required pattern of 'author.bcp47.uniq'.`, ); + static WARN_FilenameCollides = SevWarn | 0x0020; + static Warn_FilenameCollides = (o:{filename:string}) => m( + this.WARN_FilenameCollides, + `The output file '${def(o.filename)}' has two different possible source files.`, + ); + }; diff --git a/developer/src/kmc-copy/test/messages.tests.ts b/developer/src/kmc-copy/test/copier-messages.tests.ts similarity index 52% rename from developer/src/kmc-copy/test/messages.tests.ts rename to developer/src/kmc-copy/test/copier-messages.tests.ts index 0a35b8afde..0312910860 100644 --- a/developer/src/kmc-copy/test/messages.tests.ts +++ b/developer/src/kmc-copy/test/copier-messages.tests.ts @@ -44,36 +44,11 @@ describe('CopierMessages', function () { assert.isTrue(callbacks.hasMessage(CopierMessages.ERROR_InvalidLexicalModelId)); }); - // it('should generate ERROR_OutputPathAlreadyExists if output path already exists', async function () { - // const ag = new AbstractGenerator(); - // const callbacks = new TestCompilerCallbacks(); - // const options: GeneratorOptions = { - // id: 'ERROR_OutputPathAlreadyExists', - // outPath: path.dirname(fileURLToPath(import.meta.url)), - // }; - // assert(await ag.init(callbacks, options)); - // const dir = path.join(path.dirname(fileURLToPath(import.meta.url)), 'ERROR_OutputPathAlreadyExists'); - // if(!fs.existsSync(dir)) - // fs.mkdirSync(dir); - // assert.isFalse(await ag.write({})); - // assert.isTrue(callbacks.hasMessage(CopierMessages.ERROR_OutputPathAlreadyExists), - // `messageId ERROR_OutputPathAlreadyExists not generated, instead got: `+JSON.stringify(callbacks.messages,null,2)); - - // fs.rmdirSync(dir); - // }); - - // it('should generate ERROR_CannotWriteOutputFile if it cannot create a folder, e.g. invalid filename', async function () { - // const ag = new AbstractGenerator(); - // const callbacks = new TestCompilerCallbacks(); - // const options: GeneratorOptions = { - // id: 'ERROR_CannotWriteOutputFile', - // outPath: path.dirname(fileURLToPath(import.meta.url)), - // }; - // assert(await ag.init(callbacks, options)); - // assert.isFalse(await ag.write({ - // '.': {filename: '.', data: new Uint8Array([1,2,3])} - // })); - // assert.isTrue(callbacks.hasMessage(GeneratorMessages.ERROR_CannotWriteOutputFile), - // `messageId ERROR_CannotWriteOutputFile not generated, instead got: `+JSON.stringify(callbacks.messages,null,2)); - // }); + it('should generate WARN_FilenameCollision if a copied file will collide', async function() { + const copier = new KeymanProjectCopier(); + assert.isTrue(await copier.init(callbacks, {dryRun: true, outPath: 'collided'})) + const result = await copier.run(makePathToFixture('projects/collision/collision.kpj')); + assert.isNotNull(result); + assert.isTrue(callbacks.hasMessage(CopierMessages.WARN_FilenameCollides)); + }); }); diff --git a/developer/src/kmc-copy/test/fixtures/projects/collision/collision.kpj b/developer/src/kmc-copy/test/fixtures/projects/collision/collision.kpj new file mode 100644 index 0000000000..fffdca635e --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/collision/collision.kpj @@ -0,0 +1,7 @@ + + + + keyboard + 2.0 + + diff --git a/developer/src/kmc-copy/test/fixtures/projects/collision/source/collided.ico b/developer/src/kmc-copy/test/fixtures/projects/collision/source/collided.ico new file mode 100644 index 0000000000000000000000000000000000000000..84b57c5aebc31098a75ea11ed69a4c62add2fc1a GIT binary patch literal 1150 zcmd6iOAdrE3`2u72k445%Q+hNzd%Wmo@7~#_^c>Oo!D_wB9{DG+hUyk7qKS(Gg`)$ zv7C1%srl)>$5%q%=5HFBbF-Qms?9jnHTOMuomUSzz0?Ca%2m1Vc;fY4cztHITY0?9 oRP8Fq%UHq)$ literal 0 HcmV?d00001 diff --git a/developer/src/kmc-copy/test/fixtures/projects/collision/source/collision.ico b/developer/src/kmc-copy/test/fixtures/projects/collision/source/collision.ico new file mode 100644 index 0000000000000000000000000000000000000000..84b57c5aebc31098a75ea11ed69a4c62add2fc1a GIT binary patch literal 1150 zcmd6iOAdrE3`2u72k445%Q+hNzd%Wmo@7~#_^c>Oo!D_wB9{DG+hUyk7qKS(Gg`)$ zv7C1%srl)>$5%q%=5HFBbF-Qms?9jnHTOMuomUSzz0?Ca%2m1Vc;fY4cztHITY0?9 oRP8Fq%UHq)$ literal 0 HcmV?d00001 diff --git a/developer/src/kmc-copy/test/fixtures/projects/collision/source/collision.kmn b/developer/src/kmc-copy/test/fixtures/projects/collision/source/collision.kmn new file mode 100644 index 0000000000..121e224d89 --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/collision/source/collision.kmn @@ -0,0 +1,7 @@ +store(&TARGETS) 'any' +store(&NAME) 'Collision' +store(&BITMAP) 'collision.ico' + +begin Unicode > use(main) + +group(main) using keys From 0ec2664126941726d6ddd07c58f8aa427150d4d6 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Wed, 22 Jan 2025 12:52:44 +0700 Subject: [PATCH 074/155] chore(mac): clean up comments --- .../Keyman4MacIM/KMInputMethodAppDelegate.m | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 66842926b3..3c2fd7f710 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -18,7 +18,6 @@ #import "PrivacyConsent.h" #import "KMLogs.h" #import "KMSentryHelper.h" -//#include "TargetConditionals.h" @import Sentry; #if TARGET_CPU_ARM64 @@ -198,7 +197,6 @@ id _lastServerWithOSKShowing = nil; [self updateKeyboardMenuItems]; [self setPostLaunchKeymanSentryTags]; self.sentryTestingEnabled = [KMSettingsRepository.shared readForceSentryError]; - // [SentrySDK captureMessage:@"Starting Keyman [test message]"]; } - (void)startSentry { @@ -209,7 +207,6 @@ id _lastServerWithOSKShowing = nil; options.dsn = @"https://960f8b8e574c46e3be385d60ce8e1fea@o1005580.ingest.sentry.io/5983522"; options.releaseName = releaseName; options.environment = keymanVersionInfo.sentryEnvironment; - //options.debug = YES; }]; } @@ -244,23 +241,13 @@ id _lastServerWithOSKShowing = nil; NSString *keyboardFileName = [self.kmx.filePath lastPathComponent]; os_log_info([KMLogs keyboardLog], "initial kmx set to %{public}@", keyboardFileName); - // assign custom keyboard tag in Sentry for accessibility and initial keyboard + // assign custom keyboard tags in Sentry [KMSentryHelper addKeyboardTag:keyboardFileName]; [KMSentryHelper addHasAccessibilityTag:[PrivacyConsent.shared checkAccessibility]]; [KMSentryHelper addOskVisibleTag:[self.oskWindow.window isVisible]]; [KMSentryHelper addArchitectureTag:processorType]; - } -#ifdef USE_ALERT_SHOW_HELP_TO_FORCE_EASTER_EGG_CRASH_FROM_ENGINE -- (BOOL)alertShowHelp:(NSAlert *)alert { - os_log_error([KMLogs startupLog], "Sentry - KME: Got call to force crash from engine"); - [SentrySDK crash]; - os_log_error([KMLogs startupLog], "Sentry - KME: should not have gotten this far!"); - return NO; -} -#endif - - (void)handleURLEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent { [self processURL:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]]; From b51f1213d9eeea147151d92ca8ec10d61f7478b0 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 22 Jan 2025 13:20:13 +0700 Subject: [PATCH 075/155] feat(developer): support copying disorganized projects in kmc-copy Fixes: #12983 --- developer/src/kmc-copy/build.sh | 2 +- .../src/kmc-copy/src/KeymanProjectCopier.ts | 7 +- developer/src/kmc-copy/test/copier.tests.ts | 35 +- .../fixtures/projects/disorganized/HISTORY.md | 35 + .../fixtures/projects/disorganized/LICENSE.md | 21 + .../fixtures/projects/disorganized/README.md | 25 + .../projects/disorganized/alephwithbeth.ico | Bin 0 -> 1150 bytes .../projects/disorganized/alephwithbeth.js | 1 + .../projects/disorganized/alephwithbeth.kmn | 215 +++ .../projects/disorganized/alephwithbeth.kmp | Bin 0 -> 244485 bytes .../projects/disorganized/alephwithbeth.kmx | Bin 0 -> 7172 bytes .../projects/disorganized/alephwithbeth.kpj | 133 ++ .../projects/disorganized/alephwithbeth.kps | 95 + .../projects/disorganized/alephwithbeth.kvk | Bin 0 -> 1921 bytes .../projects/disorganized/alephwithbeth.kvks | 138 ++ .../other/alephwithbeth.keyman-touch-layout | 1646 +++++++++++++++++ .../other/help/KeyboardLayout.png | Bin 0 -> 97424 bytes .../other/help/KeyboardLayoutAlt.png | Bin 0 -> 61615 bytes .../other/help/KeyboardLayoutShift.png | Bin 0 -> 85201 bytes .../disorganized/other/help/alephwithbeth.php | 22 + .../projects/disorganized/other/readme.htm | 22 + .../other/welcome/KeyboardLayout.png | Bin 0 -> 97424 bytes .../other/welcome/KeyboardLayoutAlt.png | Bin 0 -> 61615 bytes .../other/welcome/KeyboardLayoutShift.png | Bin 0 -> 85201 bytes .../disorganized/other/welcome/welcome.htm | 28 + 25 files changed, 2422 insertions(+), 3 deletions(-) create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/HISTORY.md create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/LICENSE.md create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/README.md create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.ico create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.js create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kmn create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kmp create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kmx create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kpj create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kps create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kvk create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kvks create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/other/alephwithbeth.keyman-touch-layout create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/KeyboardLayout.png create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/KeyboardLayoutAlt.png create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/KeyboardLayoutShift.png create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/alephwithbeth.php create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/other/readme.htm create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/KeyboardLayout.png create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/KeyboardLayoutAlt.png create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/KeyboardLayoutShift.png create mode 100644 developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/welcome.htm diff --git a/developer/src/kmc-copy/build.sh b/developer/src/kmc-copy/build.sh index ee8615fc44..b681757be2 100755 --- a/developer/src/kmc-copy/build.sh +++ b/developer/src/kmc-copy/build.sh @@ -39,6 +39,6 @@ builder_run_action api api-extractor run --local --verbose # note: `export TEST_SAVE_ARTIFACTS=1` to save a copy of artifacts to temp path # note: `export TEST_SAVE_FIXTURES=1` to get a copy of cloud-based fixtures saved to online/ # TODO: -skip-full -builder_run_action test builder_do_typescript_tests 70 +builder_run_action test builder_do_typescript_tests 75 builder_run_action publish builder_publish_npm diff --git a/developer/src/kmc-copy/src/KeymanProjectCopier.ts b/developer/src/kmc-copy/src/KeymanProjectCopier.ts index 69eb723bfb..9e8d175991 100644 --- a/developer/src/kmc-copy/src/KeymanProjectCopier.ts +++ b/developer/src/kmc-copy/src/KeymanProjectCopier.ts @@ -380,7 +380,7 @@ export class KeymanProjectCopier implements KeymanCompiler { return true; } - private async copyGenericFile(_project: KeymanDeveloperProject, filename: string, outputPath: string, _source: string, result: CopierResult): Promise { + private async copyGenericFile(project: KeymanDeveloperProject, filename: string, outputPath: string, _source: string, result: CopierResult): Promise { if(result.artifacts[filename]) { return true; } @@ -403,6 +403,10 @@ export class KeymanProjectCopier implements KeymanCompiler { return false; } + if(KeymanFileTypes.binaryTypeFromFilename(filename) != null) { + outputPath = this.callbacks.path.join(this.outPath, 'build'); + } + result.artifacts[filename] = { data, filename: this.generateNewFilename(filename, outputPath) @@ -593,6 +597,7 @@ export class KeymanProjectCopier implements KeymanCompiler { */ private generateNewFilename(filename: string, outputPath: string): string { const {ext, base} = this.splitFilename(filename); + const newFilename = base == this.sourceId ? this.callbacks.path.join(outputPath, this.outputId + ext) : this.callbacks.path.join(outputPath, base + ext); diff --git a/developer/src/kmc-copy/test/copier.tests.ts b/developer/src/kmc-copy/test/copier.tests.ts index 7f4dccf535..6a2a8cbb1e 100644 --- a/developer/src/kmc-copy/test/copier.tests.ts +++ b/developer/src/kmc-copy/test/copier.tests.ts @@ -489,8 +489,41 @@ describe('KeymanProjectCopier', function() { }); })); + it('should copy a disorganized project into current structure', async function() { + const copier = new KeymanProjectCopier(); + assert.isTrue(await copier.init(callbacks, { + dryRun: false, + outPath: 'organized', + })); + + const result = await copier.run(makePathToFixture('projects','disorganized','alephwithbeth.kpj')); + assert.sameMembers(Object.keys(result.artifacts).map(k => result.artifacts[k].filename), [ + 'organized', // kmc-copy:outputPath + 'organized/organized.kpj', + 'organized/HISTORY.md', + 'organized/LICENSE.md', + 'organized/README.md', + // primary source files get moved to 'source/' + 'organized/source/organized.kps', + 'organized/source/organized.kmn', + 'organized/source/organized.ico', + 'organized/source/organized.kvks', + // files in 'other/' get moved to 'source/other/' + 'organized/source/other/organized.keyman-touch-layout', + 'organized/source/other/readme.htm', + 'organized/source/other/welcome/welcome.htm', + 'organized/source/other/welcome/KeyboardLayout.png', + 'organized/source/other/welcome/KeyboardLayoutAlt.png', + 'organized/source/other/welcome/KeyboardLayoutShift.png', + // build artifact files get moved to build/ + 'organized/build/organized.js', + 'organized/build/organized.kvk', + 'organized/build/organized.kmx', + // 'organized/build/organized.kmp', // TODO-COPY: do we need to copy this file as well? + ]); + }); + // TODO-COPY: additional tests - it.skip('should copy a disorganized project into current structure', async function() {}); it.skip('should copy a standalone .kmn into a new project', async function() {}); it.skip('should copy a standalone .kmn and .kps into a new project', async function() {}); }); diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/HISTORY.md b/developer/src/kmc-copy/test/fixtures/projects/disorganized/HISTORY.md new file mode 100644 index 0000000000..65dd7e13c7 --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/disorganized/HISTORY.md @@ -0,0 +1,35 @@ +alephwithbeth Change History +==================== + +1.0.6 (2024-06-11) +------------------ +* Remove source files from package + +1.0.5 (2023-02-28) +------------------ +* replaced hyphen with maqef +* added a touch-optimized keyboard layout for phone + +1.0.4 (2023-02-13) +------------------ +* Removed unnecessary version numbers. +* added description + +1.0.3 (2023-02-11) +------------------ +* Removed the faulty auto correct feature. +* Captialized all words of the title. +* Added title to .kmn + +1.0.2 (2023-02-09) +------------------ +* Renamed keyboard to "Aleph with Beth" + +1.0.1 (2023-02-08) +---------------- +* Updated author and website (in kps) +* Added copyrights where needed. + +1.0 (2023-01-28) +---------------- +* Created by Cameron Briggs diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/LICENSE.md b/developer/src/kmc-copy/test/fixtures/projects/disorganized/LICENSE.md new file mode 100644 index 0000000000..7f84a306c0 --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/disorganized/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright © 2023-2024 Cameron Briggs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/README.md b/developer/src/kmc-copy/test/fixtures/projects/disorganized/README.md new file mode 100644 index 0000000000..16edd8db20 --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/disorganized/README.md @@ -0,0 +1,25 @@ +alephwithbeth keyboard +============== + +Description +----------- +A Hebrew keyboard designed to intuitively match the standard QWERTY layout. + +Copyright +--------- +See [LICENSE.md](LICENSE.md) + +Supported Platforms +------------------- + * Windows + * macOS + * Linux + * Web + * iPhone + * iPad + * Android phone + * Android tablet + * Mobile devices + * Desktop devices + * Tablet devices + diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.ico b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.ico new file mode 100644 index 0000000000000000000000000000000000000000..84b57c5aebc31098a75ea11ed69a4c62add2fc1a GIT binary patch literal 1150 zcmd6iOAdrE3`2u72k445%Q+hNzd%Wmo@7~#_^c>Oo!D_wB9{DG+hUyk7qKS(Gg`)$ zv7C1%srl)>$5%q%=5HFBbF-Qms?9jnHTOMuomUSzz0?Ca%2m1Vc;fY4cztHITY0?9 oRP8Fq%UHq)$ literal 0 HcmV?d00001 diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.js b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.js new file mode 100644 index 0000000000..9466d76b85 --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.js @@ -0,0 +1 @@ +KeymanWeb.KR(new Keyboard_alephwithbeth());function Keyboard_alephwithbeth(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_alephwithbeth";this.KN="Aleph With Beth";this.KMINVER="14.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={"shift": ["","!","֘","֨","֜","֞","֔","֬","֝","(",")","_","+","","","","קּ","וּ","ֵ","רּ","תּ","יּ","ֻ","","וֹ","פּ","{","}","|","","","","ָ","סּ","דּ","טּ","גּ","הּ","וַיּ","כּ","לּ","״","\"","","","","","","","זּ","צּ","שּׂ","שּׁ","בּ","נּ","מּ","","ּ","?","","","","","",""],"default": ["֑","1","2","3","4","5","6","7","8","9","0","־","=","","","","ק","ו","ֶ","ר","ת","י","ע","ִ","ֹ","פ","[","]","\\","","","","ַ","ס","ד","ט","ג","ה","ח","כ","ל","ְ","'","","","","","","","ז","צ","שׂ","שׁ","ב","נ","מ","א",".","/","","","","","",""],"alt": ["","֗","֮","֙","֠","֩","֟","֡","֕","֓","֯","ֿ","◌","","","","","","ֱ","","","","","ֽ","ֳ","ף","֔","֒","֫","","","","ֲ","","","","•","̊","","ך","","׃","ׄ","","","","","","","","ץ","","","","ן","ם","֫","̈","״","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=0;this.KH="Aleph With Beth";this.KM=0;this.KBVER="1.0.6";this.KMBM=0x70;this.KRTL=1;this.KVKL={"tablet":{"displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"id":"K_HYPHEN","text":"־"},{"id":"K_EQUAL","text":"="},{"id":"K_BKSP","text":"*BkSp*","width":"100","sp":"1"}]},{"id":"2","key":[{"id":"K_Q","text":"ק","pad":"75"},{"id":"K_W","text":"ו"},{"id":"K_E","text":"ֶ"},{"id":"K_R","text":"ר"},{"id":"K_T","text":"ת"},{"id":"K_Y","text":"י"},{"id":"K_U","text":"ע"},{"id":"K_I","text":"ִ"},{"id":"K_O","text":"ֹ"},{"id":"K_P","text":"פ"},{"id":"K_LBRKT","text":"["},{"id":"K_RBRKT","text":"]"},{"id":"T_new_138","width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_BKQUOTE","text":"֑"},{"id":"K_A","text":"ַ"},{"id":"K_S","text":"ס"},{"id":"K_D","text":"ד"},{"id":"K_F","text":"ט"},{"id":"K_G","text":"ג"},{"id":"K_H","text":"ה"},{"id":"K_J","text":"ח"},{"id":"K_K","text":"כ"},{"id":"K_L","text":"ל"},{"id":"K_COLON","text":"ְ"},{"id":"K_QUOTE","text":"'"},{"id":"K_BKSLASH","text":"\\"}]},{"id":"4","key":[{"id":"K_SHIFT","text":"*Shift*","width":"160","sp":"1","nextlayer":"shift"},{"id":"K_oE2"},{"id":"K_Z","text":"ז"},{"id":"K_X","text":"צ"},{"id":"K_C","text":"שׂ"},{"id":"K_V","text":"שׁ"},{"id":"K_B","text":"ב"},{"id":"K_N","text":"נ"},{"id":"K_M","text":"מ"},{"id":"K_COMMA","text":"א"},{"id":"K_PERIOD","text":"."},{"id":"K_SLASH","text":"/"},{"id":"T_new_164","width":"10","sp":"10"}]},{"id":"5","key":[{"id":"K_LCONTROL","text":"alt","width":"130","sp":"1","nextlayer":"alt"},{"id":"K_LOPT","text":"*Menu*","width":"140","sp":"1"},{"id":"K_SPACE","width":"930"},{"id":"K_ENTER","text":"*Enter*","width":"145","sp":"1"}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_1","text":"!"},{"id":"K_2","text":"֘"},{"id":"K_3","text":"֨"},{"id":"K_4","text":"֜"},{"id":"K_5","text":"֞"},{"id":"K_6","text":"֔"},{"id":"K_7","text":"֬"},{"id":"K_8","text":"֝"},{"id":"K_9","text":"("},{"id":"K_0","text":")"},{"id":"K_HYPHEN","text":"_"},{"id":"K_EQUAL","text":"+"},{"id":"K_BKSP","text":"*BkSp*","width":"100","sp":"1"}]},{"id":"2","key":[{"id":"K_Q","text":"קּ","pad":"75"},{"id":"K_W","text":"וּ"},{"id":"K_E","text":"ֵ"},{"id":"K_R","text":"רּ"},{"id":"K_T","text":"תּ"},{"id":"K_Y","text":"יּ"},{"id":"K_U","text":"ֻ"},{"id":"K_I"},{"id":"K_O","text":"וֹ"},{"id":"K_P","text":"פּ"},{"id":"K_LBRKT","text":"{"},{"id":"K_RBRKT","text":"}"},{"id":"T_new_362","width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_BKQUOTE"},{"id":"K_A","text":"ָ"},{"id":"K_S","text":"סּ"},{"id":"K_D","text":"דּ"},{"id":"K_F","text":"טּ"},{"id":"K_G","text":"גּ"},{"id":"K_H","text":"הּ"},{"id":"K_J","text":"וַיּ"},{"id":"K_K","text":"כּ"},{"id":"K_L","text":"לּ"},{"id":"K_COLON","text":"״"},{"id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"|"}]},{"id":"4","key":[{"id":"K_SHIFT","text":"*Shift*","width":"160","sp":"1","nextlayer":"default"},{"id":"K_oE2"},{"id":"K_Z","text":"זּ"},{"id":"K_X","text":"צּ"},{"id":"K_C","text":"שּׂ"},{"id":"K_V","text":"שּׁ"},{"id":"K_B","text":"בּ"},{"id":"K_N","text":"נּ"},{"id":"K_M","text":"מּ"},{"id":"K_COMMA"},{"id":"K_PERIOD","text":"ּ"},{"id":"K_SLASH","text":"?"},{"id":"T_new_388","width":"10","sp":"10"}]},{"id":"5","key":[{"id":"K_LCONTROL","text":"alt","width":"130","sp":"1","nextlayer":"alt"},{"id":"K_LOPT","text":"*Menu*","width":"140","sp":"1"},{"id":"K_SPACE","width":"930"},{"id":"K_ENTER","text":"*Enter*","width":"145","sp":"1"}]}]},{"id":"alt","row":[{"id":"1","key":[{"id":"K_1","text":"֗"},{"id":"K_2","text":"֮"},{"id":"K_3","text":"֙"},{"id":"K_4","text":"֠"},{"id":"K_5","text":"֩"},{"id":"K_6","text":"֟"},{"id":"K_7","text":"֡"},{"id":"K_8","text":"֕"},{"id":"K_9","text":"֓"},{"id":"K_0","text":"֯"},{"id":"K_HYPHEN","text":"ֿ"},{"id":"K_EQUAL","text":"◌"},{"id":"K_BKSP","text":"*BkSp*","width":"100","sp":"1"}]},{"id":"2","key":[{"id":"K_Q","pad":"75"},{"id":"K_W"},{"id":"K_E","text":"ֱ"},{"id":"K_R"},{"id":"K_T"},{"id":"K_Y"},{"id":"K_U"},{"id":"K_I","text":"ֽ"},{"id":"K_O","text":"ֳ"},{"id":"K_P","text":"ף"},{"id":"K_LBRKT","text":"֔"},{"id":"K_RBRKT","text":"֒"},{"id":"T_new_138","width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_BKQUOTE"},{"id":"K_A","text":"ֲ"},{"id":"K_S"},{"id":"K_D"},{"id":"K_F"},{"id":"K_G","text":"•"},{"id":"K_H","text":"̊"},{"id":"K_J"},{"id":"K_K","text":"ך"},{"id":"K_L"},{"id":"K_COLON","text":"׃"},{"id":"K_QUOTE","text":"ׄ"},{"id":"K_BKSLASH","text":"֫"}]},{"id":"4","key":[{"id":"K_SHIFT","text":"*Shift*","width":"160","sp":"1","nextlayer":"shift","layer":"shift"},{"id":"K_oE2"},{"id":"K_Z"},{"id":"K_X","text":"ץ"},{"id":"K_C"},{"id":"K_V"},{"id":"K_B"},{"id":"K_N","text":"ן"},{"id":"K_M","text":"ם"},{"id":"K_COMMA","text":"֫"},{"id":"K_PERIOD","text":"̈"},{"id":"K_SLASH","text":"״"},{"id":"T_new_164","width":"10","sp":"10"}]},{"id":"5","key":[{"id":"K_LCONTROL","text":"default","width":"130","sp":"1","nextlayer":"default"},{"id":"K_LOPT","text":"*Menu*","width":"140","sp":"1"},{"id":"K_SPACE","width":"930"},{"id":"K_ENTER","text":"*Enter*","width":"145","sp":"1"}]}]}]},"phone":{"displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"id":"K_HYPHEN","text":"־"},{"id":"K_EQUAL","text":"="},{"id":"K_BKSP","text":"*BkSp*","width":"100","sp":"1"}]},{"id":"2","key":[{"id":"K_Q","text":"ק","pad":"75"},{"id":"K_W","text":"ו"},{"id":"K_E","text":"ֶ"},{"id":"K_R","text":"ר"},{"id":"K_T","text":"ת"},{"id":"K_Y","text":"י"},{"id":"K_U","text":"ע"},{"id":"K_I","text":"ִ"},{"id":"K_O","text":"ֹ"},{"id":"K_P","text":"פ"},{"id":"K_LBRKT","text":"["},{"id":"K_RBRKT","text":"]"},{"id":"T_new_138","width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_BKQUOTE","text":"֑"},{"id":"K_A","text":"ַ"},{"id":"K_S","text":"ס"},{"id":"K_D","text":"ד"},{"id":"K_F","text":"ט"},{"id":"K_G","text":"ג"},{"id":"K_H","text":"ה"},{"id":"K_J","text":"ח"},{"id":"K_K","text":"כ"},{"id":"K_L","text":"ל"},{"id":"K_COLON","text":"ְ"},{"id":"K_QUOTE","text":"'"},{"id":"K_BKSLASH","text":"\\"}]},{"id":"4","key":[{"id":"K_SHIFT","text":"*Shift*","width":"160","sp":"1","nextlayer":"shift"},{"id":"K_oE2"},{"id":"K_Z","text":"ז"},{"id":"K_X","text":"צ"},{"id":"K_C","text":"שׂ"},{"id":"K_V","text":"שׁ"},{"id":"K_B","text":"ב"},{"id":"K_N","text":"נ"},{"id":"K_M","text":"מ"},{"id":"K_COMMA","text":"א"},{"id":"K_PERIOD","text":"."},{"id":"K_SLASH","text":"/"},{"id":"T_new_164","width":"10","sp":"10"}]},{"id":"5","key":[{"id":"K_LCONTROL","text":"alt","width":"130","sp":"1","nextlayer":"alt"},{"id":"K_LOPT","text":"*Menu*","width":"140","sp":"1"},{"id":"K_SPACE","width":"930"},{"id":"K_ENTER","text":"*Enter*","width":"145","sp":"1"}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_1","text":"!"},{"id":"K_2","text":"֘"},{"id":"K_3","text":"֨"},{"id":"K_4","text":"֜"},{"id":"K_5","text":"֞"},{"id":"K_6","text":"֔"},{"id":"K_7","text":"֬"},{"id":"K_8","text":"֝"},{"id":"K_9","text":"("},{"id":"K_0","text":")"},{"id":"K_HYPHEN","text":"_"},{"id":"K_EQUAL","text":"+"},{"id":"K_BKSP","text":"*BkSp*","width":"100","sp":"1"}]},{"id":"2","key":[{"id":"K_Q","text":"קּ","pad":"75"},{"id":"K_W","text":"וּ"},{"id":"K_E","text":"ֵ"},{"id":"K_R","text":"רּ"},{"id":"K_T","text":"תּ"},{"id":"K_Y","text":"יּ"},{"id":"K_U","text":"ֻ"},{"id":"K_I"},{"id":"K_O","text":"וֹ"},{"id":"K_P","text":"פּ"},{"id":"K_LBRKT","text":"{"},{"id":"K_RBRKT","text":"}"},{"id":"T_new_362","width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_BKQUOTE"},{"id":"K_A","text":"ָ"},{"id":"K_S","text":"סּ"},{"id":"K_D","text":"דּ"},{"id":"K_F","text":"טּ"},{"id":"K_G","text":"גּ"},{"id":"K_H","text":"הּ"},{"id":"K_J","text":"וַיּ"},{"id":"K_K","text":"כּ"},{"id":"K_L","text":"לּ"},{"id":"K_COLON","text":"״"},{"id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"|"}]},{"id":"4","key":[{"id":"K_SHIFT","text":"*Shift*","width":"160","sp":"1","nextlayer":"default"},{"id":"K_oE2"},{"id":"K_Z","text":"זּ"},{"id":"K_X","text":"צּ"},{"id":"K_C","text":"שּׂ"},{"id":"K_V","text":"שּׁ"},{"id":"K_B","text":"בּ"},{"id":"K_N","text":"נּ"},{"id":"K_M","text":"מּ"},{"id":"K_COMMA"},{"id":"K_PERIOD","text":"ּ"},{"id":"K_SLASH","text":"?"},{"id":"T_new_388","width":"10","sp":"10"}]},{"id":"5","key":[{"id":"K_LCONTROL","text":"alt","width":"130","sp":"1","nextlayer":"alt"},{"id":"K_LOPT","text":"*Menu*","width":"140","sp":"1"},{"id":"K_SPACE","width":"930"},{"id":"K_ENTER","text":"*Enter*","width":"145","sp":"1"}]}]},{"id":"alt","row":[{"id":"1","key":[{"id":"K_1","text":"֗"},{"id":"K_2","text":"֮"},{"id":"K_3","text":"֙"},{"id":"K_4","text":"֠"},{"id":"K_5","text":"֩"},{"id":"K_6","text":"֟"},{"id":"K_7","text":"֡"},{"id":"K_8","text":"֕"},{"id":"K_9","text":"֓"},{"id":"K_0","text":"֯"},{"id":"K_HYPHEN","text":"ֿ"},{"id":"K_EQUAL","text":"◌"},{"id":"K_BKSP","text":"*BkSp*","width":"100","sp":"1"}]},{"id":"2","key":[{"id":"K_Q","pad":"75"},{"id":"K_W"},{"id":"K_E","text":"ֱ"},{"id":"K_R"},{"id":"K_T"},{"id":"K_Y"},{"id":"K_U"},{"id":"K_I","text":"ֽ"},{"id":"K_O","text":"ֳ"},{"id":"K_P","text":"ף"},{"id":"K_LBRKT","text":"֔"},{"id":"K_RBRKT","text":"֒"},{"id":"T_new_138","width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_BKQUOTE"},{"id":"K_A","text":"ֲ"},{"id":"K_S"},{"id":"K_D"},{"id":"K_F"},{"id":"K_G","text":"•"},{"id":"K_H","text":"̊"},{"id":"K_J"},{"id":"K_K","text":"ך"},{"id":"K_L"},{"id":"K_COLON","text":"׃"},{"id":"K_QUOTE","text":"ׄ"},{"id":"K_BKSLASH","text":"֫"}]},{"id":"4","key":[{"id":"K_SHIFT","text":"*Shift*","width":"160","sp":"1","nextlayer":"shift","layer":"shift"},{"id":"K_oE2"},{"id":"K_Z"},{"id":"K_X","text":"ץ"},{"id":"K_C"},{"id":"K_V"},{"id":"K_B"},{"id":"K_N","text":"ן"},{"id":"K_M","text":"ם"},{"id":"K_COMMA","text":"֫"},{"id":"K_PERIOD","text":"̈"},{"id":"K_SLASH","text":"״"},{"id":"T_new_164","width":"10","sp":"10"}]},{"id":"5","key":[{"id":"K_LCONTROL","text":"default","width":"130","sp":"1","nextlayer":"default"},{"id":"K_LOPT","text":"*Menu*","width":"140","sp":"1"},{"id":"K_SPACE","width":"930"},{"id":"K_ENTER","text":"*Enter*","width":"145","sp":"1"}]}]}]}};this.s7="כמנפצ";this.s8="ךםןףץ";this.s9="כּפּ";this.s10="ךּףּ";this.s11="ּ";this.s12="מּנּצּ";this.s13="םןץ";this.s14="ֽ֑֖֛֢֣֤֥֦֧֪֚֭֮֒֓֔֕֗֘֙֜֝֞֟֠֡֨֩֫֬֯־ֿ׀ׄ";this.s15="...";this.KVER="18.0.170.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,9)) {if(k.KA(0,k.KC(3,1,t),this.s7)&&k.KA(1,k.KC(2,1,t),this.s14)&&k.KCM(1,t,"ּ",1)){r=m=1;k.KIO(3,this.s8,1,t);k.KIO(-1,this.s14,2,t);k.KO(-1,t,"ּ");}else if(k.KA(0,k.KC(3,1,t),this.s7)&&k.KCM(2,t,"ּ",1)&&k.KA(2,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(3,this.s8,1,t);k.KO(-1,t,"ּ");k.KIO(-1,this.s14,3,t);}else if(k.KA(0,k.KC(2,1,t),this.s7)&&k.KCM(1,t,"ּ",1)){r=m=1;k.KIO(2,this.s8,1,t);k.KO(-1,t,"ּ");}else if(k.KA(0,k.KC(2,1,t),this.s7)&&k.KA(1,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(2,this.s8,1,t);k.KIO(-1,this.s14,2,t);}else if(k.KA(0,k.KC(2,1,t),this.s9)&&k.KA(1,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(2,this.s10,1,t);k.KIO(-1,this.s14,2,t);}else if(k.KA(0,k.KC(2,1,t),this.s12)&&k.KA(1,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(2,this.s13,1,t);k.KO(-1,t,"ּ");k.KIO(-1,this.s14,2,t);}else if(k.KA(0,k.KC(1,1,t),this.s7)){r=m=1;k.KIO(1,this.s8,1,t);}else if(k.KA(0,k.KC(1,1,t),this.s9)){r=m=1;k.KIO(1,this.s10,1,t);}else if(k.KA(0,k.KC(1,1,t),this.s12)){r=m=1;k.KIO(1,this.s13,1,t);k.KO(-1,t,"ּ");}}else if(k.KKM(e,16384,13)) {if(k.KA(0,k.KC(3,1,t),this.s7)&&k.KA(1,k.KC(2,1,t),this.s14)&&k.KCM(1,t,"ּ",1)){r=m=1;k.KIO(3,this.s8,1,t);k.KIO(-1,this.s14,2,t);k.KO(-1,t,"ּ");}else if(k.KA(0,k.KC(3,1,t),this.s7)&&k.KCM(2,t,"ּ",1)&&k.KA(2,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(3,this.s8,1,t);k.KO(-1,t,"ּ");k.KIO(-1,this.s14,3,t);}else if(k.KA(0,k.KC(2,1,t),this.s7)&&k.KCM(1,t,"ּ",1)){r=m=1;k.KIO(2,this.s8,1,t);k.KO(-1,t,"ּ");}else if(k.KA(0,k.KC(2,1,t),this.s7)&&k.KA(1,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(2,this.s8,1,t);k.KIO(-1,this.s14,2,t);}else if(k.KA(0,k.KC(2,1,t),this.s9)&&k.KA(1,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(2,this.s10,1,t);k.KIO(-1,this.s14,2,t);}else if(k.KA(0,k.KC(2,1,t),this.s12)&&k.KA(1,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(2,this.s13,1,t);k.KO(-1,t,"ּ");k.KIO(-1,this.s14,2,t);}else if(k.KA(0,k.KC(1,1,t),this.s7)){r=m=1;k.KIO(1,this.s8,1,t);}else if(k.KA(0,k.KC(1,1,t),this.s9)){r=m=1;k.KIO(1,this.s10,1,t);}else if(k.KA(0,k.KC(1,1,t),this.s12)){r=m=1;k.KIO(1,this.s13,1,t);k.KO(-1,t,"ּ");}}else if(k.KKM(e,16384,32)) {if(k.KA(0,k.KC(3,1,t),this.s7)&&k.KA(1,k.KC(2,1,t),this.s14)&&k.KCM(1,t,"ּ",1)){r=m=1;k.KIO(3,this.s8,1,t);k.KIO(-1,this.s14,2,t);k.KO(-1,t,"ּ");}else if(k.KA(0,k.KC(3,1,t),this.s7)&&k.KCM(2,t,"ּ",1)&&k.KA(2,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(3,this.s8,1,t);k.KO(-1,t,"ּ");k.KIO(-1,this.s14,3,t);}else if(k.KA(0,k.KC(2,1,t),this.s7)&&k.KCM(1,t,"ּ",1)){r=m=1;k.KIO(2,this.s8,1,t);k.KO(-1,t,"ּ");}else if(k.KA(0,k.KC(2,1,t),this.s7)&&k.KA(1,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(2,this.s8,1,t);k.KIO(-1,this.s14,2,t);}else if(k.KA(0,k.KC(2,1,t),this.s9)&&k.KA(1,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(2,this.s10,1,t);k.KIO(-1,this.s14,2,t);}else if(k.KA(0,k.KC(2,1,t),this.s12)&&k.KA(1,k.KC(1,1,t),this.s14)){r=m=1;k.KIO(2,this.s13,1,t);k.KO(-1,t,"ּ");k.KIO(-1,this.s14,2,t);}else if(k.KA(0,k.KC(1,1,t),this.s7)){r=m=1;k.KIO(1,this.s8,1,t);}else if(k.KA(0,k.KC(1,1,t),this.s9)){r=m=1;k.KIO(1,this.s10,1,t);}else if(k.KA(0,k.KC(1,1,t),this.s12)){r=m=1;k.KIO(1,this.s13,1,t);k.KO(-1,t,"ּ");}else if(1){r=m=1;k.KO(0,t," ");}}else if(k.KKM(e,16432,32)) {if(1){r=m=1;k.KO(0,t," ");}}else if(k.KKM(e,16400,32)) {if(1){r=m=1;k.KO(0,t," ");}}else if(k.KKM(e,16448,32)) {if(1){r=m=1;k.KO(0,t," ");}}else if(k.KKM(e,16400,49)) {if(1){r=m=1;k.KO(0,t,"!");}}else if(k.KKM(e,16400,222)) {if(1){r=m=1;k.KO(0,t,"\"");}}else if(k.KKM(e,16400,51)) {if(1){r=m=1;k.KO(0,t,"֨");}}else if(k.KKM(e,16400,52)) {if(1){r=m=1;k.KO(0,t,"֜");}}else if(k.KKM(e,16400,53)) {if(1){r=m=1;k.KO(0,t,"֞");}}else if(k.KKM(e,16400,55)) {if(1){r=m=1;k.KO(0,t,"֬");}}else if(k.KKM(e,16384,222)) {if(1){r=m=1;k.KO(0,t,"'");}}else if(k.KKM(e,16448,222)) {if(1){r=m=1;k.KO(0,t,"ׄ");}}else if(k.KKM(e,16400,57)) {if(1){r=m=1;k.KO(0,t,"(");}}else if(k.KKM(e,16400,48)) {if(1){r=m=1;k.KO(0,t,")");}}else if(k.KKM(e,16400,56)) {if(1){r=m=1;k.KO(0,t,"֝");}}else if(k.KKM(e,16400,187)) {if(1){r=m=1;k.KO(0,t,"+");}}else if(k.KKM(e,16448,188)) {if(1){r=m=1;k.KO(0,t,"֫");}}else if(k.KKM(e,16384,188)) {if(1){r=m=1;k.KO(0,t,"א");}}else if(k.KKM(e,16384,189)) {if(1){r=m=1;k.KO(0,t,"־");}}else if(k.KKM(e,16448,189)) {if(1){r=m=1;k.KO(0,t,"ֿ");}}else if(k.KKM(e,16384,190)) {if(1){r=m=1;k.KO(0,t,".");}}else if(k.KKM(e,16448,190)) {if(1){r=m=1;k.KO(0,t,"̈");}}else if(k.KKM(e,16384,191)) {if(1){r=m=1;k.KO(0,t,"/");}}else if(k.KKM(e,16448,191)) {if(1){r=m=1;k.KO(0,t,"״");}}else if(k.KKM(e,16384,48)) {if(1){r=m=1;k.KO(0,t,"0");}}else if(k.KKM(e,16448,48)) {if(1){r=m=1;k.KO(0,t,"֯");}}else if(k.KKM(e,16384,49)) {if(1){r=m=1;k.KO(0,t,"1");}}else if(k.KKM(e,16448,49)) {if(1){r=m=1;k.KO(0,t,"֗");}}else if(k.KKM(e,16384,50)) {if(1){r=m=1;k.KO(0,t,"2");}}else if(k.KKM(e,16448,50)) {if(1){r=m=1;k.KO(0,t,"֮");}}else if(k.KKM(e,16384,51)) {if(1){r=m=1;k.KO(0,t,"3");}}else if(k.KKM(e,16448,51)) {if(1){r=m=1;k.KO(0,t,"֙");}}else if(k.KKM(e,16384,52)) {if(1){r=m=1;k.KO(0,t,"4");}}else if(k.KKM(e,16448,52)) {if(1){r=m=1;k.KO(0,t,"֠");}}else if(k.KKM(e,16384,53)) {if(1){r=m=1;k.KO(0,t,"5");}}else if(k.KKM(e,16448,53)) {if(1){r=m=1;k.KO(0,t,"֩");}}else if(k.KKM(e,16384,54)) {if(1){r=m=1;k.KO(0,t,"6");}}else if(k.KKM(e,16448,54)) {if(1){r=m=1;k.KO(0,t,"֟");}}else if(k.KKM(e,16384,55)) {if(1){r=m=1;k.KO(0,t,"7");}}else if(k.KKM(e,16448,55)) {if(1){r=m=1;k.KO(0,t,"֡");}}else if(k.KKM(e,16384,56)) {if(1){r=m=1;k.KO(0,t,"8");}}else if(k.KKM(e,16448,56)) {if(1){r=m=1;k.KO(0,t,"֕");}}else if(k.KKM(e,16384,57)) {if(1){r=m=1;k.KO(0,t,"9");}}else if(k.KKM(e,16448,57)) {if(1){r=m=1;k.KO(0,t,"֓");}}else if(k.KKM(e,16400,186)) {if(1){r=m=1;k.KO(0,t,"״");}}else if(k.KKM(e,16448,186)) {if(1){r=m=1;k.KO(0,t,"׃");}}else if(k.KKM(e,16384,186)) {if(1){r=m=1;k.KO(0,t,"ְ");}}else if(k.KKM(e,16400,188)) {if(1){r=m=1;}}else if(k.KKM(e,16384,187)) {if(1){r=m=1;k.KO(0,t,"=");}}else if(k.KKM(e,16448,187)) {if(1){r=m=1;k.KO(0,t,"◌");}}else if(k.KKM(e,16400,190)) {if(1){r=m=1;k.KO(0,t,"ּ");}}else if(k.KKM(e,16400,191)) {if(1){r=m=1;k.KO(0,t,"?");}}else if(k.KKM(e,16400,50)) {if(1){r=m=1;k.KO(0,t,"֘");}}else if(k.KKM(e,16400,65)) {if(1){r=m=1;k.KO(0,t,"ָ");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KO(0,t,"בּ");}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KO(0,t,"שּׂ");}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KO(0,t,"דּ");}}else if(k.KKM(e,16400,69)) {if(1){r=m=1;k.KO(0,t,"ֵ");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KO(0,t,"טּ");}}else if(k.KKM(e,16400,71)) {if(1){r=m=1;k.KO(0,t,"גּ");}}else if(k.KKM(e,16400,72)) {if(1){r=m=1;k.KO(0,t,"הּ");}}else if(k.KKM(e,16400,73)) {if(1){r=m=1;}}else if(k.KKM(e,16400,74)) {if(1){r=m=1;k.KO(0,t,"וַיּ");}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KO(0,t,"כּ");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KO(0,t,"לּ");}}else if(k.KKM(e,16400,77)) {if(1){r=m=1;k.KO(0,t,"מּ");}}else if(k.KKM(e,16400,78)) {if(1){r=m=1;k.KO(0,t,"נּ");}}else if(k.KKM(e,16400,79)) {if(1){r=m=1;k.KO(0,t,"וֹ");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KO(0,t,"פּ");}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KO(0,t,"קּ");}}else if(k.KKM(e,16400,82)) {if(1){r=m=1;k.KO(0,t,"רּ");}}else if(k.KKM(e,16400,83)) {if(1){r=m=1;k.KO(0,t,"סּ");}}else if(k.KKM(e,16400,84)) {if(1){r=m=1;k.KO(0,t,"תּ");}}else if(k.KKM(e,16400,85)) {if(1){r=m=1;k.KO(0,t,"ֻ");}}else if(k.KKM(e,16400,86)) {if(1){r=m=1;k.KO(0,t,"שּׁ");}}else if(k.KKM(e,16400,87)) {if(1){r=m=1;k.KO(0,t,"וּ");}}else if(k.KKM(e,16400,88)) {if(1){r=m=1;k.KO(0,t,"צּ");}}else if(k.KKM(e,16400,89)) {if(1){r=m=1;k.KO(0,t,"יּ");}}else if(k.KKM(e,16400,90)) {if(1){r=m=1;k.KO(0,t,"זּ");}}else if(k.KKM(e,16384,219)) {if(1){r=m=1;k.KO(0,t,"[");}}else if(k.KKM(e,16448,219)) {if(1){r=m=1;k.KO(0,t,"֔");}}else if(k.KKM(e,16384,220)) {if(1){r=m=1;k.KO(0,t,"\\");}}else if(k.KKM(e,16448,220)) {if(1){r=m=1;k.KO(0,t,"֫");}}else if(k.KKM(e,16384,221)) {if(1){r=m=1;k.KO(0,t,"]");}}else if(k.KKM(e,16448,221)) {if(1){r=m=1;k.KO(0,t,"֒");}}else if(k.KKM(e,16400,54)) {if(1){r=m=1;k.KO(0,t,"֔");}}else if(k.KKM(e,16400,189)) {if(1){r=m=1;k.KO(0,t,"_");}}else if(k.KKM(e,16448,192)) {if(1){r=m=1;}}else if(k.KKM(e,16384,192)) {if(1){r=m=1;k.KO(0,t,"֑");}}else if(k.KKM(e,16448,65)) {if(1){r=m=1;k.KO(0,t,"ֲ");}}else if(k.KKM(e,16384,65)) {if(1){r=m=1;k.KO(0,t,"ַ");}}else if(k.KKM(e,16448,66)) {if(1){r=m=1;}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KO(0,t,"ב");}}else if(k.KKM(e,16448,67)) {if(1){r=m=1;}}else if(k.KKM(e,16384,67)) {if(1){r=m=1;k.KO(0,t,"שׂ");}}else if(k.KKM(e,16448,68)) {if(1){r=m=1;}}else if(k.KKM(e,16384,68)) {if(1){r=m=1;k.KO(0,t,"ד");}}else if(k.KKM(e,16448,69)) {if(1){r=m=1;k.KO(0,t,"ֱ");}}if(m) {}else if(k.KKM(e,16384,69)) {if(1){r=m=1;k.KO(0,t,"ֶ");}}else if(k.KKM(e,16448,70)) {if(1){r=m=1;}}else if(k.KKM(e,16384,70)) {if(1){r=m=1;k.KO(0,t,"ט");}}else if(k.KKM(e,16448,71)) {if(1){r=m=1;k.KO(0,t,"•");}}else if(k.KKM(e,16384,71)) {if(1){r=m=1;k.KO(0,t,"ג");}}else if(k.KKM(e,16448,72)) {if(1){r=m=1;k.KO(0,t,"̊");}}else if(k.KKM(e,16384,72)) {if(1){r=m=1;k.KO(0,t,"ה");}}else if(k.KKM(e,16448,73)) {if(1){r=m=1;k.KO(0,t,"ֽ");}}else if(k.KKM(e,16384,73)) {if(1){r=m=1;k.KO(0,t,"ִ");}}else if(k.KKM(e,16448,74)) {if(1){r=m=1;}}else if(k.KKM(e,16384,74)) {if(1){r=m=1;k.KO(0,t,"ח");}}else if(k.KKM(e,16448,75)) {if(1){r=m=1;k.KO(0,t,"ך");}}else if(k.KKM(e,16384,75)) {if(1){r=m=1;k.KO(0,t,"כ");}}else if(k.KKM(e,16448,76)) {if(1){r=m=1;}}else if(k.KKM(e,16384,76)) {if(1){r=m=1;k.KO(0,t,"ל");}}else if(k.KKM(e,16448,77)) {if(1){r=m=1;k.KO(0,t,"ם");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KO(0,t,"מ");}}else if(k.KKM(e,16448,78)) {if(1){r=m=1;k.KO(0,t,"ן");}}else if(k.KKM(e,16384,78)) {if(1){r=m=1;k.KO(0,t,"נ");}}else if(k.KKM(e,16448,79)) {if(1){r=m=1;k.KO(0,t,"ֳ");}}else if(k.KKM(e,16384,79)) {if(1){r=m=1;k.KO(0,t,"ֹ");}}else if(k.KKM(e,16448,80)) {if(1){r=m=1;k.KO(0,t,"ף");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KO(0,t,"פ");}}else if(k.KKM(e,16448,81)) {if(1){r=m=1;}}else if(k.KKM(e,16384,81)) {if(1){r=m=1;k.KO(0,t,"ק");}}else if(k.KKM(e,16448,82)) {if(1){r=m=1;}}else if(k.KKM(e,16384,82)) {if(1){r=m=1;k.KO(0,t,"ר");}}else if(k.KKM(e,16448,83)) {if(1){r=m=1;}}else if(k.KKM(e,16384,83)) {if(1){r=m=1;k.KO(0,t,"ס");}}else if(k.KKM(e,16448,84)) {if(1){r=m=1;}}else if(k.KKM(e,16384,84)) {if(1){r=m=1;k.KO(0,t,"ת");}}else if(k.KKM(e,16448,85)) {if(1){r=m=1;}}else if(k.KKM(e,16384,85)) {if(1){r=m=1;k.KO(0,t,"ע");}}else if(k.KKM(e,16448,86)) {if(1){r=m=1;}}else if(k.KKM(e,16384,86)) {if(1){r=m=1;k.KO(0,t,"שׁ");}}else if(k.KKM(e,16448,87)) {if(1){r=m=1;}}else if(k.KKM(e,16384,87)) {if(1){r=m=1;k.KO(0,t,"ו");}}else if(k.KKM(e,16448,88)) {if(1){r=m=1;k.KO(0,t,"ץ");}}else if(k.KKM(e,16384,88)) {if(1){r=m=1;k.KO(0,t,"צ");}}else if(k.KKM(e,16448,89)) {if(1){r=m=1;}}else if(k.KKM(e,16384,89)) {if(1){r=m=1;k.KO(0,t,"י");}}else if(k.KKM(e,16448,90)) {if(1){r=m=1;}}else if(k.KKM(e,16384,90)) {if(1){r=m=1;k.KO(0,t,"ז");}}else if(k.KKM(e,16400,219)) {if(1){r=m=1;k.KO(0,t,"{");}}else if(k.KKM(e,16400,220)) {if(1){r=m=1;k.KO(0,t,"|");}}else if(k.KKM(e,16400,221)) {if(1){r=m=1;k.KO(0,t,"}");}}else if(k.KKM(e,16400,192)) {if(1){r=m=1;}}return r;};} \ No newline at end of file diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kmn b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kmn new file mode 100644 index 0000000000..8ab7ab2901 --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kmn @@ -0,0 +1,215 @@ +store(&TARGETS) 'any' +store(&NAME) 'Aleph With Beth' +store(&BITMAP) 'alephwithbeth.ico' +store(&VISUALKEYBOARD) 'alephwithbeth.kvks' + +store(letters-with-final-forms) "כמנפצ" +store(sofit-forms-of-letters) "ךםןףץ" +store(presentation-dageshed-letters-with-final-forms) "כּפּ" +store(presentation-dageshed-sofit-forms-of-letters) "ךּףּ" +store(dagesh) 'ּ' +c store(vowels) "ְֱֲֳִֵֶַׇׇָֹֻׅ" + +store(normal-dageshed-letters-with-final-forms) "מּנּצּ" +store(normal-undageshed-sofit-forms-of-letters) "םןץ" + +store(punctuation) U+0591 .. U+05AF U+05BD .. U+05BF U+05C0 U+05C4 +store(whitespace) [K_SPACE] [K_ENTER] [K_TAB] + +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'other\alephwithbeth.keyman-touch-layout' +store(©RIGHT) '© Cameron Briggs' +store(&KEYBOARDVERSION) '1.0.6' +store(&KMW_HELPTEXT) 'Aleph With Beth' + +begin Unicode > use(main) + +group(main) using keys ++ [SHIFT K_I] > nul ++ [ALT K_BKQUOTE] > nul ++ [ALT K_B] > nul ++ [ALT K_V] > nul ++ [ALT K_C] > nul ++ [ALT K_Z] > nul ++ [ALT K_L] > nul ++ [ALT K_J] > nul ++ [ALT K_F] > nul ++ [ALT K_D] > nul ++ [ALT K_S] > nul ++ [ALT K_U] > nul ++ [ALT K_Y] > nul ++ [ALT K_T] > nul ++ [ALT K_R] > nul ++ [ALT K_W] > nul ++ [ALT K_Q] > nul ++ [SHIFT K_BKSLASH] > '|' ++ [SHIFT K_EQUAL] > '+' ++ [SHIFT K_HYPHEN] > '_' ++ [SHIFT K_0] > ')' ++ [SHIFT K_9] > '(' ++ [SHIFT K_SLASH] > '?' ++ [SHIFT K_QUOTE] > '"' ++ [SHIFT K_BKQUOTE] > nul ++ [K_EQUAL] > '=' ++ [K_HYPHEN] > '־' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_PERIOD] > '.' ++ [K_SLASH] > '/' ++ [K_QUOTE] > U+0027 ++ [SHIFT K_COLON] > '״' ++ [ALT K_A] > 'ֲ' ++ [SHIFT K_RBRKT] > '}' ++ [SHIFT K_LBRKT] > '{' ++ [K_BKSLASH] > '\' ++ [K_RBRKT] > ']' ++ [K_LBRKT] > '[' ++ [SHIFT K_R] > 'רּ' ++ [SHIFT CTRL K_SPACE] > ' ' ++ [SHIFT K_SPACE] > ' ' ++ [K_SPACE] > ' ' ++ [ALT K_SPACE] > ' ' ++ [SHIFT K_8] > '֝' ++ [SHIFT K_7] > '֬' ++ [SHIFT K_6] > '֔' ++ [SHIFT K_5] > '֞' ++ [SHIFT K_4] > '֜' ++ [SHIFT K_3] > '֨' ++ [SHIFT K_2] > '֘' ++ [SHIFT K_1] > '!' ++ [ALT K_SLASH] > '״' ++ [ALT K_PERIOD] > '̈' ++ [ALT K_COMMA] > '֫' ++ [ALT K_QUOTE] > 'ׄ' ++ [ALT K_COLON] > '׃' ++ [ALT K_H] > '̊' ++ [ALT K_G] > '•' ++ [ALT K_BKSLASH] > '֫' ++ [ALT K_RBRKT] > '֒' ++ [ALT K_LBRKT] > '֔' ++ [ALT K_I] > 'ֽ' ++ [ALT K_O] > 'ֳ' ++ [ALT K_E] > 'ֱ' ++ [ALT K_EQUAL] > '◌' ++ [ALT K_HYPHEN] > 'ֿ' ++ [ALT K_0] > '֯' ++ [ALT K_9] > '֓' ++ [ALT K_8] > '֕' ++ [ALT K_7] > '֡' ++ [ALT K_6] > '֟' ++ [ALT K_5] > '֩' ++ [ALT K_4] > '֠' ++ [ALT K_3] > '֙' ++ [ALT K_2] > '֮' ++ [ALT K_1] > '֗' ++ [ALT K_N] > 'ן' ++ [ALT K_P] > 'ף' ++ [ALT K_K] > 'ך' ++ [ALT K_M] > 'ם' ++ [ALT K_X] > 'ץ' ++ [SHIFT K_PERIOD] > 'ּ' ++ [SHIFT K_COMMA] > nul ++ [SHIFT K_M] > 'מּ' ++ [SHIFT K_N] > 'נּ' ++ [SHIFT K_B] > 'בּ' ++ [SHIFT K_V] > 'שּׁ' ++ [SHIFT K_C] > 'שּׂ' ++ [SHIFT K_X] > 'צּ' ++ [SHIFT K_Z] > 'זּ' ++ [SHIFT K_L] > 'לּ' ++ [SHIFT K_K] > 'כּ' ++ [SHIFT K_J] > 'וַיּ' ++ [SHIFT K_H] > 'הּ' ++ [SHIFT K_G] > 'גּ' ++ [SHIFT K_F] > 'טּ' ++ [SHIFT K_D] > 'דּ' ++ [SHIFT K_S] > 'סּ' ++ [SHIFT K_A] > 'ָ' ++ [SHIFT K_P] > 'פּ' ++ [SHIFT K_O] > 'וֹ' ++ [SHIFT K_U] > 'ֻ' ++ [SHIFT K_Y] > 'יּ' ++ [SHIFT K_T] > 'תּ' ++ [SHIFT K_E] > 'ֵ' ++ [SHIFT K_W] > 'וּ' ++ [SHIFT K_Q] > 'קּ' ++ [K_BKQUOTE] > '֑' ++ [K_COMMA] > 'א' ++ [K_M] > 'מ' ++ [K_N] > 'נ' ++ [K_B] > 'ב' ++ [K_V] > 'שׁ' ++ [K_C] > 'שׂ' ++ [K_X] > 'צ' ++ [K_Z] > 'ז' ++ [K_COLON] > 'ְ' ++ [K_L] > 'ל' ++ [K_K] > 'כ' ++ [K_J] > 'ח' ++ [K_H] > 'ה' ++ [K_G] > 'ג' ++ [K_F] > 'ט' ++ [K_D] > 'ד' ++ [K_S] > 'ס' ++ [K_A] > 'ַ' ++ [K_P] > 'פ' ++ [K_O] > 'ֹ' ++ [K_I] > 'ִ' ++ [K_U] > 'ע' ++ [K_Y] > 'י' ++ [K_T] > 'ת' ++ [K_R] > 'ר' ++ [K_E] > 'ֶ' ++ [K_W] > 'ו' ++ [K_Q] > 'ק' +c Transform final letters +any(letters-with-final-forms) + any(whitespace) > index(sofit-forms-of-letters,1) + +c Transform final letters with a dagesh +any(letters-with-final-forms) $dagesh + any(whitespace) > index(sofit-forms-of-letters,1) $dagesh +any(presentation-dageshed-letters-with-final-forms) + any(whitespace) > index(presentation-dageshed-sofit-forms-of-letters,1) +any(normal-dageshed-letters-with-final-forms) + any(whitespace) > index(normal-undageshed-sofit-forms-of-letters,1) $dagesh + +c Transform final letters with a vowel +c any(letters-with-final-forms) any(vowels) + any(whitespace) > index(sofit-forms-of-letters,1) index(vowels,2) + +c Transform final letters with a vowel and a dagesh +c any(letters-with-final-forms) any(vowels) $dagesh + any(whitespace) > index(sofit-forms-of-letters,1) index(vowels,2) $dagesh +c any(letters-with-final-forms) $dagesh any(vowels) + any(whitespace) > index(sofit-forms-of-letters,1) $dagesh index(vowels,3) +c any(presentation-dageshed-letters-with-final-forms) any(vowels) + any(whitespace) > index(presentation-dageshed-sofit-forms-of-letters,1) index(vowels,2) +c any(normal-dageshed-letters-with-final-forms) any(vowels) + any(whitespace) > index(normal-undageshed-sofit-forms-of-letters,1) $dagesh index(vowels,2) + +c Transform final letters with punctuation +any(letters-with-final-forms) any(punctuation) + any(whitespace) > index(sofit-forms-of-letters,1) index(punctuation,2) + +c Transform final letters with punctuation and a dagesh +any(letters-with-final-forms) any(punctuation) $dagesh + any(whitespace) > index(sofit-forms-of-letters,1) index(punctuation,2) $dagesh +any(letters-with-final-forms) $dagesh any(punctuation) + any(whitespace) > index(sofit-forms-of-letters,1) $dagesh index(punctuation,3) +any(presentation-dageshed-letters-with-final-forms) any(punctuation) + any(whitespace) > index(presentation-dageshed-sofit-forms-of-letters,1) index(punctuation,2) +any(normal-dageshed-letters-with-final-forms) any(punctuation) + any(whitespace) > index(normal-undageshed-sofit-forms-of-letters,1) $dagesh index(punctuation,2) + +c Transfrom final letters with a punctuation and a vowel +c any(letters-with-final-forms) any(punctuation) any(vowels) + any(whitespace) > index(sofit-forms-of-letters,1) index(punctuation,2) index(vowels,3) +c any(letters-with-final-forms) any(vowels) any(punctuation) + any(whitespace) > index(sofit-forms-of-letters,1) index(vowels,2) index(punctuation,3) + +c Transform final letters with punctuation, a vowel, and a dagesh (phew!) +c any(letters-with-final-forms) any(punctuation) any(vowels) $dagesh + any(whitespace) > index(sofit-forms-of-letters,1) index(punctuation,2) index(vowels,3) $dagesh +c any(letters-with-final-forms) any(punctuation) $dagesh any(vowels) + any(whitespace) > index(sofit-forms-of-letters,1) index(punctuation,2) $dagesh index(vowels,4) +c any(letters-with-final-forms) any(vowels) any(punctuation) $dagesh + any(whitespace) > index(sofit-forms-of-letters,1) index(vowels,2) index(punctuation,3) $dagesh +c any(letters-with-final-forms) any(vowels) $dagesh any(punctuation) + any(whitespace) > index(sofit-forms-of-letters,1) index(vowels,2) $dagesh index(punctuation,4) +c any(letters-with-final-forms) $dagesh any(punctuation) any(vowels) + any(whitespace) > index(sofit-forms-of-letters,1) $dagesh index(punctuation,3) index(vowels,4) +c any(letters-with-final-forms) $dagesh any(vowels) any(punctuation) + any(whitespace) > index(sofit-forms-of-letters,1) $dagesh index(vowels,3) index(punctuation,4) + + +c any(presentation-dageshed-letters-with-final-forms) any(punctuation) any(vowels) + any(whitespace) > index(presentation-dageshed-sofit-forms-of-letters,1) index(punctuation,2) index(vowels,3) +c any(presentation-dageshed-letters-with-final-forms) any(vowels) any(punctuation) + any(whitespace) > index(presentation-dageshed-sofit-forms-of-letters,1) index(vowels,2) index(punctuation,3) +c any(normal-dageshed-letters-with-final-forms) any(punctuation) any(vowels) + any(whitespace) > index(normal-undageshed-sofit-forms-of-letters,1) $dagesh index(punctuation,2) index(vowels,3) +c any(normal-dageshed-letters-with-final-forms) any(vowels) any(punctuation) + any(whitespace) > index(normal-undageshed-sofit-forms-of-letters,1) $dagesh index(vowels,2) index(punctuation,3) diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kmp b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kmp new file mode 100644 index 0000000000000000000000000000000000000000..d44bf1edcac4215502e9f1f2117f41573552def2 GIT binary patch literal 244485 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 z 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 z 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

}K%V+J21SA*rer$}D%R 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 YiZW22zWzV9gaDTMsbG!9Pip}CUmL7w5&!@I literal 0 HcmV?d00001 diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kmx b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kmx new file mode 100644 index 0000000000000000000000000000000000000000..867213cedd5a1452b429dd9e79a6b1eacb54fc7b GIT binary patch literal 7172 zcmd6re{5D~8HV2?FYD?k6%i51QY#{MP}{DQZmU>I?P@`+j1|O+Y%*lf0qGFgWX-Y= zvJgWUV~owNV~7(v>=2P5E2WuaA%qY_hRClW!$}%Lh*`+8Hq`5R&iB&iJ1ey6KRes~ zoaegFea?G+m-9`YIsHC&t8-7J%p2mEQlu~qMbej`RiARMi;31{NMTy_dFSf;JNLN= zT?JuTN2Vrv7VFeZKPu6;(BG2i576_!P8Vs0CHmBUiH6x2(-)b(%=DF}uQL5~)7O}O zuIZcUzmOR22>q86{W1Cw%i`EaCj2t`FDCjbdOczA68cH5&OPKFa7(FkU8eh)dzgMc z-DI4{+#@Vo1eHO{P_0|+mN2iw6RvZQvc_V~IQasrM$%W-%uO3V+%OU+^M!k7vA$z!x%xQnlpZ6F2``)=z{;Yr3zvur! ze@{nQhjVv#Oro~H6FN#d%IPH`%b)S<{Ih<&f6j04&-;!31^=S|rEl;r`9}Y;-{fEM zoBgl+7XNGis{f7O>bLnO|C-wcea_4|FBKfso{y3)8MGr0?+Zs7IqR=qRx z*vrLw)N)2^ZhGVkIS1jojAfn0?x&oK`ED#{>j9PsFJ*h%IIELz9wA?cD_60U?qT;6 z{(F=}UgByM()V^PdcL--=o-0;!nB7lxmx(iSZ)oxF_zl|H^p*0 z;g(qL0DL5tI{{ya<=Ww^DASzNYw+ODCVN?MVazLsr^UP)cu~w-0k4U94e*Yb*9squ zc}L+>G4BF=*?76!8&~0vjF*Ae3Ck-glbKE>yw%_V#w)=~g>OT7QOe1>>F{85&Ui!M zVdzfd4To<>1;)#SN1}1Y8wF>h@x~hi=b|u%D{(F#E;OF(UlCl4?lS96fJ>3Q6J?Tp zE`uvjkvfrA2~S0D8m|hTj#?6)j8P5GGM?;94Lk?!OXS3R5SG7_!IO38!?mc@!!l##&dWX@DLR4XUPqPhZ|3FBj8L_>Y_<< zS@3A%NiG}CLE*laTrON_JjoTo#V9-rlA9oGJjs>Al_)$PlA8io8BcQ4;A#|}8OhCr zXB$s)bKtosJV%n72QM(5~0I{+U<;W?MwA^3>#BzF`(j>5AqxfAdy<4Nued>)1Of#fd0my9R5cK9+1?+D3V zfv*}*av#E-D7-f$cMa~(XLIl*HvmpU;awuR+u*^*liUz^7`op@ljMfOnZ}b`7CZ`7 zo7`wP$9R&tSax>u?6y9Ny zn+?x3p5*4i3s88k$-AT$UV_3qOuRaH84B+!@s`6YP@9V;@#^7~sH>|V-zq6OAH;6} z@-^GlmEuyh4oYy}Gc8`WILOJTU9=r>QgFJ*>RYCJeY<8)ZZu-Q>m$a;yV>$jn`4i* zot8NAXw=@8r?Y-Ip0Ec4leW-%Le76Uu4vScJF*{P|GM`q*@;GqJozS--7%D zb@OW(jhEWvof4MWEAs!J(Y~CW_;F`)KAih_{gV1wTDNlV^G4U&sCB#6uj*3yHHN>d z+J8;!OX}RA{cGAE)!M3czt$XGnkuKzeO>zx)Q`S(Ue`YQo_SvTe9bg#AAOg+pnZY* zo3tON{Wk3jwSQUr@!G$lee^Bxoc7Vb_n*~18vRe&@6g)S#gCdy-_UyaD>9R}fOFrJ z;x=l(M{8b(IAgWmsr3))7ipibwLojw>O1}of0sJ`;WN5qr`9*Lh9!Sa zqC0eyu~~ssC*@8mWo61B$Fxt=tAAYkeOh;E4cq#w(kZQ{la`!OI;-`Z)_1j@ z*ZO;{f7JS(){9!hcK?|~my+o3Nz|T17m_GD>A2s~W%3&*-?w + + + $PROJECTPATH + True + True + + + + id_ede98e4633e239f933cbfd1f4e1b766c + HISTORY.md + HISTORY.md + + .md + + + id_53e892b8b41cc4caece1cfd5ef21d6e7 + LICENSE.md + LICENSE.md + + .md + + + id_0730bb7c2e8f9ea2438b52e419dd86c9 + README.md + README.md + + .md + + + id_195752eb7ec06cfb1f90ed508d2c5b54 + alephwithbeth.kps + alephwithbeth.kps + + .kps +

+ Aleph With Beth + © Cameron Briggs +
+ + + id_e72bb7d9956f6973ce3de0362e47b0d3 + alephwithbeth.kmn + alephwithbeth.kmn + 1.0.6 + .kmn +
+ Aleph With Beth + © Cameron Briggs +
+
+ + id_dc799c273ed24ff1ca06a2429e5af8b4 + alephwithbeth.ico + alephwithbeth.ico + + .ico + id_e72bb7d9956f6973ce3de0362e47b0d3 + + + id_8da344c4cea6f467013357fe099006f5 + readme.htm + other\readme.htm + + .htm + id_195752eb7ec06cfb1f90ed508d2c5b54 + + + id_724e5b4c63f10bc0abf7077f7c3172fc + welcome.htm + other\welcome\welcome.htm + + .htm + id_195752eb7ec06cfb1f90ed508d2c5b54 + + + id_101067b24e270db6fdd8b52ac6c77297 + alephwithbeth.js + alephwithbeth.js + + .js + id_195752eb7ec06cfb1f90ed508d2c5b54 + + + id_cf57b9fb0e29a5e6b4ff4b9a55fc7ef3 + alephwithbeth.kvk + alephwithbeth.kvk + + .kvk + id_195752eb7ec06cfb1f90ed508d2c5b54 + + + id_dfa1b7bb444da6106e7ffcce1b6ae59d + alephwithbeth.kmx + alephwithbeth.kmx + + .kmx + id_195752eb7ec06cfb1f90ed508d2c5b54 + + + id_92d25e21c1bb82cab07440032ea15ca1 + KeyboardLayout.png + other\welcome\KeyboardLayout.png + + .png + id_195752eb7ec06cfb1f90ed508d2c5b54 + + + id_a751525f488287b36c872b48e3c385b8 + KeyboardLayoutAlt.png + other\welcome\KeyboardLayoutAlt.png + + .png + id_195752eb7ec06cfb1f90ed508d2c5b54 + + + id_a260e1bca7e99f6955c706b3697f842c + KeyboardLayoutShift.png + other\welcome\KeyboardLayoutShift.png + + .png + id_195752eb7ec06cfb1f90ed508d2c5b54 + + + id_c296b5df3dc126e219e0173fcbc1baec + LICENSE.md + LICENSE.md + + .md + id_195752eb7ec06cfb1f90ed508d2c5b54 + + + diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kps b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kps new file mode 100644 index 0000000000..93a49e397e --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kps @@ -0,0 +1,95 @@ + + + + 17.0.325.0 + 7.0 + + + + other\readme.htm + LICENSE.md + other\welcome\welcome.htm + + + + + + + + + + + Aleph With Beth + © Cameron Briggs + Cameron Briggs + https://freehebrew.online + alephwithbeth keyboard + + + + other\readme.htm + File readme.htm + 0 + .htm + + + other\welcome\welcome.htm + File welcome.htm + 0 + .htm + + + alephwithbeth.js + File alephwithbeth.js + 0 + .js + + + alephwithbeth.kvk + File alephwithbeth.kvk + 0 + .kvk + + + alephwithbeth.kmx + Keyboard alephwithbeth + 0 + .kmx + + + other\welcome\KeyboardLayout.png + File KeyboardLayout.png + 0 + .png + + + other\welcome\KeyboardLayoutAlt.png + File KeyboardLayoutAlt.png + 0 + .png + + + other\welcome\KeyboardLayoutShift.png + File KeyboardLayoutShift.png + 0 + .png + + + LICENSE.md + + 0 + .md + + + + + Aleph With Beth + alephwithbeth + 1.0.4 + + Hebrew + + + + + diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kvk b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kvk new file mode 100644 index 0000000000000000000000000000000000000000..7772d84d9e3d4d071d0146ff51a75ba9d1236b62 GIT binary patch literal 1921 zcmZwHM{87J7>423aU#Kmzd-|Hi6xUV$zYAfNzB+wG!{fbP;en42$mmVLj~(jQS2Hu zP0*zaTWl%zg6r&DjL(yC=FY-wCf9kt^D*B!H`{VA;05f+OxVUt(` zmx%YcH!C(UZ5FFxi&zU=BN=^V9c39V<+NfBTqe$i%fHwAbkjA^P1iy5Uh8e8FG@hDq4@eb(3UqB~bS$ruGPW%;9Cw?C~@psUPzl2WwHC!s* zg{|US=-T_CYaf8FeF(btPtdhLgs%M?bnQQ(YySmZ`)BCde?!;)1-ka>JRH~F$JDj| zfUf;LbnS1T^X`HEfvYOMvgAm>Pm9xJIN+<$_x3{fTt2pNb0Qh;x%Bgw)UJuR!D8oq z3OeuW(0QMM&if*C-dCXWz5t!~CFs0QLg#%PI`1dYc|V(6I)d{q{S+j_d5=22^FGGC v?)f%!qPL)%te9BZ*-eh;S-Ht>7CXWZ(A5n>SN9RRx;xO-eT9zU`#=5#snenj literal 0 HcmV?d00001 diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kvks b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kvks new file mode 100644 index 0000000000..6b3cf3eeb9 --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/disorganized/alephwithbeth.kvks @@ -0,0 +1,138 @@ + + +
+ 10.0 + alephwithbeth + +
+ + + ! + " + ֨ + ֜ + ֞ + ֬ + ( + ) + ֝ + + + ״ + ּ + ? + ֘ + ָ + בּ + שּׂ + דּ + ֵ + טּ + גּ + הּ + וַיּ + כּ + לּ + מּ + נּ + וֹ + פּ + קּ + רּ + סּ + תּ + ֻ + שּׁ + וּ + צּ + יּ + זּ + ֔ + _ + { + | + } + + + ' + א + . + / + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + ְ + = + [ + \ + ] + ֑ + ַ + ב + שׂ + ד + ֶ + ט + ג + ה + ִ + ח + כ + ל + מ + נ + ֹ + פ + ק + ר + ס + ת + ע + שׁ + ו + צ + י + ז + ־ + 0 + + + ׄ + ֫ + ֿ + ̈ + ״ + ֯ + ֗ + ֮ + ֙ + ֠ + ֩ + ֟ + ֡ + ֕ + ֓ + ׃ + ◌ + ֔ + ֫ + ֒ + ֲ + ֱ + • + ̊ + ֽ + ך + ם + ן + ֳ + ף + ץ + + +
diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/alephwithbeth.keyman-touch-layout b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/alephwithbeth.keyman-touch-layout new file mode 100644 index 0000000000..05db57c7f9 --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/alephwithbeth.keyman-touch-layout @@ -0,0 +1,1646 @@ +{ + "tablet": { + "displayUnderlying": false, + "layer": [ + { + "id": "default", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_1", + "text": "1" + }, + { + "id": "K_2", + "text": "2" + }, + { + "id": "K_3", + "text": "3" + }, + { + "id": "K_4", + "text": "4" + }, + { + "id": "K_5", + "text": "5" + }, + { + "id": "K_6", + "text": "6" + }, + { + "id": "K_7", + "text": "7" + }, + { + "id": "K_8", + "text": "8" + }, + { + "id": "K_9", + "text": "9" + }, + { + "id": "K_0", + "text": "0" + }, + { + "id": "K_HYPHEN", + "text": "־" + }, + { + "id": "K_EQUAL", + "text": "=" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "ק", + "pad": "75" + }, + { + "id": "K_W", + "text": "ו" + }, + { + "id": "K_E", + "text": "ֶ" + }, + { + "id": "K_R", + "text": "ר" + }, + { + "id": "K_T", + "text": "ת" + }, + { + "id": "K_Y", + "text": "י" + }, + { + "id": "K_U", + "text": "ע" + }, + { + "id": "K_I", + "text": "ִ" + }, + { + "id": "K_O", + "text": "ֹ" + }, + { + "id": "K_P", + "text": "פ" + }, + { + "id": "K_LBRKT", + "text": "[" + }, + { + "id": "K_RBRKT", + "text": "]" + }, + { + "id": "T_new_138", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_BKQUOTE", + "text": "֑" + }, + { + "id": "K_A", + "text": "ַ" + }, + { + "id": "K_S", + "text": "ס" + }, + { + "id": "K_D", + "text": "ד" + }, + { + "id": "K_F", + "text": "ט" + }, + { + "id": "K_G", + "text": "ג" + }, + { + "id": "K_H", + "text": "ה" + }, + { + "id": "K_J", + "text": "ח" + }, + { + "id": "K_K", + "text": "כ" + }, + { + "id": "K_L", + "text": "ל" + }, + { + "id": "K_COLON", + "text": "ְ" + }, + { + "id": "K_QUOTE", + "text": "'" + }, + { + "id": "K_BKSLASH", + "text": "\\" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "160", + "sp": "1", + "nextlayer": "shift" + }, + { + "id": "K_oE2", + "text": "" + }, + { + "id": "K_Z", + "text": "ז" + }, + { + "id": "K_X", + "text": "צ" + }, + { + "id": "K_C", + "text": "שׂ" + }, + { + "id": "K_V", + "text": "שׁ" + }, + { + "id": "K_B", + "text": "ב" + }, + { + "id": "K_N", + "text": "נ" + }, + { + "id": "K_M", + "text": "מ" + }, + { + "id": "K_COMMA", + "text": "א" + }, + { + "id": "K_PERIOD", + "text": "." + }, + { + "id": "K_SLASH", + "text": "/" + }, + { + "id": "T_new_164", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "alt", + "width": "130", + "sp": "1", + "nextlayer": "alt" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "140", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "930" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "145", + "sp": "1" + } + ] + } + ] + }, + { + "id": "shift", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_1", + "text": "!" + }, + { + "id": "K_2", + "text": "֘" + }, + { + "id": "K_3", + "text": "֨" + }, + { + "id": "K_4", + "text": "֜" + }, + { + "id": "K_5", + "text": "֞" + }, + { + "id": "K_6", + "text": "֔" + }, + { + "id": "K_7", + "text": "֬" + }, + { + "id": "K_8", + "text": "֝" + }, + { + "id": "K_9", + "text": "(" + }, + { + "id": "K_0", + "text": ")" + }, + { + "id": "K_HYPHEN", + "text": "_" + }, + { + "id": "K_EQUAL", + "text": "+" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "קּ", + "pad": "75" + }, + { + "id": "K_W", + "text": "וּ" + }, + { + "id": "K_E", + "text": "ֵ" + }, + { + "id": "K_R", + "text": "רּ" + }, + { + "id": "K_T", + "text": "תּ" + }, + { + "id": "K_Y", + "text": "יּ" + }, + { + "id": "K_U", + "text": "ֻ" + }, + { + "id": "K_I", + "text": "" + }, + { + "id": "K_O", + "text": "וֹ" + }, + { + "id": "K_P", + "text": "פּ" + }, + { + "id": "K_LBRKT", + "text": "{" + }, + { + "id": "K_RBRKT", + "text": "}" + }, + { + "id": "T_new_362", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_BKQUOTE", + "text": "" + }, + { + "id": "K_A", + "text": "ָ" + }, + { + "id": "K_S", + "text": "סּ" + }, + { + "id": "K_D", + "text": "דּ" + }, + { + "id": "K_F", + "text": "טּ" + }, + { + "id": "K_G", + "text": "גּ" + }, + { + "id": "K_H", + "text": "הּ" + }, + { + "id": "K_J", + "text": "וַיּ" + }, + { + "id": "K_K", + "text": "כּ" + }, + { + "id": "K_L", + "text": "לּ" + }, + { + "id": "K_COLON", + "text": "״" + }, + { + "id": "K_QUOTE", + "text": "\"" + }, + { + "id": "K_BKSLASH", + "text": "|" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "160", + "sp": "1", + "nextlayer": "default" + }, + { + "id": "K_oE2", + "text": "" + }, + { + "id": "K_Z", + "text": "זּ" + }, + { + "id": "K_X", + "text": "צּ" + }, + { + "id": "K_C", + "text": "שּׂ" + }, + { + "id": "K_V", + "text": "שּׁ" + }, + { + "id": "K_B", + "text": "בּ" + }, + { + "id": "K_N", + "text": "נּ" + }, + { + "id": "K_M", + "text": "מּ" + }, + { + "id": "K_COMMA", + "text": "" + }, + { + "id": "K_PERIOD", + "text": "ּ" + }, + { + "id": "K_SLASH", + "text": "?" + }, + { + "id": "T_new_388", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "alt", + "width": "130", + "sp": "1", + "nextlayer": "alt" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "140", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "930" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "145", + "sp": "1" + } + ] + } + ] + }, + { + "id": "alt", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_1", + "text": "֗" + }, + { + "id": "K_2", + "text": "֮" + }, + { + "id": "K_3", + "text": "֙" + }, + { + "id": "K_4", + "text": "֠" + }, + { + "id": "K_5", + "text": "֩" + }, + { + "id": "K_6", + "text": "֟" + }, + { + "id": "K_7", + "text": "֡" + }, + { + "id": "K_8", + "text": "֕" + }, + { + "id": "K_9", + "text": "֓" + }, + { + "id": "K_0", + "text": "֯" + }, + { + "id": "K_HYPHEN", + "text": "ֿ" + }, + { + "id": "K_EQUAL", + "text": "◌" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "", + "pad": "75" + }, + { + "id": "K_W", + "text": "" + }, + { + "id": "K_E", + "text": "ֱ" + }, + { + "id": "K_R", + "text": "" + }, + { + "id": "K_T", + "text": "" + }, + { + "id": "K_Y", + "text": "" + }, + { + "id": "K_U", + "text": "" + }, + { + "id": "K_I", + "text": "ֽ" + }, + { + "id": "K_O", + "text": "ֳ" + }, + { + "id": "K_P", + "text": "ף" + }, + { + "id": "K_LBRKT", + "text": "֔" + }, + { + "id": "K_RBRKT", + "text": "֒" + }, + { + "id": "T_new_138", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_BKQUOTE", + "text": "" + }, + { + "id": "K_A", + "text": "ֲ" + }, + { + "id": "K_S", + "text": "" + }, + { + "id": "K_D", + "text": "" + }, + { + "id": "K_F", + "text": "" + }, + { + "id": "K_G", + "text": "•" + }, + { + "id": "K_H", + "text": "̊" + }, + { + "id": "K_J", + "text": "" + }, + { + "id": "K_K", + "text": "ך" + }, + { + "id": "K_L", + "text": "" + }, + { + "id": "K_COLON", + "text": "׃" + }, + { + "id": "K_QUOTE", + "text": "ׄ" + }, + { + "id": "K_BKSLASH", + "text": "֫" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "160", + "sp": "1", + "nextlayer": "shift", + "layer": "shift" + }, + { + "id": "K_oE2", + "text": "" + }, + { + "id": "K_Z", + "text": "" + }, + { + "id": "K_X", + "text": "ץ" + }, + { + "id": "K_C", + "text": "" + }, + { + "id": "K_V", + "text": "" + }, + { + "id": "K_B", + "text": "" + }, + { + "id": "K_N", + "text": "ן" + }, + { + "id": "K_M", + "text": "ם" + }, + { + "id": "K_COMMA", + "text": "֫" + }, + { + "id": "K_PERIOD", + "text": "̈" + }, + { + "id": "K_SLASH", + "text": "״" + }, + { + "id": "T_new_164", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "default", + "width": "130", + "sp": "1", + "nextlayer": "default" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "140", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "930" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "145", + "sp": "1" + } + ] + } + ] + } + ] + }, + "phone": { + "displayUnderlying": false, + "layer": [ + { + "id": "default", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_1", + "text": "1" + }, + { + "id": "K_2", + "text": "2" + }, + { + "id": "K_3", + "text": "3" + }, + { + "id": "K_4", + "text": "4" + }, + { + "id": "K_5", + "text": "5" + }, + { + "id": "K_6", + "text": "6" + }, + { + "id": "K_7", + "text": "7" + }, + { + "id": "K_8", + "text": "8" + }, + { + "id": "K_9", + "text": "9" + }, + { + "id": "K_0", + "text": "0" + }, + { + "id": "K_HYPHEN", + "text": "־" + }, + { + "id": "K_EQUAL", + "text": "=" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "ק", + "pad": "75" + }, + { + "id": "K_W", + "text": "ו" + }, + { + "id": "K_E", + "text": "ֶ" + }, + { + "id": "K_R", + "text": "ר" + }, + { + "id": "K_T", + "text": "ת" + }, + { + "id": "K_Y", + "text": "י" + }, + { + "id": "K_U", + "text": "ע" + }, + { + "id": "K_I", + "text": "ִ" + }, + { + "id": "K_O", + "text": "ֹ" + }, + { + "id": "K_P", + "text": "פ" + }, + { + "id": "K_LBRKT", + "text": "[" + }, + { + "id": "K_RBRKT", + "text": "]" + }, + { + "id": "T_new_138", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_BKQUOTE", + "text": "֑" + }, + { + "id": "K_A", + "text": "ַ" + }, + { + "id": "K_S", + "text": "ס" + }, + { + "id": "K_D", + "text": "ד" + }, + { + "id": "K_F", + "text": "ט" + }, + { + "id": "K_G", + "text": "ג" + }, + { + "id": "K_H", + "text": "ה" + }, + { + "id": "K_J", + "text": "ח" + }, + { + "id": "K_K", + "text": "כ" + }, + { + "id": "K_L", + "text": "ל" + }, + { + "id": "K_COLON", + "text": "ְ" + }, + { + "id": "K_QUOTE", + "text": "'" + }, + { + "id": "K_BKSLASH", + "text": "\\" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "160", + "sp": "1", + "nextlayer": "shift" + }, + { + "id": "K_oE2", + "text": "" + }, + { + "id": "K_Z", + "text": "ז" + }, + { + "id": "K_X", + "text": "צ" + }, + { + "id": "K_C", + "text": "שׂ" + }, + { + "id": "K_V", + "text": "שׁ" + }, + { + "id": "K_B", + "text": "ב" + }, + { + "id": "K_N", + "text": "נ" + }, + { + "id": "K_M", + "text": "מ" + }, + { + "id": "K_COMMA", + "text": "א" + }, + { + "id": "K_PERIOD", + "text": "." + }, + { + "id": "K_SLASH", + "text": "/" + }, + { + "id": "T_new_164", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "alt", + "width": "130", + "sp": "1", + "nextlayer": "alt" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "140", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "930" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "145", + "sp": "1" + } + ] + } + ] + }, + { + "id": "shift", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_1", + "text": "!" + }, + { + "id": "K_2", + "text": "֘" + }, + { + "id": "K_3", + "text": "֨" + }, + { + "id": "K_4", + "text": "֜" + }, + { + "id": "K_5", + "text": "֞" + }, + { + "id": "K_6", + "text": "֔" + }, + { + "id": "K_7", + "text": "֬" + }, + { + "id": "K_8", + "text": "֝" + }, + { + "id": "K_9", + "text": "(" + }, + { + "id": "K_0", + "text": ")" + }, + { + "id": "K_HYPHEN", + "text": "_" + }, + { + "id": "K_EQUAL", + "text": "+" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "קּ", + "pad": "75" + }, + { + "id": "K_W", + "text": "וּ" + }, + { + "id": "K_E", + "text": "ֵ" + }, + { + "id": "K_R", + "text": "רּ" + }, + { + "id": "K_T", + "text": "תּ" + }, + { + "id": "K_Y", + "text": "יּ" + }, + { + "id": "K_U", + "text": "ֻ" + }, + { + "id": "K_I", + "text": "" + }, + { + "id": "K_O", + "text": "וֹ" + }, + { + "id": "K_P", + "text": "פּ" + }, + { + "id": "K_LBRKT", + "text": "{" + }, + { + "id": "K_RBRKT", + "text": "}" + }, + { + "id": "T_new_362", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_BKQUOTE", + "text": "" + }, + { + "id": "K_A", + "text": "ָ" + }, + { + "id": "K_S", + "text": "סּ" + }, + { + "id": "K_D", + "text": "דּ" + }, + { + "id": "K_F", + "text": "טּ" + }, + { + "id": "K_G", + "text": "גּ" + }, + { + "id": "K_H", + "text": "הּ" + }, + { + "id": "K_J", + "text": "וַיּ" + }, + { + "id": "K_K", + "text": "כּ" + }, + { + "id": "K_L", + "text": "לּ" + }, + { + "id": "K_COLON", + "text": "״" + }, + { + "id": "K_QUOTE", + "text": "\"" + }, + { + "id": "K_BKSLASH", + "text": "|" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "160", + "sp": "1", + "nextlayer": "default" + }, + { + "id": "K_oE2", + "text": "" + }, + { + "id": "K_Z", + "text": "זּ" + }, + { + "id": "K_X", + "text": "צּ" + }, + { + "id": "K_C", + "text": "שּׂ" + }, + { + "id": "K_V", + "text": "שּׁ" + }, + { + "id": "K_B", + "text": "בּ" + }, + { + "id": "K_N", + "text": "נּ" + }, + { + "id": "K_M", + "text": "מּ" + }, + { + "id": "K_COMMA", + "text": "" + }, + { + "id": "K_PERIOD", + "text": "ּ" + }, + { + "id": "K_SLASH", + "text": "?" + }, + { + "id": "T_new_388", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "alt", + "width": "130", + "sp": "1", + "nextlayer": "alt" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "140", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "930" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "145", + "sp": "1" + } + ] + } + ] + }, + { + "id": "alt", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_1", + "text": "֗" + }, + { + "id": "K_2", + "text": "֮" + }, + { + "id": "K_3", + "text": "֙" + }, + { + "id": "K_4", + "text": "֠" + }, + { + "id": "K_5", + "text": "֩" + }, + { + "id": "K_6", + "text": "֟" + }, + { + "id": "K_7", + "text": "֡" + }, + { + "id": "K_8", + "text": "֕" + }, + { + "id": "K_9", + "text": "֓" + }, + { + "id": "K_0", + "text": "֯" + }, + { + "id": "K_HYPHEN", + "text": "ֿ" + }, + { + "id": "K_EQUAL", + "text": "◌" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "", + "pad": "75" + }, + { + "id": "K_W", + "text": "" + }, + { + "id": "K_E", + "text": "ֱ" + }, + { + "id": "K_R", + "text": "" + }, + { + "id": "K_T", + "text": "" + }, + { + "id": "K_Y", + "text": "" + }, + { + "id": "K_U", + "text": "" + }, + { + "id": "K_I", + "text": "ֽ" + }, + { + "id": "K_O", + "text": "ֳ" + }, + { + "id": "K_P", + "text": "ף" + }, + { + "id": "K_LBRKT", + "text": "֔" + }, + { + "id": "K_RBRKT", + "text": "֒" + }, + { + "id": "T_new_138", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_BKQUOTE", + "text": "" + }, + { + "id": "K_A", + "text": "ֲ" + }, + { + "id": "K_S", + "text": "" + }, + { + "id": "K_D", + "text": "" + }, + { + "id": "K_F", + "text": "" + }, + { + "id": "K_G", + "text": "•" + }, + { + "id": "K_H", + "text": "̊" + }, + { + "id": "K_J", + "text": "" + }, + { + "id": "K_K", + "text": "ך" + }, + { + "id": "K_L", + "text": "" + }, + { + "id": "K_COLON", + "text": "׃" + }, + { + "id": "K_QUOTE", + "text": "ׄ" + }, + { + "id": "K_BKSLASH", + "text": "֫" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "160", + "sp": "1", + "nextlayer": "shift", + "layer": "shift" + }, + { + "id": "K_oE2", + "text": "" + }, + { + "id": "K_Z", + "text": "" + }, + { + "id": "K_X", + "text": "ץ" + }, + { + "id": "K_C", + "text": "" + }, + { + "id": "K_V", + "text": "" + }, + { + "id": "K_B", + "text": "" + }, + { + "id": "K_N", + "text": "ן" + }, + { + "id": "K_M", + "text": "ם" + }, + { + "id": "K_COMMA", + "text": "֫" + }, + { + "id": "K_PERIOD", + "text": "̈" + }, + { + "id": "K_SLASH", + "text": "״" + }, + { + "id": "T_new_164", + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "default", + "width": "130", + "sp": "1", + "nextlayer": "default" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "140", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "930" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "145", + "sp": "1" + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/KeyboardLayout.png b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/KeyboardLayout.png new file mode 100644 index 0000000000000000000000000000000000000000..d0998e288b1e18536d87cee7e0fad5ae3d211bca GIT binary patch literal 97424 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
-!f@lFY8?d3JlD9c$!ml8F-EO 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

~ZF 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 gzp17`|ibnP2GkkYu)#Z<}FU2QZ2 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 literal 0 HcmV?d00001 diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/KeyboardLayoutAlt.png b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/KeyboardLayoutAlt.png new file mode 100644 index 0000000000000000000000000000000000000000..f740eec1e3fbf840a32b6802240c23b73aebd8e8 GIT binary patch literal 61615 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 literal 0 HcmV?d00001 diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/KeyboardLayoutShift.png b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/KeyboardLayoutShift.png new file mode 100644 index 0000000000000000000000000000000000000000..9b243d4dd2f2ef9e0d75748e615fb72951fcb6bc GIT binary patch literal 85201 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 literal 0 HcmV?d00001 diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/alephwithbeth.php b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/alephwithbeth.php new file mode 100644 index 0000000000..48a2c2e7c8 --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/help/alephwithbeth.php @@ -0,0 +1,22 @@ + + + +

Start Using Aleph with Beth

+ +

Desktop Layout

+ +

Base layout

+Keyboard layout +

Layout when shift is pressed

+Keyboard layout (when shift key is pressed) +

Layout when alt is pressed

+Keyboard layout (when alt key is pressed) + diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/readme.htm b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/readme.htm new file mode 100644 index 0000000000..f187388c1e --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/readme.htm @@ -0,0 +1,22 @@ + + + + + + alephwithbeth + + + + +

Aleph With Beth

+ +

A Hebrew keyboard designed to intuitively match the standard QWERTY layout.

+ +

© Cameron Briggs

+ + + diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/KeyboardLayout.png b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/KeyboardLayout.png new file mode 100644 index 0000000000000000000000000000000000000000..d0998e288b1e18536d87cee7e0fad5ae3d211bca GIT binary patch literal 97424 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
-!f@lFY8?d3JlD9c$!ml8F-EO z=K(-3=+#0<8$R!(_m$;@!*uP%f+Tf=7Wz~{;aDC{-Vx@=kyJ*c6n)gft{V{e6**_h zh=X74obIZ7U9&Cq3GTJb209uXUm0_aS1lCAmiTtW5|v@NB2bB)Sj^+c42Ju*Z4S=l z7ZK$;A%c$MVll!VF{Yt~&9gO>ZX!qDE0)XRZMKt6O|7%U5~nfZvl_5R%oFFwr@ql(XDFGc&+RkIxr&DWG!;Y4PyG1M|3ggp6S|DEl$-@=k_|7I%Zy3 za|G}Fvc>7`HT|lFS9|714cmC*iuUnYK-5$=Ff62L@Y^RQUeds5oIKx=r4~=>*^V}7 zjr+9WOcxwZY1p=l;Vm=xD$b6n)4Tc+TD%>H|M)=G1cHybRw0>^lW_) zp4a91fuPO}sfgWj>BQi~v)i4}+ zpVQ8>Dy6r(#@#BV+;{)X)pD)%FRsvUGl}U*Dc8X<}ZtB{$r?+`9t)Ji3n-c z|IWIAB}sE|8N%fp#Havo$BB0^W>EMCAqCjZY!dV-SC#;0tGjlqRI;1f)bC%aujJ&G zGUKbl51+YKv8LpkJo1gHiO4I;iWL?rsM=N-9rFt%pBjYd_zSpsdLFi#nJIxPu?*9@ z6kj$#i9f9=PznDuncr=#6iF`YD&D2Hm?|O~&o5u^D`M69u1qVmSJ^Cai|TuTUNN7< zf`69%tZMMP?Q`K<+Kp4!Qu255N6sbLgh@AJ zU8{{ckX>PHtz17&oAZPwxnj1v(QJ_Q0|#%V^*wu#Qc?4dVp_tGt?a_OIov2cGXw@t zyb6=#cg|o_;JgLSI&?2`#hTE@WKt8M0{#5gsjFd}!zUv; z8W4`TGOMD?*IeRUir(Hg$SG`8BxMt{t5+Wejnn1nx5%XXPtiu_rcJ|Yf{W|6Jq0)= z`!PCE7myKuS1KjudWUht|4(M@Av^Z)V`H=c;CO(P-T(aI?>u9(cC;p)R!>K{^dota{|9LxLRRv94Jfsx} z2Oy6t!6Ql6F~AH4TpOQXwig`BFMbghZ+)}*XMn;J-kOXDt zUsOo(KxeCjWLgk`z`EY)*}jaAEAun;-=zho>@o)%HrjzfMS>@3uN0rEXAZvRXSpDQ zP%?j3V+AyOiZvb$(PFJ{r~sak|L^<~_Eb#8oSY7G;1;_Mrc99ODj@}UVA};lR10KC zp12>W=n@vg6g}<(+5{j&4=ABdpf#S6FwH~dbW)&|KeC{~<%ui&W%*t5c0+k7Og}&> zXvW~nlB+yZ3G;fON=c4M^3z|I2%h9$2>n&4YWvNqRB3;#;-ob0kf>@VPj@seDko#H zg+yfI%rEt@AY%Eh&=IfWw~(RxV!i~yDIIw0nh<~fe0H3mBZ#1HH({_N2vloXCA+((--Oyc=PdJ?M)$@PPPV+Ew^ zcdP#3KbRmHrLbT_!%+@K%|25HnP|k!@@CO$M^9B=Pl+8kJuj*eEo=J$3sl!;2)5ku zaYzgUsr=}y%2P1PAp9yTj@4l}1WDd@$E3P6N4S_XsG6=zfTaz|M|p;6;*qTuV`M#G z5xe(hrH~MwvLjGo-CJri=IIi-lBUE|V|chdE<54~cEkzj8KK~So=iX>&D_fQ;wS;Y zVhKFY6iSD7JWBYAwut$Q#O!{m6v`*1#`++|HUkl*7#Wsld5~~2lCaRem1NBL=tc=j zD9(bakHh8b@}e9aQ_H-yOD`)#8S??kj7k`$$*)=Jua%;V2zUNSgH#{Dw%Aa4_gMd$ z3E~1MKSv!tqInSuOveQoM;?JcXT6>9r87wch+knIxG78-ZMuBx81(B`5Bu4Youcf-1*1er=6fovX71YNWm zVRW>TgHS(BPZs_n4;3mUo|OjWuHX_JOgLeu(o};gR{sJ^U>4M35{fxu0+@|yy)p^| z<<@lq8vGPf2}TlQu*hpT0WwYIAn8h%bR-M=vfGmc~XT-p2@{y=ZN@o6YJ);;P1c`~b zb#~~ffwBTrQv-fS+P`XMZ`c#MLZElJX=(X4m?L2w`!PkAHpwM% z0FkKpgHbZwsdgc!ScVCmgEk-`j{{gxxy;h*k2sM+K=W^NjSQJy)0+8adnf^Si7$6n zNdY~1l~w9;dWnqXOOUi`kEzNEXV+f%4i@kh39dan&0DcauwQ@tIlBHaIhUP;LZd7L z^f{?zjMMEpO`4%W!BIyvMqmEEjj58)i;I^Bia><2$VxwEc5}}Vxd_dFEE!5KhE%UW zEH^kfY6pUfEn<^BGHVuE3~H@#h4D^lj7XRv z0#0XKqQ7RC4yaK~er*$~gvSnc0UahwNez!vyz_{RXaVR6a(Bf^JyO+=ofn~W_&?uk zGaO3YukE-81DQ4dUw9yeQDTP#CN*wWFq(a#ITe|S5jk+o zLC@4RX;>>HUy@)b7LAs_gIi=G#a{%kffO&`(v`Dx$6A=XsZHDc0|t^avCclWoaU-` zmzXqDU%`A@&6APGC40Vu&X{1exfgL`Fnfb}S+2;dK~#wm=j z;e*=vfpYy~L92Nd%R zhcNopFD0ivlGirG(UqjD@LA&WHN{UFWSGgHT3El8$fd>4Jk?180?sLE>!I;DYMBnU zOy&#N)p-NV*hvNE6jFIrY@9&c9A&zUf(IRZdRe*tr30PlhMb5&cLsg z?wvlL>3w}e0BuysWKzT;Kns`E1hBWGn(^>a(y4dg$ zCtwo{jiv^8H~_-Nh_lNvi1jTkJba}E8a)q%j?mn*O7J|)vO>QH?Y{Ow({-e#jw63w z&DYRz0xcMo!ZrBAY*;@Aw|5w`e~t5C^YfnzE^_lfYjMAk{Wtgl!m9tZ927V+P#Ox2 zTa{Z+RUlm~fY9K#=-Z|bXU!Cgmw*8oglhIv+(1;^YD(i`{&Shl^n|u$+ZF;q2`sH5 zF9fY&XOaRtQzGTyPv}JHb`h`N3NENq&>|3|$-jT} zuS>F%4lxn}{Be$y1;CK>7h0k`WtB4Gkf&(5&GvUtKd#^mjxO9j4#c0g(J*G?<0XzrX1XZdyuzHb z@Toe0VAS^!#J_`^yT`;$`|7JHe^w10HGcuDh%nqlFxSj>rNQp1(MUvav!M`@3vr2T zzw{V#|0)Y0)WREWfl4kgP#fKcSo3nk8fz;SH}W=~NYadL1V zIO5o7%{ZkbBz(K1ye>hV7|!?);FT|m%!nHd^^i`fDdz_glVTa|FAz(s4=C#_k%F_c zs=Mn=D#y@PRi@($CII;Z{H@=`t5Ro@F)$eRS;ygE#|9~VjrPT@XYSnc0^T58_AJA$ zMone)gQYCa)|PoG3R)H$F_OBa#uwABt@YyK$<@_$Y2y>Kp3kd&m`SEC(jVY`C}ux8 z{vR~4RX$V+WT zCrN{Uf%*X+lYo*;DHGuzZCnQhK!`D2QjS4wFCHjCOFgDvdy^H*IKkQ5!~o>$mj3Hg zpAX_A-l6V^)X&rY#3n{XI27q{#1~WYN5+h}_-n@lYqi{a49TV`Pk=xct`F)Ic{BaW ze0-}GAhDE*{Q$94UvhGMGx;HXow@>DF@&*mLgc!mVO?Szn8;g2fccm15d%zJtL)Yi z$XX!M>UVVRaT;v`OT5~pdjjy46a{*r(a3ZtIQ~PoDP;Z3B2u!hw*eYG?hcZ!)|kS+ z3~RpR7($aXc!!OPXJBJP>Y1$54fVhkSHlCTvy-kc{@v+}Wnt+xH8&sGI=?;%;vnQUxgZ0e*CZnV5*8RjSN*Ue?`K0dZ{@fwg5Lyr~A)D z5wkcDilaQu+Fy|oa}mu=u#k(@jFtM9$UEeswegL{Fk^Vdj!=R1OKE_s z^L|0;V(z>@VB_K#=r@IAMiYd?gYxK=68>mM2z-?*_;r*!zNuF}O(JxdueJKh%;?V}YmW~wY`|2Em~EnD}-7OWparXDHJtX-oA z&;R`g5r>MI{mocn@=GR`ar#&%mzPoiUrIq$5va8ow95KDdB1qP@0Zfou0{p`C=_l; zGby$H*FH&_LAJ18Bw10)s0GD;lv9{?^EXVuat^wZGZ4}BfEhC8pe;=vp?+V~^>mtT7>k4`HE2GA8gLc5n-zVXlb#UUEb(YXjud z2ZB&A5(=O*T1DI}>;H5q08*2-wzkr%u!q@??d`msLr#x67du~OFZRpR26w=#PuxHe z8&FaYSV)r*wOm zjMhu#_IHR;H6@8lyL5o^lFgP3De(fo=R*pzHav)3xUV&1|^Fu3#A`5Ehd3RF+E&;mL zsC&>Iz%!u&|9^!uvT@MA3t#@@8-Rd{%p2Y+YVz<@!V3!v{|2~*%F#dsSDZh}*;9eY zhtK{TzZJ@S4*TGbzuVwT3lq%xgxVV?WAB2yML_O;h7;a3#6Vu+Mgoa2`( z7hIn<=K&I=6f`5G!4Zk_l99S{Nm5{Fjh52J?x5LG`m*Cr0&O#xQoU=^YKP)Y{?23| zBS6B5!+s|1(E;sZ02r)|l@`EC)g?V;c{~mw-R6%Ndyo7MX>qk4UYmN zZz=#w;*NzmqPA7i0nlV^tZ3RX2P0lMz_R^Sd&vWrfBTRX8wYBUEd#pPbtE{PyC%N` zjnQY36rG2~-A6wIK0^AC?o)ZNrxNZuQ;3pkWmLW<5Rvt$$*BkAJ%?ub5Mueh!iVSC zxahq_zC8A8EED_l<^hxB|Aq`T+<-|EX4lflpT;eFMe~R1H?XmJN`rJS@?Dp!J9?MV z72O{QAbj92z9Vg3JOF}n_VXU~WG(@aAC%vUtx?Xu0WU9jD3A?Pdt>I;xf*N%Rbj2n z0but$59u8lz0v_fX|Q(INz<@8kPZL=bmF2vzzYrd|A_+M(EeHmL156?_4mrJ z*?xYxMIC5uf!%EI%5Pb^hjd(y0Ve$fpOm_FW8q~$i4g@s9lQRPS(x{KbW?Cidbl`; z5KtNTq^->-h;CSFEh%1yEX$A(_7h(Qnst6f6ZB`ue3xsJFH%vohPIh>@ajq6=#sxE zq5q6kwAfei?r#qH;Ewd?d;Gz}`9i+?9@h>O`{eE7ds&ySBc$C1ug^I7j-uKRYcu3h z4fuXY?R}MP3Mo0~o4cJ1KUlWD;jB9j^-}ESbiNxs-cXa5EYAN|77zHHrV<@|^<3y) zXwG$wU+6CCd=Lbs`R!)qsVMFtyy1R`?tI74zm$=0ug^{~E=Q9@Na=Gwq~UxyxW5z# zsb6p!IeM%uIv9wrtzA|A=#jgB9rNY3Y-${^RB458^9zW|iw}F%kkGu@*rejLNP?>JLKjWT`K8 zVx$DOvm5+wD8d-L7QGq;Ci_&S7VkBD$sJEI`|jmRYKXP|rn55uQiwVmY?JU>f8Kc) z>V2S)Q;wpWwS7+XXEDhYJLzYd=mgsjLo^#B_t1h0pe`WmgGVSOPw}hk?ry)ISubx8 zsC@T#PoeQ~3f0&2GcNtL=9RePduE?3>AhvF-s?}0d}40w{4Yd_n3fXn6~|nlH>afS zR&Dv=SoILe?_B~R&mGb^uX`>5H_3No(y!osj`wUyRIZ4pWk^@>I2bWz={uPcHTSV2 z=Z(}A`_yzu9v0%+*xvhV?`fNLVQPhL&z&iCEGLfO3YkQ%#b#&rFhldK+h5`(8z21r z%1P#wMO(@Dah8?L3C_GO)(;j;JaLmReIO$D{O%hNP6!m$`M89d!26H3p`nkQj(?f& z`9d2yRa3^^v_A_D>x5lDjgU`)HFhn*k4D45SyqDxm&&ZDFcDu`Q8%)AuUb5hWlnmz z{|?3%ojtEn8MIrE_XF^=YKa3yufAVgtQX(C zYEgH)e9?gFwCG!IArUo;9U=q|Mr}lKuJwfaVHXH$7C=f(?9zfRS&cH}T3b%{alX+VKKrkL!M7 zKrak}*e<&;{@uK^Qu@^BchK|m)a>urw10^!$j9}jtLV9Sjjo@PYfKH4S+eouT7PmY z1=0ID$~L~(&|`<_W#>scSaO>S^QdEAS!Dd>@s-BzG{nq;qR3?s5O<$^@aG!J%H(l~ zbZW}i$|^WvVhA#Y`C^LrJzn0}#HP{D@vi-g%YxewS8eMpmmgSaiw@!4X>i!Z1y5ql z4!*CGfBZ9ux~}m9)ZEEft$X0PgooY}6DZkV6-wCq5mDUv3DSV}kI&kpq*`c$t^(La z_WXIDkM8xSe35vLCudl%wr929EQUDnUk++p?hvP6pd|0irS{da+G#@h{GWC|mD-;s zrEjBW=ZknhG>aYH?u$mQ+jGi6#w<56o!9yohrFP=6)ihU;T&;-)%G06d6AN$#U_v1 z+8MCm@g}9=%(IfBg+pm*lu5Ia1=m7eMt`QI!g;wv-q!J(+FObuO9nH*P%6IH5UFGH zgchNFfq2_ufKMm3OiD>LboEqn)OFKK=3vGkt=stDK|Eb@f4H}I;|yXlec*agxgYR} z^By00B&o$RW{DiO3P`ARO$m}AD};R~CBs}=3L@G*hrnVhg1(2}5lV(rH&>hUyDU9% zO|wexwJK4G|85P5`ijk?c(92nqd@e^2GGn!E}QlTGTiN`8_8sI1*>U`4$W%OX zVrE0rDkZ^yT^Ci9Uo0JF4~PtEasORBj|0o>xM1e4g0tBX)m_Nn#>TA(Wc?k^66Gf@CzC z{9}?@rWw#}jaz=i5#y!RS|ipshMn(nt?bX-@PovG)BTV0fW10ruFgSEELH^keROxg?lp6$)lsz-GjIqzn5D_D=SR99Q~Yv1&% zGp3y?-&5LlGB{7lHO+M>SbF*I@eheeP}0Q8=nmULzBx(7wRZyQAJ_TPfEvlihqOEU z&68@ZdNf-|HA$j{41| z<;!xXw?*BF7Y$mxi*cvira4*Osi%+~VdnnqQ>XbKTHEFdydFsIe|HZJp$z zlwM$3+Gf?uTo;=2s3*AfxFscvjZ4aO4%dEOctGkZ=MS^BZi#l=Yt1#U+->ui7`O7b zT@XGwJxMX(@>f?fmU-JVSc0>CHs`H@yWdncMpnTrSHVNk(zh+jo~xrE>^1DUlUbft zmG?AHHqd5y*D33?e0eSYO#e$R5f!i~*iRC_%ZxC}pZ6;x7Y#=hoGzH<2{K$icHaEC zzbrWK_ITcFi%=jCHE2a!Fy^VN7z@u_0p2v8g}=-W4M}ty61h0%fCJIAa$dr)B>QXl zkv022ZA|;TU?uuP7BF;M%#|zoBlynq#!Tq$)_PG;)R|b+;}3zD9p3QFxAmfC?NOgZ zC(5R17RyYvZ!7vJfO|5M*Rt6)3KVTh*r@wFmdo1tJ@_ZFaHcN%v~I4s#CBivgwuuU zjP0;o&UZTR!w}M%3)VTe-A^@lSJiw|ls>#dZn_QFiFsryr&Qq4saGVJ9krx@w>LBl z%{hViH_qe-fAL5ltp4`}Z!&dgoUFhnKb!U5#-(npe<%V+N`+8?p9|EY zB%Ps7xNfk{xQypkSe+YNSQe#>aro64jn=F#Q$7rqq;>d3dOssn%{>LD|XAs3%s@kEONRV$o3m6 z$F*Aq$HNzE!|F95ZmuS^!#pL?>bL9iSvIk@m$@ zmKgvc2OVc?D>f0y4H=?ty9y9MwdA!QVuFsVRusdqz3V@cE_!NmW&Vty$AEk8U0=6~RH>ZsGbZsCi+tzA}-z zfKN{Y`_14)&pc2j@PDthn4m|?CWD7}7!)oDRF6fzrpgSiLtAlrSDU{EgtWFK%%S83 za|R#bug`Cg-E%jS#^a5II5hkMVTXoxYx^?dF_!p1juX`Mtfn@R&-R3_&q3?sIk5FQ z`r<_r;3~J^?)AhV7Q$sQ|FcYhWUEWng%l+bwU3Nfa}1jqb$08VLZSYcJs_}cK@F}0 zjnVy2<9peN(0x!zw}b+f_me+J>QK98oMW9ir0pv)^qrw9x^c$wST+fSgQ%4EZnOKa zeLGR)4TutApRo`4ei8HCa-wS6$Ruf0$NXu(_eUID)J+W@$SNP%Z3#%!I6RDx`ptJo zk#yB2x-59PDk$1^o-7pRnc>=-s&Uv!J~g1EHCGvK?@DRzr0MIRF`mjY>YYbI-99{j zfm?T-%W&9M`RXKF0H~1vcQ5KWJ_yiw+xI4JPwah>GvQM~Q6FmIJIpz1Yy+-nH(=A=b8yg% zcmH8;TUsQU8Wq*IQnGl%eoM>vw~WLDC68f`l{0c{U|`~xRvctt09YEzE!x}4&`L(t zb-857s}=Tn1%P6w2_KyJEydje-L+5HTcrY=6s23&B_;Y|wUmw_V3Fam@=`sqZ$vXZ zQ9P9}*T?Jvy7}hf+kbmaEe|sH1y%GmNBX&bv#@85^J%GMT3LSZ*gLn>9`_?F$2mJ1 zvljnUIm=p-W$9R^E)@2j{kNO=s^Po%Mc@ds%D9S;6G>_ehfS|CCMW{M4UaoB75KZN zis(+M;K{?AKSl-4{b0K6e(F$3LpX5%{}l)^+8DfNLA>EaKEVytGU9SdT2**BYkLT{ z_;)^WU~(cpzXDBS8FC46_!J)goI!kDF*HDYDxD84n6Mns5X#K{_Ir$NBKU6^j_G_6 zpqN4qF7Swn=7#2T#_8GdBJ%!#EG@ZhVzGa_;QOMW6{F_;b>!lG(EOrBjpe`DPMkco z1bV@~(F(l1!Xj{bPtPlK%3^A%6FvqJ)KuLCg(g^76ifhM!+i~{khnGD(`p_>VI@W= z3r=Pc=-uwBIA9Giiu}WRZpxY{P|&ebmozf_9mBf*SbGo9Qz(D?hGoTP&knewi9Ubt zRoEyBQDMy>U_rj)sOAI{n(+z^0n0|uP}Ee1}n`G>YM5`)-7N1Pr) zN^Wi>DqA=M;6Df?zui5(0IUuHaKsjhbDEil>=KUS;N!y1?~eh#ml5@R4kT;DU_n<$ zH@nVB>`AHf{F`r`efj0unF4o=x0{s}YDm?a9W*Mpmd~`E8E~`x5ti zglW=BP1nOL%_o!GxYQPDo&G)N1OKLd{og$|{!5{GSkb^Q{(l*E{4X!oN*(ItdvS+? zeeRIDtj{ZecKiDogI)g%e3pNC1paF#(MpZH zob!oyKa_L*`%=pUvK)tB+6Ubh2?5veRL)8ObooEtG52XFJ58P5iG$;Uz7w^pr2Dg0 zPN~1&`-kIR9ETg!)T5J(oDB%`c@OHo*p#6^XMXquTKr2=EjOflG{^_?8;wOD6+o$_W)^%qpH;c)4+;_>6I<1|lgzkeg$0dKUDLjZpuK^%J z{q5HNLVw*M1(oQgB+Ww!*@H%?pPeR^HNlP7d+^S2B4=E8+8Arg{JT5>e(s}xI{N=m z_Lfm?^?kQ)3oY&~u7x7St+*5m?jGD-ixsC>C|2AZiZula!6CR?aCdiiIl1rWJnz~2 z>`yymWH4A6Sy}p*^_%mW;J2lRNoY@5S-bmt(m6BXKNZ0|+u6mRX(>|MZrf<}RTd;h ze-aktee}xv$9n|t9!*j5TG9Eo6^+OA->Um@kz@k+6dQITKw7WCobF8RLh6q=qE*vrZUxuW~_|K>&n(DG-as*Nt;&G_fYGX41X z)Y=7c_!NmBY_rVHF8`<%z$OzQ=X-$7o4d^9{<09}DLu+-DJ5}NqPc9=_=gm!H9DW}(hCtDP7Ybd0)b~Q`_ z8Gb+ABEE(Ltl-TQNBZSZEu10r2mjNQ7#xj9FsQ+;?4{AdM2a>C_L`W^0!y|& zIeLWn-YxyQWqu{sxnzH2B9+Rl=OiDrTccl`WbD@J3MoDa41SQtB_z-uNq)-3U( zqG4^7gkk|iCRZ}$2WXt_xxDR#Shrv-L1rE%W&${h@xmwu>y>5Ad-P3f&UR}^`}S!G zr%lLkO?}t@k@;xt5P=Ms^zTL16o%*UZgtv*m;XV+x*{%Lk4q2-PMMYJ5Cy3awabv9 zY9`s-guu!P(=;-~kCZb#m=5<9<%yXcerpqJ682f^SZo?(z=Ky7EO9Gr>2DEF%ST1Q ze$RAQcTJO4+kw3{pT_?Tsy9f9pJFRgB`TCl|2^St*EPT_?nQ0#u5Jz4CE3>$lxVT4 z&0E7&@M`&IMvm#uSdflD99;qjb;06`Xv+Am*RGuW$w!6G$+Ai2f;x?E$tWHV{pt-h zjbiX(67~;lRrS;pe7Lu|`qlY7Te)sPpy~W9!P-&_pJSN*Kf`ioxcxmnq7E8FQ_=bZ z8t{j$?w6a7=rjJJ+XcAZ3T}i*rYlQEZN4}PXp2i(>G=B85FB9DG~ag8#pZu3u=p2> z=~~ZmW5)Wp9Cj2AC;mW#eQJrS+#N~1u&@|Ql+TtfQhyEDV*ABN^IBd{X{CcL_e04u~J1D&@O`VqQ`&5iQz1G%

~ZF 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 gzp17`|ibnP2GkkYu)#Z<}FU2QZ2 z95Io0HL^O)IZOG#E!5T2)l`ZUA=jdz5~BeWIR|yrrrH(dTdGQiT@C71XUn}bpycvZ zaT!U{xN(liqBPnlBjy4%thSxA4|spuYv%A$B_(fgs)2K7shH^ zb?@mVVN8CnUGQ+Bw4)6{O2C=+ZTC$;Amz)ZdnTU`65${Hh7YXTQ%7HSM%FenL^~_| zZzUdkUrvO5IdP@r%H?!cG057V5l2_+3`x3-d1odXe8k>RBRfCV8FoAeKb_7g&QlF9 z&b_*-|U67@lV*IhjdxNu8mnas(+oeZhowGk|RYWmsUwTo{aFYB%+P;7Ae zO$Y@!lf4EBe?KW74aT=!JRPCT1el1ldB2azn&zb}gC|Fo!b(l7el~{oT|c-VBSE!z z{bQYz#es0(bFWcb3T3RZ(^%R5`ngX&5!8!>^5y;`E8Esj#%hftp$M_p4YNYqn&09# zM*I5S&=sfrWSDNlIr{01%V5~Ks6aMD_q${_eAUGV_q51;FUS$Qd6lh5e7n~j8E~t7R^-$i z!ba}a`DbS7dhP@d4)`I>ieS7`I$x$KGMqNOI$L=pHVim&e;l@|E-B;Ny#lakVbvk> zG)Z+2cu5?WO&#nP(N3b<6r$n3FJ}^dwX`evh|qc~9ROb|>bh~AqF&CU$AzJ%Hj&{d zIFfFdjhQ;@TL>Y8yz=V}Xb1EKX4CBA{mb2|=_A0xJVmX~B62v$vEZFn_&YHuIi2P& z@lNH{vw%~lvm!q%vhnGzc_K46LQX~xGiX=9?U~Kv{-oQ%$me~jM0Ea-rn-r=Yy!xT z#;$-nX|@ePqxs?~T1Nq89|Hq;xT2xc!E{+@H*Mj#Yh1dtDv5lGXjk~lT0lqaNYU9| zyz-Lgd$?0$rIR<{hA*Zp#6lI7NzjL4qvEOJwn=&F>olq=7vLLyfdUtxy`^pEng4m= zL?~z_ptks`5bPeR5#@W(Wi8vya8=SHBZJitHuHQrdKwA!eRrZ6h}W^pfBVh%0(!^m zWl=#H?)WsHC}2BB{2mYx1bwXLJx!QlGu1l&EU>y%biUy9!t^+Df#~H@|Mc!%M;_Iq z$eglcP5pZ*&LrEV`~@0xV9Z+Z%R#Z%O)tH()>8a!m`0T0U4dv@l^C1HN>2mLTJDdy zfGi>@&8YY&)rIr27S3zW+m+`>#YdyQnxU{_h9s=W{A>o`3 z+IaE`1gug2F(h?ZqRy9wwIe=E(xKB=#G0kU1!DmkoPG4$96SO)U_7<`cbofx-%FBe zwv1Sn6*fBD-Vf?m?vLm$o??>qaIHKF`yM3GpN_Y0bE;3-;?60Mp--r%l2JlGP;6|N zrKYEM=rcnEa##1HZu@pluT~!Xe7A~v&o+M|D=i&iGmIf^ejmEV@u2h}uJC=byKN!# zsbaF1C{UGX$dsaP44mul*BhAJ?0RFlO~{_Z%7grVsO*YTB(N8H>+bucXVlH4EXlrG z=MqtNG_51t>E|Fczd$$16I+z@`mO3TqmGG7 z12k1DcvRH8i~120I6#3bff;Z>+rX;=7L=RQ$lFCYYiclu^!sqWEe1sB99`RG?+V%_ zUCg?6iJ)Scy&(2CTNAfo7J)$Ho9#3QT?QAvoV($JY4~IrzIpQY&wdLPtx)DlCrWAq zu@Hs8IJg*L{=+}wzkK8Yd+xBbZieKBXP7}1G7XW}p5X2LOlu(YX5DO7kQ*d2#fR$U zPzlt0yS7d8ebJ<W{8Q{yuug+Fv`u#GSPw32u$2a-dWTY>a^2cDjd* zooLFX9~`dxtIeUSgc0pn!t1eNbWPsKA20X=*CFH3l>K{{vOg$RR4Bs8NQPP$YzNH% zg)m|#Q701+{2WX&hBUBy8KcDgRBlou5WE6e7qh>>88^Zm`VY|WJJ6?!GtrlY7p#}< z9ADBE|GQUVo_lM}-)x&Qz4`b+tFRR3!;FByfcukY^5^h?r_ockfCD}(PvX_MiRHa) zj)!m@uQkzL%I9j)9yss$nd|XlMJQ%e7++kQ(0QWF@C!T2!gDYC?PJ|(^vfl*4SK)v zg7z{9y(RZONc(Wvz<(+sNp9;xkyeW83oMt=Tb;0vhp4aCEYyg-<Lz^6>Hoq{ise~%tWKwt+1?NJK~F)W?bG}WlG#*cWH!BAf4?rzNoxHH z`6dJx&7O}1F1u`9{frM1Agd^?%*qGF#H_EgDT`?}jp!f--n=sO^1x|&Xr8CFKPjw; zp3$&YKg{O|y@#kz%*#4@{ysrHBw3EEAVcdIvpivdui@<;6?~)>sc7nGgSUYWm*^&| zGS^ZN5=1hx8G7j(>|%v-2o;iWVF{9LAMtNx!B?2@L!IND1hYV1w`_7jyhVXiYW;>w z=Q>tLx#?$a9Dq>@p;#07y&iz_7-QyO09P zQswvLl+uZI?_=@VdXOX8p25`Om^v3>;Q0?}OedvtF z>=%}b7^wulhkkthMo#R04@|dC!nx4mR&SIgEcC@;E61|LZ0W~!HW!b-fe{BT8qi|B zr|b&IjgOaNs88PSS_Z(1Xt30&{_m&xwg2~D&JTxE zE$yBnLB|w>?_f)2{QF)QFvLKy|Mw4dzTm%gtLTF-vEOMRo%6j6ni@NLwKI zJ}9_n#cq{c?74Z5m{NI%^xLu*W2Vu4PqNu;Y##XXY zb_D~;O0*_D);s+-P?IQ~7=aE;4&VoQowJbeEC^n4v;YEzH>(+B;!m%2a3WnS2SCv7 zGk`RSrpLNi*8U?BX*X!gdWQpmjTF%ipzq@VWSLZN#C4m({i`$C5|Xh5#443Q@ceC? z<@7KX{E?7I1)=4|HXB{O&)}A8`<`2^Rch{UV9%GG4xfWHV! zlz21|oq#NEK#z4VxXZdgz=LZhjaS$b)-n|p=hCTf#mzH_YgY61W3Ox!PdQg#|JNwk zNSsoqjDFSsZfM^OVP9^Z1|~eyq|8XyG9JTT`ub5uPE3PJxBaTGyx5M z@D+T6e;;hgOkwi;i0k?Zzkq%x(iBfrt)ZggbtVy2NnAcRWgn0!^^{0}dq7(y>IS3k zcr+LH)f*qNkq}?k3m;?VNJwH+rpf+FdNKZ@hv2{!rfuYRr3`#&RkEa)F?BK~9*nj~ zl%r*4D-S4-1|75T8~X@RTwY4zpxv4*7&pdob6eOkm&cb4Shg5C35(yP`<`$bXagL! zm~Wy-mVZ9f=+BS+wYi|b*!9cnmPw)w7a*#AS0G^Kw$ks(cBe$b#d#q2++rA|Wo>s} zHYSs)@sp_hL1qAyNK>jY@P0O$QBIUOqa}Gax=FV_~lJIJaws7IoRhTjQ5==t^?&KD_8cE(nd~+5+*Y70HX>IK%P)7@i%=Q zu=p>>ibQ2_eywFe6a9)Amy)IC>uNi~nv{|KTGPS=BH7+oW^QcY=(u6W;Ds&Q1B{X> zqR*tDm|I9GGqDc)M@4?1Z8HsT7HPAf$U#0A(8dmPgx+3Lifp)#VSYvbj3 z{WL%`Otc5zztu1z8^k3ZhvY@Am6L(LzVUnT49~4QyN&9plice?5*nWe4mD-iKIVAD zgtv%U%~LuDFe`6ND{9gVPx~978t#~yCo1r)E?`H zC6yQ;eU!bfl}haAlu96Zpf8h6__j8wB#`ZEe<+nPDU**%qyG8=CkkFS0W)gfmICjE1)A z{D|6Eji{~sA=eLyD(qwWjb8-jYD*-+iRyEO3ft#z-)r6_27TH4sN+M|KJaySL?%>T zpx9zli*dk};8Bj&zFe}&HQA(P`OBZ5(p7y#OXzlHAFV2NHAC-e%?kau&*4Yd)hy}| zNUzt#fp`8?(N&tiPp6j6m{g{v-N4W4s+TQar)>JcC63R=>aT2px+b@FjBG}?EiFLJ zaR48mMl+kJ;HVCdX0JJ}onj9@Xw`_i^du}u(y#x{(fF0Or?1RCL{1vQy+~9rQpp2w z1wbZGjz0qMNF(C9Y+H!>9p-kgm+)vbp$Rbu3o&tJ6E+-b?#MmXKH#1{j10&(q4<$c zJtfsL3h+ypBG&xV;6g-PP2_nff@u}sdc+&G(xEGSMbK_L?YA$k-}MKlim#-RAPHQw z()LM|U17m!cCz_>JLtB9b`j=91)-qY@TgYRQOv5vB{=XOO2wNHNfBBc@-wd_? zTGAvZ3I2D#oZkO#wsWvK5Fd6;dh%@z6c=;orXJWrBZ>AtQ1zZoRiM)WYaNxXz!{d7 z?im#Nz`LZs1pvrkYUf9*ov#2zrVwnEED>j7N_%v$besk`N8 zIFs|w=*uI_utME^emeR=VSl{r2WGGsaqQawAa4)s+!KvtR zU{$P0%^`V360g*a?^3*cgvZ3T-@U*T%4i zE^Eq!(rjUPO6DOgz5TuKvgL~$d+s%P#(Zp)UhN?0I3>*Xg}3me1SrLsrpC`0qrn*b z8;&stTfsVIVjSWNnhj$IRQ*|``(FiPaMvUh@Q`aTXfpz(HxCyxc~YqgG{$B7t1~Gb z|4zsh7s9MVCidWt@UAZbD_2Ug`@U-a765T^avV!5&AVaqnmEf(O=@{by?bkP_&No! zSCNc$aP&+tqTjrjI1&o4AiFi9Y8hwT@V+X;eogzEw7fQhuzyeEywY|1fX|>M=blNm z_*B(FWok6A=^NKL>!5jcs_GHvUS&cWn(H~;f<-KnO^WQxkDAWHfT9ZC@6LR`ugR;g ziC{_z*H8>sxtMqnV}4x7+|3}_6~oV)3$aJQ0 zH`gVewEk%!&3ob&(fuwpC&fcoK~D=fKWm>NEbwuf>4}L`PfDDP+`X=82nE(cT|PcE z%wqhBWJ>E-99ef!EG7By29QZwlLE=}beOpHAnKEKmOH$A+j9e!2UPH${JfA46P9#5&vmXY3^L9uN$C}2h;@=4II$_drlz|mduHAe~-NmVm_Ba(rXiI z+y*KQ08HjaC5eOcb8X|6^z)w}wu%RoeOni+uF^H)gQ`h#7bIW01>p#(xCt+zQbivs z;0Hp-xKA0AbBtTtiE<-qxfz<}u4j(@M+YaQkVXuuzno(KG_jLdX={3aev6iFP6C)RW|-M5^Eqv+oBy3g)e{^dH$ zow+M~91siIN^zv)iZRcUY|t9;PKHE|{1f5;f0dB`HMhPss;nb zN>WAWw)4MT2h3r<1dqktX^M5B{GUMo*E)s zu%sKCY(sforec{ZVP}3~6XziLzx@{M3HGH0DE^@##9SysvJoWLl6TzlHCm3MNP(=X z=so8h=jM54R=_wcdPTyQv=y0p9;=LOT8`mYewjTTjxxS#>j9bOmxiQ*@rL;10*b7^ ztSeUEhHpw+Bj-nU8sXcL_hSnVN6%>u!w$H9_jtv|W@^q6X?mba-AGtwJ7|1;Ny?Wu zuyo_^L7`1B&g}W0{kRErn^rX596s5I&S?oX^5+XHQqw#zZ&EJ`jZD4YOu2>KEO+*% zY~yI&xIagj?fb|mn_hw`SBG<2B8>dm!@5oJx26juYt-c!EG*gYN3hSXN0-}1mr2`w zTYa@Hs%zZda^*ZDh~7O{xU4^7Bv1N5wk2X;T`gHyv0opr*skm-2MGUYXnGW>3tpSj zHhM~!hE~WIbEW1OSufd2u!IBrk!D5=x{}aSTpaA*Z!j&~@)4lXX}D|MlJ!iZ*UDoK zMk5fw^H45*2@8 zkophTZr*}(f7O-Pn0*&`!;K#)1vbzscUU~qWV29B7mc;ku2@~{wkv;Pu&YfACF1O% zibA3}{56fP3iwnVa`&~EJ&A|L3eD6@83ij6cP7U*V*rLLSxoQZq46aAWD|FYQ zIUIhHVf!KUa<+Hg)78X{V#7ul13)8G9`HzVE-YD<+Zrx=C2Su3`bs!ttvT{!%^xjX z0_DvkSWogsyHvmD@KC5sli$V7Zyw{<9XgTb*4bfb`N4L{UV~I2roX1ru$`;M+b#WO zU7iH*tNP6nc72|ALtv}LKXSep5qlgg(z-Ms+_1}6ijP;0v$qvB;~75Ex!hgy>o>V# z(%7|z_osbh);Jt1)jz6r^xXcP8y{Pq89<^gOCEo3IpR4twi!Z>#;z7Zo*!g-L1@NmtX49@@l4QS6x83zqw1!ZS zBxB@vfu4aS$(nbYj|rT31;s8~U3OkKVBWLo@Dz>w7`uY(IzJCNNT3=|M0Y6PIH&7? zd)z;52?*o}W3W=qJw;; z=kn7lCqJQ>s?ftDw%*B-QcFjqISqs=9g+q)a?NW&+$92H4Tcf_Fs7U`va4-DzO(+) z4A;r<+rtES+4cNAU9xLg=4*FwW~r}vWm}nRqVk|BPb#KhT7g^%z8XkcGiKnuqo6cP zxvv`A$GC_XGmlHMkt~5ou3{}{_=S}+TmZ$z=V^nHa3NbbMLM~KIo<4Zj#2Q_8qht4rYpn_@rQxI8NsfzgFyajWSEohHswuv_i$BJ>0E3;(;=?j(?#`RktAWU zHeG|ZDfyJRV8p>chHs7nRV$W955E_C@*-Uy_8hn4_kKtgYcyB}AwA`2c6*c7PKi6%jXQ70>6b#PWo`%_tIeIJ=dMq8mILx2D4 z9?tGnI~Pvi{e;tgVq$e(0&u~tY8@~<2ZksbaH{8Jz9vv!ONeD%?fiOC67FpRNnJb4 z{e+QO`bDsGDGe>Y;1@xe%;!dz)g-6Y*{`GPcS&UUJZ%#?U42P*eUsplrU%^0*OtKp zs&vSU!f+V`zwM|BA%apQ&+WHj{<8FRfVU0Bj7H2khUC~+K`wkXGnuIDj!`3M;N4%; zFk?b}M#9wjA=N8Wk~^5E^Zo?at@TIj!MuvKDznkGP%G_w=#80Y4suV#|I^-AMzzs? zabm?Or7ccFfg+_yfEITxuEAYfytqq)6_;YAKp{{xc<|uv6!$_21h)W1yLtQmclYdm z*>m>ne%gJ$%$(%ROytg;``qUz>W{`}cp@J)gC5syvesSR_0sMJD$66mD~8UFmw|d9 zP0oU>J6C2Ar3>2%cZn)Ka_d3JG7d|HsyRyqxcZMTF$t;Fk%mBXvtB(Qj0rsNd5nK? zNZaQ+fE6hRw}D67r2d>D$Sg^e$*VZDl%SX#W1|c~zRouwQi?a-53C_&P@ouYVjhtN z+5GmRd|yVPIaF9xmm&H68@sP4ZP?#C^xcymn0DZ9`i~N=i$ylH}hs=@*$+$Z;S?_^wqwzI2(#PSmo5kx4sKZ@w z`&TJ7MDgGiPU)iL?ye)dSw}+19PY5%R`Kf%A_`neId7}{*gD6M|=+0W5wx4M_CiLAKo{eFbv6f(~bKn29_vq z^9U!&<^%dBYR&rYJ0JPkWFUo^P=1tMH@Thn5QP&|2=%O?JJ3S0;?@NEO?Qle(nvDk zJ!Z_VvZ+$~^quEH>FkU#-Jt&CL2KMXdo?&$1lmz`b%W7z2g_|A`l6XAd2qKF;m)R_ z!f5K52UrcqR)3f;pb?Qr*NsvkctCx=lzc6Q5Iy|>N(1?hZVvA@=xGkUNQy4yeTCpp zl54Iy!592@S`FpB0lO;rP1?N9Pa0)NdYiwR7?g;+3!2eY=3<~$XH4SC*K#TL*PDr^ z-b^8i;;LV?+H7&kkke*FH08?$FHIU;~2Q-3e;ms_w+ z_F6EXZ)=1SW9Ys#mU16J5I3UAKN!Qphz_Ab7^A#<>FCREzjs+Yo*1VlLfquQU z2Ghw^?>7P!Z7vWkNg-OjH5tMk6^dRrT*Xv>$nKGW))jjWCq#c|i`kF|n_V&0{>8AXOqe5=c7$V`2i7R;e z%Gu=#f~9r#q|s}GDK-mlU5C8E?$RrdmoL<#?c<3bzJC`**s_E2wBInjkU7_g`E?xq zde0SsafVvHF=sKIa7O%*^*t4BY37`nC<}js^kZjc@URBPg%M9T;EtoR?QK`EcgVz zOxzs6qq^Fp^f?393cAa~`o~t9^i`0XnQ}#sH z9620vE%vi>H&Xc0KlpLPJMtt1xB-YDlpjDaOm42v)jFQ$Y}S#zbqmr;KL|3rml5t% z)S10?4)hoM2c6Ej1T&drJwN4FH+%1+OzsXGg2zXP>BDuFrsJ1qQW~%Cmwb-8=)PM~ zlgB(wu7zaiwEy`r@Pg}wQ`HhQ>bE0wt(LFxmh7Nl$>_c~On+f@MAMm8bZ%~W5b`-r z!2NS4sfh-n7?X5AjXk==AQpb({#95afk;#AR*c=-KxK|QKZoXq$}0Dk*d@@1qDZ3U zjl>{-n#MRE4y-T?)s*>WnBHLh#2R?wUHJ>u&w4T_Jl;?&YM>$@(Op!;{d4mjai%mN z9F?C2sW8zHvag7`ipIW^5^>x*ch|8$<*?<-?nQ(HTU##8$E{Y5%Vb|YA)D2cekoS8 zdTBSeCct@=W!SSZ4?QZ2G3#5tB0afoiFpg!DBeS>wo)GbM6u>>ln?1m%{=GOWeVuK z?XJ2_@(?W47%0xRRe1*F2-3%rLg`~HeUCXP!8_-75`*5aw0w9sf!DA?kkz7m@L8ey z@>r8j2pB69=-fD+4l{lQNlRd$rtkg@D-%4w$En!@V(m65pp_$TuCb7AD{~G3PsEH1 z*wT{+%9M6{0ti^rN$*`rIpo`wXaGJ?(C0pGOP(Ytk74FSoi48jWXt|f{UiJ*>C+xM zq#{AS^n%ldR?gly*fouSe-oF}O96=(rv2 zgB_+G(aRSVt>Cis??4()G$s3ySJ}n9ltJ>M9=Od|lBF^ddW69UCqrGS?0Q$A;z2rm zAIRMG?0{b4L@N{Gs6mHI0kfqj)4t!mQ;n_q@~!4!gS+9ua}4`5fDYFlqT0!adOjF| zc<~z(R;4734fNe6Y8iFot)KiJuyHVwsWYTK2uQ*gUF8yV5|?Fk)_?WV+OCf$1$GUAGJ^Ju{x1J67Bkw?q)Hj3eOc^lr2x3C9>0`47tvkyD_$RB-~WBfq=i&AalR2p-#6;nQj_P!H5 z5A(ldSTXJZ@?3vJnGfPO zpU+j*i#yn$Sf~zf#4Ad6SCmA2zp3u{&8gmT6VvX`ryEisNHs;pitYRXG~aV{@uv=g z=jrF#7yHK%0qpO0%)hqBhU?RuH9^xPYdXlNdVZdn^}4Im_ax<2m5wz{!qKXP_sQ(F zW|~WA1&63N|9MD)6yS!k;**B?MX=BPD43#(x~wL8%?z;Lc^G6?*6qv$($S%HS>G3- z%I0`(??)VI>hqu<sCk3q+h%JW}4^8WS@$N#QohrVrja~Vp6z*R;R%ilZ8<+kl04H+VzwI}u6=gGn z8*qppPjWMTmz5J5jWB!wo2Jv+VdQ;-$C&hd*_m6#mQotd(3mLWX@T|Yg!ggbXc}fx zd-ub&pJe;N7jmtr&F8pXnEKgd#Nu}k=u+-qoHw+()sbSm^*S)xr*LSm8Ow7t)%3tN zi<4fe#Bt^SBxHI$5d+5#a_XDzvoEID&=?pP=t++is7d)XDL^is4@WJq4bh zL4cIb8Sc4&Ov5ZEoqNTR4i@#!X~V8`%@~5+xLk2Pj1^D z`N8LkDm_1=yJ7k=c!G3Zg8P>j`&P9Q#A{Eu&GmW`069pNI;ZFpwjU>0T2v8BM?FI$ z%3190IU#tasghGCuPsk3&oKW*S}f`gvpvtH>+PMpr)j_5lj!&UlizfA>w&91yM1zX z6!2_Zj3<_%U)OHnyXH%7OXt$~FSWFxf!#=+tmn$Xw2oeam(OIqJ3=LyKlL^d*DNTV z+00RY1LKKBl5R}IBtX_|o7Q1TlKAU}&%#w6B2Gsu;qK>3)J<2^1+^@nN8!j_{w{>h zkwbk4^$vK>CQL4HD;({TIbx&+Va<2aljY$H9d@}VF*VDAsP*w!22hOO!z+JXS@~Bf zry8A62$dQdbabhZgN!I|@h+ZQ!X&xI9jXl1=iM<(7$~J@UgQ(Kx8@Z{_l68B%b%#%xveH>-49DvjO zwTc=Ao%=HF0CsKOch%n;K-945)t7Zwe6(kdK{`HNhz7X&t=I2bfLzM?Xe?0I<_%vg zI4P69n8*sJM1DP;%}nQH_R}w^d3VCtxc5AQ6v`nm9a5Mh$(|xjp~gYGzgY9z32m=h zmf^&vfgI;cO-qBxOT$bCV{drqHm^^WzRND3*D*fHAD($ z!Zik}d!N!U+8aUg-F&f5^l1i-pY^$7c*RgJ%03suDCV`R7g=v8E&6Ub&|~#>R>w2p zjlkbv&Udl}sa64qpZQadw{j?x!=rwwlUSu!;uQ4r@TbYX21SgJB-%I%unenZnb()f zn?Pgj^P+}MYrNd%-Qe+tc_B)myJ>2Rv>4$vHz@W_m3wi&N>yoJ-r;q(Tl+KHnA<~K z!a~NL=0Fhy;>w`-FX zOeR|gEw2)6<~g2L_Ax{hr?>xpKo{&M;DuKTwC)4)5B(`*0^vxrG0T%4^uuDDp%k!mYwr!n;50!} z13NN|ByV@Aw%9>Vv%YYB$-`Y{j-IoqtU%=Mhi=5;?NG+0+{skoBRwcP_#A4aUdm3P3Y$Xe9}5}1xEatsQ4+NF-#0{sP{hJK~SsMSPOkdlMkO#SoQk*^a077__O1q4?^}>xeoS-d%rA zSB^6)mdF>#CfsR}n6nHPDlZ<1UZY3M%{GFO1B+~4`c7(L%~0SRFPqI&RO(Ep`Pn)f z~g$1ov63J>x!ay~VN3Utt- ztj7xc;?XtPP9K>QL@Z-Uw7f_oBO-SnPeWMpB3XI&2uyyiggY}2GKTvcM%3^8*1{aL zp)8kg(sv|Oj-meSK;pGec93Bk*&?tUzPipOIHI`8H)tELW#cXrm#;gf{r=gm-!qk2 z(G8|_p6^3fy~7YH)p_$z``znS3e~U7!FCF)+JkGzk1L3<@ybXBdIj-x1!>(UcBhle z>xl`^0A^G-3B;WxSqk>=AE(=e8kd{{$vlA|vR4H_flNuwwa9_>^b^|PRF#Pg!5(ScacqEz{r+KyVn*%seQ}0Sfw!4@9dv{ z6kA(ns0*9Z`vJxSx9NWgRBjgs7u2^Wr01@JP1HO(!lSe1gz!B*t$e&6ZJpxhE1yxB z;jkO`$hhM%Bxe%hQe`s;M&xuIIuo@bcw&QYg}Kz_d0r7&Kp7|(2UK$Uej}y?g)$XN zzqR>7j2#s!2u(FbbSNg@0c_;MkgF*vQoLsavfHjahG2&Igq-z2)jGHEW4}ZNqgVm6Z-Y80D=?gJx}jp z>xfSK2pK&|p>!EW16ivw#HUi`=i>3b@91jfhyq$JAl~MbelG9Rhh`(+7EprW071_W zn-EAwEGThx|7`C(Wb|Q738pq@jI3yav;{5qvXU(OwvV}+2h$ImF!&dF3op!1_9V0v zst_U;BaC%P61EZZi&F#RHX(&T6hQpyC-&FeQKsfNAte`BM;>?n7niN##WYIW_ZPug zfp^Cb0bQZ4&-!}gV!z&Fq;F5#rR-spYre8cYP|qdn83@${mFVuukVs+ole`rw{BP# zeb?~%vlDLg11BOMS{)r??z^RHX8DjpAdp7U>X6=W*pldX1$6HvfY@r1_tfS}%W0xX z`d9>0nKOLh8$M3*Ehb{gjtLDpJE4io#LpO<@Bpa z!xnZWty0KS7cD(IH&6424Wz_qdzTCBvB%2z%|+wFu3OJNSHEe#%;yazQLZM=ALjBn z07yRnwwSzIZ6s1U0?ahQKacpyyRE6JYUx-XBI}jX#spRj43ug#VevUPkhQY~O7O+> z7P3)jKX^JMTAhkK6ap;}e``@ku*p13l}m-xFc-X{MX;s5`Wh4_YBR0<1WI?lpenR0 z6L2vYiAH-`2=04LGbS&y*)Z-12GgXE*LGN z7$ok=xMEc-tnHoFF0m-KY=NE!9DO?XS!%i(&=OLo4;{s;0{i8#RqxWf%Rr3ft8X9k zr)bFpkL5&tZykOg{K5u~1cs$Z+_?u_a_cr6-OXGcThx%oM$jWD8$V^h&{ANu&V`t1iP z2<{*JwLov2^lg4$PBPf2b9R`Z`hhx|bB65jR`bB;YZ4yGad4gV}ecVzj%=-?B*G#js)fEGTycGS)UjwA5r~DdD~i7{JfOQS;e52Gv3} z%8z^|^}E?`f_6u$$02;mGNN-oOoTV=tr-s7f|59s;025Phb^sVv+FYR=RHCDI~QGh zUY#Y2b~OtmLa&uxsu*WQuC8JGH`1G2*qX(3ZiO>V$Ap@g;QJmVrY+f1#@+_9=))~= z{PBSE2wkU++0-0Qc_i^JkAd^Rvya?VvuT`!m#91ux@qysNmnbovC|rRZ=`C~@5qT2 ziLg#g3DI5BHRR&tsTfj~0?E01L~vd_hq46j>*Pw^IbQ*q@hXE!`5^$@Y(I(fn>hI$ z@6(P$f;SS{-m**AA1h|Y+hw}eA7L3~BNRLmJ`dT9jEzAIR|4b+UM|Ud3w$gUB}I96 zRu09TN6;}p0hdn*VI7Bq7IqJ`ZB}v9X9^CzI|_$vz0F9kb;f{O-;=)3buK8sp}M)W znoGf}X59#1t7TE3CXy72`;_#c<5>jM;gLluWRr#nH;a8ZR2)TGLWgiK&xI^Y{r1O$ z(IGtRDp2KolH5W=_S!=1_%6@OIWYl;J5F0{x#U}_T(2QhWppl@LX-C4qg={@zGQ@v zF33NJ(I`gVI?6kfU7mCTzbi|_BZq1OmjJW#<->}tn=d-fujiLt-v#SQG=rUs)63{) z{m%BL?SKpGT5AetH)t~ktxFgHPAT0PviK2d)bJy97-8g>$WrwEWT#}@upvtK{QP`l z!Ac$GtjYQ%Gqbm!6}?NgvP%t$xB(foE$j!7FYJTG?&AL`+L1vu2A;@I8Ronz^Vm-l zSdS-JbMtkYgJ1DH?F))KL2C%4r05d2-_qp>2H}8NI?4lI?_8Ha9>c>H%C?WU_L!&yhX!c z?XQ>^xq|~&&?URRKV0!}h(U{^E;VIeQY^bM<>0?!-q=#y$PSe&H?Z;VcNeLY4UT66?7^|^k2eZag~H1=~S91X3|tv|DG ziCFlEeSHt{xh6u3ascrw{is>d`aXf{$d6^0z?|US=eUTCvne~*gAJv4;iCGoj6uVY zHi*wgFVnmPU4%M3_6fQ0lgbjw1~ich8PNJ2%L%>n*B@*VknN%RKox?kLo`6~itY1k zCbLCVhjo3|PTf07^{veBB9U`C-?HnT%;`+L-j#%g80W>_HVX|ALk4k+lo9OcuhHx9 z-~8#t2vPDK8xg~_vU=W^P@@67_I_MGkv+7y1Ck_U;lXx<(9l0ivqbJX{Z;}01m%Cm z{{gboe*y;W5b?jkl=}Y%|JQ#4z5Tz=OZ$K5*FFrZI8Q<6Ub6qr^~+x>n8U^eKNNn* z@rZ1a3C#oew_6}9+n`vKg83kx4gE624vl6MVxu9BnB~l8S>Q&M13g<)Plty%p$e6A zE{!g(34c>$vl#76-U1h7)Nz)JshQqmR{|V*!vIyUT=SaFg0h!(JUSftVTTO%$(Rqy zW(ZS01v=Ncqj1IO9u8{mZ$oGYKR`1f{1QQEBA>aY$mj7rL}!9Cx?%j&P1vZRSX;5_ z{3bvYIKgRc4t#X%ATejfyHgkUH^}N)SU0IacfRlxAys+oR#Vb)3Wq&FK8sN3-1b?Q zEew6p=0CBxXdg-EdB+h=4<;cpP`sJf5*p!oC-tCAZqFxK^HZGs%FZOC$Y=Ef4M0PS zC#ffU%)&?WiAr`ht)My14HSOzdxzwy?!1Wz653k1NfT*`+;kI{r8gS^ z-zLt37L%f(+iQ}4t>f$;vQfqP%{vLh-ngu(q{Su1TkX`Pj9FC}sYzd;jT%2`XyB3y zYKMBokLaM^qrUZUJx(#SHsCjC=0-!$_bIasyc3d$JO_Tf%yZRXZvHk)-J88P`Qj#Y ze7jpRIJf?mtg?3Us-Rp+j`=C!J204|J%K;d#=3T4g8X3_X8~sdZ1UcGVsHA_u&Yq| zOc2w}V_NaQQRpx@AHuL zt#^9;Ch;ZSqT(wdrR&?~8S$6k++|jJlhGMYYeWi$pC9Am4+WzG(*H(Q3-@3fR?~&* z8eMW&`5N4r-7AoCerk% z0wjU1`YGq48EJ*Ma#fASSB zo!#+{*IwC8ajg$=8J!b^>MDpYY&#-RGxeL+=YgK~|-= zERPAE#-M2_BAFE|4r_ytz0iPrZ3jKv%mQK;-FUr=Y(JSIw?DjYS2m!gM61x|$~N~@ zB43yD>c3%pC_*g&%tTcgp1aO_F4pAvffpCwF$vI+fEt{?X_XXT=-13tCQIgNOyJTW z*O?Evcg#+FmXB`&7O6Yj4rF#ZmP$?JJ=zB(?PRXwb>fv+v<=siHj4vH-KK{Ww@^Uz zZNDRuOvfD9QDcZEzD?nFFAZwaK4dRvex_2xhdA@ygkhV3M1ViK2OaB+v9lMa<6nrR zFId})Ns}@{Z%f@;v?2_G=!3L;Q>Ab+EjhKRZ0ftRb@Uz1Z9vr;5)P%wd0x~D>0U~Z ze@xiXW06`b-FZwau`u7}qBGkQmomE7wmsTDOA!yCe&N@s7@1u+Y%OH?J_}9MkdiNs z64uci)*Nkv@VZaSs25E+D1RSTVQ(3&Ao-{itktqe^KW_cpGVEcqnH0Fv;Nt@(0(re rHRqzY|0}}L`v1UQ`kxQR{rLwEwTb;+@<#D926`yUsmWGIn}7T-8o0S^ literal 0 HcmV?d00001 diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/KeyboardLayoutAlt.png b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/KeyboardLayoutAlt.png new file mode 100644 index 0000000000000000000000000000000000000000..f740eec1e3fbf840a32b6802240c23b73aebd8e8 GIT binary patch literal 61615 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 literal 0 HcmV?d00001 diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/KeyboardLayoutShift.png b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/KeyboardLayoutShift.png new file mode 100644 index 0000000000000000000000000000000000000000..9b243d4dd2f2ef9e0d75748e615fb72951fcb6bc GIT binary patch literal 85201 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 literal 0 HcmV?d00001 diff --git a/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/welcome.htm b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/welcome.htm new file mode 100644 index 0000000000..717e7bedeb --- /dev/null +++ b/developer/src/kmc-copy/test/fixtures/projects/disorganized/other/welcome/welcome.htm @@ -0,0 +1,28 @@ + + + + + + Start Using alephwithbeth + + + + +

Start Using Aleph With Beth

+ +

Keyboard Layouts

+ +

Base layout

+Keyboard layout +

Layout when shift is pressed

+Keyboard layout (when shift key is pressed) +

Layout when alt is pressed

+Keyboard layout (when alt key is pressed) + + + From 7b478993e2d27720416bb0a9d0f664fdb54b57df Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 22 Jan 2025 15:18:03 +0700 Subject: [PATCH 076/155] fix(android/engine): Revert how keyboard picker menu launches Revert #10806 --- android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java index cc12b36dca..3cfa41c3a0 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java @@ -2267,6 +2267,7 @@ public final class KMManager { if (kbType == KeyboardType.KEYBOARD_TYPE_SYSTEM) { i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); } i.putExtra(KMKey_DisplayKeyboardSwitcher, kbType == KeyboardType.KEYBOARD_TYPE_SYSTEM); From a2e6947eb1281323a0f385f130071047a8a24100 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Wed, 22 Jan 2025 15:40:55 +0700 Subject: [PATCH 077/155] fix(mac): opening OSK does not require existence of KVK Fixes: #12928 --- mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 3c2fd7f710..73afb9271d 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -158,7 +158,7 @@ id _lastServerWithOSKShowing = nil; os_log_debug([KMLogs lifecycleLog], "--- inputMethodActivated, kvk is non-nil: %{public}@ showOskOnActivate: %{public}@", (_kvk!=nil)?@"true":@"false", [KMInputMethodLifecycle.shared shouldShowOskOnActivate]?@"true":@"false"); - if (_kvk != nil && ([KMInputMethodLifecycle.shared shouldShowOskOnActivate])) { + if ([KMInputMethodLifecycle.shared shouldShowOskOnActivate]) { os_log_debug([KMLogs oskLog], "***KMInputMethodAppDelegate inputMethodActivated, showing OSK"); [KMSentryHelper addBreadCrumb:@"lifecycle" message:@"opening OSK on input method activation"]; [self showOSK]; From e3c02bf045919e142e3fb79fc3f8d4e7b33394ad Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Wed, 22 Jan 2025 16:21:56 +0700 Subject: [PATCH 078/155] chore: adds platform to what's new titles --- android/docs/engine/whatsnew.md | 2 +- android/docs/help/about/whatsnew.md | 2 +- ios/docs/help/about/whatsnew.md | 2 +- linux/docs/help/about/whatsnew.md | 2 +- mac/docs/help/about/whatsnew.md | 2 +- windows/docs/help/about/whatsnew.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/android/docs/engine/whatsnew.md b/android/docs/engine/whatsnew.md index e8c2a3d694..af3f8932d6 100644 --- a/android/docs/engine/whatsnew.md +++ b/android/docs/engine/whatsnew.md @@ -1,5 +1,5 @@ --- -title: What's New +title: What's New in Keyman Engine 18.0 for Android --- ## Keyman Engine for Android Breaking Changes: ## diff --git a/android/docs/help/about/whatsnew.md b/android/docs/help/about/whatsnew.md index 500d0a9593..0f0e891e42 100644 --- a/android/docs/help/about/whatsnew.md +++ b/android/docs/help/about/whatsnew.md @@ -1,5 +1,5 @@ --- -title: What's New +title: What's New in Keyman 18.0 for Android --- Here are some of the new features we have added to Keyman 18.0 for Android: diff --git a/ios/docs/help/about/whatsnew.md b/ios/docs/help/about/whatsnew.md index b744839398..6d10900289 100644 --- a/ios/docs/help/about/whatsnew.md +++ b/ios/docs/help/about/whatsnew.md @@ -1,5 +1,5 @@ --- -title: What's New +title: What's New in Keyman 18.0 for iOS --- Here are some of the new features we have added to Keyman for iPhone and iPad 18.0: diff --git a/linux/docs/help/about/whatsnew.md b/linux/docs/help/about/whatsnew.md index 62228c5e20..4a4d5a30e1 100644 --- a/linux/docs/help/about/whatsnew.md +++ b/linux/docs/help/about/whatsnew.md @@ -1,5 +1,5 @@ --- -title: What's New +title: What's New in Keyman 18.0 for Linux --- Here are some of the new features we have added to Keyman for Linux 18.0: diff --git a/mac/docs/help/about/whatsnew.md b/mac/docs/help/about/whatsnew.md index f4b11b973c..73ccb4d49b 100644 --- a/mac/docs/help/about/whatsnew.md +++ b/mac/docs/help/about/whatsnew.md @@ -1,5 +1,5 @@ --- -title: What's New +title: What's New in Keyman 18.0 for macOS --- Here are some of the new features we have added to Keyman 18.0 for macOS: diff --git a/windows/docs/help/about/whatsnew.md b/windows/docs/help/about/whatsnew.md index 82087dd701..4f11c82ec2 100644 --- a/windows/docs/help/about/whatsnew.md +++ b/windows/docs/help/about/whatsnew.md @@ -1,5 +1,5 @@ --- -title: What's New +title: What's New in Keyman 18.0 for Windows --- Here are some of the new features we have added to Keyman 18.0 for Windows: From eb617cb28fac16d2303ac65537d2d640ce44fe51 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Wed, 22 Jan 2025 17:35:09 +0700 Subject: [PATCH 079/155] chore: adds platforms to welcome titles --- android/docs/help/about/welcome.md | 2 +- ios/docs/help/about/welcome.md | 2 +- linux/docs/help/about/welcome.md | 2 +- mac/docs/help/about/welcome.md | 2 +- windows/docs/help/about/welcome.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/docs/help/about/welcome.md b/android/docs/help/about/welcome.md index 9c2ff5652a..f21aabeeba 100644 --- a/android/docs/help/about/welcome.md +++ b/android/docs/help/about/welcome.md @@ -1,5 +1,5 @@ --- -title: Welcome to Keyman +title: Welcome to Keyman for Android --- Thank you for installing Keyman for Android. Whether you're a new or returning user, we believe you will appreciate the significant enhancements in this latest version of Keyman for Android. diff --git a/ios/docs/help/about/welcome.md b/ios/docs/help/about/welcome.md index deeb156a54..05246c7ca4 100644 --- a/ios/docs/help/about/welcome.md +++ b/ios/docs/help/about/welcome.md @@ -1,5 +1,5 @@ --- -title: Welcome to Keyman +title: Welcome to Keyman for iPhone and iPad --- Thank you for installing Keyman for iPhone and iPad. Whether you're a new or returning user, diff --git a/linux/docs/help/about/welcome.md b/linux/docs/help/about/welcome.md index 6dc3dd4265..eacc8c449c 100644 --- a/linux/docs/help/about/welcome.md +++ b/linux/docs/help/about/welcome.md @@ -1,5 +1,5 @@ --- -title: Welcome to Keyman +title: Welcome to Keyman for Linux --- Thank you for installing Keyman for Linux. Whether you're a new or returning user, we believe you will appreciate the significant enhancements in this latest version of Keyman for Linux. diff --git a/mac/docs/help/about/welcome.md b/mac/docs/help/about/welcome.md index 5bd92f2fd8..ec67a871e8 100644 --- a/mac/docs/help/about/welcome.md +++ b/mac/docs/help/about/welcome.md @@ -1,5 +1,5 @@ --- -title: Welcome to Keyman +title: Welcome to Keyman for macOS --- Thank you for installing Keyman for macOS. Whether you're a new or returning user, diff --git a/windows/docs/help/about/welcome.md b/windows/docs/help/about/welcome.md index 79c01e4fcd..3512a566f8 100644 --- a/windows/docs/help/about/welcome.md +++ b/windows/docs/help/about/welcome.md @@ -1,5 +1,5 @@ --- -title: Welcome to Keyman +title: Welcome to Keyman for Windows --- Thank you for installing Keyman. Whether you're a new or returning user, From e01f9deefa3e1fce0c843713791b830a01394357 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Wed, 22 Jan 2025 17:36:10 +0700 Subject: [PATCH 080/155] changes from ios to iPhone and iPad --- ios/docs/help/about/whatsnew.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/docs/help/about/whatsnew.md b/ios/docs/help/about/whatsnew.md index 6d10900289..aa4cf6b333 100644 --- a/ios/docs/help/about/whatsnew.md +++ b/ios/docs/help/about/whatsnew.md @@ -1,5 +1,5 @@ --- -title: What's New in Keyman 18.0 for iOS +title: What's New in Keyman 18.0 for iPhone and iPad --- Here are some of the new features we have added to Keyman for iPhone and iPad 18.0: From 5efac80b90011e926faf594f41d5b18002118042 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Wed, 22 Jan 2025 17:46:49 +0700 Subject: [PATCH 081/155] chore: adds platforms to history titles --- android/docs/help/about/history.md | 2 +- ios/docs/help/about/history.md | 2 +- linux/docs/help/about/history.md | 2 +- mac/docs/help/about/history.md | 2 +- windows/docs/help/about/history.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/docs/help/about/history.md b/android/docs/help/about/history.md index 3a0b9af3a6..2774029615 100644 --- a/android/docs/help/about/history.md +++ b/android/docs/help/about/history.md @@ -1,5 +1,5 @@ --- -title: Version History +title: Version History of Keyman for Android --- A frequent updated changelog for Keyman is kept at [help.keyman.com/version-history](https://help.keyman.com/version-history/) on the Keyman Help website. diff --git a/ios/docs/help/about/history.md b/ios/docs/help/about/history.md index 17905b7e5a..60aba2b0f3 100644 --- a/ios/docs/help/about/history.md +++ b/ios/docs/help/about/history.md @@ -1,5 +1,5 @@ --- -title: Version History +title: Version History of Keyman for iPhone and iPad --- A frequently-updated changelog for Keyman is kept at [help.keyman.com/version-history](https://help.keyman.com/version-history/) on the Keyman Help website. diff --git a/linux/docs/help/about/history.md b/linux/docs/help/about/history.md index 6343e0313e..5eb733255f 100644 --- a/linux/docs/help/about/history.md +++ b/linux/docs/help/about/history.md @@ -1,5 +1,5 @@ --- -title: Version History +title: Version History of Keyman for Linux --- A frequent updated changelog for Keyman is kept at [help.keyman.com/version-history](https://help.keyman.com/version-history) on the Keyman Help website. diff --git a/mac/docs/help/about/history.md b/mac/docs/help/about/history.md index 3a0b9af3a6..76320b31e5 100644 --- a/mac/docs/help/about/history.md +++ b/mac/docs/help/about/history.md @@ -1,5 +1,5 @@ --- -title: Version History +title: Version History of Keyman for macOS --- A frequent updated changelog for Keyman is kept at [help.keyman.com/version-history](https://help.keyman.com/version-history/) on the Keyman Help website. diff --git a/windows/docs/help/about/history.md b/windows/docs/help/about/history.md index 2d48a601db..ae2a2cb851 100644 --- a/windows/docs/help/about/history.md +++ b/windows/docs/help/about/history.md @@ -1,5 +1,5 @@ --- -title: Version History +title: Version History of Keyman for Windows --- A frequently updated changelog for Keyman is kept at From 606e6af365d5464038858385aced24b7b6519a4d Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 22 Jan 2025 15:47:48 +0100 Subject: [PATCH 082/155] chore(linux): update package index before installing packages We need to run `apt-get update` first before trying to install packages. We did update the package index when we built the base image, but that might have been some time ago so that the index is now outdated. --- resources/docker-images/android/Dockerfile | 1 + resources/docker-images/core/Dockerfile | 4 ++-- resources/docker-images/linux/Dockerfile | 3 ++- resources/docker-images/web/Dockerfile | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/resources/docker-images/android/Dockerfile b/resources/docker-images/android/Dockerfile index 91cd095a69..2b289ce077 100644 --- a/resources/docker-images/android/Dockerfile +++ b/resources/docker-images/android/Dockerfile @@ -22,6 +22,7 @@ RUN < Date: Wed, 22 Jan 2025 13:02:26 -0500 Subject: [PATCH 083/155] auto: increment master version to 18.0.176 --- HISTORY.md | 11 +++++++++++ VERSION.md | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 6ffda9827b..fc8e7f8edd 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,16 @@ # Keyman Version History +## 18.0.175 alpha 2025-01-22 + +* feat(windows): Fixes check now to use SM and LastUpdateCheckTime key on first run. (#12922) +* chore(developer): validate keyboard and model IDs in kmc-generate (#12958) +* fix(developer): use correct terms in kmc-generate lexical model help (#12960) +* fix(developer): use 1.0.0 as default for ldml keyboards in kmc-generate (#12962) +* chore: adds h1 tags (#12967) +* fix(web): prevent warning that occurs when multitapping longpressable modifier keys (#12964) +* chore(developer): add test for basic transform to kmc-generate (#12966) +* fix(android/engine): Revert how keyboard picker menu launches (#12986) + ## 18.0.174 alpha 2025-01-21 * chore(developer): validate targets parameter in kmc-generate (#12955) diff --git a/VERSION.md b/VERSION.md index e1b3341dda..99dea35f58 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.175 \ No newline at end of file +18.0.176 \ No newline at end of file From eebf0bb10826ae532eb4e9bf2a56d1b8eaf7aed8 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 23 Jan 2025 09:54:36 +1000 Subject: [PATCH 084/155] fix(windows): Apply suggestions from code review Co-authored-by: Marc Durdin --- .../kmshell/main/Keyman.System.UpdateStateMachine.pas | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index 407765d8fd..34986cf238 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -1005,11 +1005,11 @@ begin FPackage.Install2(True); Result := True; except - on E: Exception do - begin - TKeymanSentryClient.ReportHandledException(E, - 'Failed to install keyboard package'); - end; + on E:Exception do + begin + TKeymanSentryClient.ReportHandledException(E, + 'Failed to install keyboard package'); + end; end; FPackage := nil; From d0a0f0d9ff9506ff60b0c22fcd1656369eaf0d7a Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 23 Jan 2025 08:13:41 +0700 Subject: [PATCH 085/155] chore(web): remove abandoned dev artifact file (within PR) --- web/src/test/manual/web/package-loader.html | 107 -------------------- 1 file changed, 107 deletions(-) delete mode 100644 web/src/test/manual/web/package-loader.html diff --git a/web/src/test/manual/web/package-loader.html b/web/src/test/manual/web/package-loader.html deleted file mode 100644 index 1e6b7496ef..0000000000 --- a/web/src/test/manual/web/package-loader.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - KeymanWeb Sample Page - Unminified Source - - - - - - - - - - - - - - - - - - - - -

KeymanWeb Sample Page - Unminified Source

- -
- - -
-

--End of Document--

- - - - - From 9bb8038da987e39ea84041b00bf3a594217a3b69 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 23 Jan 2025 09:11:11 +0700 Subject: [PATCH 086/155] feat(web): adds complex nul-context handling unit tests --- .../js-processor/engine/context.tests.js | 149 +++++++++++++++++- .../engine/notany_context.tests.js | 2 + 2 files changed, 143 insertions(+), 8 deletions(-) diff --git a/web/src/test/auto/headless/engine/js-processor/engine/context.tests.js b/web/src/test/auto/headless/engine/js-processor/engine/context.tests.js index a355ead265..b09a20c01e 100644 --- a/web/src/test/auto/headless/engine/js-processor/engine/context.tests.js +++ b/web/src/test/auto/headless/engine/js-processor/engine/context.tests.js @@ -9,6 +9,8 @@ import { NodeKeyboardLoader } from 'keyman/engine/keyboard/node-keyboard-loader' import { NodeProctor, RecordedKeystrokeSequence } from '@keymanapp/recorder-core'; +const NUL = '\uFFFE'; + /* * ABOUT THIS TEST SUITE * --------------------- @@ -36,20 +38,15 @@ let device = { browser: 'native' } +/** @type {KeyboardInterface} */ let keyboardWithHarness; -var toSupplementaryPairString = function(code){ - var H = Math.floor((code - 0x10000) / 0x400) + 0xD800; - var L = (code - 0x10000) % 0x400 + 0xDC00; - - return String.fromCharCode(H, L); -} - function runEngineRuleSet(ruleSet, defaultNoun) { defaultNoun = defaultNoun ? defaultNoun : "Rule"; for(var i = 0; i < ruleSet.length; i++) { var ruleDef = ruleSet[i]; // for example, DEADKEY_TEST_1. + keyboardWithHarness.resetContextCache(); var matchDefs = [{ sequence: ruleDef.baseSequence, @@ -844,6 +841,122 @@ var DEADKEY_STORE_TEST_4 = { }] }; +/* Keyman language equivalent: + * + * nul > 'success' + */ +var NUL_TEST_1 = { + id: 1, + // Match condition for rule + rule: [{t: 'n'}], + // Start of context relative to cursor + n: 1, + ln: 1, + // Resulting context map + contextCache: [ NUL ], + + baseSequence: { "output": "", "inputs": []}, + fullMatchDefs: [] +}; + +/* Keyman language equivalent: + * + * nul any(abc) > 'success' + */ +var NUL_TEST_2 = { + id: 1, + // Match condition for rule + rule: [{t: 'n'}, {t: 'a', a: ['a', 'b', 'c']}], + // Start of context relative to cursor + n: 2, + ln: 2, + // Resulting context map + contextCache: [ NUL, 'a' ], + + baseSequence: { "output": "a", "inputs": [ + {"type":"key","keyCode":65,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true}, //a + ]}, + fullMatchDefs: [] +}; + +/* Keyman language equivalent: + * + * nul nul any(abc) context(3) > 'success' + * + * This one may... "stretch" what's actually allowed by Keyman language rules, + * but we wish to ensure that the actual context management is capable of + * handling this. + */ +var NUL_TEST_3 = { + id: 1, + // Match condition for rule + rule: [{t: 'n'}, {t: 'n'}, {t: 'a', a: ['a', 'b', 'c']}, {t: 'c', c: 3}], + // Start of context relative to cursor + n: 4, + ln: 4, + // Resulting context map + contextCache: [ NUL, NUL, 'a', 'a' ], + + baseSequence: { "output": "a", "inputs": [ + {"type":"key","keyCode":65,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true}, //a + {"type":"key","keyCode":65,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true}, //a + ]}, + fullMatchDefs: [ + { + sequence: { "output": "a", "inputs": [ + {"type":"key","keyCode":50,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true}, //1 + {"type":"key","keyCode":65,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true}, //a + {"type":"key","keyCode":65,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true} //a + ]}, + result: false, + msg: "Rule 2: matched deadkey with nul" + }, { + sequence: { "output": "a", "inputs": [ + {"type":"key","keyCode":65,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true}, //a + {"type":"key","keyCode":65,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true}, //a + {"type":"key","keyCode":65,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true} //a + ]}, + result: false, + msg: "Rule 2: matched character with nul" + } + ] +}; + +/* Keyman language equivalent: + * + * nul nul dk(1) any(abc) > 'success' + * + * This may also "stretch" what's actually allowed by Keyman language rules, + * but we wish to ensure that the actual context management is capable of + * handling this. + */ +var NUL_TEST_4 = { + id: 1, + // Match condition for rule + rule: [{t: 'n'}, {t: 'n'}, {t: 'd', d: 1}, {t: 'a', a: ['a', 'b', 'c']}], + // Start of context relative to cursor + n: 4, + ln: 4, + // Resulting context map + contextCache: [ NUL, NUL, 1, 'a' ], + + baseSequence: { "output": "a", "inputs": [ + {"type":"key","keyCode":50,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true}, //1 + {"type":"key","keyCode":65,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true}, //a + ]}, + fullMatchDefs: [ + { + sequence: { "output": "a", "inputs": [ + {"type":"key","keyCode":50,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true}, //1 + {"type":"key","keyCode":50,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true}, //1 + {"type":"key","keyCode":65,"states":10752,"modifiers":0,"modifierChanged":false,"isVirtualKey":true} //a + ]}, + result: false, + msg: "Rule 2: matched extra deadkey with nul" + } + ] +}; + /* Keyman language equivalent: * * store(match) 'abc' @@ -975,10 +1088,12 @@ var ANY_INDEX_RULE_SET = [ ANY_INDEX_TEST_1, ANY_INDEX_TEST_2, ANY_INDEX_TEST_3 var DEADKEY_STORE_RULE_SET = [ DEADKEY_STORE_TEST_1, DEADKEY_STORE_TEST_2, DEADKEY_STORE_TEST_3, DEADKEY_STORE_TEST_4 ]; +var NUL_RULE_SET = [ NUL_TEST_1, NUL_TEST_2, NUL_TEST_3, NUL_TEST_4 ]; + var NOTANY_NUL_RULE_SET = [ NOTANY_NUL_TEST_1, NOTANY_NUL_TEST_2, NOTANY_NUL_TEST_3 ]; var FULL_RULE_SET = [].concat(DEADKEY_RULE_SET, ANY_CONTEXT_RULE_SET, ANY_INDEX_RULE_SET, - DEADKEY_STORE_RULE_SET, NOTANY_NUL_RULE_SET); + DEADKEY_STORE_RULE_SET, NUL_RULE_SET, NOTANY_NUL_RULE_SET); // ----------- @@ -1087,6 +1202,24 @@ describe('Engine - Context Matching', function() { }); }); + describe('handles interactions with nul in requested context', function() { + it('with only a single nul in context range; no text: NUL_TEST_1', function () { + runEngineRuleSet([NUL_TEST_1]); + }); + + it(`with context [nul, 'a'] in range: NUL_TEST_2`, function () { + runEngineRuleSet([NUL_TEST_2]); + }); + + it(`with context [nul, 'a', 'a'] in range: NUL_TEST_3`, function () { + runEngineRuleSet([NUL_TEST_3]); + }); + + it(`with context [nul, dk(1), 'a'] in range: NUL_TEST_4`, function () { + runEngineRuleSet([NUL_TEST_4]); + }); + }); + describe('handles interactions between notany and nul in context', function() { it('with notany against a store with pure characters: NOTANY_NUL_TEST_1', function() { runEngineRuleSet([NOTANY_NUL_TEST_1]); diff --git a/web/src/test/auto/headless/engine/js-processor/engine/notany_context.tests.js b/web/src/test/auto/headless/engine/js-processor/engine/notany_context.tests.js index ecc7dd92d0..86a35058ae 100644 --- a/web/src/test/auto/headless/engine/js-processor/engine/notany_context.tests.js +++ b/web/src/test/auto/headless/engine/js-processor/engine/notany_context.tests.js @@ -20,10 +20,12 @@ const device = { browser: 'native' } +/** @type {KeyboardInterface} */ let keyboardWithHarness; function runEngineRuleSet(ruleSet) { for(let ruleDef of ruleSet) { + keyboardWithHarness.resetContextCache(); // Prepare the context! const ruleSeq = new RecordedKeystrokeSequence(ruleDef); const proctor = new NodeProctor(keyboardWithHarness, device, assert.equal); From 38b6c3ceb8e79f52ba2b721294e102a620c9aac6 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 23 Jan 2025 09:25:56 +0700 Subject: [PATCH 087/155] fix(android): Remove READ_MEDIA_IMAGES and READ_MEDIA_VIDEO permissions --- android/KMAPro/kMAPro/src/main/AndroidManifest.xml | 4 ---- .../main/java/com/tavultesoft/kmapro/CheckPermissions.java | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/android/KMAPro/kMAPro/src/main/AndroidManifest.xml b/android/KMAPro/kMAPro/src/main/AndroidManifest.xml index 3ba7eaf9fc..bdb1d18a43 100644 --- a/android/KMAPro/kMAPro/src/main/AndroidManifest.xml +++ b/android/KMAPro/kMAPro/src/main/AndroidManifest.xml @@ -7,10 +7,6 @@ - - - - diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/CheckPermissions.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/CheckPermissions.java index 888d430b0b..431d97e353 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/CheckPermissions.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/CheckPermissions.java @@ -35,8 +35,8 @@ public class CheckPermissions { checkPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE); } else { // API 33+ - //https://developer.android.com/about/versions/13/behavior-changes-13#granular-media-permissions - // Manifest.permission.READ_MEDIA_AUDIO doesn't seem to be needed + // We had to remove these MEDIA permissions from AndroidManifest.xml so these will end up failing + // https://support.google.com/googleplay/android-developer/answer/14115180?hl=en permissionsOK = permissionsOK && checkPermission(activity, Manifest.permission.READ_MEDIA_IMAGES); permissionsOK = permissionsOK && checkPermission(activity, Manifest.permission.READ_MEDIA_VIDEO); } From 4832903b0a463ee98047ec97e0d279d04dd1c6e3 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 23 Jan 2025 09:13:01 +0700 Subject: [PATCH 088/155] fix(web): do not simplify nul-prefixed contexts when rule-matching Fixes: #12987 --- web/src/engine/js-processor/src/kbdInterface.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/web/src/engine/js-processor/src/kbdInterface.ts b/web/src/engine/js-processor/src/kbdInterface.ts index b39b2baea2..efca7b8a80 100644 --- a/web/src/engine/js-processor/src/kbdInterface.ts +++ b/web/src/engine/js-processor/src/kbdInterface.ts @@ -373,18 +373,6 @@ export default class KeyboardInterface extends KeyboardHarness { // Now that we have the cache... var subCache = cache; subCache.valContext = subCache.valContext.slice(0, ln); - for(var i=0; i < subCache.valContext.length; i++) { - if(subCache.valContext[i] == '\ufffe') { - subCache.valContext.splice(0, 1); - subCache.deadContext.splice(0, 1); - } - } - - if(subCache.valContext.length == 0) { - subCache.valContext = ['\ufffe']; - subCache.deadContext = []; - } - this.cachedContextEx.set(n, ln, subCache); return subCache; From 660d4c3d67b8caafcd58a028f39f15a7e3b2614a Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 23 Jan 2025 09:36:21 +0700 Subject: [PATCH 089/155] docs(android): Update storage permission help Reference: https://support.google.com/googleplay/android-developer/answer/14115180?hl=en --- .../help/troubleshooting/grant-storage-permission.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/android/docs/help/troubleshooting/grant-storage-permission.md b/android/docs/help/troubleshooting/grant-storage-permission.md index 1b8554d7f0..7b47cdf4ea 100644 --- a/android/docs/help/troubleshooting/grant-storage-permission.md +++ b/android/docs/help/troubleshooting/grant-storage-permission.md @@ -19,13 +19,7 @@ permission to access storage / "file and media". The screenshot below is from An ### Android 13.0+ Devices -Step 1) -Go to Android Settings. +Due to Google Play Store's "Photo and Video Permissions policy", +Keyman for Android must use a system picker to browse for .kmp files from within the Keyman app. -Step 2) -Depending on your device, click "Apps" and grant Keyman permission to the following: - * Photos and videos --> Always allow all - -The screenshot below is from Android 14.0. - -![](../android_images/keyman-storage-permission-34b.png) +Follow the steps in [Installing Custom Keyboards/Dictionaries](../basic/installing-custom-packages). From 064a5623ee8b1994bd8b297a6cacb2fdcfc1aee1 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 23 Jan 2025 10:46:12 +0700 Subject: [PATCH 090/155] fix(android): add null-guard in KMKeyboardJSHandler.initialKeyboard --- .../src/main/java/com/keyman/engine/KMKeyboardJSHandler.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardJSHandler.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardJSHandler.java index d403a29235..ecd55c2bc9 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardJSHandler.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboardJSHandler.java @@ -75,7 +75,10 @@ public class KMKeyboardJSHandler { Keyboard kbd = Keyboard.getDefaultKeyboard(context); int index = prefs.getInt(KMManager.KMKey_UserKeyboardIndex, -1); if (index >= 0) { - kbd = KMManager.getKeyboardInfo(this.context, index); + // It is possible for this method to return `null` - especially + // if the KeyboardController instance hasn't yet been initialized. + Keyboard lastKbd = KMManager.getKeyboardInfo(this.context, index); + kbd = lastKbd != null ? lastKbd : kbd; } return kbd.toStub(context); } From 4dd207da9f9cdc6a4dd5c8cf3011b82c4ccea92b Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 23 Jan 2025 10:47:09 +0700 Subject: [PATCH 091/155] fix(android): use try-catch to bypass early kbd loading when not possible --- android/KMEA/app/src/main/assets/android-host.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/android/KMEA/app/src/main/assets/android-host.js b/android/KMEA/app/src/main/assets/android-host.js index 5a25367223..3cb74f88c4 100644 --- a/android/KMEA/app/src/main/assets/android-host.js +++ b/android/KMEA/app/src/main/assets/android-host.js @@ -37,7 +37,14 @@ function init() { keyman.beepKeyboard = beepKeyboard; // Readies the keyboard stub for instant loading during the init process. - KeymanWeb.registerStub(JSON.parse(jsInterface.initialKeyboard())); + try { + let starterStubStr = jsInterface.initialKeyboard(); + if(starterStubStr) { + KeymanWeb.registerStub(JSON.parse(starterStubStr)); + } + // If a Java exception triggers during this time... okay, we can't + // load a keyboard during startup. Rely on older loading techniques. + } catch (err) {} keyman.init({ 'embeddingApp':device, From c9c47e8438a99793b8bb1595ebfeed1edad482be Mon Sep 17 00:00:00 2001 From: sgschantz Date: Thu, 23 Jan 2025 11:42:47 +0700 Subject: [PATCH 092/155] chore(mac): fixed else statement for architecture tag --- mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 3c2fd7f710..b3020e1a55 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -24,7 +24,7 @@ NSString *processorType = @"ARM"; #elif TARGET_CPU_X86_64 NSString *processorType = @"Intel"; -#elif +#else NSString *processorType = @"Unknown"; #endif From 11459ceec0a7421afbec3118bd2c848d6da3ffe6 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 23 Jan 2025 15:15:17 +1000 Subject: [PATCH 093/155] feat(windows): add localized button labels --- windows/src/desktop/kmshell/kmshell.dproj | 32 +++++++++++-------- ...yman.Configuration.UI.UfrmStartInstall.dfm | 2 +- ...yman.Configuration.UI.UfrmStartInstall.pas | 11 +++++++ ...n.Configuration.UI.UfrmStartInstallNow.dfm | 13 ++++---- ...n.Configuration.UI.UfrmStartInstallNow.pas | 11 +++++++ 5 files changed, 48 insertions(+), 21 deletions(-) diff --git a/windows/src/desktop/kmshell/kmshell.dproj b/windows/src/desktop/kmshell/kmshell.dproj index 2bb3c24512..fd30bf1dcf 100644 --- a/windows/src/desktop/kmshell/kmshell.dproj +++ b/windows/src/desktop/kmshell/kmshell.dproj @@ -356,11 +356,9 @@
frmInstallNow
- dfm
frmStartInstall
- dfm
@@ -429,24 +427,30 @@ true - - - kmshell.exe - true - - - - - kmshell.exe - true - - .\ true + + + kmshell.exe + true + + + + + kmshell.rsm + true + + + + + kmshell.exe + true + + 1 diff --git a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.dfm b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.dfm index b7766d09bc..0ca96f7123 100644 --- a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.dfm +++ b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.dfm @@ -34,7 +34,7 @@ object frmStartInstall: TfrmStartInstall Top = 104 Width = 75 Height = 25 - Caption = 'Install' + Caption = 'Update' ModalResult = 1 TabOrder = 0 end diff --git a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.pas b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.pas index 5d3b11767a..1abfcbbcee 100644 --- a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.pas +++ b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.pas @@ -28,12 +28,23 @@ type lblInstallUpdate: TLabel; private public + constructor Create(AOwner: TComponent); override; end; implementation +uses + MessageIdentifiers, + MessageIdentifierConsts; {$R *.dfm} +constructor TfrmStartInstall.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + cmdInstall.Caption := MsgFromId(S_Update); + cmdLater.Caption := MsgFromId(S_Button_Close); + lblInstallUpdate.Caption := 'Keyman Update ready to install.'; +end; end. diff --git a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.dfm b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.dfm index 8c0e467033..4bb30bbf56 100644 --- a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.dfm +++ b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.dfm @@ -14,14 +14,15 @@ object frmStartInstallNow: TfrmStartInstallNow Font.Style = [] OldCreateOrder = False Position = poScreenCenter + OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object lblUpdateMessage: TLabel - Left = 32 - Top = 48 - Width = 290 - Height = 41 - Caption = 'Your computer will be restarted if you update now.' + Left = 16 + Top = 32 + Width = 323 + Height = 19 + Caption = 'Updating now will require a computer restart.' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -16 @@ -35,7 +36,7 @@ object frmStartInstallNow: TfrmStartInstallNow Top = 120 Width = 75 Height = 25 - Caption = 'Update now' + Caption = 'Update' ModalResult = 1 TabOrder = 0 end diff --git a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.pas b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.pas index ce3fd29da0..b613a7c856 100644 --- a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.pas +++ b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.pas @@ -26,14 +26,25 @@ type cmdInstall: TButton; cmdLater: TButton; lblUpdateMessage: TLabel; + procedure FormCreate(Sender: TObject); private public end; implementation +uses + MessageIdentifiers, + MessageIdentifierConsts; {$R *.dfm} +procedure TfrmStartInstallNow.FormCreate(Sender: TObject); +begin + inherited; + cmdInstall.Caption := MsgFromId(S_Update); + cmdLater.Caption := MsgFromId(S_Button_Close); + lblUpdateMessage.Caption := 'Updating now will require a computer restart.'; +end; end. From 4a99018f1b81cec6218cc832624e41609905b7e4 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 23 Jan 2025 14:20:31 +0700 Subject: [PATCH 094/155] fix(developer): produce correct index parameter value for context in kmw compiler The KMW compiler would produce incorrect indices for the corresponding character in the context after adjusting for the presence of `nul` and `if` statements at the start of the context string, when using the `context` and `context(n)` statements in the output. This fix addresses the offset calculation for those scenarios and adds a unit test to verify that the new offsets are correct. Fixes: #12980 --- .../src/kmw-compiler/javascript-strings.ts | 9 +++---- .../test/fixtures/kmw/test_index_12980.kmn | 25 +++++++++++++++++++ .../kmc-kmn/test/kmw/kmw-compiler.tests.ts | 23 +++++++++++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 developer/src/kmc-kmn/test/fixtures/kmw/test_index_12980.kmn diff --git a/developer/src/kmc-kmn/src/kmw-compiler/javascript-strings.ts b/developer/src/kmc-kmn/src/kmw-compiler/javascript-strings.ts index 9cdb28a3d9..d31ccdb14c 100644 --- a/developer/src/kmc-kmn/src/kmw-compiler/javascript-strings.ts +++ b/developer/src/kmc-kmn/src/kmw-compiler/javascript-strings.ts @@ -669,7 +669,7 @@ export function JavaScript_OutputString(fk: KMX.KEYBOARD, FTabStops: string, fkp switch(recContext.Code) { case KMX.KMXFile.CODE_ANY: - Index = AdjustIndex(fkp.dpContext, ContextIndex) + 1; // I3910 // I4611 + Index = AdjustIndex(fkp.dpContext, ContextIndex); // I3910 // I4611 Result += nlt + `k.KIO(${len},this.s${JavaScript_Name(recContext.Any.StoreIndex, recContext.Any.Store.dpName)},${Index},t);`; // I4611 break; case KMX.KMXFile.CODE_DEADKEY: @@ -681,7 +681,7 @@ export function JavaScript_OutputString(fk: KMX.KEYBOARD, FTabStops: string, fkp // Note that this is checked in compiler.cpp as well, so this error can probably never occur throw new Error('Unexpected: notany() encountered with invalid version'); } - Result += nlt + `k.KCXO(${len},t,${AdjustIndex(fkp.dpContext, xstrlen(fkp.dpContext))},${AdjustIndex(fkp.dpContext, ContextIndex)+1});`; + Result += nlt + `k.KCXO(${len},t,${AdjustIndex(fkp.dpContext, xstrlen(fkp.dpContext))},${AdjustIndex(fkp.dpContext, ContextIndex)});`; break; case KMX.KMXFile.CODE_IFOPT: case KMX.KMXFile.CODE_IFSYSTEMSTORE: @@ -759,7 +759,7 @@ export function JavaScript_OutputString(fk: KMX.KEYBOARD, FTabStops: string, fkp case KMX.KMXFile.CODE_CONTEXT: if (x > 0 || len == -1) { let xContext = 0; - let n = 0; + let n = 1; while(xContext < fkp.dpContext.length) { // I4611 if(!isGroupReadOnly(fk, fgp)) { Result += ContextChar(n, fkp.dpContext, xContext); @@ -767,7 +767,6 @@ export function JavaScript_OutputString(fk: KMX.KEYBOARD, FTabStops: string, fkp n++; xContext = incxstr(fkp.dpContext, xContext); } - //Result := Result + Format('k.KO(%d,t,k.KC(%d,%d,t));', [len, xstrlen_printing(fkp.dpContext), xstrlen_printing(fkp.dpContext)]); } // else, we don't need to output anything - just don't delete the context len = -1; @@ -779,7 +778,7 @@ export function JavaScript_OutputString(fk: KMX.KEYBOARD, FTabStops: string, fkp } if(!isGroupReadOnly(fk, fgp)) { - Result += ContextChar(rec.ContextEx.Index, fkp.dpContext, xContext); // I4611 + Result += ContextChar(rec.ContextEx.Index + 1, fkp.dpContext, xContext); // I4611 } len = -1; break; diff --git a/developer/src/kmc-kmn/test/fixtures/kmw/test_index_12980.kmn b/developer/src/kmc-kmn/test/fixtures/kmw/test_index_12980.kmn new file mode 100644 index 0000000000..c568a04ab9 --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/kmw/test_index_12980.kmn @@ -0,0 +1,25 @@ +c test_index_12980 generated from template at 2025-01-22 13:25:35 +c Validates index() offsets when used with if() - see #12980 + +store(&VERSION) '14.0' +store(&NAME) 'test_index_12980' +store(&TARGETS) 'web' + + +begin Unicode > use(main) + +group(main) using keys + +store(a) '1' +store(b) '2' +store(c) '3' +store(d) '4' +store(e) '5' +store(f) '6' + +if(&platform = 'web') any(a) + 'a' > context 'A' +if(&platform = 'web') any(b) + 'b' > context(2) 'B' +if(&platform = 'web') notany(c) + 'c' > context 'C' +if(&platform = 'web') notany(d) + 'd' > context(2) 'D' +nul any(e) + 'e' > context 'E' +nul any(f) + 'f' > context(2) 'F' diff --git a/developer/src/kmc-kmn/test/kmw/kmw-compiler.tests.ts b/developer/src/kmc-kmn/test/kmw/kmw-compiler.tests.ts index d90b33c312..dec9f9d494 100644 --- a/developer/src/kmc-kmn/test/kmw/kmw-compiler.tests.ts +++ b/developer/src/kmc-kmn/test/kmw/kmw-compiler.tests.ts @@ -218,6 +218,29 @@ describe('KeymanWeb Compiler', function() { assert.lengthOf(callbacks.messages, 2); }); + it('should generate correct index offsets (#12980) for context and context(n) when building a KMW keyboard', async function() { + const filenames = generateTestFilenames('test_index_12980'); + + let result = await kmnCompiler.run(filenames.source, null); + assert.isNotNull(result); + const data = new TextDecoder('utf-8').decode(result.artifacts.js.data); + + function doMatchKIO(s: string) { + const regex = new RegExp('k\\.KIO\\(-1,this\\.'+s+',(.+?),t\\);'); + const m = regex.exec(data); + assert.isNotNull(m, `Could not find match for ${s}`); + assert.equal(m[1], '1', `Expected '${s}' usage to have an index parameter == 1`); + } + + doMatchKIO('s_a_6'); + doMatchKIO('s_b_7'); + + const matches = [...data.matchAll(/k\.KCXO\(-1,t,1,1\);/g)]; + assert.lengthOf(matches, 2); + + doMatchKIO('s_e_10'); + doMatchKIO('s_f_11'); + }); }); async function run_test_keyboard(kmnCompiler: KmnCompiler, id: string): From e97308a1a7022b91136bbc4f5270f5a992441372 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 23 Jan 2025 14:25:23 +0700 Subject: [PATCH 095/155] fix(android): removes "where context is null" reporting Fixes: #10032 --- .../java/com/keyman/engine/logic/ResourcesUpdateTool.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java b/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java index 18b29ceb76..14696f9122 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java @@ -520,10 +520,6 @@ public class ResourcesUpdateTool implements KeyboardEventHandler.OnKeyboardDownl @Override public void onPackageInstalled(List> keyboardsInstalled) { - if (!isContextAvailable()) { - KMLog.LogError(TAG, "onPackageInstalled where context is null."); - } - if (! openUpdates.isEmpty() && keyboardsInstalled != null) { for (Map k : keyboardsInstalled) { String _langid = k.get(KMManager.KMKey_LanguageID); @@ -537,10 +533,6 @@ public class ResourcesUpdateTool implements KeyboardEventHandler.OnKeyboardDownl @Override public void onLexicalModelInstalled(List> lexicalModelsInstalled) { - if (!isContextAvailable()) { - KMLog.LogError(TAG, "onLexicalModelInstalled where context is null."); - } - if (! openUpdates.isEmpty()) { for(Map _lm:lexicalModelsInstalled) { String _langid = _lm.get(KMManager.KMKey_LanguageID); From 7ffa001617ce7b2b0cb29cfa5e4506badf013385 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 23 Jan 2025 14:27:14 +0700 Subject: [PATCH 096/155] change(android): use higher-level context for Toasts --- .../java/com/keyman/engine/logic/ResourcesUpdateTool.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java b/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java index 14696f9122..0d3eeca1d0 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java @@ -558,14 +558,15 @@ public class ResourcesUpdateTool implements KeyboardEventHandler.OnKeyboardDownl // TODO: make it smoother. Documented as #11097. KMManager.clearKeyboardCache(); + Context appContext = currentContext.getApplicationContext(); if (failedUpdateCount > 0) { - BaseActivity.makeToast(currentContext, R.string.update_failed, Toast.LENGTH_SHORT); + BaseActivity.makeToast(appContext, R.string.update_failed, Toast.LENGTH_SHORT); lastUpdateCheck = Calendar.getInstance(); updateFailed = true; checkingUpdates = false; } else { lastUpdateCheck = Calendar.getInstance(); - SharedPreferences prefs = currentContext.getSharedPreferences(currentContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); + SharedPreferences prefs = appContext.getSharedPreferences(currentContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putLong(PREF_KEY_LAST_UPDATE_CHECK, lastUpdateCheck.getTime().getTime()); editor.commit(); From dbb780e6fa6c0a98e4e658e4fb01a7033022354e Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Thu, 23 Jan 2025 13:02:51 -0500 Subject: [PATCH 097/155] auto: increment master version to 18.0.177 --- HISTORY.md | 12 ++++++++++++ VERSION.md | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index fc8e7f8edd..b64e4ca1e5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,17 @@ # Keyman Version History +## 18.0.176 alpha 2025-01-23 + +* chore(developer): stub out icon support in kmc-generate (#12971) +* chore(developer): remove '--rename' option from kmc-copy (#12973) +* feat(developer): add 'verbose' and 'debug' log levels to kmc (#12976) +* chore(developer): validate output folder name in kmc-copy (#12979) +* chore(developer): report on filename collisions in kmc-copy (#12982) +* feat(developer): support copying disorganized projects in kmc-copy (#12984) +* chore(linux): docker build: update package index before installing packages in Dockerfiles (#12992) +* feat(web): allow main manual-test page to load from KMP (#12977) +* fix(android): Remove access to MEDIA storage permissions (#12999) + ## 18.0.175 alpha 2025-01-22 * feat(windows): Fixes check now to use SM and LastUpdateCheckTime key on first run. (#12922) diff --git a/VERSION.md b/VERSION.md index 99dea35f58..45e53027cb 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.176 \ No newline at end of file +18.0.177 \ No newline at end of file From e6adf379f0811aa26e9a614b2d7d79dab33cedb9 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Thu, 23 Jan 2025 20:48:53 +0100 Subject: [PATCH 098/155] chore(linux): docker-build: fix Linux docker image This change fixes two issues in the Linux docker image that showed up when running tests: - some directories had wrong permissions - we have to build keyman-system-service in a docker-specific directory as well so that the location of the service executable can be found when running the tests in docker --- resources/docker-images/linux/Dockerfile | 9 ++++++--- resources/docker-images/run.sh | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/resources/docker-images/linux/Dockerfile b/resources/docker-images/linux/Dockerfile index bd975139ad..2083ce8c55 100644 --- a/resources/docker-images/linux/Dockerfile +++ b/resources/docker-images/linux/Dockerfile @@ -28,9 +28,12 @@ RUN LCOV_VERSION=$(dpkg -s lcov | grep Version | cut -d' ' -f2) && \ rm /tmp/lcov.deb ; \ fi -RUN mkdir -p /var/run/1000 && \ - chown build:build /var/run/1000 && \ - echo "export XDG_RUNTIME_DIR=/var/run/1000" >> /usr/bin/bashwrapper +RUN mkdir -p /run/user/1000 && \ + chown build:build /run/user/1000 && \ + chmod 700 /run/user/1000 && \ + mkdir -p /tmp/.X11-unix && \ + chmod 1777 /tmp/.X11-unix && \ + echo "export XDG_RUNTIME_DIR=/run/user/1000" >> /usr/bin/bashwrapper COPY run-tests.sh /usr/bin/run-tests.sh diff --git a/resources/docker-images/run.sh b/resources/docker-images/run.sh index c42d6c2a02..63d299f7e3 100755 --- a/resources/docker-images/run.sh +++ b/resources/docker-images/run.sh @@ -36,9 +36,11 @@ run_core() { run_linux() { mkdir -p "${KEYMAN_ROOT}/linux/build/docker-linux" + mkdir -p "${KEYMAN_ROOT}/linux/keyman-system-service/build/docker-linux" docker run -it --privileged --rm -v "${KEYMAN_ROOT}":/home/build/build \ -v "${KEYMAN_ROOT}/core/build/docker-core":/home/build/build/core/build \ -v "${KEYMAN_ROOT}/linux/build/docker-linux":/home/build/build/linux/build \ + -v "${KEYMAN_ROOT}/linux/keyman-system-service/build/docker-linux":/home/build/build/linux/keyman-system-service/build \ -e DESTDIR=/tmp \ keymanapp/keyman-linux-ci:default \ "${builder_extra_params[@]}" From 1131b978121048b61e886f12e0c969002c90d850 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 24 Jan 2025 08:45:39 +0700 Subject: [PATCH 099/155] fix(android): restores DOMRect polyfill for old Chrome support --- .../KMEA/app/src/main/java/com/keyman/engine/KMManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java index 3cfa41c3a0..0e4c261232 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java @@ -921,6 +921,9 @@ public final class KMManager { copyAsset(context, KMFilename_KmwCss, "", true); copyAsset(context, KMFilename_KmwGlobeHintCss, "", true); copyAsset(context, KMFilename_Osk_Ttf_Font, "", true); + + // Needed until our minimum version of Chrome is 61.0+. + copyAsset(context, KMFilename_JSPolyfill2, "", true); // Copy default keyboard font copyAsset(context, KMDefault_KeyboardFont, "", true); From 71ce8d6c91cf7914f28e888369af9faff0054f6b Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 24 Jan 2025 08:56:21 +0700 Subject: [PATCH 100/155] chore(developer): extend notany tests in kmc-kmn --- developer/src/kmc-kmn/test/fixtures/kmw/test_index_12980.kmn | 4 ++++ developer/src/kmc-kmn/test/kmw/kmw-compiler.tests.ts | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/developer/src/kmc-kmn/test/fixtures/kmw/test_index_12980.kmn b/developer/src/kmc-kmn/test/fixtures/kmw/test_index_12980.kmn index c568a04ab9..26d2164928 100644 --- a/developer/src/kmc-kmn/test/fixtures/kmw/test_index_12980.kmn +++ b/developer/src/kmc-kmn/test/fixtures/kmw/test_index_12980.kmn @@ -16,6 +16,8 @@ store(c) '3' store(d) '4' store(e) '5' store(f) '6' +store(g) '7' +store(h) '8' if(&platform = 'web') any(a) + 'a' > context 'A' if(&platform = 'web') any(b) + 'b' > context(2) 'B' @@ -23,3 +25,5 @@ if(&platform = 'web') notany(c) + 'c' > context 'C' if(&platform = 'web') notany(d) + 'd' > context(2) 'D' nul any(e) + 'e' > context 'E' nul any(f) + 'f' > context(2) 'F' +nul notany(g) + 'g' > context 'G' +nul notany(h) + 'h' > context(2) 'H' diff --git a/developer/src/kmc-kmn/test/kmw/kmw-compiler.tests.ts b/developer/src/kmc-kmn/test/kmw/kmw-compiler.tests.ts index dec9f9d494..5060dc8757 100644 --- a/developer/src/kmc-kmn/test/kmw/kmw-compiler.tests.ts +++ b/developer/src/kmc-kmn/test/kmw/kmw-compiler.tests.ts @@ -235,8 +235,9 @@ describe('KeymanWeb Compiler', function() { doMatchKIO('s_a_6'); doMatchKIO('s_b_7'); + // matches the 4 notany() rules const matches = [...data.matchAll(/k\.KCXO\(-1,t,1,1\);/g)]; - assert.lengthOf(matches, 2); + assert.lengthOf(matches, 4); doMatchKIO('s_e_10'); doMatchKIO('s_f_11'); From 46279140aa9873072513d51b88e7579f06803b2f Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 23 Jan 2025 15:24:19 +0700 Subject: [PATCH 101/155] chore(android): undoes variable tweak Fixes: KEYMAN-ANDROID-3BQ Fixes: KEYMAN-ANDROID-3Q8 --- .../main/java/com/keyman/engine/logic/ResourcesUpdateTool.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java b/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java index 0d3eeca1d0..9f02480bf2 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java @@ -566,7 +566,7 @@ public class ResourcesUpdateTool implements KeyboardEventHandler.OnKeyboardDownl checkingUpdates = false; } else { lastUpdateCheck = Calendar.getInstance(); - SharedPreferences prefs = appContext.getSharedPreferences(currentContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); + SharedPreferences prefs = currentContext.getSharedPreferences(currentContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putLong(PREF_KEY_LAST_UPDATE_CHECK, lastUpdateCheck.getTime().getTime()); editor.commit(); From ab63e051090f1512074abe19637012092cf60fce Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 23 Jan 2025 11:48:54 +0700 Subject: [PATCH 102/155] change(android): error filtering/validation - checks if it's caused by a "Java exception" Fixes: #13000 Fixes: KEYMAN-WEB-F9 --- android/KMEA/app/src/main/assets/android-host.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/android/KMEA/app/src/main/assets/android-host.js b/android/KMEA/app/src/main/assets/android-host.js index 3cb74f88c4..0bd199b4d6 100644 --- a/android/KMEA/app/src/main/assets/android-host.js +++ b/android/KMEA/app/src/main/assets/android-host.js @@ -42,9 +42,15 @@ function init() { if(starterStubStr) { KeymanWeb.registerStub(JSON.parse(starterStubStr)); } + } catch (err) { // If a Java exception triggers during this time... okay, we can't // load a keyboard during startup. Rely on older loading techniques. - } catch (err) {} + // + // Note: no information about the Java-side error is available here. + if(err.message.indexOf("Java exception") < 0) { + throw err; + } + } keyman.init({ 'embeddingApp':device, From 39549927e763b60117d4865695662b8370f896ee Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 24 Jan 2025 10:43:00 +0700 Subject: [PATCH 103/155] feat(android): add breadcrumbing during package install about package file, source --- .../java/com/tavultesoft/kmapro/KMPBrowserActivity.java | 2 ++ .../src/main/java/com/tavultesoft/kmapro/MainActivity.java | 7 +++++-- .../java/com/keyman/engine/packages/PackageProcessor.java | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java index bb770ef5b2..4410761e6d 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java @@ -23,6 +23,7 @@ import androidx.appcompat.app.AppCompatActivity; import com.keyman.engine.BaseActivity; import com.keyman.engine.KMManager; +import com.keyman.engine.util.KMLog; import com.keyman.engine.util.KMPLink; import com.keyman.engine.util.KMString; import com.keyman.engine.util.WebViewUtils; @@ -105,6 +106,7 @@ public class KMPBrowserActivity extends BaseActivity { // Create intent with keyboard download link for KMAPro main activity to handle Intent intent = new Intent(context, MainActivity.class); intent.setData(downloadURI); + KMLog.LogBreadcrumb(TAG, "Successful keyboard search now triggering package install", true); startActivity(intent); // Finish activity diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java index 2ae689364c..44f0cddc49 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java @@ -262,6 +262,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene if (loadingIntentUri != null) { String scheme = loadingIntentUri.getScheme().toLowerCase(); + final String link = loadingIntentUri.toString(); switch (scheme) { // content:// Android DownloadManager // file:// Chrome downloads and Filebrowsers @@ -269,6 +270,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene case "file": requestPermissionIntentUri = loadingIntentUri; if (CheckPermissions.isPermissionOK(this)) { + KMLog.LogBreadcrumb(TAG, "Installing local KMP: " + loadingIntentUri, true); useLocalKMP(context, loadingIntentUri); } else { CheckPermissions.requestPermission(this, context); @@ -277,14 +279,16 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene case "http" : case "https" : // Might need to modify link like KMPBrowserActivity - String link = loadingIntentUri.toString(); if (KMPLink.isKeymanInstallLink(link)) { loadingIntentUri = KMPLink.getKeyboardDownloadLink(link); } + // Is usually triggered by KMPBrowserActivity + KMLog.LogBreadcrumb(TAG, "Installing via HTTPS intent: " + link, true); downloadKMP(loadingIntentUri, KmpInstallMode.Full); break; case "keyman" : // TODO: Only accept download links from Keyman browser activities when universal links work + KMLog.LogBreadcrumb(TAG, "Installing via keyman-link intent: " + link, true); if (KMPLink.isKeymanDownloadLink(loadingIntentUri.toString())) { // Convert opaque URI to hierarchical URI so the query parameters can be parsed @@ -296,7 +300,6 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene loadingIntentUri = Uri.parse(builder.build().toString()); downloadKMP(loadingIntentUri, KmpInstallMode.Full); } else if (KMPLink.isLegacyKeymanDownloadLink(loadingIntentUri.toString())) { - link = loadingIntentUri.toString(); loadingIntentUri = KMPLink.getLegacyKeyboardDownloadLink(link); downloadKMP(loadingIntentUri, KmpInstallMode.Full); } else { diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/packages/PackageProcessor.java b/android/KMEA/app/src/main/java/com/keyman/engine/packages/PackageProcessor.java index 1e3bff4a76..65252e63bb 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/packages/PackageProcessor.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/packages/PackageProcessor.java @@ -447,6 +447,9 @@ public class PackageProcessor { public String getPackageTarget(File kmpPath) { try { File tempPath = unzipKMP(kmpPath); + String kmpFilename = kmpPath.getName(); + + KMLog.LogBreadcrumb(TAG, "Determining package type for " + kmpFilename, false); String target = getPackageTarget(loadPackageInfo(tempPath)); FileUtils.deleteDirectory(tempPath); return target; From 40b31a08a6ff452475cc4e7c8a64c6b9d0ab0413 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 10:45:04 +0700 Subject: [PATCH 104/155] chore: add platforms to troubleshooting titles and windows to help homepage --- android/docs/help/troubleshooting/index.md | 2 +- ios/docs/help/troubleshooting/index.md | 2 +- mac/docs/help/troubleshooting/index.md | 2 +- windows/docs/help/index.md | 2 +- windows/docs/help/troubleshooting/index.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/docs/help/troubleshooting/index.md b/android/docs/help/troubleshooting/index.md index 474f4f8119..eb62977439 100644 --- a/android/docs/help/troubleshooting/index.md +++ b/android/docs/help/troubleshooting/index.md @@ -1,5 +1,5 @@ --- -title: Troubleshooting +title: Keyman for Android Troubleshooting --- * [How To - Getting Keyboard Help](keyboard-help) diff --git a/ios/docs/help/troubleshooting/index.md b/ios/docs/help/troubleshooting/index.md index 2f31716c95..1509c74ee6 100644 --- a/ios/docs/help/troubleshooting/index.md +++ b/ios/docs/help/troubleshooting/index.md @@ -1,5 +1,5 @@ --- -title: Troubleshooting +title: Keyman for iPhone and iPad Troubleshooting --- * [How To - Installing fonts](installing-fonts) diff --git a/mac/docs/help/troubleshooting/index.md b/mac/docs/help/troubleshooting/index.md index 2190a7c3cb..9325371dae 100644 --- a/mac/docs/help/troubleshooting/index.md +++ b/mac/docs/help/troubleshooting/index.md @@ -1,5 +1,5 @@ --- -title: Troubleshooting +title: Keyman for macOS Troubleshooting --- * [Configure macOS security for Keyman](configure-security) diff --git a/windows/docs/help/index.md b/windows/docs/help/index.md index 7f5ddfd463..c7cccc7695 100644 --- a/windows/docs/help/index.md +++ b/windows/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman 18.0 Help +title: Keyman for Windows 18.0 Help --- Need help using Keyman for Windows? You'll find everything you need here, including product documentation, diff --git a/windows/docs/help/troubleshooting/index.md b/windows/docs/help/troubleshooting/index.md index cafa510647..d8d9e385c8 100644 --- a/windows/docs/help/troubleshooting/index.md +++ b/windows/docs/help/troubleshooting/index.md @@ -1,5 +1,5 @@ --- -title: Troubleshooting +title: Keyman for Windows Troubleshooting --- * [How To - Fix Font Issues](font) From 7e30a9fd5c06edb7edffa5a4dfaeb37180c17c69 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 24 Jan 2025 10:46:32 +0700 Subject: [PATCH 105/155] fix(developer): escape font facename in touch layout editor Fixes: #13017 --- developer/src/tike/xml/layoutbuilder/builder.js | 13 ++++++++++--- developer/src/tike/xml/layoutbuilder/prepare-key.js | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/developer/src/tike/xml/layoutbuilder/builder.js b/developer/src/tike/xml/layoutbuilder/builder.js index 3f30b1061c..8915308d6f 100644 --- a/developer/src/tike/xml/layoutbuilder/builder.js +++ b/developer/src/tike/xml/layoutbuilder/builder.js @@ -348,6 +348,13 @@ $(function() { return builder.renameSpecialKey(hint); } + this.escapeFontName = function(fontName) { + if(!fontName) { + return ""; + } + return JSON.stringify(fontName); + } + this.prepareLayer = function () { var layer = KVKL[builder.lastPlatform].layer[builder.lastLayerIndex]; @@ -380,11 +387,11 @@ $(function() { } $('#kbd,#sub-key-groups') - .css('font-family', KVKL[builder.lastPlatform].font) + .css('font-family', this.escapeFontName(KVKL[builder.lastPlatform].font)) .css('font-size', KVKL[builder.lastPlatform].fontsize || "1em"); $('#inpKeyCap,#inpSubKeyCap') - .css('font-family', KVKL[builder.lastPlatform].font) + .css('font-family', this.escapeFontName(KVKL[builder.lastPlatform].font)) .css('font-size', '18pt'); $('#kbd div').remove(); @@ -421,7 +428,7 @@ $(function() { .css('height', (100 * this.yscale) + 'px') .css('margin-top', (builder.keyMargin * this.yscale) + 'px') .css('margin-left', p + 'px') - .css('font-family', key.font) + .css('font-family', this.escapeFontName(key.font)) .css('font-size', key.fontsize); if(this.specialCharacters[text]) diff --git a/developer/src/tike/xml/layoutbuilder/prepare-key.js b/developer/src/tike/xml/layoutbuilder/prepare-key.js index 2b7819f7ed..46c5e29839 100644 --- a/developer/src/tike/xml/layoutbuilder/prepare-key.js +++ b/developer/src/tike/xml/layoutbuilder/prepare-key.js @@ -140,7 +140,7 @@ $(function() { .data('direction', key.direction) // used only by flicks .data('default', key.default) // used only by longpress .css('width', (100 * 0.7) + 'px') - .css('font-family', key.font) + .css('font-family',builder.escapeFontName(key.font)) .css('font-size', key.fontsize); if(builder.specialCharacters[text]) { From 69c0f3861e05b43da6cc06ed8ed828add275d184 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Fri, 24 Jan 2025 14:03:09 +1000 Subject: [PATCH 106/155] fix(windows): add GetContextEx and TIPProcessKeyEx Add the api calls that include the output bool isSelected, which is true if text is selected. --- windows/src/engine/keyman32/appint/aiTIP.cpp | 74 +++++++++++++++++-- windows/src/engine/keyman32/globals.h | 4 +- windows/src/engine/keyman32/keyman32.def | 1 + windows/src/engine/keyman32/keyman64.def | 1 + .../src/engine/kmtip/keyman32interface.cpp | 8 ++ windows/src/engine/kmtip/kmkey.cpp | 18 ++++- windows/src/engine/kmtip/kmtip.h | 9 ++- 7 files changed, 102 insertions(+), 13 deletions(-) diff --git a/windows/src/engine/keyman32/appint/aiTIP.cpp b/windows/src/engine/keyman32/appint/aiTIP.cpp index 2010dee5b0..21d716a022 100644 --- a/windows/src/engine/keyman32/appint/aiTIP.cpp +++ b/windows/src/engine/keyman32/appint/aiTIP.cpp @@ -114,10 +114,12 @@ void ProcessToggleChange(UINT key) { // I4793 } } -extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKey(WPARAM wParam, LPARAM lParam, // I3589 // I3588 - PKEYMANPROCESSOUTPUTFUNC outfunc, PKEYMANGETCONTEXTFUNC ctfunc, BOOL Updateable, BOOL Preserved) { - - PKEYMAN64THREADDATA _td = ThreadGlobals(); +BOOL TIPProcessKeyInternal( + PKEYMAN64THREADDATA _td, + WPARAM wParam, + LPARAM lParam, + BOOL Updateable, + BOOL Preserved) { if(!_td) { return FALSE; } @@ -202,13 +204,11 @@ extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKey(WPARAM wParam, LPARAM _td->state.charCode = CharFromVK(&_td->state.vkey, Globals::get_ShiftState()); // I4582 - _td->TIPProcessOutput = outfunc; - _td->TIPGetContext = ctfunc; - BOOL res = ProcessHook(); _td->TIPProcessOutput = NULL; _td->TIPGetContext = NULL; + _td->TIPGetContextEx = NULL; SendDebugMessageFormat("Success, res=%d", res); @@ -226,6 +226,58 @@ extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKey(WPARAM wParam, LPARAM } return_SendDebugExit(res); + +} + + + +extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKey( + WPARAM wParam, + LPARAM lParam, // I3589 // I3588 + PKEYMANPROCESSOUTPUTFUNC outfunc, + PKEYMANGETCONTEXTFUNC ctfunc, + BOOL Updateable, + BOOL Preserved) { + + PKEYMAN64THREADDATA _td = ThreadGlobals(); + if(!_td) { + return FALSE; + } + + _td->TIPProcessOutput = outfunc; + _td->TIPGetContext = ctfunc; + BOOL res = TIPProcessKeyInternal(_td, wParam, lParam, Updateable, Preserved); + if (res == FALSE) { + _td->TIPProcessOutput = NULL; + _td->TIPGetContext = NULL; + } + return res; + +} + +// This includes the PKEYMANGETCONTEXTISSELECTEDFUNC to report if text is selected +extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKeyEx( + WPARAM wParam, + LPARAM lParam, // I3589 // I3588 + PKEYMANPROCESSOUTPUTFUNC outfunc, + PKEYMANGETCONTEXTISSELECTEDFUNC ctfunc, + BOOL Updateable, + BOOL Preserved) { + + PKEYMAN64THREADDATA _td = ThreadGlobals(); + if(!_td) { + return FALSE; + } + + _td->TIPProcessOutput = outfunc; + _td->TIPGetContextEx = ctfunc; + BOOL res = TIPProcessKeyInternal(_td, wParam, lParam, Updateable, Preserved); + if (res == FALSE) { + _td->TIPProcessOutput = NULL; + _td->TIPGetContextEx = NULL; + } + return res; + } /* AI constructor and destructor */ @@ -279,7 +331,13 @@ BOOL AITIP::ReadContext(PWSTR buf) { return FALSE; } - if (_td->TIPGetContext && (*_td->TIPGetContext)(MAXCONTEXT - 1, buf, &isTextSelected) == S_OK) { // I3575 // I4262 + if (_td->TIPGetContextEx && (*_td->TIPGetContextEx)(MAXCONTEXT - 1, buf, &isTextSelected) == S_OK) { // I3575 // I4262 + if(ShouldDebug()) { + SendDebugMessageFormat("full context [Updateable=%d] %s", _td->TIPFUpdateable, Debug_UnicodeString(buf)); + } + useLegacy = FALSE; // I3575 + return TRUE; + } else if (_td->TIPGetContext && (*_td->TIPGetContext)(MAXCONTEXT - 1, buf) == S_OK) { // I3575 // I4262 if(ShouldDebug()) { SendDebugMessageFormat("full context [Updateable=%d] %s", _td->TIPFUpdateable, Debug_UnicodeString(buf)); } diff --git a/windows/src/engine/keyman32/globals.h b/windows/src/engine/keyman32/globals.h index ae311f5ef2..2c8ec80858 100644 --- a/windows/src/engine/keyman32/globals.h +++ b/windows/src/engine/keyman32/globals.h @@ -151,7 +151,8 @@ public: /* External interface functions */ typedef HRESULT (WINAPI *PKEYMANPROCESSOUTPUTFUNC)(int n, WCHAR *buf, int nbuf); -typedef HRESULT (WINAPI *PKEYMANGETCONTEXTFUNC)(int n, PWSTR buf, BOOL* isTextSelected); +typedef HRESULT (WINAPI *PKEYMANGETCONTEXTFUNC)(int n, PWSTR buf); +typedef HRESULT (WINAPI *PKEYMANGETCONTEXTISSELECTEDFUNC)(int n, PWSTR buf, BOOL* isTextSelected); typedef BOOL (WINAPI *PTIPCALLBACK)(); // Tells the TIP to update its status (used to be done through 0x88) typedef BOOL (WINAPI *PKeymanOutputBackspace)(HWND hwnd); @@ -208,6 +209,7 @@ typedef struct tagKEYMAN64THREADDATA PKEYMANPROCESSOUTPUTFUNC TIPProcessOutput; PKEYMANGETCONTEXTFUNC TIPGetContext; + PKEYMANGETCONTEXTISSELECTEDFUNC TIPGetContextEx; BOOL TIPFUpdateable, TIPFPreserved; // I4290 diff --git a/windows/src/engine/keyman32/keyman32.def b/windows/src/engine/keyman32/keyman32.def index 4b509e6f60..a61a78b463 100644 --- a/windows/src/engine/keyman32/keyman32.def +++ b/windows/src/engine/keyman32/keyman32.def @@ -17,6 +17,7 @@ EXPORTS TIPActivateEx TIPActivateKeyboard TIPProcessKey + TIPProcessKeyEx TIPIsKeymanRunning GetKeyboardPreservedKeys diff --git a/windows/src/engine/keyman32/keyman64.def b/windows/src/engine/keyman32/keyman64.def index 9f46c08cb8..69eddd8e3d 100644 --- a/windows/src/engine/keyman32/keyman64.def +++ b/windows/src/engine/keyman32/keyman64.def @@ -17,6 +17,7 @@ EXPORTS TIPActivateEx TIPActivateKeyboard TIPProcessKey + TIPProcessKeyEx TIPIsKeymanRunning GetKeyboardPreservedKeys diff --git a/windows/src/engine/kmtip/keyman32interface.cpp b/windows/src/engine/kmtip/keyman32interface.cpp index ae06c9edad..cd42af3d7a 100644 --- a/windows/src/engine/kmtip/keyman32interface.cpp +++ b/windows/src/engine/kmtip/keyman32interface.cpp @@ -12,6 +12,9 @@ extern "C" { BOOL WINAPI TIPProcessKey(WPARAM wParam, LPARAM lParam, PKEYMANPROCESSOUTPUTFUNC outfunc, PKEYMANGETCONTEXTFUNC ctfunc, BOOL Updateable, BOOL Preserved); + BOOL WINAPI TIPProcessKeyEx(WPARAM wParam, LPARAM lParam, PKEYMANPROCESSOUTPUTFUNC outfunc, + PKEYMANGETCONTEXTISSELECTEDFUNC ctfunc, BOOL Updateable, BOOL Preserved); + BOOL WINAPI GetKeyboardPreservedKeys(PreservedKey **pPreservedKeys, size_t *cPreservedKeys); BOOL WINAPI TIPIsKeymanRunning(); @@ -43,6 +46,11 @@ BOOL Keyman32Interface::TIPProcessKey(WPARAM wParam, LPARAM lParam, PKEYMANPROCE return ::TIPProcessKey(wParam, lParam, outfunc, ctfunc, Updateable, Preserved); } +BOOL Keyman32Interface::TIPProcessKeyEx(WPARAM wParam, LPARAM lParam, PKEYMANPROCESSOUTPUTFUNC outfunc, + PKEYMANGETCONTEXTISSELECTEDFUNC ctfunc, BOOL Updateable, BOOL Preserved) { + return ::TIPProcessKeyEx(wParam, lParam, outfunc, ctfunc, Updateable, Preserved); +} + BOOL Keyman32Interface::GetKeyboardPreservedKeys(PreservedKey **pPreservedKeys, size_t *cPreservedKeys) { return ::GetKeyboardPreservedKeys(pPreservedKeys, cPreservedKeys); } diff --git a/windows/src/engine/kmtip/kmkey.cpp b/windows/src/engine/kmtip/kmkey.cpp index 210ced4c6c..fcf73cac96 100644 --- a/windows/src/engine/kmtip/kmkey.cpp +++ b/windows/src/engine/kmtip/kmkey.cpp @@ -173,7 +173,18 @@ extern "C" __declspec(dllexport) HRESULT WINAPI ExtKeymanProcessOutput(int n, WC return res; } -extern "C" __declspec(dllexport) HRESULT WINAPI ExtKeymanGetContext(int n, PWSTR buf, BOOL* isTextSelected) // I3567 +extern "C" __declspec(dllexport) HRESULT WINAPI ExtKeymanGetContext(int n, PWSTR buf) // I3567 +{ + SendDebugEntry(); + HRESULT res; + BOOL isTextSelectedDummy; // not used + if (ExtEditSession) res = ExtEditSession->KeymanGetContext(n, buf, &isTextSelectedDummy); + else res = E_FAIL; // I3567 + SendDebugExit(); + return res; +} + +extern "C" __declspec(dllexport) HRESULT WINAPI ExtKeymanGetContextIsSelected(int n, PWSTR buf, BOOL* isTextSelected) // I3567 { SendDebugEntry(); HRESULT res; @@ -198,6 +209,11 @@ STDAPI CKeymanEditSession::DoEditSession(TfEditCookie ec) _hr = E_FAIL; // TODO: use S_FALSE -> this tells _KeymanProcessKeystroke to pass keystroke on } + if (!Keyman32Interface::TIPProcessKeyEx(_wParam, _lParam, ExtKeymanProcessOutput, ExtKeymanGetContextIsSelected, _fUpdate, _fPreserved)) { + SendDebugMessage(L"TIPProcessKeyEx did not handle the keystroke"); + _hr = E_FAIL; // TODO: use S_FALSE -> this tells _KeymanProcessKeystroke to pass keystroke on + } + ExtEditSession = NULL; // Call keyman32.processtipkey; this may call "KeymanGetContext(n, buf, isTextSelected)"; diff --git a/windows/src/engine/kmtip/kmtip.h b/windows/src/engine/kmtip/kmtip.h index bb5459cbb0..b4f307488b 100644 --- a/windows/src/engine/kmtip/kmtip.h +++ b/windows/src/engine/kmtip/kmtip.h @@ -139,9 +139,9 @@ private: // typedef HRESULT(WINAPI *PKEYMANPROCESSOUTPUTFUNC)(int n, WCHAR *buf, int nbuf); // I3567 -// Adding a new interface call IsTextSelected could make sense however this would -// also require update TIPProcessKey to have another call back function as an argument -typedef HRESULT(WINAPI *PKEYMANGETCONTEXTFUNC)(int n, PWSTR buf, BOOL* isTextSelected); // I3567 + +typedef HRESULT(WINAPI *PKEYMANGETCONTEXTFUNC)(int n, PWSTR buf); // I3567 +typedef HRESULT(WINAPI *PKEYMANGETCONTEXTISSELECTEDFUNC)(int n, PWSTR buf, BOOL* isTextSelected); class Keyman32Interface { public: @@ -155,6 +155,9 @@ public: static BOOL TIPProcessKey(WPARAM wParam, LPARAM lParam, PKEYMANPROCESSOUTPUTFUNC outfunc, PKEYMANGETCONTEXTFUNC ctfunc, BOOL Updateable, BOOL Preserved); + static BOOL TIPProcessKeyEx(WPARAM wParam, LPARAM lParam, PKEYMANPROCESSOUTPUTFUNC outfunc, + PKEYMANGETCONTEXTISSELECTEDFUNC ctfunc, BOOL Updateable, BOOL Preserved); + static BOOL GetKeyboardPreservedKeys(PreservedKey **pPreservedKeys, size_t *cPreservedKeys); static BOOL TIPIsKeymanRunning(); From cb8330ef08b8b71fb017cc46852ee0437ebf9bc5 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 11:05:25 +0700 Subject: [PATCH 107/155] chore: add platforms to system requirements and download-and-install docs --- android/docs/help/start/installing-keyboards.md | 2 +- mac/docs/help/about/requirements.md | 2 +- mac/docs/help/start/install-keyboard.md | 2 +- windows/docs/help/about/requirements.md | 2 +- windows/docs/help/start/download-and-install-keyboard.md | 2 +- windows/docs/help/start/download-and-install-keyman.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/android/docs/help/start/installing-keyboards.md b/android/docs/help/start/installing-keyboards.md index 8e4df5f880..248bc74ebe 100644 --- a/android/docs/help/start/installing-keyboards.md +++ b/android/docs/help/start/installing-keyboards.md @@ -1,5 +1,5 @@ --- -title: How To - Download and Install a Keyman Keyboard +title: How To - Download and Install a Keyman Keyboard on Android --- ## Adding New Keyboards diff --git a/mac/docs/help/about/requirements.md b/mac/docs/help/about/requirements.md index d92272a730..07745f9efc 100644 --- a/mac/docs/help/about/requirements.md +++ b/mac/docs/help/about/requirements.md @@ -1,5 +1,5 @@ --- -title: System Requirements +title: System Requirements - Keyman for macOS Help --- ## Supported Mac Operating Systems diff --git a/mac/docs/help/start/install-keyboard.md b/mac/docs/help/start/install-keyboard.md index bf9310c8bb..e22b3fad56 100644 --- a/mac/docs/help/start/install-keyboard.md +++ b/mac/docs/help/start/install-keyboard.md @@ -1,5 +1,5 @@ --- -title: Install a Keyman Keyboard +title: Install a Keyman Keyboard on macOS --- You must have a Keyman keyboard installed to type with Keyman for macOS in your language. diff --git a/windows/docs/help/about/requirements.md b/windows/docs/help/about/requirements.md index 3c241bc858..5730a6ec73 100644 --- a/windows/docs/help/about/requirements.md +++ b/windows/docs/help/about/requirements.md @@ -1,5 +1,5 @@ --- -title: System Requirements +title: System Requirements - Keyman for Windows Help --- ## Supported Windows Operating Systems diff --git a/windows/docs/help/start/download-and-install-keyboard.md b/windows/docs/help/start/download-and-install-keyboard.md index cd1ddb18c0..b512fcc03b 100644 --- a/windows/docs/help/start/download-and-install-keyboard.md +++ b/windows/docs/help/start/download-and-install-keyboard.md @@ -1,5 +1,5 @@ --- -title: How To - Download and Install a Keyman Keyboard +title: How To - Download and Install a Keyman Keyboard on Windows --- You must have a Keyman keyboard installed to type with Keyman in your diff --git a/windows/docs/help/start/download-and-install-keyman.md b/windows/docs/help/start/download-and-install-keyman.md index 00a8538508..bf316692bb 100644 --- a/windows/docs/help/start/download-and-install-keyman.md +++ b/windows/docs/help/start/download-and-install-keyman.md @@ -1,5 +1,5 @@ --- -title: How To - Download and Install Keyman +title: How To - Download and Install Keyman on Windows --- ## Downloading Keyman From 5034ce8830175d219f7e7487a507ede0e3333ef1 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Fri, 24 Jan 2025 14:06:36 +1000 Subject: [PATCH 108/155] fix(windows): remove blank lines --- windows/src/engine/keyman32/appint/aiTIP.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/windows/src/engine/keyman32/appint/aiTIP.cpp b/windows/src/engine/keyman32/appint/aiTIP.cpp index 21d716a022..f94066a7d9 100644 --- a/windows/src/engine/keyman32/appint/aiTIP.cpp +++ b/windows/src/engine/keyman32/appint/aiTIP.cpp @@ -229,8 +229,6 @@ BOOL TIPProcessKeyInternal( } - - extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKey( WPARAM wParam, LPARAM lParam, // I3589 // I3588 From 8b1e05b60ae2f54035ea1e365e2ff087043d2f8e Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 12:00:10 +0700 Subject: [PATCH 109/155] chore: add mac platform to titles --- mac/docs/help/basic/index.md | 2 +- mac/docs/help/troubleshooting/uninstall-keyman.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mac/docs/help/basic/index.md b/mac/docs/help/basic/index.md index 8b3d0df07a..e09ff4f7b5 100644 --- a/mac/docs/help/basic/index.md +++ b/mac/docs/help/basic/index.md @@ -1,5 +1,5 @@ --- -title: Basic Help +title: Keyman for macOS Basic Help --- * [Keyman Configuration](config/) diff --git a/mac/docs/help/troubleshooting/uninstall-keyman.md b/mac/docs/help/troubleshooting/uninstall-keyman.md index 64ba2648e0..e1add66120 100644 --- a/mac/docs/help/troubleshooting/uninstall-keyman.md +++ b/mac/docs/help/troubleshooting/uninstall-keyman.md @@ -1,5 +1,5 @@ --- -title: Uninstalling Keyman +title: Uninstalling Keyman for macOS --- To uninstall Keyman for macOS: From 72540a5e9462ee00a1da6ff0ede8bd5c19da1321 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 12:07:22 +0700 Subject: [PATCH 110/155] chore: add linux platform to titles --- linux/docs/help/about/index.md | 2 +- linux/docs/help/common/index.md | 2 +- linux/docs/help/reference/index.md | 4 ++-- linux/docs/help/start/index.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/linux/docs/help/about/index.md b/linux/docs/help/about/index.md index 5064ed6a09..0bf3142c40 100644 --- a/linux/docs/help/about/index.md +++ b/linux/docs/help/about/index.md @@ -1,5 +1,5 @@ --- -title: About Keyman +title: About Keyman for Linux --- * [Welcome to Keyman](welcome) diff --git a/linux/docs/help/common/index.md b/linux/docs/help/common/index.md index e1bbbdc225..b2d606b38d 100644 --- a/linux/docs/help/common/index.md +++ b/linux/docs/help/common/index.md @@ -1,5 +1,5 @@ --- -title: Common Questions +title: Keyman for Linux Common Questions --- See also [Knowledge Base articles](https://help.keyman.com/knowledge-base/). diff --git a/linux/docs/help/reference/index.md b/linux/docs/help/reference/index.md index 7b8f704018..4553779096 100644 --- a/linux/docs/help/reference/index.md +++ b/linux/docs/help/reference/index.md @@ -1,8 +1,8 @@ --- -title: Keyman 17.0 for Linux Reference +title: Keyman 18.0 for Linux Reference --- -## Keyman 17.0 for Linux Overview +## Keyman 18.0 for Linux Overview Keyman for Linux makes it possible for you to type in over 2,000 languages on Linux. diff --git a/linux/docs/help/start/index.md b/linux/docs/help/start/index.md index b3aad00bd5..530b67016d 100644 --- a/linux/docs/help/start/index.md +++ b/linux/docs/help/start/index.md @@ -1,5 +1,5 @@ --- -title: Getting Started +title: Getting Started with Keyman for Linux --- * [How To - Installing Keyboards with Keyman for Linux](installing-keyboard) From 71e0d3eb4bf671f3d8b83201d3bd9e2ecc73edb9 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 12:07:51 +0700 Subject: [PATCH 111/155] Revert "chore: add linux platform to titles" This reverts commit 72540a5e9462ee00a1da6ff0ede8bd5c19da1321. --- linux/docs/help/about/index.md | 2 +- linux/docs/help/common/index.md | 2 +- linux/docs/help/reference/index.md | 4 ++-- linux/docs/help/start/index.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/linux/docs/help/about/index.md b/linux/docs/help/about/index.md index 0bf3142c40..5064ed6a09 100644 --- a/linux/docs/help/about/index.md +++ b/linux/docs/help/about/index.md @@ -1,5 +1,5 @@ --- -title: About Keyman for Linux +title: About Keyman --- * [Welcome to Keyman](welcome) diff --git a/linux/docs/help/common/index.md b/linux/docs/help/common/index.md index b2d606b38d..e1bbbdc225 100644 --- a/linux/docs/help/common/index.md +++ b/linux/docs/help/common/index.md @@ -1,5 +1,5 @@ --- -title: Keyman for Linux Common Questions +title: Common Questions --- See also [Knowledge Base articles](https://help.keyman.com/knowledge-base/). diff --git a/linux/docs/help/reference/index.md b/linux/docs/help/reference/index.md index 4553779096..7b8f704018 100644 --- a/linux/docs/help/reference/index.md +++ b/linux/docs/help/reference/index.md @@ -1,8 +1,8 @@ --- -title: Keyman 18.0 for Linux Reference +title: Keyman 17.0 for Linux Reference --- -## Keyman 18.0 for Linux Overview +## Keyman 17.0 for Linux Overview Keyman for Linux makes it possible for you to type in over 2,000 languages on Linux. diff --git a/linux/docs/help/start/index.md b/linux/docs/help/start/index.md index 530b67016d..b3aad00bd5 100644 --- a/linux/docs/help/start/index.md +++ b/linux/docs/help/start/index.md @@ -1,5 +1,5 @@ --- -title: Getting Started with Keyman for Linux +title: Getting Started --- * [How To - Installing Keyboards with Keyman for Linux](installing-keyboard) From 7f14b9cb2b50f5515a9281186179db346e92d014 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 12:08:19 +0700 Subject: [PATCH 112/155] Reapply "chore: add linux platform to titles" This reverts commit 71e0d3eb4bf671f3d8b83201d3bd9e2ecc73edb9. --- linux/docs/help/about/index.md | 2 +- linux/docs/help/common/index.md | 2 +- linux/docs/help/reference/index.md | 4 ++-- linux/docs/help/start/index.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/linux/docs/help/about/index.md b/linux/docs/help/about/index.md index 5064ed6a09..0bf3142c40 100644 --- a/linux/docs/help/about/index.md +++ b/linux/docs/help/about/index.md @@ -1,5 +1,5 @@ --- -title: About Keyman +title: About Keyman for Linux --- * [Welcome to Keyman](welcome) diff --git a/linux/docs/help/common/index.md b/linux/docs/help/common/index.md index e1bbbdc225..b2d606b38d 100644 --- a/linux/docs/help/common/index.md +++ b/linux/docs/help/common/index.md @@ -1,5 +1,5 @@ --- -title: Common Questions +title: Keyman for Linux Common Questions --- See also [Knowledge Base articles](https://help.keyman.com/knowledge-base/). diff --git a/linux/docs/help/reference/index.md b/linux/docs/help/reference/index.md index 7b8f704018..4553779096 100644 --- a/linux/docs/help/reference/index.md +++ b/linux/docs/help/reference/index.md @@ -1,8 +1,8 @@ --- -title: Keyman 17.0 for Linux Reference +title: Keyman 18.0 for Linux Reference --- -## Keyman 17.0 for Linux Overview +## Keyman 18.0 for Linux Overview Keyman for Linux makes it possible for you to type in over 2,000 languages on Linux. diff --git a/linux/docs/help/start/index.md b/linux/docs/help/start/index.md index b3aad00bd5..530b67016d 100644 --- a/linux/docs/help/start/index.md +++ b/linux/docs/help/start/index.md @@ -1,5 +1,5 @@ --- -title: Getting Started +title: Getting Started with Keyman for Linux --- * [How To - Installing Keyboards with Keyman for Linux](installing-keyboard) From df2e398cfaf1bb6e808026c01ef6fe846b4c1587 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 12:10:16 +0700 Subject: [PATCH 113/155] chore: add linux platform to titles --- linux/docs/help/about/index.md | 2 +- linux/docs/help/common/index.md | 2 +- linux/docs/help/reference/index.md | 4 ++-- linux/docs/help/start/index.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/linux/docs/help/about/index.md b/linux/docs/help/about/index.md index 5064ed6a09..0bf3142c40 100644 --- a/linux/docs/help/about/index.md +++ b/linux/docs/help/about/index.md @@ -1,5 +1,5 @@ --- -title: About Keyman +title: About Keyman for Linux --- * [Welcome to Keyman](welcome) diff --git a/linux/docs/help/common/index.md b/linux/docs/help/common/index.md index e1bbbdc225..b2d606b38d 100644 --- a/linux/docs/help/common/index.md +++ b/linux/docs/help/common/index.md @@ -1,5 +1,5 @@ --- -title: Common Questions +title: Keyman for Linux Common Questions --- See also [Knowledge Base articles](https://help.keyman.com/knowledge-base/). diff --git a/linux/docs/help/reference/index.md b/linux/docs/help/reference/index.md index 7b8f704018..4553779096 100644 --- a/linux/docs/help/reference/index.md +++ b/linux/docs/help/reference/index.md @@ -1,8 +1,8 @@ --- -title: Keyman 17.0 for Linux Reference +title: Keyman 18.0 for Linux Reference --- -## Keyman 17.0 for Linux Overview +## Keyman 18.0 for Linux Overview Keyman for Linux makes it possible for you to type in over 2,000 languages on Linux. diff --git a/linux/docs/help/start/index.md b/linux/docs/help/start/index.md index b3aad00bd5..530b67016d 100644 --- a/linux/docs/help/start/index.md +++ b/linux/docs/help/start/index.md @@ -1,5 +1,5 @@ --- -title: Getting Started +title: Getting Started with Keyman for Linux --- * [How To - Installing Keyboards with Keyman for Linux](installing-keyboard) From 825250bbe1b18e0bd82ad0a231e87bd982bc1d04 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 24 Jan 2025 12:14:43 +0700 Subject: [PATCH 114/155] fix: use correct path for resources/build/version Fixes: #12915 --- resources/build/increment-version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/build/increment-version.sh b/resources/build/increment-version.sh index da459776eb..3be11dba1f 100755 --- a/resources/build/increment-version.sh +++ b/resources/build/increment-version.sh @@ -179,7 +179,7 @@ if [ "$action" == "commit" ]; then # In order to avoid potential git conflicts, we run the history collater # again on the master HISTORY.md. Note that the script always exits 1 to # indicate it hasn't updated VERSION.md. We could tweak that in the future. - node resources/build/version/lib/index.js history --no-write-github-comment --github-pr -t "$GITHUB_TOKEN" -b "$base" || true + node resources/build/version/build/src/index.js history --no-write-github-comment --github-pr -t "$GITHUB_TOKEN" -b "$base" || true # If HISTORY.md has been updated, then we want to create a branch and push # it for review From 82e8cd139cc16cc86ec1041ff53592b7a0b2bbb8 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 12:21:14 +0700 Subject: [PATCH 115/155] chore: add ios platform to titles --- ios/docs/engine/guides/in-app/index.md | 2 +- ios/docs/engine/guides/system-keyboard/index.md | 2 +- ios/docs/help/about/index.md | 2 +- ios/docs/help/basic/index.md | 2 +- ios/docs/help/context/gestures.md | 2 +- ios/docs/help/start/index.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ios/docs/engine/guides/in-app/index.md b/ios/docs/engine/guides/in-app/index.md index 3dfebbf82d..14ba8ba4c5 100644 --- a/ios/docs/engine/guides/in-app/index.md +++ b/ios/docs/engine/guides/in-app/index.md @@ -1,5 +1,5 @@ --- -title: Guide: build an in-app keyboard +title: Guide: build an in-app keyboard for iPhone and iPad with Keyman Engine --- Keyman Engine for iPhone and iPad allows you to use any Keyman touch diff --git a/ios/docs/engine/guides/system-keyboard/index.md b/ios/docs/engine/guides/system-keyboard/index.md index ea652360b2..4a533f08d8 100644 --- a/ios/docs/engine/guides/system-keyboard/index.md +++ b/ios/docs/engine/guides/system-keyboard/index.md @@ -1,5 +1,5 @@ --- -title: Guide: build a system keyboard app +title: Guide: build a system keyboard app on iPhone and iPad with Keyman Engine --- In [part 1](../in-app/) of this series, we looked at the steps involved diff --git a/ios/docs/help/about/index.md b/ios/docs/help/about/index.md index 71ead99252..d37b9ed978 100644 --- a/ios/docs/help/about/index.md +++ b/ios/docs/help/about/index.md @@ -1,5 +1,5 @@ --- -title: About Keyman +title: About Keyman for iPhone and iPad --- * [Welcome to Keyman](welcome) diff --git a/ios/docs/help/basic/index.md b/ios/docs/help/basic/index.md index b67688e03c..e93f77f3aa 100644 --- a/ios/docs/help/basic/index.md +++ b/ios/docs/help/basic/index.md @@ -1,5 +1,5 @@ --- -title: Basic Help +title: Keyman for iPhone and iPad Basic Help --- * [Using the Banner on the Keyboard](using-the-banner) diff --git a/ios/docs/help/context/gestures.md b/ios/docs/help/context/gestures.md index 251de0f1ce..ab15c3203d 100644 --- a/ios/docs/help/context/gestures.md +++ b/ios/docs/help/context/gestures.md @@ -1,5 +1,5 @@ --- -title: Gesture Hints and Tips +title: Gesture Hints and Tips - Keyman for iPhone and iPad --- ## Using Gestures on the Keyboard Keys diff --git a/ios/docs/help/start/index.md b/ios/docs/help/start/index.md index f48fc3f185..d7bb7ad72e 100644 --- a/ios/docs/help/start/index.md +++ b/ios/docs/help/start/index.md @@ -1,5 +1,5 @@ --- -title: Getting Started +title: Getting Started with Keyman for iPhone and iPad --- * [How To - Adding a Keyboard](searching-for-keyboards) From 45a2e172a4f20f0b0e7acca9b95d8f96dec4d858 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 12:21:42 +0700 Subject: [PATCH 116/155] Revert "chore: add ios platform to titles" This reverts commit 82e8cd139cc16cc86ec1041ff53592b7a0b2bbb8. --- ios/docs/engine/guides/in-app/index.md | 2 +- ios/docs/engine/guides/system-keyboard/index.md | 2 +- ios/docs/help/about/index.md | 2 +- ios/docs/help/basic/index.md | 2 +- ios/docs/help/context/gestures.md | 2 +- ios/docs/help/start/index.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ios/docs/engine/guides/in-app/index.md b/ios/docs/engine/guides/in-app/index.md index 14ba8ba4c5..3dfebbf82d 100644 --- a/ios/docs/engine/guides/in-app/index.md +++ b/ios/docs/engine/guides/in-app/index.md @@ -1,5 +1,5 @@ --- -title: Guide: build an in-app keyboard for iPhone and iPad with Keyman Engine +title: Guide: build an in-app keyboard --- Keyman Engine for iPhone and iPad allows you to use any Keyman touch diff --git a/ios/docs/engine/guides/system-keyboard/index.md b/ios/docs/engine/guides/system-keyboard/index.md index 4a533f08d8..ea652360b2 100644 --- a/ios/docs/engine/guides/system-keyboard/index.md +++ b/ios/docs/engine/guides/system-keyboard/index.md @@ -1,5 +1,5 @@ --- -title: Guide: build a system keyboard app on iPhone and iPad with Keyman Engine +title: Guide: build a system keyboard app --- In [part 1](../in-app/) of this series, we looked at the steps involved diff --git a/ios/docs/help/about/index.md b/ios/docs/help/about/index.md index d37b9ed978..71ead99252 100644 --- a/ios/docs/help/about/index.md +++ b/ios/docs/help/about/index.md @@ -1,5 +1,5 @@ --- -title: About Keyman for iPhone and iPad +title: About Keyman --- * [Welcome to Keyman](welcome) diff --git a/ios/docs/help/basic/index.md b/ios/docs/help/basic/index.md index e93f77f3aa..b67688e03c 100644 --- a/ios/docs/help/basic/index.md +++ b/ios/docs/help/basic/index.md @@ -1,5 +1,5 @@ --- -title: Keyman for iPhone and iPad Basic Help +title: Basic Help --- * [Using the Banner on the Keyboard](using-the-banner) diff --git a/ios/docs/help/context/gestures.md b/ios/docs/help/context/gestures.md index ab15c3203d..251de0f1ce 100644 --- a/ios/docs/help/context/gestures.md +++ b/ios/docs/help/context/gestures.md @@ -1,5 +1,5 @@ --- -title: Gesture Hints and Tips - Keyman for iPhone and iPad +title: Gesture Hints and Tips --- ## Using Gestures on the Keyboard Keys diff --git a/ios/docs/help/start/index.md b/ios/docs/help/start/index.md index d7bb7ad72e..f48fc3f185 100644 --- a/ios/docs/help/start/index.md +++ b/ios/docs/help/start/index.md @@ -1,5 +1,5 @@ --- -title: Getting Started with Keyman for iPhone and iPad +title: Getting Started --- * [How To - Adding a Keyboard](searching-for-keyboards) From 01ed5f711e1d9ffd26c78d9430422a85053ddba3 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 12:22:13 +0700 Subject: [PATCH 117/155] Reapply "chore: add ios platform to titles" This reverts commit 45a2e172a4f20f0b0e7acca9b95d8f96dec4d858. --- ios/docs/engine/guides/in-app/index.md | 2 +- ios/docs/engine/guides/system-keyboard/index.md | 2 +- ios/docs/help/about/index.md | 2 +- ios/docs/help/basic/index.md | 2 +- ios/docs/help/context/gestures.md | 2 +- ios/docs/help/start/index.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ios/docs/engine/guides/in-app/index.md b/ios/docs/engine/guides/in-app/index.md index 3dfebbf82d..14ba8ba4c5 100644 --- a/ios/docs/engine/guides/in-app/index.md +++ b/ios/docs/engine/guides/in-app/index.md @@ -1,5 +1,5 @@ --- -title: Guide: build an in-app keyboard +title: Guide: build an in-app keyboard for iPhone and iPad with Keyman Engine --- Keyman Engine for iPhone and iPad allows you to use any Keyman touch diff --git a/ios/docs/engine/guides/system-keyboard/index.md b/ios/docs/engine/guides/system-keyboard/index.md index ea652360b2..4a533f08d8 100644 --- a/ios/docs/engine/guides/system-keyboard/index.md +++ b/ios/docs/engine/guides/system-keyboard/index.md @@ -1,5 +1,5 @@ --- -title: Guide: build a system keyboard app +title: Guide: build a system keyboard app on iPhone and iPad with Keyman Engine --- In [part 1](../in-app/) of this series, we looked at the steps involved diff --git a/ios/docs/help/about/index.md b/ios/docs/help/about/index.md index 71ead99252..d37b9ed978 100644 --- a/ios/docs/help/about/index.md +++ b/ios/docs/help/about/index.md @@ -1,5 +1,5 @@ --- -title: About Keyman +title: About Keyman for iPhone and iPad --- * [Welcome to Keyman](welcome) diff --git a/ios/docs/help/basic/index.md b/ios/docs/help/basic/index.md index b67688e03c..e93f77f3aa 100644 --- a/ios/docs/help/basic/index.md +++ b/ios/docs/help/basic/index.md @@ -1,5 +1,5 @@ --- -title: Basic Help +title: Keyman for iPhone and iPad Basic Help --- * [Using the Banner on the Keyboard](using-the-banner) diff --git a/ios/docs/help/context/gestures.md b/ios/docs/help/context/gestures.md index 251de0f1ce..ab15c3203d 100644 --- a/ios/docs/help/context/gestures.md +++ b/ios/docs/help/context/gestures.md @@ -1,5 +1,5 @@ --- -title: Gesture Hints and Tips +title: Gesture Hints and Tips - Keyman for iPhone and iPad --- ## Using Gestures on the Keyboard Keys diff --git a/ios/docs/help/start/index.md b/ios/docs/help/start/index.md index f48fc3f185..d7bb7ad72e 100644 --- a/ios/docs/help/start/index.md +++ b/ios/docs/help/start/index.md @@ -1,5 +1,5 @@ --- -title: Getting Started +title: Getting Started with Keyman for iPhone and iPad --- * [How To - Adding a Keyboard](searching-for-keyboards) From 6c9de83368f48f0160cd517fbc9f539d8f734e59 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 12:22:36 +0700 Subject: [PATCH 118/155] chore: add ios platform to titles --- ios/docs/engine/guides/in-app/index.md | 2 +- ios/docs/engine/guides/system-keyboard/index.md | 2 +- ios/docs/help/about/index.md | 2 +- ios/docs/help/basic/index.md | 2 +- ios/docs/help/context/gestures.md | 2 +- ios/docs/help/start/index.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ios/docs/engine/guides/in-app/index.md b/ios/docs/engine/guides/in-app/index.md index 14ba8ba4c5..3dfebbf82d 100644 --- a/ios/docs/engine/guides/in-app/index.md +++ b/ios/docs/engine/guides/in-app/index.md @@ -1,5 +1,5 @@ --- -title: Guide: build an in-app keyboard for iPhone and iPad with Keyman Engine +title: Guide: build an in-app keyboard --- Keyman Engine for iPhone and iPad allows you to use any Keyman touch diff --git a/ios/docs/engine/guides/system-keyboard/index.md b/ios/docs/engine/guides/system-keyboard/index.md index 4a533f08d8..ea652360b2 100644 --- a/ios/docs/engine/guides/system-keyboard/index.md +++ b/ios/docs/engine/guides/system-keyboard/index.md @@ -1,5 +1,5 @@ --- -title: Guide: build a system keyboard app on iPhone and iPad with Keyman Engine +title: Guide: build a system keyboard app --- In [part 1](../in-app/) of this series, we looked at the steps involved diff --git a/ios/docs/help/about/index.md b/ios/docs/help/about/index.md index d37b9ed978..71ead99252 100644 --- a/ios/docs/help/about/index.md +++ b/ios/docs/help/about/index.md @@ -1,5 +1,5 @@ --- -title: About Keyman for iPhone and iPad +title: About Keyman --- * [Welcome to Keyman](welcome) diff --git a/ios/docs/help/basic/index.md b/ios/docs/help/basic/index.md index e93f77f3aa..b67688e03c 100644 --- a/ios/docs/help/basic/index.md +++ b/ios/docs/help/basic/index.md @@ -1,5 +1,5 @@ --- -title: Keyman for iPhone and iPad Basic Help +title: Basic Help --- * [Using the Banner on the Keyboard](using-the-banner) diff --git a/ios/docs/help/context/gestures.md b/ios/docs/help/context/gestures.md index ab15c3203d..251de0f1ce 100644 --- a/ios/docs/help/context/gestures.md +++ b/ios/docs/help/context/gestures.md @@ -1,5 +1,5 @@ --- -title: Gesture Hints and Tips - Keyman for iPhone and iPad +title: Gesture Hints and Tips --- ## Using Gestures on the Keyboard Keys diff --git a/ios/docs/help/start/index.md b/ios/docs/help/start/index.md index d7bb7ad72e..f48fc3f185 100644 --- a/ios/docs/help/start/index.md +++ b/ios/docs/help/start/index.md @@ -1,5 +1,5 @@ --- -title: Getting Started with Keyman for iPhone and iPad +title: Getting Started --- * [How To - Adding a Keyboard](searching-for-keyboards) From 66e3f3acc769361f59a2c25c064298502ac2321d Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 24 Jan 2025 12:23:21 +0700 Subject: [PATCH 119/155] chore: add ios platform to titles --- ios/docs/engine/guides/in-app/index.md | 2 +- ios/docs/engine/guides/system-keyboard/index.md | 2 +- ios/docs/help/about/index.md | 2 +- ios/docs/help/basic/index.md | 2 +- ios/docs/help/context/gestures.md | 2 +- ios/docs/help/start/index.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ios/docs/engine/guides/in-app/index.md b/ios/docs/engine/guides/in-app/index.md index 3dfebbf82d..14ba8ba4c5 100644 --- a/ios/docs/engine/guides/in-app/index.md +++ b/ios/docs/engine/guides/in-app/index.md @@ -1,5 +1,5 @@ --- -title: Guide: build an in-app keyboard +title: Guide: build an in-app keyboard for iPhone and iPad with Keyman Engine --- Keyman Engine for iPhone and iPad allows you to use any Keyman touch diff --git a/ios/docs/engine/guides/system-keyboard/index.md b/ios/docs/engine/guides/system-keyboard/index.md index ea652360b2..4a533f08d8 100644 --- a/ios/docs/engine/guides/system-keyboard/index.md +++ b/ios/docs/engine/guides/system-keyboard/index.md @@ -1,5 +1,5 @@ --- -title: Guide: build a system keyboard app +title: Guide: build a system keyboard app on iPhone and iPad with Keyman Engine --- In [part 1](../in-app/) of this series, we looked at the steps involved diff --git a/ios/docs/help/about/index.md b/ios/docs/help/about/index.md index 71ead99252..d37b9ed978 100644 --- a/ios/docs/help/about/index.md +++ b/ios/docs/help/about/index.md @@ -1,5 +1,5 @@ --- -title: About Keyman +title: About Keyman for iPhone and iPad --- * [Welcome to Keyman](welcome) diff --git a/ios/docs/help/basic/index.md b/ios/docs/help/basic/index.md index b67688e03c..e93f77f3aa 100644 --- a/ios/docs/help/basic/index.md +++ b/ios/docs/help/basic/index.md @@ -1,5 +1,5 @@ --- -title: Basic Help +title: Keyman for iPhone and iPad Basic Help --- * [Using the Banner on the Keyboard](using-the-banner) diff --git a/ios/docs/help/context/gestures.md b/ios/docs/help/context/gestures.md index 251de0f1ce..ab15c3203d 100644 --- a/ios/docs/help/context/gestures.md +++ b/ios/docs/help/context/gestures.md @@ -1,5 +1,5 @@ --- -title: Gesture Hints and Tips +title: Gesture Hints and Tips - Keyman for iPhone and iPad --- ## Using Gestures on the Keyboard Keys diff --git a/ios/docs/help/start/index.md b/ios/docs/help/start/index.md index f48fc3f185..d7bb7ad72e 100644 --- a/ios/docs/help/start/index.md +++ b/ios/docs/help/start/index.md @@ -1,5 +1,5 @@ --- -title: Getting Started +title: Getting Started with Keyman for iPhone and iPad --- * [How To - Adding a Keyboard](searching-for-keyboards) From 4004fe3b6c57e0a5bb715d82b7bcdb25a7c94e6b Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 24 Jan 2025 12:31:20 +0700 Subject: [PATCH 120/155] fix(web): unblock font loading from data URL --- web/src/engine/dom-utils/src/stylesheets.ts | 36 +++++++++++---------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/web/src/engine/dom-utils/src/stylesheets.ts b/web/src/engine/dom-utils/src/stylesheets.ts index 977f253ff7..71518fd3f7 100644 --- a/web/src/engine/dom-utils/src/stylesheets.ts +++ b/web/src/engine/dom-utils/src/stylesheets.ts @@ -148,29 +148,31 @@ export class StylesheetManager { const formatStartIndex = 'data:font/'.length; const format = data.substring(formatStartIndex, data.indexOf(';', formatStartIndex)); s +=`src:url('${data}'), format('${format}');`; - } else if(os == DeviceSpec.OperatingSystem.iOS) { - if(ttf != '') { - if(this.doCacheBusting) { - ttf = this.cacheBust(ttf); - } - source = "url('"+encodeURI(ttf)+"') format('truetype')"; - } } else { - if(woff != '') { - source = "url('"+encodeURI(woff)+"') format('woff')"; + if(os == DeviceSpec.OperatingSystem.iOS) { + if(ttf != '') { + if(this.doCacheBusting) { + ttf = this.cacheBust(ttf); + } + source = "url('"+encodeURI(ttf)+"') format('truetype')"; + } + } else { + if(woff != '') { + source = "url('"+encodeURI(woff)+"') format('woff')"; + } + + if(ttf != '') { + source = "url('"+encodeURI(ttf)+"') format('truetype')"; + } } - if(ttf != '') { - source = "url('"+encodeURI(ttf)+"') format('truetype')"; + if(!source) { + return null; } + + s += 'src:'+source+';'; } - if(!source) { - return null; - } - - s += 'src:'+source+';'; - s=s+'\n}\n'; const sheet = createStyleSheet(s); From d25bcd25c7042195da831e599a77d36b997c0272 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:40:47 +1000 Subject: [PATCH 121/155] feat(windows): add keyman update mesg strings.xml Add strings for the pop ups that inform the user Keyman update is ready to install. Messages that updates are not/available and computer restart required. --- ...yman.Configuration.UI.UfrmStartInstall.pas | 8 +++---- ...n.Configuration.UI.UfrmStartInstallNow.pas | 2 +- .../src/desktop/kmshell/xml/keyman_update.xsl | 4 ++-- windows/src/desktop/kmshell/xml/strings.xml | 23 ++++++++++++++++--- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.pas b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.pas index 1abfcbbcee..b2353bc6fd 100644 --- a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.pas +++ b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstall.pas @@ -26,9 +26,9 @@ type cmdInstall: TButton; cmdLater: TButton; lblInstallUpdate: TLabel; + procedure FormCreate(Sender: TObject); private public - constructor Create(AOwner: TComponent); override; end; @@ -39,12 +39,12 @@ uses {$R *.dfm} -constructor TfrmStartInstall.Create(AOwner: TComponent); +procedure TfrmStartInstall.FormCreate(Sender: TObject); begin - inherited Create(AOwner); + inherited; cmdInstall.Caption := MsgFromId(S_Update); cmdLater.Caption := MsgFromId(S_Button_Close); - lblInstallUpdate.Caption := 'Keyman Update ready to install.'; + lblInstallUpdate.Caption := MsgFromId(S_Ready_To_Install); end; end. diff --git a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.pas b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.pas index b613a7c856..b4b7290d5f 100644 --- a/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.pas +++ b/windows/src/desktop/kmshell/main/Keyman.Configuration.UI.UfrmStartInstallNow.pas @@ -44,7 +44,7 @@ begin inherited; cmdInstall.Caption := MsgFromId(S_Update); cmdLater.Caption := MsgFromId(S_Button_Close); - lblUpdateMessage.Caption := 'Updating now will require a computer restart.'; + lblUpdateMessage.Caption := MsgFromId(S_Update_Restart_Req); end; end. diff --git a/windows/src/desktop/kmshell/xml/keyman_update.xsl b/windows/src/desktop/kmshell/xml/keyman_update.xsl index 0daa6ace3b..34da73faff 100644 --- a/windows/src/desktop/kmshell/xml/keyman_update.xsl +++ b/windows/src/desktop/kmshell/xml/keyman_update.xsl @@ -23,10 +23,10 @@
- Updates are available which will be applied when Windows is next restarted: + - No updates are available. +
diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml index 24909d3486..3c8f20a369 100644 --- a/windows/src/desktop/kmshell/xml/strings.xml +++ b/windows/src/desktop/kmshell/xml/strings.xml @@ -156,9 +156,6 @@ T - - - @@ -591,6 +588,26 @@ Diagnostics + + + + No Updates are available. + + + + + Updates are available which will be applied when Windows is next restarted. + + + + + Updating now will require a computer restart. + + + + + Keyman Update ready to install. + From a689f65188f6f6e780206e0e06a654ed21558bd4 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 24 Jan 2025 13:07:43 +0700 Subject: [PATCH 122/155] fix(developer): don't list .js keyboards for multi-keyboard packages in kmc-keyboard-info Because the build process for multi-keyboard packages does not deploy .js keyboards to s.keyman.com, it does not make sense to list them, even if the package may contain .js keyboards for mobile platforms. Fixes: #12853 --- .../src/kmc/src/commands/buildClasses/BuildKeyboardInfo.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/developer/src/kmc/src/commands/buildClasses/BuildKeyboardInfo.ts b/developer/src/kmc/src/commands/buildClasses/BuildKeyboardInfo.ts index 6309064dd0..3109038a3a 100644 --- a/developer/src/kmc/src/commands/buildClasses/BuildKeyboardInfo.ts +++ b/developer/src/kmc/src/commands/buildClasses/BuildKeyboardInfo.ts @@ -35,7 +35,11 @@ export class BuildKeyboardInfo extends BuildActivity { } const keyboard = project.files.find(file => file.fileType == KeymanFileTypes.Source.KeymanKeyboard); - const jsFilename = keyboard ? project.resolveOutputFilePath(keyboard, KeymanFileTypes.Source.KeymanKeyboard, KeymanFileTypes.Binary.WebKeyboard) : null; + + // If the project has more than one keyboard, we should not list any .js files (#12853) + const canListJsFile = project.files.filter(file => file.fileType == KeymanFileTypes.Source.KeymanKeyboard).length == 1; + + const jsFilename = canListJsFile && keyboard ? project.resolveOutputFilePath(keyboard, KeymanFileTypes.Source.KeymanKeyboard, KeymanFileTypes.Binary.WebKeyboard) : null; const historyPath = path.join(project.projectPath, KeymanFileTypes.HISTORY_MD); const lastCommitDate = getLastGitCommitDate(fs.existsSync(historyPath) ? historyPath : project.projectPath); const sources = { From 6353eccf591c8ffeb6a0fe861a888749be1a892f Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 24 Jan 2025 08:54:04 +0700 Subject: [PATCH 123/155] fix(web): add null guard for focusing next element via keystroke Fixes: #13011 Fixes: KEYMAN-COM-1MB Fixes: KEYMAN-COM-1EM --- web/src/app/browser/src/hardwareEventKeyboard.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/app/browser/src/hardwareEventKeyboard.ts b/web/src/app/browser/src/hardwareEventKeyboard.ts index 0bb594e897..5e8b30ce4f 100644 --- a/web/src/app/browser/src/hardwareEventKeyboard.ts +++ b/web/src/app/browser/src/hardwareEventKeyboard.ts @@ -326,7 +326,7 @@ export default class HardwareEventKeyboard extends HardKeyboard { inputEle.form.submit(); } else { const nextElement = this.contextManager.page.findNeighboringInput(inputEle, false); - nextElement.focus(); + nextElement?.focus(); } } return true; From 6de6f879ca8a9e511e565d31d35c370d01f5f9c0 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 24 Jan 2025 12:35:38 +0700 Subject: [PATCH 124/155] fix(web): change font-url enclosing quotes Fixes: #13018 Fixes: #13022 --- web/src/engine/dom-utils/src/stylesheets.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/web/src/engine/dom-utils/src/stylesheets.ts b/web/src/engine/dom-utils/src/stylesheets.ts index 71518fd3f7..47e09eeb26 100644 --- a/web/src/engine/dom-utils/src/stylesheets.ts +++ b/web/src/engine/dom-utils/src/stylesheets.ts @@ -149,20 +149,21 @@ export class StylesheetManager { const format = data.substring(formatStartIndex, data.indexOf(';', formatStartIndex)); s +=`src:url('${data}'), format('${format}');`; } else { + // Note: encodeURI("'") == "'", but encodeURI('"') == "%22". if(os == DeviceSpec.OperatingSystem.iOS) { if(ttf != '') { if(this.doCacheBusting) { ttf = this.cacheBust(ttf); } - source = "url('"+encodeURI(ttf)+"') format('truetype')"; + source = "url(\""+encodeURI(ttf)+"\") format('truetype')"; } } else { if(woff != '') { - source = "url('"+encodeURI(woff)+"') format('woff')"; + source = "url(\""+encodeURI(woff)+"\"') format('woff')"; } if(ttf != '') { - source = "url('"+encodeURI(ttf)+"') format('truetype')"; + source = "url(\""+encodeURI(ttf)+"\") format('truetype')"; } } From d6b831cb67a6ab60fa8962fa335e2f741bb5398a Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 24 Jan 2025 13:11:18 +0700 Subject: [PATCH 125/155] fix(web): fix font-family name escaping --- web/src/engine/dom-utils/src/stylesheets.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/src/engine/dom-utils/src/stylesheets.ts b/web/src/engine/dom-utils/src/stylesheets.ts index 47e09eeb26..8c96b2e5f6 100644 --- a/web/src/engine/dom-utils/src/stylesheets.ts +++ b/web/src/engine/dom-utils/src/stylesheets.ts @@ -136,8 +136,9 @@ export class StylesheetManager { } // Build the font-face definition according to the browser being used - var s='@font-face {\nfont-family:' - + fd.family + ';\nfont-style:normal;\nfont-weight:normal;\n'; + // The OSK will similarly remove double-quotes from font-family names. (#13018, #13022) + var s='@font-face {\nfont-family:"' + + fd.family.replace(/\u0022/g, '') + '";\nfont-style:normal;\nfont-weight:normal;\n'; // Build the font source string according to the browser, // but return without adding the style sheet if the required font type is unavailable From d74f5544fc2daaceaf990d3cdef7e6a9f4923fc2 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 24 Jan 2025 13:12:13 +0700 Subject: [PATCH 126/155] chore(web): apply suggestion linking issue numbers Co-authored-by: Marc Durdin --- web/src/engine/dom-utils/src/stylesheets.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/engine/dom-utils/src/stylesheets.ts b/web/src/engine/dom-utils/src/stylesheets.ts index 8c96b2e5f6..c0b03b85a5 100644 --- a/web/src/engine/dom-utils/src/stylesheets.ts +++ b/web/src/engine/dom-utils/src/stylesheets.ts @@ -150,7 +150,7 @@ export class StylesheetManager { const format = data.substring(formatStartIndex, data.indexOf(';', formatStartIndex)); s +=`src:url('${data}'), format('${format}');`; } else { - // Note: encodeURI("'") == "'", but encodeURI('"') == "%22". + // Note: encodeURI("'") == "'", but encodeURI('"') == "%22" (#13018, #13022) if(os == DeviceSpec.OperatingSystem.iOS) { if(ttf != '') { if(this.doCacheBusting) { From ee7ca4c6e160dc04173dda2ba3ff3196ae52cc9e Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 24 Jan 2025 13:13:16 +0700 Subject: [PATCH 127/155] chore(web): also link issues near font-family fix --- web/src/engine/dom-utils/src/stylesheets.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/src/engine/dom-utils/src/stylesheets.ts b/web/src/engine/dom-utils/src/stylesheets.ts index c0b03b85a5..5318e28f61 100644 --- a/web/src/engine/dom-utils/src/stylesheets.ts +++ b/web/src/engine/dom-utils/src/stylesheets.ts @@ -136,7 +136,8 @@ export class StylesheetManager { } // Build the font-face definition according to the browser being used - // The OSK will similarly remove double-quotes from font-family names. (#13018, #13022) + // The OSK will similarly remove double-quotes from font-family names and double-quote + // the name itself. (#13018, #13022) var s='@font-face {\nfont-family:"' + fd.family.replace(/\u0022/g, '') + '";\nfont-style:normal;\nfont-weight:normal;\n'; From 9bd76bd1c86fc27b85853d083713be5ab28b821e Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 24 Jan 2025 13:30:14 +0700 Subject: [PATCH 128/155] chore(android): tweak uri string reference for consistency per review Co-authored-by: Marc Durdin --- .../src/main/java/com/tavultesoft/kmapro/MainActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java index 44f0cddc49..908d2f4538 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java @@ -270,7 +270,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene case "file": requestPermissionIntentUri = loadingIntentUri; if (CheckPermissions.isPermissionOK(this)) { - KMLog.LogBreadcrumb(TAG, "Installing local KMP: " + loadingIntentUri, true); + KMLog.LogBreadcrumb(TAG, "Installing local KMP: " + link, true); useLocalKMP(context, loadingIntentUri); } else { CheckPermissions.requestPermission(this, context); From 5090aeefd93eabdc4576cb41dc89159532275fc5 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Thu, 23 Jan 2025 20:48:53 +0100 Subject: [PATCH 129/155] fix(linux): improve test script This changes the test script: when running in Docker it doesn't make sense to restart ibus when exiting the tests. This works around a problem where the `ibus start` command would hang. --- linux/ibus-keyman/tests/scripts/test-helper.inc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/ibus-keyman/tests/scripts/test-helper.inc.sh b/linux/ibus-keyman/tests/scripts/test-helper.inc.sh index a32fef8689..940c5ad310 100755 --- a/linux/ibus-keyman/tests/scripts/test-helper.inc.sh +++ b/linux/ibus-keyman/tests/scripts/test-helper.inc.sh @@ -251,7 +251,7 @@ function _setup_ibus() { #shellcheck disable=SC2086 ibus-daemon ${ARG_VERBOSE-} --daemonize --panel=disable --address=unix:abstract="${TEMP_DATA_DIR}/test-ibus" ${IBUS_CONFIG-} &> /tmp/ibus-daemon.log PID=$(pgrep -f "${TEMP_DATA_DIR}/test-ibus") - if [[ "${STANDALONE}" == "--standalone" ]]; then + if [[ "${STANDALONE}" == "--standalone" ]] && [[ ! "${DOCKER_RUNNING:-false}" ]]; then # manual test run echo "if kill -9 ${PID}; then ibus restart || ibus start; fi # ibus-daemon" >> "${CLEANUP_FILE}" else From 759c0e0af540fa689aa43e5b86b113163e95402a Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 24 Jan 2025 13:03:59 -0500 Subject: [PATCH 130/155] auto: increment master version to 18.0.178 --- HISTORY.md | 19 +++++++++++++++++++ VERSION.md | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index b64e4ca1e5..76767e69f4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,24 @@ # Keyman Version History +## 18.0.177 alpha 2025-01-24 + +* fix(android): restores DOMRect polyfill for old Chrome support (#13012) +* fix(developer): produce correct index parameter value for context in kmw compiler (#13003) +* chore: add platform to what's new titles (#12989) +* chore: add platforms to welcome titles (#12990) +* chore: add platforms to version history titles (#13016) +* chore: add platforms to troubleshooting titles and windows to help homepage (#13019) +* chore: add platforms to system requirements and download-and-install docs (#13024) +* chore: add mac platform to titles (#13027) +* chore: add linux platform to titles (#13028) +* chore: add ios platform to titles (#13031) +* fix(developer): escape font facename in touch layout editor (#13020) +* fix: use correct path for resources/build/version (#13029) +* fix(developer): don't list .js keyboards for multi-keyboard packages in kmc-keyboard-info (#13034) +* fix(web): do not simplify nul-prefixed contexts when rule-matching (#12998) +* feat(android): add breadcrumbing during package install about package file, source (#13021) +* fix(linux): correct permissions and paths in Linux docker image (#13008) + ## 18.0.176 alpha 2025-01-23 * chore(developer): stub out icon support in kmc-generate (#12971) diff --git a/VERSION.md b/VERSION.md index 45e53027cb..2f5970df3b 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.177 \ No newline at end of file +18.0.178 \ No newline at end of file From 077229e89c7de60d56385e3ebf47a8f8c2340abc Mon Sep 17 00:00:00 2001 From: sgschantz Date: Mon, 27 Jan 2025 09:21:26 +0700 Subject: [PATCH 131/155] chore(mac): added comments and renamed function --- .../KMConfigurationWindowController.m | 2 +- .../Keyman4MacIM/KMInputMethodAppDelegate.m | 10 ++++---- .../Keyman4MacIM/KMInputMethodEventHandler.m | 6 ++--- .../Keyman4MacIM/KMInputMethodLifecycle.m | 6 ++--- .../Keyman4MacIM/Logging/KMSentryHelper.h | 4 ++-- .../Keyman4MacIM/Logging/KMSentryHelper.m | 24 +++++++++---------- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m index 6f63bcfccf..8a35afd31c 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m @@ -472,7 +472,7 @@ - (void)installPackageFile:(NSString *)kmpFile { // kmpFile could be a temp file (in fact, it always is!), so don't display the name. os_log_debug([KMLogs dataLog], "kmpFile - ready to unzip/install Package File: %{public}@", kmpFile); - [KMSentryHelper addBreadCrumb:@"configure" message:@"install package file"]; + [KMSentryHelper addInfoBreadCrumb:@"configure" message:@"install package file"]; BOOL didUnzip = [self.AppDelegate unzipFile:kmpFile]; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index b3020e1a55..cfff0d80cd 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -134,7 +134,7 @@ id _lastServerWithOSKShowing = nil; - (void)inputMethodDeactivated:(NSNotification *)notification { if ([self.oskWindow.window isVisible]) { os_log_debug([KMLogs oskLog], "***KMInputMethodAppDelegate inputMethodDeactivated, hiding OSK"); - [KMSentryHelper addBreadCrumb:@"lifecycle" message:@"hiding OSK on input method deactivation"]; + [KMSentryHelper addInfoBreadCrumb:@"lifecycle" message:@"hiding OSK on input method deactivation"]; [self.oskWindow.window setIsVisible:NO]; } else { os_log_debug([KMLogs oskLog], "***KMInputMethodAppDelegate inputMethodDeactivated, OSK already hidden"); @@ -160,7 +160,7 @@ id _lastServerWithOSKShowing = nil; if (_kvk != nil && ([KMInputMethodLifecycle.shared shouldShowOskOnActivate])) { os_log_debug([KMLogs oskLog], "***KMInputMethodAppDelegate inputMethodActivated, showing OSK"); - [KMSentryHelper addBreadCrumb:@"lifecycle" message:@"opening OSK on input method activation"]; + [KMSentryHelper addInfoBreadCrumb:@"lifecycle" message:@"opening OSK on input method activation"]; [self showOSK]; } } @@ -347,7 +347,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef os_log_debug([KMLogs eventsLog], "*** kKeymanEventKeyCode = 0xFF"); } else { if ([OSKView isOskKeyDownEvent:event]) { - [KMSentryHelper addBreadCrumb:@"event" message:@"processing OSK-generated keydown event"]; + [KMSentryHelper addInfoBreadCrumb:@"event" message:@"processing OSK-generated keydown event"]; NSEventModifierFlags oskEventModifiers = [OSKView extractModifierFlagsFromOskEvent:event]; appDelegate.receivedKeyDownFromOsk = YES; appDelegate.oskEventModifiers = oskEventModifiers; @@ -438,7 +438,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef CoreKeyboardInfo *keyboardInfo = [self.kme loadKeyboardFromKmxFile:kmx]; os_log_info([KMLogs keyboardLog], "loadKeyboardFromKmxFile, keyboard info: %{public}@", keyboardInfo); - [KMSentryHelper addBreadCrumb:@"configure" message:[NSString stringWithFormat:@"loadKeyboardFromKmxFile: %@", [self getKmxFileName]]]; + [KMSentryHelper addInfoBreadCrumb:@"configure" message:[NSString stringWithFormat:@"loadKeyboardFromKmxFile: %@", [self getKmxFileName]]]; [KMSentryHelper addKeyboardTag:[self getKmxFileName]]; _modifierMapping = [[KMModifierMapping alloc] init:keyboardInfo]; @@ -864,7 +864,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef [self setSelectedKeyboard:keyboardName]; [self setContextBuffer:nil]; - [KMSentryHelper addBreadCrumb:@"startup" message:[NSString stringWithFormat:@"setDefaultSelectedKeyboard: %@", keyboardName]]; + [KMSentryHelper addInfoBreadCrumb:@"startup" message:[NSString stringWithFormat:@"setDefaultSelectedKeyboard: %@", keyboardName]]; } - (void) addKeyboardPlaceholderMenuItem { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m index fcb381013e..d4ab67d10f 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m @@ -46,7 +46,7 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; _apiCompliance = [[TextApiCompliance alloc]initWithClient:sender applicationId:clientAppId]; os_log_info([KMLogs lifecycleLog], "KMInputMethodEventHandler initWithClient, clientAppId: %{public}@", clientAppId); - [KMSentryHelper addBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"KMInputMethodEventHandler initWithClient, clientAppId '%@'", clientAppId]]; + [KMSentryHelper addInfoBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"KMInputMethodEventHandler initWithClient, clientAppId '%@'", clientAppId]]; [KMSentryHelper addClientAppIdTag:clientAppId]; return self; @@ -167,7 +167,7 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; */ - (void)handleBackspace:(NSEvent *)event { os_log_debug([KMLogs eventsLog], "KMInputMethodEventHandler handleBackspace, event = %{public}@", event); - [KMSentryHelper addBreadCrumb:@"user" message:@"handle backspace for non-compliant app"]; + [KMSentryHelper addInfoBreadCrumb:@"user" message:@"handle backspace for non-compliant app"]; if (self.generatedBackspaceCount > 0) { self.generatedBackspaceCount--; @@ -441,7 +441,7 @@ CGEventSourceRef _sourceForGeneratedEvent = nil; NSString *value = [options objectForKey:key]; if(key && value) { os_log_debug([KMLogs keyLog], "persistOptions, key: %{public}@, value: %{public}@", key, value); - [KMSentryHelper addBreadCrumb:@"event" message:@"persist options"]; + [KMSentryHelper addInfoBreadCrumb:@"event" message:@"persist options"]; [[KMSettingsRepository shared] writeOptionForSelectedKeyboard:key withValue:value]; } else { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m index 6c98c17b3c..ba53d9ffa6 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m @@ -199,7 +199,7 @@ typedef enum { break; case Activate: os_log_info([KMLogs lifecycleLog], "performTransition: Activate, new application ID: %{public}@", currentClientAppId); - [KMSentryHelper addBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"activated input method '%@' for application ID '%@'", currentInputSource, currentClientAppId]]; + [KMSentryHelper addInfoBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"activated input method '%@' for application ID '%@'", currentInputSource, currentClientAppId]]; /** * Perform two actions when activating the input method. * Change the client first which prepares the event handler. @@ -210,12 +210,12 @@ typedef enum { break; case Deactivate: os_log_info([KMLogs lifecycleLog], "performTransition: Deactivate, new InputSourceId: %{public}@, new application ID: %{public}@", currentInputSource, currentClientAppId); - [KMSentryHelper addBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"deactivated input method '%@' for application ID '%@'", currentInputSource, currentClientAppId]]; + [KMSentryHelper addInfoBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"deactivated input method '%@' for application ID '%@'", currentInputSource, currentClientAppId]]; [self deactivateInputMethod]; break; case ChangeClients: os_log_info([KMLogs lifecycleLog], "performTransition: ChangeClients, new InputSourceId: %{public}@, new application ID: %{public}@", currentInputSource, currentClientAppId); - [KMSentryHelper addBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"change clients for input method '%@' to application ID '%@'", currentInputSource, currentClientAppId]]; + [KMSentryHelper addInfoBreadCrumb:@"lifecycle" message:[NSString stringWithFormat:@"change clients for input method '%@' to application ID '%@'", currentInputSource, currentClientAppId]]; [self changeClient]; break; } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h index adbce67a53..8a7d458967 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h @@ -1,5 +1,5 @@ /* - * Keyman is copyright (C) SIL International. MIT License. + * Keyman is copyright (C) SIL Global. MIT License. * * Created by Shawn Schantz on 2025-01-13. * @@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN + (void)addKeyboardTag:(NSString *)value; + (void)addHasAccessibilityTag:(BOOL)value; + (void)addActiveKeyboardCountTag:(NSUInteger)value; -+ (void)addBreadCrumb:(NSString *)category message:(NSString *)messageText; ++ (void)addInfoBreadCrumb:(NSString *)category message:(NSString *)messageText; + (void)addDebugBreadCrumb:(NSString *)category message:(NSString *)messageText; + (void)addUserBreadCrumb:(NSString *)category message:(NSString *)messageText; + (void)addDetailedBreadCrumb:(NSString *)category message:(NSString *)messageText data:( NSDictionary *) map; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m index b28e0b5b76..7c37be9ad9 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.m @@ -1,5 +1,5 @@ /* - * Keyman is copyright (C) SIL International. MIT License. + * Keyman is copyright (C) SIL Global. MIT License. * * Created by Shawn Schantz on 2025-01-13. * @@ -53,7 +53,7 @@ NSString * const kLifecycleStateTagName = @"lifecycleState"; } /** - *assign custom keyboard tag in Sentry to initial keyboard + *assign custom keyboard tag in Sentry for the given name and value */ + (void)addCustomTag:(NSString *)tagName withValue:(NSString *)value { [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { @@ -61,7 +61,10 @@ NSString * const kLifecycleStateTagName = @"lifecycleState"; }]; } -+ (void)addBreadCrumb:(NSString *)category message:(NSString *)messageText { +/** + *add a Sentry breadcrumb message of level Info with the specified category + */ ++ (void)addInfoBreadCrumb:(NSString *)category message:(NSString *)messageText { SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; crumb.level = kSentryLevelInfo; crumb.category = category; @@ -69,6 +72,9 @@ NSString * const kLifecycleStateTagName = @"lifecycleState"; [SentrySDK addBreadcrumb:crumb]; } +/** + *add a Sentry breadcrumb message of level debug with the specified category + */ + (void)addDebugBreadCrumb:(NSString *)category message:(NSString *)messageText { SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; crumb.level = kSentryLevelDebug; @@ -77,6 +83,9 @@ NSString * const kLifecycleStateTagName = @"lifecycleState"; [SentrySDK addBreadcrumb:crumb]; } +/** + *add a Sentry breadcrumb message of type 'user' and level debug with the specified category + */ + (void)addUserBreadCrumb:(NSString *)category message:(NSString *)messageText { SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; crumb.type = @"user"; @@ -86,13 +95,4 @@ NSString * const kLifecycleStateTagName = @"lifecycleState"; [SentrySDK addBreadcrumb:crumb]; } -+ (void)addDetailedBreadCrumb:(NSString *)category message:(NSString *)messageText data:( NSDictionary *) map { - SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; - crumb.level = kSentryLevelInfo; - crumb.category = category; - crumb.message = messageText; - crumb.data = map; - [SentrySDK addBreadcrumb:crumb]; -} - @end From 4ea79bcbead252af338bfd8216fd046d2612ccc1 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 27 Jan 2025 09:44:45 +0700 Subject: [PATCH 132/155] chore(common): Update crowdin strings for Spanish (Latin America) --- .../src/main/res/values-b+es+419/strings.xml | 17 ++++++-- .../src/main/res/values-b+es+419/strings.xml | 13 +++++-- .../es-419.lproj/Localizable.strings | 18 +++++++++ .../desktop/kmshell/locale/es-419/strings.xml | 39 +++++++++++++++++-- 4 files changed, 77 insertions(+), 10 deletions(-) diff --git a/android/KMAPro/kMAPro/src/main/res/values-b+es+419/strings.xml b/android/KMAPro/kMAPro/src/main/res/values-b+es+419/strings.xml index bc75863cb5..856c14c922 100644 --- a/android/KMAPro/kMAPro/src/main/res/values-b+es+419/strings.xml +++ b/android/KMAPro/kMAPro/src/main/res/values-b+es+419/strings.xml @@ -53,6 +53,7 @@ Para instalar los paquetes del teclado, permite que Keyman acceda al almacenamiento externo. Se ha denegado la solicitud de permiso de almacenamiento. La instalación del paquete de teclado podría fallar + Falló la solicitud de permiso de almacenamiento. Seleccione Configuración de Keyman - Instalar desde archivo local Configuración @@ -67,6 +68,8 @@ Ajustar la altura del teclado + Adjust longpress delay + Leyenda de barra espaciadora Teclado @@ -86,11 +89,11 @@ No mostrar leyenda en la barra espaciadora Vibrar al escribir - + Mostrar siempre el banner - + A implementar - + Cuando está desactivado, solo se muestra cuando el texto predictivo está habilitado Permitir el envío de informes de fallas a través de la red @@ -122,6 +125,14 @@ Rota el dispositivo para ajustar el modo vertical y horizontal Restaurar valores predeterminados + + Delay Time: %1$.1f seconds + + Delay time longer + + Delay time shorter + + Longpress delay time slider Buscar o escribir una dirección web diff --git a/android/KMEA/app/src/main/res/values-b+es+419/strings.xml b/android/KMEA/app/src/main/res/values-b+es+419/strings.xml index 8cefeeeefd..c0bd0412ed 100644 --- a/android/KMEA/app/src/main/res/values-b+es+419/strings.xml +++ b/android/KMEA/app/src/main/res/values-b+es+419/strings.xml @@ -107,7 +107,7 @@ La descarga del diccionario inició en segundo plano El diccionario seleccionado ya se está descargando; inténtalo de nuevo en un momento. - + La descarga del diccionario ha finalizado. Error al descargar @@ -119,7 +119,7 @@ "¡Todos los recursos están actualizados!" ¡Uno o más recursos no se han actualizado! - + ¡Recursos actualizados correctamente! Versión del diccionario @@ -133,10 +133,15 @@ Teclado %1$s instalado Teclado borrado - + Habilitar correcciones - + Habilitar predicciones + + Desactivar sugerencias + Sólo predicciones + Predicciones con correcciones + Predicciones con autocorrecciones Diccionario diff --git a/ios/engine/KMEI/KeymanEngine/es-419.lproj/Localizable.strings b/ios/engine/KMEI/KeymanEngine/es-419.lproj/Localizable.strings index e94c1e7da6..756eb0a49b 100644 --- a/ios/engine/KMEI/KeymanEngine/es-419.lproj/Localizable.strings +++ b/ios/engine/KMEI/KeymanEngine/es-419.lproj/Localizable.strings @@ -226,6 +226,24 @@ /* Text showing name of spacebar caption - language + keyboard */ "menu-settings-spacebar-item-languageKeyboard" = "Idioma y teclado"; +/* Label for the "Adjust Keyboard Height" item on the main settings screen */ +"menu-settings-adjust-keyboard-height" = "Ajustar altura del teclado"; + +/* Title for the "Adjust Keyboard Height" settings child screen */ +"adjust-keyboard-height-title" = "Ajustar teclado"; + +/* Label for "Reset to Default Keyboard Height" button on the adjust height screen */ +"button-label-reset-default-keyboard-height" = "Restablecer altura de teclado predeterminada"; + +/* Instruction text to drag keyboard to resize */ +"keyboard-drag-instructions" = "Arrastre el control de flecha para ajustar la altura del teclado."; + +/* Instruction to rotate to adjust landscape keyboard height (displayed when device is portrait) */ +"portrait-keyboard-rotate-instructions" = "Gire el dispositivo para pasar al modo horizontal."; + +/* Instruction to rotate to adjust portrait keyboard height (displayed when device is landscape) */ +"landscape-keyboard-rotate-instructions" = "Gire el dispositivo para pasar al modo vertical."; + /* Short text for notification: download failure for keyboard */ "notification-download-failure-keyboard" = "Error al descargar el teclado"; diff --git a/windows/src/desktop/kmshell/locale/es-419/strings.xml b/windows/src/desktop/kmshell/locale/es-419/strings.xml index 9d5f2a3696..24ef2431e7 100644 --- a/windows/src/desktop/kmshell/locale/es-419/strings.xml +++ b/windows/src/desktop/kmshell/locale/es-419/strings.xml @@ -295,6 +295,10 @@ Simular AltGr con Ctrl+Alt + + Allow right modifier for hotkeys + + Tratar las teclas muertas de hardware como teclas simples @@ -323,6 +327,10 @@ Mostrar pantalla de bienvenida + + Buscar actualizaciones y descargar automáticamente + + Buscar actualizaciones automáticamente en keyman.com cada semana @@ -420,6 +428,14 @@ Derechos de autor © SIL International. Todos los derechos reservados. + + Creado por %1$s + + + + Derechos de autor © %1$s. Todos los derechos reservados. + + Versión @@ -537,6 +553,10 @@ El atajo de teclado %1$s entra en conflicto con otro atajo de teclado. Si continúas, se eliminará el otro atajo. ¿Continuar\? + + Actualizar + + Componentes de Keyman actualizados disponibles @@ -606,16 +626,27 @@ Sa&lir de la búsqueda de actualizaciones en línea + + + + Aplicar actualización ahora + + + + Buscar nuevas actualizaciones - Keyman Iniciar Keyman + + Iniciar %1$s + + Salir @@ -657,7 +688,6 @@ - Keyman @@ -781,7 +811,6 @@ - Keyman @@ -904,6 +933,10 @@ Selecciona un teclado de Keyman para encontrar fuentes relacionadas. + + + + No se encontró ninguna fuente recomendada para el Teclado %1$s. From 938d3ab61e6c8a6a6580624fbdf6623f1bd350cc Mon Sep 17 00:00:00 2001 From: sgschantz Date: Mon, 27 Jan 2025 12:30:18 +0700 Subject: [PATCH 133/155] fix(mac): OSK window default state must be not visible to be certain that it only opens due to settings or in response to a user action --- mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m | 7 +++++-- mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m | 5 ++--- .../Keyman4MacIM/OnScreenKeyboard/OSKWindowController.xib | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 73afb9271d..87abd97864 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -148,7 +148,7 @@ id _lastServerWithOSKShowing = nil; } /** - * When the input method is activated, show the OSK and enable the low-level event tap + * When the input method is activated, enable the low-level event tap and show the OSK */ - (void)inputMethodActivated:(NSNotification *)notification { if (self.lowLevelEventTap && !CGEventTapIsEnabled(self.lowLevelEventTap)) { @@ -966,8 +966,11 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef } - (NSWindowController *)oskWindow { - if (!_oskWindow) + if (!_oskWindow) { _oskWindow = [[OSKWindowController alloc] initWithWindowNibName:@"OSKWindowController"]; + + os_log_debug([KMLogs oskLog], "Loaded oskWindow from Nib, isVisible: %{public}@ readShowOskOnActivate: %{public}@", [_oskWindow.window isVisible]?@"true":@"false", [KMSettingsRepository.shared readShowOskOnActivate]?@"true":@"false"); + } return _oskWindow; } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m index 6c98c17b3c..176906492f 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodLifecycle.m @@ -278,11 +278,10 @@ typedef enum { } /** - * Returns true if lifecycleState is Active and the Settings require us to show the OSK + * Returns true the Settings require us to show the OSK on activation */ - (BOOL)shouldShowOskOnActivate { - return [KMSettingsRepository.shared readShowOskOnActivate] - && (self.lifecycleState == Active); + return [KMSettingsRepository.shared readShowOskOnActivate]; } @end diff --git a/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.xib b/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.xib index b753e43802..6a55541cb5 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.xib +++ b/mac/Keyman4MacIM/Keyman4MacIM/OnScreenKeyboard/OSKWindowController.xib @@ -14,7 +14,7 @@ - + From e5820f532237812b63c32e7a103a57020dd3d920 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Mon, 27 Jan 2025 12:52:41 +0700 Subject: [PATCH 134/155] chore(mac): remove extraneous code --- .../KMConfiguration/KMConfigurationWindowController.m | 4 +--- .../KMDownloadKeyboard/KMDownloadKBWindowController.m | 1 - mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m index 8a35afd31c..2b06db4cad 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m @@ -418,12 +418,10 @@ if ([info objectForKey:@"HeaderTitle"] != nil) { keyboardName = [info objectForKey:@"HeaderTitle"]; - [self.deleteAlertView setMessageText:[NSString localizedStringWithFormat:deleteKeyboardMessage, keyboardName]]; } else { keyboardName = [info objectForKey:kKMKeyboardNameKey]; - [self.deleteAlertView setMessageText:[NSString localizedStringWithFormat:deleteKeyboardMessage, keyboardName]]; } - + [self.deleteAlertView setMessageText:[NSString localizedStringWithFormat:deleteKeyboardMessage, keyboardName]]; os_log_debug([KMLogs configLog], "entered removeAction for keyboardName: %{public}@", keyboardName); [self.deleteAlertView beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDownloadKeyboard/KMDownloadKBWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDownloadKeyboard/KMDownloadKBWindowController.m index 2fec9f8b32..4b5ce44dea 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDownloadKeyboard/KMDownloadKBWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDownloadKeyboard/KMDownloadKBWindowController.m @@ -9,7 +9,6 @@ #import "KMDownloadKBWindowController.h" #import "KMInputMethodAppDelegate.h" #import "KMLogs.h" -#import "KMSentryHelper.h" @interface KMDownloadKBWindowController () @property (nonatomic, weak) IBOutlet WebView *webView; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h index 8a7d458967..75a5c27282 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/Logging/KMSentryHelper.h @@ -22,7 +22,6 @@ NS_ASSUME_NONNULL_BEGIN + (void)addInfoBreadCrumb:(NSString *)category message:(NSString *)messageText; + (void)addDebugBreadCrumb:(NSString *)category message:(NSString *)messageText; + (void)addUserBreadCrumb:(NSString *)category message:(NSString *)messageText; -+ (void)addDetailedBreadCrumb:(NSString *)category message:(NSString *)messageText data:( NSDictionary *) map; @end From e1d98dfdba912a6654e90ee033421689cb484cfd Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 27 Jan 2025 13:47:29 +0700 Subject: [PATCH 135/155] chore: adjust bookmark links in developer docs --- .../advanced/unicode-breaker-extension.md | 16 +++++++-------- .../lexical-models/advanced/word-breaker.md | 6 +++--- .../help/reference/file-types/metadata.md | 20 +++++++++---------- .../docs/help/reference/file-types/tsv.md | 2 +- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/developer/docs/help/guides/lexical-models/advanced/unicode-breaker-extension.md b/developer/docs/help/guides/lexical-models/advanced/unicode-breaker-extension.md index a9e4d3776c..100f523acf 100644 --- a/developer/docs/help/guides/lexical-models/advanced/unicode-breaker-extension.md +++ b/developer/docs/help/guides/lexical-models/advanced/unicode-breaker-extension.md @@ -23,16 +23,16 @@ the specification itself. There are three ways - all of them optional - to extend and customize the word-breaking rules themselves: -* If you need to prevent splits in very specific scenarios and/or add splits in other specific scenarios, you may specify [context-based rules](#rules) to obtain the desired behavior. +* If you need to prevent splits in very specific scenarios and/or add splits in other specific scenarios, you may specify [context-based rules](#toc-custom-word-breaking-rules) to obtain the desired behavior. * If certain characters are not handled appropriately for their role in - your language, you may [map characters](#map) to different + your language, you may [map characters](#toc-character-property-remapping) to different word-breaking character classes - including custom ones. This will override the default property they are assigned by the default implementation, with the new property applying for all word-breaking rules. * If the default word-breaking classes from the specification are too general for certain aspects of your language, it is possible to - [define custom character classes](#define) for use in custom + [define custom character classes](#toc-defining-and-using-new-word-breaking-properties) for use in custom rules. ## A first example @@ -183,7 +183,7 @@ the potential boundary. ### Word-breaking property names The names used in each array must be defined in one of the following places: * https://unicode.org/reports/tr29/#Table_Word_Break_Property_Values -* `customProperties` - your [declaration of any custom property types](#define) +* `customProperties` - your [declaration of any custom property types](#toc-defining-and-using-new-word-breaking-properties) * One of the special property types `"Other"`, `"sot"`, or `"eot"`: * `Other`: a character without an associated word-breaking property value * `sot`: "start of text" - a marker indicating the beginning of the string being word-broken @@ -277,7 +277,7 @@ As noted at the top of the file: ### Redefining character properties -Of note from [our first example](#example): +Of note from [our first example](#toc-a-first-example): ```typescript /*** Character class overrides for specific characters ***/ @@ -324,7 +324,7 @@ words (and/or names) in some languages. Default word-breaking behavior will spl hyphenated words and names apart, but by changing the property of hyphens, it is possible to disable this behavior. -Noting [rule WB6](#WB6) and WB7, the `MidLetter` class is designed to prevent +Noting [rule WB6](#toc-custom-word-breaking-rules) and WB7, the `MidLetter` class is designed to prevent word-breaks from occurring when its characters lie directly between letters - hence the property name. Assigning hyphens to this class can provide the desired behavior. @@ -364,7 +364,7 @@ the second example above. (After all, `can'` could be the end of a quoted phrase in English - `'sure you can'` - in which case we might want the split to occur.) -Revisiting [an earlier example](#example) and simplifying a little bit: +Revisiting [an earlier example](#toc-redefining-character-properties) and simplifying a little bit: ```typescript /*** Definition of extra word-breaking rules ***/ @@ -440,7 +440,7 @@ included a couple of extra rules: } ``` -By replicating [WB6](#WB6) and WB7's structure and allowing `Hyphen` to match in the same +By replicating [WB6](#toc-custom-word-breaking-rules) and WB7's structure and allowing `Hyphen` to match in the same position as `MidLetter` in the original rules, we can prevent word-breaking splits after additional text has been typed after a `Hyphen`-property character. This does not _replace_ the behavior of WB6 and WB7 - it merely _extends_ it to include the new property. diff --git a/developer/docs/help/guides/lexical-models/advanced/word-breaker.md b/developer/docs/help/guides/lexical-models/advanced/word-breaker.md index f8f321327a..1b5881f823 100644 --- a/developer/docs/help/guides/lexical-models/advanced/word-breaker.md +++ b/developer/docs/help/guides/lexical-models/advanced/word-breaker.md @@ -13,9 +13,9 @@ However, in languages written in other scripts — especially East Asian scripts like Chinese, Japanese, Khmer, Lao, and Thai — there are no obvious break in between words. For these languages, there must be special rules for determining when words start and stop. This is what a _word breaker function_ is responsible for. It is a little bit of code that looks at some text to determine where the words are. You can customize the word breaker in three ways: -- If your language uses its writing system in an unconventional way (e.g., use spaces to separate words in Thai, Lao, Burmese, or Khmer), you can [override the script's default behaviour](#overrides) -- If the default word breaker creates **too many splits**, you can [choose which strings join words together](#join). -- If the default word breaker creates **not enough splits**, you must [create your own word breaker function](#custom). +- If your language uses its writing system in an unconventional way (e.g., use spaces to separate words in Thai, Lao, Burmese, or Khmer), you can [override the script's default behaviour](#toc-overriding-script-defaults) +- If the default word breaker creates **too many splits**, you can [choose which strings join words together](#toc-customize-joining-rules). +- If the default word breaker creates **not enough splits**, you must [create your own word breaker function](#toc-writing-a-custom-word-breaker-function). - Alternatively, you may choose to [customize and extend the wordbreaker's behavior](./unicode-breaker-extension) by adding extra rules and changing how it treats specific characters. ## Overriding script defaults diff --git a/developer/docs/help/reference/file-types/metadata.md b/developer/docs/help/reference/file-types/metadata.md index 1a0d631820..59d30375dc 100644 --- a/developer/docs/help/reference/file-types/metadata.md +++ b/developer/docs/help/reference/file-types/metadata.md @@ -38,25 +38,25 @@ The kmp.json file is a base object described as : `Object` - [`System`](#obj-system) object. + [`System`](#toc-the-system-object) object. `options` : `Object` - An [`Options`](#obj-options) object. + An [`Options`](#toc-the-options-object) object. `startMenu` : `Object` - [`Start Menu`](#obj-startMenu) object. + [`Start Menu`](#toc-the-start-menu-object) object. `info` : `Object` - [`Info`](#obj-info) object. + [`Info`](#toc-the-info-object) object. `files` @@ -69,13 +69,13 @@ The kmp.json file is a base object described as : `Object` - Array of [`Keyboard`](#obj-keyboard) objects. + Array of [`Keyboard`](#toc-the-keyboard-object) objects. `lexicalModels` : `Object` - Array of [`LexicalModel`](#obj-lexicalModel) objects. + Array of [`LexicalModel`](#toc-the-lexicalmodel-object) objects. ### The System object @@ -139,7 +139,7 @@ The `StartMenu` object is used by Keyman Desktop to install windows : `Array` - An array of [Item](#obj-item) objects + An array of [Item](#toc-the-item-object) objects ### The Item Object @@ -229,7 +229,7 @@ The `Keyboard` object describes an individual keyboard in the Keyman package. A : `Array` - An array of [`Language`](#obj-language) objects linked to the keyboard. + An array of [`Language`](#toc-the-language-object) objects linked to the keyboard. `displayFont` @@ -247,7 +247,7 @@ The `Keyboard` object describes an individual keyboard in the Keyman package. A : `Array` - An array of [`Example`](#obj-example) objects linked to the keyboard. + An array of [`Example`](#toc-the-example-object) objects linked to the keyboard. ### The Language object @@ -342,4 +342,4 @@ The `LexicalModel` object describes an individual model in the Keyman package. A : `Array` - An array of [`Language`](#obj-language) objects linked to the model. + An array of [`Language`](#toc-the-language-object) objects linked to the model. diff --git a/developer/docs/help/reference/file-types/tsv.md b/developer/docs/help/reference/file-types/tsv.md index b926ed9572..1e82d62981 100644 --- a/developer/docs/help/reference/file-types/tsv.md +++ b/developer/docs/help/reference/file-types/tsv.md @@ -16,7 +16,7 @@ Details: Spreadsheet programs such as Microsoft Excel and Google Sheets can export into TSV format. TSVs can also be programmatically generated from other data sources. For advanced users, see [File - Format](#file-format) for more details. + Format](#toc-file-format) for more details. Distributed with lexical model: : No. This is a development file and should not be distributed. From dfa51b003cd8f2d119dc6cceeaf110f731d77ece Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 27 Jan 2025 14:00:49 +0700 Subject: [PATCH 136/155] chore: adjust one bookmark link in windows doc --- windows/docs/help/start/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/docs/help/start/tutorial.md b/windows/docs/help/start/tutorial.md index dd09de98db..7eaf4bd00a 100644 --- a/windows/docs/help/start/tutorial.md +++ b/windows/docs/help/start/tutorial.md @@ -16,7 +16,7 @@ it is running you will see the Keyman icon: ## Step 2 If the Keyman icon is in the Windows Taskbar near the clock, continue on -to [Step 5](#step-5-). +to [Step 5](#toc-step-5). ![](../desktop_images/start_tray.png) From 5d2d740cb0611a645650072f0488a5de123af5d8 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Mon, 27 Jan 2025 12:59:30 +0700 Subject: [PATCH 137/155] fix(web): always return error for keyboard stub Cloud API error states Fixes: #13043 Fixes: KEYMAN-COM-1BN Fixes: HELP-KEYMAN-COM-DCA --- .../keyboard-storage/src/cloud/queryEngine.ts | 18 +++++++++--------- .../src/keyboardRequisitioner.ts | 5 +++-- .../keyboard-storage/src/keyboardStub.ts | 12 +++++++++++- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/web/src/engine/keyboard-storage/src/cloud/queryEngine.ts b/web/src/engine/keyboard-storage/src/cloud/queryEngine.ts index 5f38c32aea..49d2179e08 100644 --- a/web/src/engine/keyboard-storage/src/cloud/queryEngine.ts +++ b/web/src/engine/keyboard-storage/src/cloud/queryEngine.ts @@ -2,7 +2,7 @@ import { EventEmitter } from 'eventemitter3'; import { PathConfiguration } from 'keyman/engine/interfaces'; -import { default as KeyboardStub, ErrorStub, KeyboardAPISpec, mergeAndResolveStubPromises } from '../keyboardStub.js'; +import { default as KeyboardStub, ErrorStub, KeyboardAPISpec } from '../keyboardStub.js'; import { LanguageAPIPropertySpec, ManagedPromise, Version } from 'keyman/engine/keyboard'; import CloudRequesterInterface from './requesterInterface.js'; @@ -310,7 +310,7 @@ export default class CloudQueryEngine extends EventEmitter { * @param x keyboard name string or keyboard metadata JSON object * @returns resolved or rejected promise with merged array of stubs. */ - async fetchCloudStubs(cloudList: string[]): Promise<(KeyboardStub|ErrorStub)[]> { + async fetchCloudStubs(cloudList: string[]): Promise<(KeyboardStub)[]> { // // Ensure keymanweb is initialized before continuing to add keyboards // if(!this.keymanweb.initialized) { // await this.deferment; @@ -328,17 +328,17 @@ export default class CloudQueryEngine extends EventEmitter { comma=','; } - let errorStubs: ErrorStub[] = []; // Request keyboard metadata from the Keyman Cloud keyboard metadata server try { - let result: (KeyboardStub|ErrorStub)[]|Error = await this.keymanCloudRequest(cmd,false); - return mergeAndResolveStubPromises(result, errorStubs); + return await this.keymanCloudRequest(cmd,false); } catch(err) { // We don't have keyboard info for this ErrorStub - console.error(err); - let stub: ErrorStub = {error: err}; - errorStubs.push(stub); - return Promise.reject(errorStubs); + if(err instanceof Error) { + console.error(`Error for request command-string ${cmd}: ${err.message}\n ${err.stack}`); + } else { + console.error(err); + } + return Promise.reject(err); } } } \ No newline at end of file diff --git a/web/src/engine/keyboard-storage/src/keyboardRequisitioner.ts b/web/src/engine/keyboard-storage/src/keyboardRequisitioner.ts index fb2807de6f..5ca184b217 100644 --- a/web/src/engine/keyboard-storage/src/keyboardRequisitioner.ts +++ b/web/src/engine/keyboard-storage/src/keyboardRequisitioner.ts @@ -18,6 +18,7 @@ import { toUnprefixedKeyboardId as unprefixed } from "./index.js"; import { default as CloudRequesterInterface } from "./cloud/requesterInterface.js"; +import { rejectErrorStubs } from "./keyboardStub.js"; class CloudRequestEntry { id: string; @@ -287,7 +288,7 @@ export default class KeyboardRequisitioner { if(cmd == '') { // No command so return errors - return Promise.reject(errorStubs); + return rejectErrorStubs(errorStubs); } return this.cloudQueryEngine.keymanCloudRequest('&keyboardid='+cmd, false).then(async (result) => { @@ -305,7 +306,7 @@ export default class KeyboardRequisitioner { console.error(err); let stub: ErrorStub = {error: err}; errorStubs.push(stub); - return Promise.reject(errorStubs); + return rejectErrorStubs(errorStubs); }); } diff --git a/web/src/engine/keyboard-storage/src/keyboardStub.ts b/web/src/engine/keyboard-storage/src/keyboardStub.ts index a2b1d87d6f..b2dfc32a88 100644 --- a/web/src/engine/keyboard-storage/src/keyboardStub.ts +++ b/web/src/engine/keyboard-storage/src/keyboardStub.ts @@ -205,12 +205,22 @@ export interface ErrorStub { error: Error; } +export function rejectErrorStubs(errorStubs: ErrorStub[]) { + if(errorStubs.length > 1) { + const msgs = errorStubs.map((entry) => `${entry.error.message}:\n ${entry.error.stack ?? ''}`); + return Promise.reject(new Error(msgs.join('\n\n'))); + } else { + // The messages for errors we'd return here should already include data about their triggering request. + return Promise.reject(errorStubs[0].error); + } +} + export function mergeAndResolveStubPromises(keyboardStubs: (KeyboardStub|ErrorStub)[], errorStubs: ErrorStub[]) : Promise<(KeyboardStub|ErrorStub)[]> { if (errorStubs.length == 0) { return Promise.resolve(keyboardStubs); } if (keyboardStubs.length == 0) { - return Promise.reject(errorStubs); + return rejectErrorStubs(errorStubs); } else { // Merge this with errorStubs let result: (KeyboardStub|ErrorStub)[] = keyboardStubs; From 9ec66664535daeb41e2c69541f661fd47e60b22a Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Mon, 27 Jan 2025 12:59:54 +0700 Subject: [PATCH 138/155] change(web): adjust keyboard-error page for testing prior commit's changes --- .../manual/web/sentry-integration/errorhdr.js | 78 +++++++++++-------- .../manual/web/sentry-integration/index.html | 4 + 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/web/src/test/manual/web/sentry-integration/errorhdr.js b/web/src/test/manual/web/sentry-integration/errorhdr.js index b784f6a476..8cab6d4da7 100644 --- a/web/src/test/manual/web/sentry-integration/errorhdr.js +++ b/web/src/test/manual/web/sentry-integration/errorhdr.js @@ -4,39 +4,49 @@ This script is designed to test KeymanWeb error message handling. */ - function loadKeyboards() - { - var kmw=keyman; +function loadKeyboards() { + var kmw=keyman; + + // We start by adding a keyboard correctly. It's best to include a 'control' in our experiment. + kmw.addKeyboards({id:'us',name:'English',languages:{id:'en',name:'English'}, + filename:'../us-1.0.js'}); - // We start by adding a keyboard correctly. It's best to include a 'control' in our experiment. - kmw.addKeyboards({id:'us',name:'English',languages:{id:'en',name:'English'}, - filename:'../us-1.0.js'}); - - // Insert a keyboard that cannot be found. - kmw.addKeyboards({id:'lao_2008_basic',name:'wrong-filename', - languages:{ - id:'lo',name:'debugging',region:'Asia', - font:{family:'LaoWeb',source:['../font/saysettha_web.ttf','../font/saysettha_web.woff','../font/saysettha_web.eot']} - }, - filename:'./missing_file.js' // Intentional error - the file doesn't exist, so the