From d488f22fd9590c55af7fd1c97ac6b8b3f792f5fb Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Mon, 21 Aug 2023 10:42:06 +0700 Subject: [PATCH 001/107] feat(web): browser-KMW support for default subkeys --- .../src/keyboards/activeLayout.ts | 6 + .../src/keyboards/defaultLayouts.ts | 1 + .../src/input/gestures/browser/subkeyPopup.ts | 13 +- .../engine/osk/src/keyboard-layout/oskKey.ts | 1 + .../web/default-subkey/default_subkey.js | 1 + .../test/manual/web/default-subkey/index.html | 99 +++ .../web/default-subkey/kbd_source/HISTORY.md | 6 + .../web/default-subkey/kbd_source/LICENSE.md | 21 + .../web/default-subkey/kbd_source/README.md | 30 + .../kbd_source/default_subkey.keyboard_info | 7 + .../kbd_source/default_subkey.kpj | 110 +++ .../kbd_source/source/default_subkey.ico | Bin 0 -> 1150 bytes .../source/default_subkey.keyman-touch-layout | 717 ++++++++++++++++++ .../kbd_source/source/default_subkey.kmn | 16 + .../kbd_source/source/default_subkey.kps | 65 ++ .../kbd_source/source/default_subkey.kvks | 8 + .../kbd_source/source/readme.htm | 24 + .../kbd_source/source/welcome.htm | 26 + web/src/test/manual/web/index.html | 1 + 19 files changed, 1145 insertions(+), 7 deletions(-) create mode 100644 web/src/test/manual/web/default-subkey/default_subkey.js create mode 100644 web/src/test/manual/web/default-subkey/index.html create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/HISTORY.md create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/LICENSE.md create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/README.md create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/default_subkey.keyboard_info create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/default_subkey.kpj create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.ico create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.keyman-touch-layout create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kmn create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kps create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kvks create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/source/readme.htm create mode 100644 web/src/test/manual/web/default-subkey/kbd_source/source/welcome.htm diff --git a/common/web/keyboard-processor/src/keyboards/activeLayout.ts b/common/web/keyboard-processor/src/keyboards/activeLayout.ts index e6d2ab9f15..9050d393a1 100644 --- a/common/web/keyboard-processor/src/keyboards/activeLayout.ts +++ b/common/web/keyboard-processor/src/keyboards/activeLayout.ts @@ -48,6 +48,12 @@ export class ActiveKey implements LayoutKey { _baseKeyEvent: KeyEvent; isMnemonic: boolean = false; + /** + * Only available on subkeys, but we don't distinguish between base keys and subkeys + * at this level yet in KMW. + */ + default?: boolean; + proportionalPad: number; proportionalX: number; proportionalWidth: number; diff --git a/common/web/keyboard-processor/src/keyboards/defaultLayouts.ts b/common/web/keyboard-processor/src/keyboards/defaultLayouts.ts index 8d187ac854..7e0153d0a5 100644 --- a/common/web/keyboard-processor/src/keyboards/defaultLayouts.ts +++ b/common/web/keyboard-processor/src/keyboards/defaultLayouts.ts @@ -22,6 +22,7 @@ export type LayoutKey = { "nextlayer"?: string, "pad"?: string | number, "sk"?: LayoutKey[] + "default"?: boolean } export type LayoutRow = { diff --git a/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts b/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts index e36b24b0e8..9d7f003000 100644 --- a/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts +++ b/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts @@ -219,25 +219,24 @@ export default class SubkeyPopup implements RealizedGesture { let skElement = popupBase.childNodes[i].firstChild; // Preference order: - // #1: if a default subkey has been specified, select it. (pending, for 15.0+) + // #1: if a default subkey has been specified, select it. // #2: if no default subkey is specified, default to a subkey with the same // key ID and layer / modifier spec. - //if(skSpec.isDefault) { TODO for 15.0 - // bk = skElement; - // break; - //} else - if(!baseKey.key || !baseKey.key.spec) { + if(skSpec.default) { + bk = skElement; + break; + } else if(!baseKey.key || !baseKey.key.spec) { continue; } if(skSpec.elementID == baseKey.key.spec.elementID) { bk = skElement; - break; // Best possible match has been found. (Disable 'break' once above block is implemented.) } } if(bk) { vkbd.keyPending = bk; + this.currentSelection = bk; // Subkeys never get key previews, so we can directly highlight the subkey. bk.key.highlight(true); } diff --git a/web/src/engine/osk/src/keyboard-layout/oskKey.ts b/web/src/engine/osk/src/keyboard-layout/oskKey.ts index b99d207625..77d8927b60 100644 --- a/web/src/engine/osk/src/keyboard-layout/oskKey.ts +++ b/web/src/engine/osk/src/keyboard-layout/oskKey.ts @@ -25,6 +25,7 @@ export class OSKKeySpec implements LayoutKey { nextlayer?: string; pad?: number; sk?: OSKKeySpec[]; + default?: boolean; constructor(id: string, text?: string, width?: number, sp?: ButtonClass, nextlayer?: string, pad?: number) { this.id = id; diff --git a/web/src/test/manual/web/default-subkey/default_subkey.js b/web/src/test/manual/web/default-subkey/default_subkey.js new file mode 100644 index 0000000000..1d65601875 --- /dev/null +++ b/web/src/test/manual/web/default-subkey/default_subkey.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_default_subkey());}function Keyboard_default_subkey(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_default_subkey";this.KN="default-subkey";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={};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='';this.KM=0;this.KBVER="1.0";this.KMBM=0x0000;this.KVKD="T_d_default";this.KVKL={"tablet":{"font":"Tahoma","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_Q","text":"q"},{"id":"K_W","text":"w"},{"id":"K_E","text":"e"},{"id":"K_R","text":"r"},{"id":"K_T","text":"t"},{"id":"K_Y","text":"y"},{"id":"K_U","text":"u"},{"id":"K_I","text":"i"},{"id":"K_O","text":"o"},{"id":"K_P","text":"p"}]},{"id":"2","key":[{"id":"K_A","pad":"70","text":"a","sk":[{"id":"U_00E1","text":"\u00E1"},{"id":"U_00E0","text":"\u00E0"},{"id":"K_A","text":"a"},{"id":"U_00E4","text":"\u00E4"},{"id":"U_00E5","text":"\u00E5"},{"id":"U_00E2","text":"\u00E2"},{"id":"U_00E3","text":"\u00E3"}]},{"id":"K_S","text":"s"},{"id":"K_D","text":"d","sk":[{"id":"U_010F","text":"\u010F"},{"id":"U_0111","text":"\u0111"},{"id":"U_0257","text":"\u0257"},{"id":"T_d_default","text":"default","default":true},{"id":"U_0221","text":"\u0221"}]},{"id":"K_F","text":"f"},{"id":"K_G","text":"g"},{"id":"K_H","text":"h"},{"id":"K_J","text":"j"},{"id":"K_K","text":"k"},{"id":"K_L","text":"l"},{"width":"10","id":"T_new_88","sp":"10"}]},{"id":"3","key":[{"nextlayer":"shift","width":"110","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_Z","text":"z"},{"id":"K_X","text":"x"},{"id":"K_C","text":"c"},{"id":"K_V","text":"v"},{"id":"K_B","text":"b"},{"id":"K_N","text":"n"},{"id":"K_M","text":"m"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"140","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_Q","text":"Q"},{"id":"K_W","text":"W"},{"id":"K_E","text":"E"},{"id":"K_R","text":"R"},{"id":"K_T","text":"T"},{"id":"K_Y","text":"Y"},{"id":"K_U","text":"U"},{"id":"K_I","text":"I"},{"id":"K_O","text":"O"},{"id":"K_P","text":"P"}]},{"id":"2","key":[{"id":"K_A","pad":"70","text":"A"},{"id":"K_S","text":"S"},{"id":"K_D","text":"D"},{"id":"K_F","text":"F"},{"id":"K_G","text":"G"},{"id":"K_H","text":"H"},{"id":"K_J","text":"J"},{"id":"K_K","text":"K"},{"id":"K_L","text":"L"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","width":"110","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"id":"K_Z","text":"Z"},{"id":"K_X","text":"X"},{"id":"K_C","text":"C"},{"id":"K_V","text":"V"},{"id":"K_B","text":"B"},{"id":"K_N","text":"N"},{"id":"K_M","text":"M"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"140","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","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":"2","key":[{"layer":"shift","id":"K_4","pad":"70","text":"$"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"width":"110","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_LBRKT","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_LBRKT","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_RBRKT","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"layer":"default","id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"layer":"default","id":"K_SLASH","text":"\/"},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"140","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="17.0.162.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,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"default");}}return r;};} \ No newline at end of file diff --git a/web/src/test/manual/web/default-subkey/index.html b/web/src/test/manual/web/default-subkey/index.html new file mode 100644 index 0000000000..728355c43b --- /dev/null +++ b/web/src/test/manual/web/default-subkey/index.html @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + KeymanWeb Testing Page - Predictive Text: robust testing + + + + + + + + + + + + + + + + +

KeymanWeb Sample Page - default subkey bootstrap-testing

+

Note: the intended tests require use of a touch-form-factor device or emulation thereof. +

+

+ The primary test is held on the default layer's 'd' key - the key labeled 'default' should + be autoselected. +

+

+ A secondary test is held on the default layer's 'a' key - the key labeled 'a', matching the + base key, should be autoselected. +

+
+ +
+ +

Type in your language in this text area:

+ + +

or in this input field:

+ + +

Return to testing home page

+
+ + + + + diff --git a/web/src/test/manual/web/default-subkey/kbd_source/HISTORY.md b/web/src/test/manual/web/default-subkey/kbd_source/HISTORY.md new file mode 100644 index 0000000000..cbd807699c --- /dev/null +++ b/web/src/test/manual/web/default-subkey/kbd_source/HISTORY.md @@ -0,0 +1,6 @@ +default-subkey Change History +==================== + +1.0 (2023-08-21) +---------------- +* Created by SIL International diff --git a/web/src/test/manual/web/default-subkey/kbd_source/LICENSE.md b/web/src/test/manual/web/default-subkey/kbd_source/LICENSE.md new file mode 100644 index 0000000000..b582b3f908 --- /dev/null +++ b/web/src/test/manual/web/default-subkey/kbd_source/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +© 2023 SIL International + +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/web/src/test/manual/web/default-subkey/kbd_source/README.md b/web/src/test/manual/web/default-subkey/kbd_source/README.md new file mode 100644 index 0000000000..9fb82bd00b --- /dev/null +++ b/web/src/test/manual/web/default-subkey/kbd_source/README.md @@ -0,0 +1,30 @@ +default-subkey keyboard +============== + +Version 1.0 + +Description +----------- +default-subkey generated from template + +Links +----- + +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/web/src/test/manual/web/default-subkey/kbd_source/default_subkey.keyboard_info b/web/src/test/manual/web/default-subkey/kbd_source/default_subkey.keyboard_info new file mode 100644 index 0000000000..1677ce4c2f --- /dev/null +++ b/web/src/test/manual/web/default-subkey/kbd_source/default_subkey.keyboard_info @@ -0,0 +1,7 @@ +{ + "license": "mit", + "languages": [ + + ], + "description": "default-subkey generated from template" +} diff --git a/web/src/test/manual/web/default-subkey/kbd_source/default_subkey.kpj b/web/src/test/manual/web/default-subkey/kbd_source/default_subkey.kpj new file mode 100644 index 0000000000..4de714dbd3 --- /dev/null +++ b/web/src/test/manual/web/default-subkey/kbd_source/default_subkey.kpj @@ -0,0 +1,110 @@ + + + + $PROJECTPATH\build + True + True + True + keyboard + + + + id_8305ac63cf6c1388736030b6b94f996d + default_subkey.kmn + source\default_subkey.kmn + 1.0 + .kmn +
+ default-subkey + © SIL International +
+
+ + id_f586f51f683bde64c75f566e643e59bd + default_subkey.kps + source\default_subkey.kps + + .kps +
+ default-subkey + © SIL International +
+
+ + id_ede98e4633e239f933cbfd1f4e1b766c + HISTORY.md + HISTORY.md + + .md + + + id_53e892b8b41cc4caece1cfd5ef21d6e7 + LICENSE.md + LICENSE.md + + .md + + + id_0730bb7c2e8f9ea2438b52e419dd86c9 + README.md + README.md + + .md + + + id_9cc75be74cee7f9a4937893e80b91b5f + default_subkey.keyboard_info + default_subkey.keyboard_info + + .keyboard_info + + + id_d8483af80632f8b611983c11137efccd + default_subkey.ico + source\default_subkey.ico + + .ico + id_8305ac63cf6c1388736030b6b94f996d + + + id_5086f2e8ef1d731c015a78f418aba1e8 + default_subkey.kmx + source\..\build\default_subkey.kmx + + .kmx + id_f586f51f683bde64c75f566e643e59bd + + + id_c8c9acd9c28010e45856034bff6c9d90 + default_subkey.js + source\..\build\default_subkey.js + + .js + id_f586f51f683bde64c75f566e643e59bd + + + id_7b38ddd4f3836ebf9365696475ade08a + default_subkey.kvk + source\..\build\default_subkey.kvk + + .kvk + id_f586f51f683bde64c75f566e643e59bd + + + id_356e5d149c1e539356d72698c1e401a6 + welcome.htm + source\welcome.htm + + .htm + id_f586f51f683bde64c75f566e643e59bd + + + id_8da344c4cea6f467013357fe099006f5 + readme.htm + source\readme.htm + + .htm + id_f586f51f683bde64c75f566e643e59bd + +
+
diff --git a/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.ico b/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.ico new file mode 100644 index 0000000000000000000000000000000000000000..e3628ccc9b2823958484107ff80fed06c5a02228 GIT binary patch literal 1150 zcmZQzU<5(|0R;vS$Y5b$5ChU0Kr8^n3P8*VCV>o~96C5~=orH&9{4bbXx+$=mmkd# zkzd3xqcs{FCor)*pxBz$B8EJmngi=Pu*Mg%T;438e`aB-M^=L#=g4x+>yCl#L$QBW v2Ln1E*$ia;", + "layer": "shift" + }, + { + "id": "K_RBRKT", + "text": "}", + "layer": "shift" + } + ] + }, + { + "id": "K_EQUAL", + "text": "+", + "layer": "shift" + }, + { + "id": "K_HYPHEN", + "text": "-", + "layer": "default" + }, + { + "id": "K_8", + "text": "*", + "layer": "shift" + }, + { + "id": "K_SLASH", + "text": "/", + "layer": "default" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": 90, + "sp": 1 + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_LOWER", + "text": "*abc*", + "width": 140, + "sp": 1, + "nextlayer": "default" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": 120, + "sp": 1 + }, + { + "id": "K_SPACE", + "text": "", + "width": 630, + "sp": 0 + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": 140, + "sp": 1 + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kmn b/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kmn new file mode 100644 index 0000000000..f1ac06ea5e --- /dev/null +++ b/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kmn @@ -0,0 +1,16 @@ +c default_subkey generated from template at 2023-08-21 10:14:50 +c with name "default-subkey" +store(&VERSION) '10.0' +store(&NAME) 'default-subkey' +store(©RIGHT) '© SIL International' +store(&KEYBOARDVERSION) '1.0' +store(&TARGETS) 'any' +store(&BITMAP) 'default_subkey.ico' +store(&VISUALKEYBOARD) 'default_subkey.kvks' +store(&LAYOUTFILE) 'default_subkey.keyman-touch-layout' + +begin Unicode > use(main) + +group(main) using keys + ++ [ T_d_default ] > "default" diff --git a/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kps b/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kps new file mode 100644 index 0000000000..291e349d76 --- /dev/null +++ b/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kps @@ -0,0 +1,65 @@ + + + + 17.0.162.0 + 7.0 + + + + readme.htm + + + + + + + + + + default-subkey + © SIL International + SIL International + + + + + ..\build\default_subkey.kmx + + 0 + .kmx + + + ..\build\default_subkey.js + + 0 + .js + + + ..\build\default_subkey.kvk + + 0 + .kvk + + + welcome.htm + + 0 + .htm + + + readme.htm + + 0 + .htm + + + + + default-subkey + default_subkey + 1.0 + + + + + diff --git a/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kvks b/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kvks new file mode 100644 index 0000000000..830237b17e --- /dev/null +++ b/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kvks @@ -0,0 +1,8 @@ + + +
+ 10.0 + default_subkey + +
+
diff --git a/web/src/test/manual/web/default-subkey/kbd_source/source/readme.htm b/web/src/test/manual/web/default-subkey/kbd_source/source/readme.htm new file mode 100644 index 0000000000..8bce21ff5d --- /dev/null +++ b/web/src/test/manual/web/default-subkey/kbd_source/source/readme.htm @@ -0,0 +1,24 @@ + + + + + + default-subkey + + + + +

default-subkey

+ +

+ default-subkey 1.0 generated from template. +

+ +

© SIL International

+ + + diff --git a/web/src/test/manual/web/default-subkey/kbd_source/source/welcome.htm b/web/src/test/manual/web/default-subkey/kbd_source/source/welcome.htm new file mode 100644 index 0000000000..cdf7e1e234 --- /dev/null +++ b/web/src/test/manual/web/default-subkey/kbd_source/source/welcome.htm @@ -0,0 +1,26 @@ + + + + + + Start Using default-subkey + + + + +

Start Using default-subkey

+ +

+ default-subkey 1.0 generated from template. +

+ +

Keyboard Layout

+ + + + + \ No newline at end of file diff --git a/web/src/test/manual/web/index.html b/web/src/test/manual/web/index.html index 9931e3998b..fce84d11a6 100644 --- a/web/src/test/manual/web/index.html +++ b/web/src/test/manual/web/index.html @@ -64,6 +64,7 @@

Test Start of Sentence (#3621)

Test start of sentence keyboard rules (#5963)

Tests predictive text & other handling of rule matching when the final rule group does not match (#6005)

+

Tests handling of new default-subkey feature (#9430)

Other

Keystroke processing regression test engine.

Return to main index. From dc033b98bf5430f1d9963088aad6c9194443bfed Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Mon, 21 Aug 2023 10:57:51 +0700 Subject: [PATCH 002/107] docs(android): markers for sites to add default subkey handling code --- .../KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java index bc0aed1d04..cf299230d0 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java @@ -397,6 +397,7 @@ final class KMKeyboard extends WebView { if (action == MotionEvent.ACTION_UP) { // Cleanup popups. #6636 dismissKeyPreview(0); + // TODO: default subkey handling dismissSubKeysWindow(); } @@ -970,6 +971,7 @@ final class KMKeyboard extends WebView { @SuppressLint({"InflateParams", "ClickableViewAccessibility"}) private void showSubKeys(Context context) { + // TODO: we'll need to pre-select the default key if it exists here! if (subKeysList == null || subKeysWindow != null) { return; } @@ -1060,6 +1062,7 @@ final class KMKeyboard extends WebView { // Helps keep things from totally breaking when the event handler triggering subkey menu // generation and the menu's event handler stop talking to each other. final ArrayList> subkeyList = subKeysList; + // NOTE: keys are currently only executed from an actual 'click'. button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -1117,6 +1120,7 @@ final class KMKeyboard extends WebView { break; } } + // TODO: Is there a default subkey? If so, and we're still within the key-grid or similar, trigger it. dismissSubKeysWindow(); return true; } else if (action == MotionEvent.ACTION_MOVE) { From 3adf4dc6ebbbb7de6f569047fd9b93107bc6cddd Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Mon, 21 Aug 2023 11:41:44 +0700 Subject: [PATCH 003/107] fix(web): stuck base-key highlighting upon default selection --- web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts | 2 ++ web/src/test/manual/web/default-subkey/default_subkey.js | 2 +- .../kbd_source/source/default_subkey.keyman-touch-layout | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts b/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts index 9d7f003000..94dcf2a65c 100644 --- a/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts +++ b/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts @@ -235,6 +235,8 @@ export default class SubkeyPopup implements RealizedGesture { } if(bk) { + // Prevent sticky-highlighting should the default key be selected. + vkbd.keyPending?.key.highlight(false); vkbd.keyPending = bk; this.currentSelection = bk; // Subkeys never get key previews, so we can directly highlight the subkey. diff --git a/web/src/test/manual/web/default-subkey/default_subkey.js b/web/src/test/manual/web/default-subkey/default_subkey.js index 1d65601875..556acda19a 100644 --- a/web/src/test/manual/web/default-subkey/default_subkey.js +++ b/web/src/test/manual/web/default-subkey/default_subkey.js @@ -1 +1 @@ -if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_default_subkey());}function Keyboard_default_subkey(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_default_subkey";this.KN="default-subkey";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={};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='';this.KM=0;this.KBVER="1.0";this.KMBM=0x0000;this.KVKD="T_d_default";this.KVKL={"tablet":{"font":"Tahoma","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_Q","text":"q"},{"id":"K_W","text":"w"},{"id":"K_E","text":"e"},{"id":"K_R","text":"r"},{"id":"K_T","text":"t"},{"id":"K_Y","text":"y"},{"id":"K_U","text":"u"},{"id":"K_I","text":"i"},{"id":"K_O","text":"o"},{"id":"K_P","text":"p"}]},{"id":"2","key":[{"id":"K_A","pad":"70","text":"a","sk":[{"id":"U_00E1","text":"\u00E1"},{"id":"U_00E0","text":"\u00E0"},{"id":"K_A","text":"a"},{"id":"U_00E4","text":"\u00E4"},{"id":"U_00E5","text":"\u00E5"},{"id":"U_00E2","text":"\u00E2"},{"id":"U_00E3","text":"\u00E3"}]},{"id":"K_S","text":"s"},{"id":"K_D","text":"d","sk":[{"id":"U_010F","text":"\u010F"},{"id":"U_0111","text":"\u0111"},{"id":"U_0257","text":"\u0257"},{"id":"T_d_default","text":"default","default":true},{"id":"U_0221","text":"\u0221"}]},{"id":"K_F","text":"f"},{"id":"K_G","text":"g"},{"id":"K_H","text":"h"},{"id":"K_J","text":"j"},{"id":"K_K","text":"k"},{"id":"K_L","text":"l"},{"width":"10","id":"T_new_88","sp":"10"}]},{"id":"3","key":[{"nextlayer":"shift","width":"110","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_Z","text":"z"},{"id":"K_X","text":"x"},{"id":"K_C","text":"c"},{"id":"K_V","text":"v"},{"id":"K_B","text":"b"},{"id":"K_N","text":"n"},{"id":"K_M","text":"m"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"140","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_Q","text":"Q"},{"id":"K_W","text":"W"},{"id":"K_E","text":"E"},{"id":"K_R","text":"R"},{"id":"K_T","text":"T"},{"id":"K_Y","text":"Y"},{"id":"K_U","text":"U"},{"id":"K_I","text":"I"},{"id":"K_O","text":"O"},{"id":"K_P","text":"P"}]},{"id":"2","key":[{"id":"K_A","pad":"70","text":"A"},{"id":"K_S","text":"S"},{"id":"K_D","text":"D"},{"id":"K_F","text":"F"},{"id":"K_G","text":"G"},{"id":"K_H","text":"H"},{"id":"K_J","text":"J"},{"id":"K_K","text":"K"},{"id":"K_L","text":"L"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","width":"110","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"id":"K_Z","text":"Z"},{"id":"K_X","text":"X"},{"id":"K_C","text":"C"},{"id":"K_V","text":"V"},{"id":"K_B","text":"B"},{"id":"K_N","text":"N"},{"id":"K_M","text":"M"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"140","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","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":"2","key":[{"layer":"shift","id":"K_4","pad":"70","text":"$"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"width":"110","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_LBRKT","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_LBRKT","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_RBRKT","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"layer":"default","id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"layer":"default","id":"K_SLASH","text":"\/"},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"140","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="17.0.162.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,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"default");}}return r;};} \ No newline at end of file +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_default_subkey());}function Keyboard_default_subkey(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_default_subkey";this.KN="default-subkey";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={};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='';this.KM=0;this.KBVER="1.0";this.KMBM=0x0000;this.KVKD="T_d_default";this.KVKL={"tablet":{"font":"Tahoma","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_Q","text":"q"},{"id":"K_W","text":"w"},{"id":"K_E","text":"e"},{"id":"K_R","text":"r"},{"id":"K_T","text":"t"},{"id":"K_Y","text":"y"},{"id":"K_U","text":"u"},{"id":"K_I","text":"i"},{"id":"K_O","text":"o"},{"id":"K_P","text":"p"}]},{"id":"2","key":[{"id":"K_A","pad":"70","text":"a","sk":[{"id":"U_00E1","text":"\u00E1"},{"id":"U_00E0","text":"\u00E0"},{"id":"K_A","text":"a"},{"id":"U_00E4","text":"\u00E4"},{"id":"U_00E5","text":"\u00E5"},{"id":"U_00E2","text":"\u00E2"},{"id":"U_00E3","text":"\u00E3"}]},{"id":"K_S","text":"s"},{"id":"K_D","text":"d","sk":[{"id":"K_D","text":"d"},{"id":"U_010F","text":"\u010F"},{"id":"U_0111","text":"\u0111"},{"id":"U_0257","text":"\u0257"},{"id":"T_d_default","text":"default","default":true},{"id":"U_0221","text":"\u0221"}]},{"id":"K_F","text":"f"},{"id":"K_G","text":"g"},{"id":"K_H","text":"h"},{"id":"K_J","text":"j"},{"id":"K_K","text":"k"},{"id":"K_L","text":"l"},{"width":"10","id":"T_new_88","sp":"10"}]},{"id":"3","key":[{"nextlayer":"shift","width":"110","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_Z","text":"z"},{"id":"K_X","text":"x"},{"id":"K_C","text":"c"},{"id":"K_V","text":"v"},{"id":"K_B","text":"b"},{"id":"K_N","text":"n"},{"id":"K_M","text":"m"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"140","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_Q","text":"Q"},{"id":"K_W","text":"W"},{"id":"K_E","text":"E"},{"id":"K_R","text":"R"},{"id":"K_T","text":"T"},{"id":"K_Y","text":"Y"},{"id":"K_U","text":"U"},{"id":"K_I","text":"I"},{"id":"K_O","text":"O"},{"id":"K_P","text":"P"}]},{"id":"2","key":[{"id":"K_A","pad":"70","text":"A"},{"id":"K_S","text":"S"},{"id":"K_D","text":"D"},{"id":"K_F","text":"F"},{"id":"K_G","text":"G"},{"id":"K_H","text":"H"},{"id":"K_J","text":"J"},{"id":"K_K","text":"K"},{"id":"K_L","text":"L"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","width":"110","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"id":"K_Z","text":"Z"},{"id":"K_X","text":"X"},{"id":"K_C","text":"C"},{"id":"K_V","text":"V"},{"id":"K_B","text":"B"},{"id":"K_N","text":"N"},{"id":"K_M","text":"M"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"140","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","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":"2","key":[{"layer":"shift","id":"K_4","pad":"70","text":"$"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"width":"110","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_LBRKT","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_LBRKT","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_RBRKT","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"layer":"default","id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"layer":"default","id":"K_SLASH","text":"\/"},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"140","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="17.0.162.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,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"default");}}return r;};} \ No newline at end of file diff --git a/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.keyman-touch-layout b/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.keyman-touch-layout index a0641c4079..41cbf16e1d 100644 --- a/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.keyman-touch-layout +++ b/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.keyman-touch-layout @@ -96,6 +96,10 @@ "id": "K_D", "text": "d", "sk": [ + { + "text": "d", + "id": "K_D" + }, { "text": "ď", "id": "U_010F" From bf713d10439fd56f31cff273f60933cacaf2ac89 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Mon, 21 Aug 2023 12:16:22 +0700 Subject: [PATCH 004/107] fix(web): test resource package compilation --- .../web/default-subkey/kbd_source/source/default_subkey.kps | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kps b/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kps index 291e349d76..97cbafecd7 100644 --- a/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kps +++ b/web/src/test/manual/web/default-subkey/kbd_source/source/default_subkey.kps @@ -58,7 +58,9 @@ default-subkey default_subkey 1.0 - + + English + From 909331df62734410c11741c60d0b321632082430 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Mon, 21 Aug 2023 12:22:52 +0700 Subject: [PATCH 005/107] feat(web): allows small fudge-factor before cancelling default --- .../src/input/gestures/browser/subkeyPopup.ts | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts b/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts index 94dcf2a65c..8482aa85e8 100644 --- a/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts +++ b/web/src/engine/osk/src/input/gestures/browser/subkeyPopup.ts @@ -36,6 +36,9 @@ export default class SubkeyPopup implements RealizedGesture { public readonly baseKey: KeyElement; public readonly promise: Promise; + private initialX: number; + private initialY: number; + // Resolves the promise that generated this SubkeyPopup. private resolver: (keyEvent: KeyEvent) => void; @@ -269,7 +272,33 @@ export default class SubkeyPopup implements RealizedGesture { } updateTouch(input: InputEventCoordinate) { - this.currentSelection = null; + // For 'default' subkey handling, we want a small fudge factor. + if(this.initialX === undefined || this.initialY === undefined) { + this.initialX = input.x; + this.initialY = input.y; + } + + const deltaX = this.initialX - input.x; + const deltaY = this.initialY - input.y; + const dist = Math.sqrt(deltaX * deltaX + deltaY * deltaY); + + if(dist > 5) { + this.initialX = Number.MAX_SAFE_INTEGER; // it'll always exceed the threshold hereafter. + this.currentSelection = null; + } else { + // The function that calls this to perform subkey updates auto-unhighlights the active selection; + // make sure that highlighting is maintained if no new key was selected, but we haven't cancelled + // default-selection mode yet. + this.currentSelection.key.highlight(true); + + // Even if we technically have a different subkey underneath the touchpoint, we're still in + // default-selection mode. Require more movement before cancelling default-selection mode. + // + // Can occur for large subkey menus or when subkey menus are "constrained" within OSK bounds, + // as with the iOS app. + return; + } + this.baseKey.key.highlight(false); for(let i=0; i < this.baseKey['subKeys'].length; i++) { From 1817a2d9d0f9f83bce3cfca868c0f944a68c7487 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 11 Sep 2023 03:37:19 +0700 Subject: [PATCH 006/107] chore(web): Add other non-printing characters from OSK font Addresses #6167 for KeymanWeb by defining PUA points per https://github.com/silnrsi/font-symchar/blob/v3.000/documentation/encoding.md --- web/src/engine/osk/src/specialCharacters.ts | 27 +++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/web/src/engine/osk/src/specialCharacters.ts b/web/src/engine/osk/src/specialCharacters.ts index 0f2a3adb95..0a88283cb5 100644 --- a/web/src/engine/osk/src/specialCharacters.ts +++ b/web/src/engine/osk/src/specialCharacters.ts @@ -1,4 +1,4 @@ -// Defines the PUA code mapping for the various 'special' modifier/control keys on keyboards. +// Defines the PUA code mapping for the various 'special' modifier/control/non-printing keys on keyboards. // `specialCharacters` must be kept in sync with the same variable in builder.js. See also CompileKeymanWeb.pas: CSpecialText10 let specialCharacters = { '*Shift*': 8, @@ -40,9 +40,32 @@ let specialCharacters = { '*RTLBkSp*': 0x72, '*ShiftLock*': 0x73, '*ShiftedLock*': 0x74, - '*ZWNJ*': 0x75, // If this one is specified, auto-detection will kick in. + '*ZWNJ*': 0x79, // If this one is specified, auto-detection will kick in. '*ZWNJiOS*': 0x75, // The iOS version will be used by default, but the '*ZWNJAndroid*': 0x76, // Android platform has its own default glyph. + // Added in Keyman 17.0. + // Reference: https://github.com/silnrsi/font-symchar/blob/v3.000/documentation/encoding.md + '*Sp*': 0x80, // Space + '*NBSp*': 0x82, // No-break Space + '*NarNBSp*': 0x83, // Narrow No-break Space + '*EnQ*': 0x84, // En Quad + '*EmQ*': 0x85, // Em Quad + '*EnSp*': 0x86, // En Space + '*EmSp*': 0x87, // Em Space + // TODO: Skipping #-per-em-space + '*PunctSp*': 0x8c, // Punctuation Space + '*ThSp*': 0x8d, // Thin Space + '*HSp*': 0x8e, // Hair Space + '*ZWSp*': 0x81, // Zero Width Space + '*ZWJ*': 0x77, // Zero Width Joiner + '*WJ*': 0x78, // Word Joiner + '*CGJ*': 0x7a, // Combining Grapheme Joiner + '*LTRM*': 0x90, // Left-to-right Mark + '*RTLM*': 0x91, // Right-to-left Mark + '*SH*': 0xa1, // Soft Hyphen + '*HTab*': 0xa2, // Horizontal Tabulation + // TODO: Skipping size references + }; export default specialCharacters; \ No newline at end of file From 159e2df50a09b8b4f9e641560f0dd61904ae7886 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 11 Sep 2023 08:19:57 +0700 Subject: [PATCH 007/107] chore(web): Update test keyboard for non-printing space characters --- .../manual/web/issue9469/test9469/HISTORY.md | 4 + .../web/issue9469/test9469/build/test9469.js | 2 +- .../source/test9469.keyman-touch-layout | 78 +++++++++---------- .../issue9469/test9469/source/test9469.kmn | 7 +- .../web/issue9469/test9469/test9469.kpj | 2 +- 5 files changed, 50 insertions(+), 43 deletions(-) diff --git a/web/src/test/manual/web/issue9469/test9469/HISTORY.md b/web/src/test/manual/web/issue9469/test9469/HISTORY.md index 8e3fdbb7ce..d520e02942 100644 --- a/web/src/test/manual/web/issue9469/test9469/HISTORY.md +++ b/web/src/test/manual/web/issue9469/test9469/HISTORY.md @@ -1,6 +1,10 @@ test9469 Change History ==================== +1.1 (2023-09-12) +---------------- +* Add non-printing space characters + 1.0 (2023-08-17) ---------------- * Created by SIL International diff --git a/web/src/test/manual/web/issue9469/test9469/build/test9469.js b/web/src/test/manual/web/issue9469/test9469/build/test9469.js index 624b9990bd..edbf705ebc 100644 --- a/web/src/test/manual/web/issue9469/test9469/build/test9469.js +++ b/web/src/test/manual/web/issue9469/test9469/build/test9469.js @@ -1 +1 @@ -if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_test9469());}function Keyboard_test9469(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_test9469";this.KN="test9469";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={};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='';this.KM=0;this.KBVER="1.0";this.KMBM=0x0000;this.KVKL={"phone":{"font":"Tahoma","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_TAB","text":"*Tab*"},{"id":"T_TABLEFT","text":"*TabLeft*"},{"id":"K_E","text":"e"},{"id":"K_R","text":"r"},{"id":"K_T","text":"t"},{"id":"K_Y","text":"y"},{"id":"K_U","text":"u"},{"id":"K_I","text":"i"},{"id":"K_O","text":"o"},{"id":"K_P","text":"p"}]},{"id":"2","key":[{"id":"K_A","pad":"50","text":"a"},{"id":"K_S","text":"s"},{"id":"K_D","text":"d"},{"id":"K_F","text":"f"},{"id":"K_G","text":"g"},{"id":"K_H","text":"h"},{"id":"K_J","text":"j"},{"id":"K_K","text":"k"},{"id":"T_RTLBKSP","sp":"1","text":this._v>13?"*RTLBkSp*":"*BkSp*"},{"id":"T_new_338","sp":"1","text":this._v>13?"*LTRBkSp*":"*BkSp*"}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*","sk":[{"id":"T_new_206","text":"*Alt*"},{"id":"T_new_205","text":"*Ctrl*"},{"id":"T_new_207","text":"*Caps*"},{"id":"T_new_208","text":"*ABC*"},{"id":"T_new_209","text":"*abc*"},{"id":"T_new_210","text":"*Symbol*"},{"id":"T_new_211","text":"*AltGr*"},{"id":"T_new_212","text":"*LAlt*"},{"id":"T_new_258","text":"*RAlt*"},{"id":"T_new_259","text":"*LCtrl*"},{"id":"T_new_260","text":"*RCtrl*"},{"id":"T_new_261","text":"*LAltCtrlShift*"},{"id":"T_new_262","text":"*RAltCtrlShift*"},{"id":"T_new_263","text":"*AltShift*"},{"id":"T_new_264","text":"*CtrlShift*"},{"id":"T_new_265","text":"*AltCtrlShift*"},{"id":"T_new_266","text":"*LAltShift*"},{"id":"T_new_267","text":"*RAltShift*"},{"id":"T_new_268","text":"*LCtrlShift*"},{"id":"T_new_269","text":"*RCtrlShift*"},{"id":"T_new_292","text":this._v>13?"*ShiftLock*":"*Shift*"},{"id":"T_new_293","text":this._v>13?"*ShiftedLock*":"*Shifted*"}]},{"id":"T_ZWNJ","text":this._v>13?"*ZWNJ*":"<|>"},{"id":"T_ZWNJIOS","text":this._v>13?"*ZWNJiOS*":"<|>"},{"id":"T_ZWNJANDROID","text":this._v>13?"*ZWNJAndroid*":"<|>"},{"id":"K_V","text":"v"},{"id":"K_B","text":"b"},{"id":"K_N","text":"n"},{"id":"K_M","text":"m"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"id":"K_ROPT","text":"*Hide*"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*","sk":[{"id":"T_new_270","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"T_new_295","text":this._v>13?"*LTREnter*":"*Enter*"}]}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_Q","text":"*Alt*"},{"id":"K_W","text":"*Ctrl*"},{"id":"K_E","text":"*Caps*"},{"id":"K_R","text":"*ABC*"},{"id":"K_T","text":"*abc*"},{"id":"K_Y","text":"*123*"},{"id":"K_U","text":"*Symbol*"},{"id":"K_I","text":"*Currency*"},{"id":"K_O","text":"*Shifted*"},{"id":"K_P","text":"*AltGr*"}]},{"id":"2","key":[{"id":"K_A","pad":"50","text":"*LAlt*"},{"id":"K_S","text":"*RAlt*"},{"id":"K_D","text":"*LCtrl*"},{"id":"K_F","text":"*RCtrl*"},{"id":"K_G","text":"*LAltCtrl*"},{"id":"K_H","text":"*RAltCtrl*"},{"id":"K_J","text":"*LAltCtrlShift*"},{"id":"K_K","text":"*RAltCtrlShift*"},{"id":"K_L","text":"*AltShift*"},{"id":"T_new_232","text":"*CtrlShift*"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shifted*"},{"id":"K_Z","text":"*AltCtrlShift*"},{"id":"K_X","text":"*LAltShift*"},{"id":"K_C","text":"*RAltShift*"},{"id":"K_V","text":"*RAltShift*"},{"id":"K_B","text":"*RCtrlShift*"},{"id":"K_N","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"K_M","text":this._v>13?"*LTREnter*":"*Enter*"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","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":"2","key":[{"layer":"shift","id":"K_4","pad":"50","text":"$"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_LBRKT","pad":"110","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_LBRKT","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_RBRKT","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"id":"K_SLASH","text":"\/"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.141.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;return r;};} \ No newline at end of file +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_test9469());}function Keyboard_test9469(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_test9469";this.KN="test9469";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={};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='';this.KM=0;this.KBVER="1.1";this.KMBM=0x0000;this.KVKD="T_ZWNJ T_ZWNJIOS T_ZWNJANDROID";this.KVKL={"phone":{"font":"Tahoma","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_TAB","text":"*Tab*"},{"id":"T_TABLEFT","text":"*TabLeft*"},{"id":"U_0020","text":"*Sp*"},{"id":"U_00A0","text":"*NBSp*"},{"id":"U_202F","text":"*NarNBSp*"},{"id":"U_2000","text":"*EnQ*"},{"id":"U_2001","text":"*EmQ*"},{"id":"U_2002","text":"*EnSp*"},{"id":"U_2003","text":"*EmSp*"},{"id":"U_2008","text":"*PunctSp*"}]},{"id":"2","key":[{"id":"U_2009","pad":"50","text":"*ThSp*"},{"id":"U_200A","text":"*HSp*"},{"id":"U_200B","text":"*ZWSp*"},{"id":"U_200E","text":"*LTRM*"},{"id":"U_200F","text":"*RTLM*"},{"id":"U_00AD","text":"*SH*"},{"id":"T_0009","text":"*HTab*"},{"id":"U_200F","text":"*RTLM*"},{"id":"T_RTLBKSP","sp":"1","text":this._v>13?"*RTLBkSp*":"*BkSp*"},{"id":"T_new_338","sp":"1","text":this._v>13?"*LTRBkSp*":"*BkSp*"}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*","sk":[{"id":"T_new_206","text":"*Alt*"},{"id":"T_new_205","text":"*Ctrl*"},{"id":"T_new_207","text":"*Caps*"},{"id":"T_new_208","text":"*ABC*"},{"id":"T_new_209","text":"*abc*"},{"id":"T_new_210","text":"*Symbol*"},{"id":"T_new_211","text":"*AltGr*"},{"id":"T_new_212","text":"*LAlt*"},{"id":"T_new_258","text":"*RAlt*"},{"id":"T_new_259","text":"*LCtrl*"},{"id":"T_new_260","text":"*RCtrl*"},{"id":"T_new_261","text":"*LAltCtrlShift*"},{"id":"T_new_262","text":"*RAltCtrlShift*"},{"id":"T_new_263","text":"*AltShift*"},{"id":"T_new_264","text":"*CtrlShift*"},{"id":"T_new_265","text":"*AltCtrlShift*"},{"id":"T_new_266","text":"*LAltShift*"},{"id":"T_new_267","text":"*RAltShift*"},{"id":"T_new_268","text":"*LCtrlShift*"},{"id":"T_new_269","text":"*RCtrlShift*"},{"id":"T_new_292","text":this._v>13?"*ShiftLock*":"*Shift*"},{"id":"T_new_293","text":this._v>13?"*ShiftedLock*":"*Shifted*"}]},{"id":"T_ZWNJ","text":this._v>13?"*ZWNJ*":"<|>"},{"id":"T_ZWNJIOS","text":this._v>13?"*ZWNJiOS*":"<|>"},{"id":"T_ZWNJANDROID","text":this._v>13?"*ZWNJAndroid*":"<|>"},{"id":"U_200D","text":"*ZWJ*"},{"id":"U_2060","text":"*WJ*"},{"id":"U_034F","text":"*CGJ*"},{"id":"K_M","text":"m"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"590","id":"K_SPACE"},{"id":"K_ROPT","text":"*Hide*"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*","sk":[{"id":"T_new_270","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"T_new_295","text":this._v>13?"*LTREnter*":"*Enter*"}]}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_Q","text":"*Alt*"},{"id":"K_W","text":"*Ctrl*"},{"id":"K_E","text":"*Caps*"},{"id":"K_R","text":"*ABC*"},{"id":"K_T","text":"*abc*"},{"id":"K_Y","text":"*123*"},{"id":"K_U","text":"*Symbol*"},{"id":"K_I","text":"*Currency*"},{"id":"K_O","text":"*Shifted*"},{"id":"K_P","text":"*AltGr*"}]},{"id":"2","key":[{"id":"K_A","pad":"50","text":"*LAlt*"},{"id":"K_S","text":"*RAlt*"},{"id":"K_D","text":"*LCtrl*"},{"id":"K_F","text":"*RCtrl*"},{"id":"K_G","text":"*LAltCtrl*"},{"id":"K_H","text":"*RAltCtrl*"},{"id":"K_J","text":"*LAltCtrlShift*"},{"id":"K_K","text":"*RAltCtrlShift*"},{"id":"K_L","text":"*AltShift*"},{"id":"T_new_232","text":"*CtrlShift*"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shifted*"},{"id":"K_Z","text":"*AltCtrlShift*"},{"id":"K_X","text":"*LAltShift*"},{"id":"K_C","text":"*RAltShift*"},{"id":"K_V","text":"*RAltShift*"},{"id":"K_B","text":"*RCtrlShift*"},{"id":"K_N","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"K_M","text":this._v>13?"*LTREnter*":"*Enter*"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","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":"2","key":[{"layer":"shift","id":"K_4","pad":"50","text":"$"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_LBRKT","pad":"110","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_LBRKT","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_RBRKT","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"id":"K_SLASH","text":"\/"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.141.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,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,257)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,258)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}return r;};} \ No newline at end of file diff --git a/web/src/test/manual/web/issue9469/test9469/source/test9469.keyman-touch-layout b/web/src/test/manual/web/issue9469/test9469/source/test9469.keyman-touch-layout index b771afc4e7..5edff50120 100644 --- a/web/src/test/manual/web/issue9469/test9469/source/test9469.keyman-touch-layout +++ b/web/src/test/manual/web/issue9469/test9469/source/test9469.keyman-touch-layout @@ -17,36 +17,36 @@ "text": "*TabLeft*" }, { - "id": "K_E", - "text": "e" + "id": "U_0020", + "text": "*Sp*" }, { - "id": "K_R", - "text": "r" + "id": "U_00A0", + "text": "*NBSp*" }, { - "id": "K_T", - "text": "t" + "id": "U_202F", + "text": "*NarNBSp*" }, { - "id": "K_Y", - "text": "y" + "id": "U_2000", + "text": "*EnQ*" }, { - "id": "K_U", - "text": "u" + "id": "U_2001", + "text": "*EmQ*" }, { - "id": "K_I", - "text": "i" + "id": "U_2002", + "text": "*EnSp*" }, { - "id": "K_O", - "text": "o" + "id": "U_2003", + "text": "*EmSp*" }, { - "id": "K_P", - "text": "p" + "id": "U_2008", + "text": "*PunctSp*" } ] }, @@ -54,37 +54,37 @@ "id": 2, "key": [ { - "id": "K_A", - "text": "a", + "id": "U_2009", + "text": "*ThSp*", "pad": 50 }, { - "id": "K_S", - "text": "s" + "id": "U_200A", + "text": "*HSp*" }, { - "id": "K_D", - "text": "d" + "id": "U_200B", + "text": "*ZWSp*" }, { - "id": "K_F", - "text": "f" + "id": "U_200E", + "text": "*LTRM*" }, { - "id": "K_G", - "text": "g" + "id": "U_200F", + "text": "*RTLM*" }, { - "id": "K_H", - "text": "h" + "id": "U_00AD", + "text": "*SH*" }, { - "id": "K_J", - "text": "j" + "id": "T_0009", + "text": "*HTab*" }, { - "id": "K_K", - "text": "k" + "id": "U_200F", + "text": "*RTLM*" }, { "id": "T_RTLBKSP", @@ -210,16 +210,16 @@ "text": "*ZWNJAndroid*" }, { - "id": "K_V", - "text": "v" + "id": "U_200D", + "text": "*ZWJ*" }, { - "id": "K_B", - "text": "b" + "id": "U_2060", + "text": "*WJ*" }, { - "id": "K_N", - "text": "n" + "id": "U_034F", + "text": "*CGJ*" }, { "id": "K_M", @@ -294,7 +294,7 @@ { "id": "K_SPACE", "text": "", - "width": 610, + "width": 590, "sp": 0 }, { diff --git a/web/src/test/manual/web/issue9469/test9469/source/test9469.kmn b/web/src/test/manual/web/issue9469/test9469/source/test9469.kmn index 966efcc6f9..d0f84c749a 100644 --- a/web/src/test/manual/web/issue9469/test9469/source/test9469.kmn +++ b/web/src/test/manual/web/issue9469/test9469/source/test9469.kmn @@ -3,7 +3,7 @@ c with name "test9469" store(&VERSION) '10.0' store(&NAME) 'test9469' store(©RIGHT) '© 2023 SIL International' -store(&KEYBOARDVERSION) '1.0' +store(&KEYBOARDVERSION) '1.1' store(&TARGETS) 'any' store(&BITMAP) 'test9469.ico' store(&VISUALKEYBOARD) 'test9469.kvks' @@ -14,4 +14,7 @@ begin Unicode > use(main) group(main) using keys -c This keyboard is just to visually inspect the touch layout key caps / longpress so none of the T_new_ keys are defined +c This keyboard is just to visually inspect the touch layout key caps / longpress so nearly all of the T_new_ keys are not defined ++ [T_ZWNJ] > U+200C ++ [T_ZWNJIOS] > U+200C ++ [T_ZWNJANDROID] > U+200C diff --git a/web/src/test/manual/web/issue9469/test9469/test9469.kpj b/web/src/test/manual/web/issue9469/test9469/test9469.kpj index a1608952d8..d5530227c2 100644 --- a/web/src/test/manual/web/issue9469/test9469/test9469.kpj +++ b/web/src/test/manual/web/issue9469/test9469/test9469.kpj @@ -12,7 +12,7 @@ id_9f818ee943306f4c53feb65bb5cadcce test9469.kmn source\test9469.kmn - 1.0 + 1.1 .kmn

test9469 From dbd03aa320188d192c0a5ce11ec3db27d3ad626e Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 11 Sep 2023 08:25:48 +0700 Subject: [PATCH 008/107] chore(android): Update test harness keyboard --- .../app/src/main/assets/test9469.kmp | Bin 4222 -> 4416 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/android/Tests/KeyboardHarness/app/src/main/assets/test9469.kmp b/android/Tests/KeyboardHarness/app/src/main/assets/test9469.kmp index 100cc1d70b6adc30fa4502e58797f021908c5012..76f3480fac8195ec553e2b17a88f93915299b63b 100644 GIT binary patch delta 3425 zcmZu!1yB@R*Isg2K}tFVmy(bY5S9`N0jZ_-T_h!Bmo8}*K~j)dN?J--RvM&h=@5`^ z5Re9g&JXAP{{Q{IZ~i-T?#!Ke&Ye5YIdjkRT(P%;Q992E2x$NS5)#1gC;YHZz#NMZ z9sqEC6F>j}VCUd0h;X#=i0#+H2~#Q`CtXm)!PpI;XW50MLVWjivmemX+Jor|7~{nv zOs4PH%15+VeUtchZ)&=`J99e?J6532DC2fSI6mk2 ztcTKPfAGML#0@L;Y@$#=@bROAc6AG_Em{ysyy^Rb&0N7MMFWF}(MQAWoD-#?JNX!e zTZCcg5ihXMlVO8O=_znOG&07V@^)w&BokP!Qf727UvC_mE|J2_-znccZ>A)_!>0CC z#ZycoK1lVEgur&w1{8Cp-RO}?9?0WsD$>o#@e>+~dUnHW_ag9|{Dbx_>KQ5S-n)Azxb??W(GtRmQak zQ3a54S%HD4w{)Rxnt}9WWii14f&TkBEZkwaO>&`**H6n`#{0hN@RPQNw-T4 zB}WEOgE@ZO=`>mlH@8r|zQtvd`#>r9EAGmC!vL?ipju~@RBc6xO+7%!@7gBZCt#mC z`e}@9hq$U1R-?iM%b>$KB6{d#dSiS-NUsa#Po$rcK=#4_ksTTwm=nNA|Z%>HM zC7C>eo=CjZ9c7v%lqhOn^OPdwpwHu!3u z_wH5Ci}X8MooiI2&Q!~ZclVldx0vO%GTtHphe~nlxXHlm zK=S<{L*tUV7V# z98SV3BIDEwMJs6*V)kXhw8bfD%u;rY;DPNsh=R}uU%y0C!7iENb0uo*ZX6j~bAE>C)VS#6F%&{|WOLL#5 ziTV7H<1Ap^NxWayXS6|KU;g~|to&L_`L^1Dw5EGNfzy@nnLgy9@OACJ(+g?D-pUfL z{PIfteD){ve|8;@KGuWs<{$NB1pr9@PuB?|-R9xft}`l>r~q1Jhv3yd3?cEX&NPw6 zi>K!HtuB^nBR$SjOr#Na@zdG{4)D$r{Npp<#2S8Nt3?!yB7TMC&pRFO9UUD#cj*du zqq}1jlfqNQuuYeH{}wt8t|%rdAU5!Gz}5V@-mFp%Lf%=5_Q9S5D+OazKpG>1CgXTz zgUWG~Km@g=C8}$T^^KcfCyAf*nV${B78%3xomCc~6S=J>lk4m9ouQyGjYOJd)>o`x z?_xnhv>#?jCi*cPPD}#bb*A&NkrI(k$( z_}zofn|SOV4R#;tdj%PrS0w0D4NSZ7TdB_{_NkuiixYed+&qmVjt z63aD-r>LMj^yMI^ZZlWJ^_rZ;-qF1-bUB|k}bSZaz7U@qGL+cnIBgA2vp4tU)X;l5?lP%5iou5JKp}mM# zryIL!BU=ud|C{fn7iQHpZ3Eao<3q0`HI>2yMK!CgE^_y5MYJDPrEUM#9yl98IVO{Pow%+o``%D?v78%^#l6WS1Z(v?l+!>D?W6YWI;cK}0p#_(}?dt^A#@kkY`)89{c7 zv-VryCNNuu^{=6=SXG|-bE7w-`?6iYLi|gF@$KV{?~oEFfPdvAV#J4GNvm`^=g|hC z<068SDDMyw)T^v#m3Ew|LMUGCtH3^ripUDG!t(?mY|KQ4E)R&;8h(&d~0VkZ_LoGJx`FPh4<4!{RK+EpBZiNbVaUnT+lrs>6VO z*-yHcQgYeG)k@vDFM}pZW3Vga)RzwTy$E4#K{}$E*LGBRsfnY_-K)svLMkI_{gL8` zS^~&dM5`iXj<*%(_e<(vNz?a76#=={Ky9o=R4CLLv-fobx``Xon^D0^O- zqh(bCuMKmkmiQ+lMSEskN*xTvWMR=%cco1dKn!cQZq$EG2XMi(gUv&=c&Z2x+qX!107*#A0u+ z!f$+b@W`7)P!X0;^6lefrHK38`M&*X=H)WbPGYNwFE5MbU>6B9LC$T|1^w&m-^GTN zCNOkp?C+4n0$`}O`INmGr>g-eys{AflQP9a2y;kGrt)%^$K1;@yb!wV&b;2F!h@I! zRc>z9z3(co;huWrUpcIR)u%x_fEK$Q&KItu!!%Xw?Sh2#K*r-GqeW?i92r$=#(JBn zRr5tkpO9wpqOFrA)+4CTn2fg50b!L1b1J;5&CIUiPuYH)!YGxrV&wSh-Op-a<)jI$ zMxbKOd7?t2yrw9GJhw24&{;j2g}_h!$K%l?Op((DQ_p)py%wDwJ+mw_4tgdi(yPI6V=%`xO0t%d$Mpxy#s1A|d%i=i)RI~#53zo7Jfo-X@=~5 zpxGnk`@k$wuA5EpT!&oFfIOSU?>);CDfYX((IvX^?m}_R%|m^5l%LEhoY{RAt(PB< z1@yGPwrv_}&p-v#Nje1P=2^2fcC8uEmL^ihKyLIY_b6yE zetDnav;NTLWe(BCn&bDTmq{4a=_@JHhWFtyCTG936oM1hDjI{&*{H) z_05F6S?o8VkCvyPhyQ=V?+@Z{%-D?_{2v+kM+NFU!^5Wm{OyJQWd8T?{wGrzT}r`3 kaPtE600lFC02z9dLK1Ht4W^XD*Ct0BQ?d|$p!kFS7jzaw(EtDd delta 3229 zcmZvf2T&8(7KTFykr0Y>LJ3VukRF;SXrv<|ASi?;Rgm5>C<@YKA&7=vHbDiXcMyaG zK?D|*8ZZe<2WbKc67b>do88$r@6Mb%b7sz&x$~cY=6ttX@qCipR35&q+Orttf<2inwOgT z6{IXL^6)YNqrY;1qP+mOaT%0GERuaj2+gaG9*uIOX-Z-Dl&Qi4LHIi@qS1t8WjZwN zw^<7K(t=qF^0g2tF^9W{8?%KG=4F0S?5N|aR3o*Y!pLY@{%MzHZTqp*JGa#^WW^=- zmA%D*sWIv7`}t5kbRC_0gY6a&D{s260TF=rTGyEHT`mQsaT~8*3E}lp%9#l~7}+|3 zDgw(OChaRZeeis))enh{v-NbC6y$tWSSZ!(L4_z1tW5)2U^A}5bi(&4L|K$!y0#)W zL+?YJEO&id*^^;DyXCz3a{-(7%d!!E?fy>4h``9vo&{@!ThRz5YyG}h99s~jn7t$= zhxv-g7nipw*gDKs9R0s#O}MECy?rWaCF7~m|CQA@A>^i~ib|$sO0h_;bO5dxg17T#S1GpWBCN;Qb_dTnN~N~CnfL;wyG9<7 zuvR*km$S~YWO#_5mAhPJ{@qEk0Dbd~QHvPYVqZmPTFn8dUc{zybfUl6)VIzrMpKh2 z`11~8B!X&bz;eOnSS-8p(@Fecyk6FRe7Q96GBTY!$zV-vT7CCd5p4|XnPhEKb@ z9fcDUxTbTXlzi<%s2zp#%!AQwFZw^V=3CFX$H9*!EB2BvvM=!MF(MnV=Q=$Q4<{RZ zOA0isD^=4Ib+8e-Wy^}=8f*2c9Gia#ptSR-DrjS+wlDALYMb=6T;J+qwVL`uIyGVT zt?#iF8e7c_&3CuBu9Jg+$uB8Yn3o#z;mI-KLcN?D$3#$i)w_YlTNSvb?#!m7jRhbJ zi9;s!m2Y5|Oqc&rG}3{%u}92n%D){V&#RZZez@?H#;Qyz9Fo;u3>#*aMV!QJ&EwrF z7u|et85#1L%P8SJ-QFKHUTzpy#R{1@-2z=r$HigHAzU}j6jEz)2q#=?Cv4^a={1M^ zBlQ{;-ky3;6pdOt8jWd3BqFC0_-$3!Wywd2AE$n#zUvx5isnRRpho!Dj{Q!W4}|}1 znSx=*mJDV9U{x3ZVE@}Pr;hOrnRD>BnKuTVC``}JWkssIh%fGeb7nhD7q`Smx0_mX zF%JoH2e8ULp;7X-vsTd^HH-dEPIEt8$>{PJ&*E{Br+g|kNe z=Cc=trl4zH9(95YI7}&anJse>S|2EI@NH2obyMNPcL<@Mw-tG zCc+MCzg>K~yVKv}elsL486(#w!_R3psQoEd0?sG?_5<{6X40@9|KvDUf;o@qGTBFS zSAnc}%RRk&@Ak8o*5*!we2w_TlHC0qm2!jvR>GfNytDuNYvdCqk8G7D&o>%E+G+y@ zuxE9QzZ*K|jF)I+IS!`3hHM-<*F=T+YV&*%kSmo_m}>bZXM?v(?DJ1#9FSbjvsV4{ zS`3Ir{9aps*w%jHX5F{B7ILA6oeWyZW(McnbAP4NAGa+Qv7Z&^;Vm5#VK1XCYmxqf zK(3lw?XRwm971N+N?2r+UzMtG|F9`xVrSw^QAG3vvq6xLoamH2*ceTmlUDXpsLpYE zYN}|9J)@dB9j0j3<#Vdk(oAHYcwU%0^ch&6KN;T&+rEQPOz~eI6?QC@JovWLU+ZZv zRaB$KzKem?7@x>XUN*VNe}B1jPL^-|IycXTzRfLJ0MbO^%*(m(R>MnTos2x+8mf*& zgGwr|5#D=u{-_;NUGpX}j9A8mc1>y3`gmrcE?)%wgpFSVPyWstL*V5zZdxyNr{+t)2JAw;(?Z1i zptVl2l`S2$9`|^@)X%8SwM5|x?79hT@WK`CD!ZKVGx4{=Y5g94_X`_Q*d~|j2{=i0|`tZnL zcClg=kFQvZ;nrAWRdg#8jx6wYWze>aV*!R*O8WC_viVcy?2th2zX8K z`6xnyL;VOIz{oLjI-Mm#Zn?Aj=28=}Xns~*5V4DL8AlM8j4lFbTN&p{U zGs~)YEH#(T^ZhX+Vd0XT<D($n>Jdc;q|7DWf*cldwE^sC~pnu$}8`U{}`;-~9obo9J{ zzy1-wI{$Zb{?o~b3IYi+oW20{3?xk7!H%i`!RUlh3m_PMItL2OCBjSu{;K{Due}0I From 301cd687e8fa8104ccf75503670bd398f94ac39c Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 21 Sep 2023 20:07:47 +0700 Subject: [PATCH 009/107] chore(web): Update keymanweb-osk.ttf to 4.0 --- web/src/resources/osk/keymanweb-osk.ttf | Bin 43568 -> 35164 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/web/src/resources/osk/keymanweb-osk.ttf b/web/src/resources/osk/keymanweb-osk.ttf index 5b3c6219797cb4a0348d0e5ece31df8dedd4e002..e0651b14d4f770d2a9b15e8850203c05112a23d7 100644 GIT binary patch delta 3545 zcmaJD3s6+o_1yb@%hz3&-30{p%d)`oaXod1vS>B`#3voqTyLPu9 z>MvUXz|{gY9O-ClX)Ss=k zku#uU3~+{y!3~*?1j0e?Dl`LxbpW9~^Z*+34@d=&kX1rowG$Xb+k=?k}N}Yrug&h&aaJo{IM--(V`RBm;LV7=T5`0g?g<0aZW~ zNDtTo?!clzLttB=C-7w8Sl}mtUj)tv-VTS63hDeMT(&RrmxR9pFl6CMj~wAk|FI0| z_v?@9d-PrUGZAF~CPbFvDu*So1{x9SfW7#hedd7^Tu=8HWR9J=z7lH>?!ctg< zK5IY=I#5FzMj<7lTZ1?aWI-*eItIUiQTU2fkv1|&J|?$lBF&@^(v$QJdV@)39Lz@M zb>AAFk_+>Rd3Ku zr$ehGyU4B|PE3&2YI{LdRe`;lKFwGrZ_uL92dxFw)ddCBRS_v(s>G6skwU&EMM;!B zFT6mCtc^7_>(|%RG;&Hh7^)+EQb*`7H4P0l)r}2UpfCm(m^9{)zgl4}Su#y4c|_t7 zFNh*_L`g%(h*Ap53z^6OT;SIu({V+vZ-yzP6q%84W1qdU?h~ibdYgH^&wFV)@?8SXcN+ zYi_Q?_Qd9jdW}10(foz`va{!xJ8V`*3K6EQ5w`1eYnSDFRO%HaYq||OPkym`YrWg1 zx2lpSu1s4=!9~5~lF*NhS&PlftkN+?jnPe<>RB&WXi0BV;cKK&>LBcrv}p}o7FFw{ z(fT@ac4F7)P{ZxQQf4i;0hWZ}GrK(@KQ?(0;lv^hr|_HBQuAm~{sG z)(sS$i1}&-Bf67|?Z`zxL^ZgxZ8Q0Nekz~isBXR?~1h?;OZvm~NsG42dBOINvWK@ss#jbT+8RXIkLF*Y%pxzve` ztZU*DeSKP+bXDQHb4e8HCcV?TfD7v+gAZ<@PYm`mJvPqy_{mZ^RgB3h*Rov9T1_g? z=Q>K=F6-2#;XQuqSxIwAZD&nQXYJIxeD&(`3XiAa8*nT6?t9PjAp(t!V^pMEls=HYPmYmEa!j(tJv-hl)DZ(QgobIY z6!04oht>d63+YYCmMZ6XfULtL2NgYCkom`F)mXS?|dnA-90YY zMe*({q6nZs{f4OixfpFT=1>8~-1&dD@T}Qn$t}}rosQD79Jf=$e8ZZu))!+g^L&wX z|KhvS{o?k#k7fHMhdBGhcyjO5j8o6vyh%D{*Zt<3HwDGbo4|xGN;ZazL|VX(5Q#K{ zjZ2V&T~5XxlLM_7TzIEW@qj3f$zcWt#~>S&f1OG0b{s*bP=Jg{Ps_I?Ge-I3OFH*Z z@-3P_fO&rnKQajzj+nwB*QQgL-i~Ijzh1S^S5G;b$Bbepo{J3Mk&|RL!7!_$DM`6+ z&M*Qc;S%ZzpTdd&9a>&O4I_AY1Z-gu`k*(0$6WE*#OJ0yC3u8GKp$Yt0GxPHHWA}T zcK>%{aH09-KN;tH`)~5(zDi zTkLw;E3nvJ0GrFX_fiIz`xtP9ON6`pI1Vo&Jc+sKut192MZsb=u|PGcDJiV3nwF`} zxn)k=BPFfV>a@I&%wh+2I?8nX)R()ODJ!++%GHoe1;L4ExiriSPX#T;7u&%UH}(U8 z=gZ`X`&`u&TZASxnX;P8q=TgN_e-~>zROpnKI!(!$FC6GtMir=$365^a>IheoK?$; z+e^hzcs#K4p#4TUI*Qobw zUM^+sKHTuQy{q(S_tr;?z9*D=9XhAiSF_>Kbl19(lO%;~yBur4YtkPi>Gj;AQ*SlU zt(m1Qzw}pF=FQPqo$5{V8UvqSdo@q5%Qlu5m$~QmUH#`L-uYV$`HuR7&s7#=q*uph z%nAMJwDifQM6&U{6Z=1Hwm64h+&x}rE#JEO@aoC~Pb@qBO!?uSRp7&mpM&!rPQxrV zBOEyKMk6qRWc)V;Q-qtNFoSdCjwsB=&~T6eZ$GHqz%2k$ZBc1+@r#m@*TWj0SbMKsPWdvqtdl$O>UnG){ A(f|Me delta 12017 zcmZ`f2Ut|c)-!YO-33J4!U7_~E(eBh#3CgB2%&1H z;+aJ=qPUr_z}P)dVvC_cv%9Yg)NeuwD4w^lCM_x9B)~Qy#0{Q1e|phD;qpF&WZ}@( zIURo@N(5gRn z%L@Aq{ta;q459DPZ~v8^IN)=82h}Rf@)PhbLxi=$9}p=&LA3}eX4yOJ9SXBF6Lct8 zuk`n^)bw$S8}=c>OD*AeDDG&Pi$g>kI!tT`vBD#C-wELZy-(7Hjsl8Y+>YWnExJlh zqfe!=v25b*IE3ssNdqk84su6`7DKrYlv6u}$} z=M5+?`oK>$lxPHlrQ!ho6~>)zF_SLQDHIt=0y<7^pi+JT@`sWyABf6@98`i=p;FS0 zRzsP_4Md~)J*b|I<&4M=o)@90V0;mjJ5a_znFb{kN*R<%P%5FY{vsIrE`w!r^pxe$ zE|xm^p;|zug0f3Ehbo}7L;Vo{13Dy2fWC9+5CEPAwiUB60JKZiE{$!6{t9Sg&k{Bc z>ZJge(o^@AKaWD8Z5R|4v?szm+n}hRBywj^3co-Eezl`{FljB6c0f`A&k`sVFo4dO6PzQ z{{%ywicU3vX*;7khjmWqw04$v+B)kyn>%0bJP2U8`!_Tig`q(B=i0d&{`n)M^?~9g zO$k4KpRt->yi1I~ z<1566gpv$WPd1PfoSf5fgSm2U6L*P^=NtL`{8|2MffGUmi;yCu3k5=nP$jGucF0oX z{hWNA>YRRap6}w;C#26F*U5ePzF+inQmj}0rWQNgr)%OpR(lTf3hFO-E4|wXp4Ck9}a$z@-E4_>T2m?fXx^fxy!1x>Q|_?vj79|1|##{SXS8Fu!gXc;cnqM;ctb182)pFS42)kS;TV@TO(eJ zcq`(Yh{s}NXynYu`pA=!Polh|YNIYjeI3;ut&TQC4~kwE;}jDfQykM0^N*N+#@sdr z8k3CUjB|{Q#?8hf#*a;MQ@ClB>5|#atTU&WbIeudjpjGa@0zchZ<>F%^s#tZ43=e< z4$GZb|JWI^>ter*BXQceF>$lv7RDWk`#N43KPoR!urJ|* zgvW_ai9-@+Caz6vPrNZmF(_!zkUu@{C*af&IYASacffF4Ox5S@2i&Z0Iwg>#GtE=>#E@QCiaF<9G+ zfDgt;)W4;U#51}MKQ&z(OjiNZ1u^TUcF>wgOd5ZGy}wN3-V))Y6|W^vDV{4B41#=w z)7W9L-rlhh0X_+CZbS4V(hJ7?g`i}m_)1!NQOV#CW1_#iB2D35keWJ^p8XRY4?cAU z83pJ#Bu9OaCs3f&E7gnuxgqW;57?-T*qZAX)~HIxT(|kie76l;o1h9}n^u+ADw1ssL#X61D@B?n?=(JAsUl zpq9c@=#HcQ=z=Iul_X*SOlyM3LupcSy+WaJml=$)7IToqEsq`s8a@8j9&L@DSXDKV zm9V6wFjoHdUM0(U)GiBmjG0(vO$rMiG9)}K>7i>?gar3g8|az+CJiM%ax2hd0D6K@ zFsOzMg(y(V9+v~5-QBd9hT<)M4ltl#!VJ3{h1lERDbV}SuaGCV?CYZw?-Q-PlW6H_ zD?Qy)4YgXG4qL4cUF4e|mdazHcF}4D6!Z!G4hwP&4r>7NLwZ0D3XNl#hIs0O7$4-o z1%t`M!(@z&Gs$Ee28qStbLs2xqgfVIC0b*J&1O`T1=>e?mMzjL}L!GMrc-F}S0Po*_OVRf> z3GK0ZAj0T>nTU(MqDt=d2z`rQu}oe~0*Nzsq@_Ti75}#HB=G-iIk@TQ?qrhD-3rto zPgqbi(VhnGv-Wb-jBHXnur%7*>@bSZLwBL(?p>@$E%ne{j7<Tv`ynfAJOna)DvW0$2IF;{Ud@W$Vp8iYqE2n%STSkzoB=xcRQjFO zmO+nYG-b417zLgpI%8EXPS0q{+kGyzDV3f{CE?FeD}ISi!#mdC(&zD7x)47{tJcs> z9JbO{U`~Fwna47B6oA4}3?L-}5Cno8r}9(=8JG`jh{8+JnfS{BWe!5(&s;q@e8zK z;E^LAUDMJ}`;hRc>ZuL&ho+L8oY(hz70y#pHHnOvbQxcFNt+q{%qprmkZ!-12)rxr zzAI}GPKh9`eIR5S0NTga8K6`I^4Ns+nCShL3X`$7jq7=rHDLNFy^h0hC^hWw`ei?# zNj7ZUxS{LIKifA;4R{W1k~`sQT<#<%mmlZgIZTG=L+*#a+UYvc(FihwO1kd~3gHm! zQaD6(C{QMo2N`7Y04_F=aV(Bk%LL$4Y@8?bcz9ro*&qY2;>p_7z(kqG!_ycmDEN4D z?($ck(0p$JXT5xEHxASj`b%QN*m$QSp2@+nb7}0B?6kr9ApT(LIPsChJ6|K97oZk4fDQ{PL!3^!>Ey+ox+&6t!yUDUA3>y_1CM>oG<$X|D zzn7}Afo&j?9XM2YQxZtFi~2}nP(q7)zj7y~D<{0!jnuP?HRd_#&X|o~O$*5+5J@G1 zL$*GMSj;N0Zm|0*PhUbNRUdu%jRVyUJFHe&Xc#T*!tdSx10T76j}H0m9lGq8%eZlD zl4*1*i2;uefh>ZhIGyh~U z$C;Q{0%?Wq@E{j{jm*?X4{B&giqL09{@PDBYXQbCvPzi?#tUZY_?GyX$zjpjbLVtX zVUuIxpGomgg0R_pM1Ub!3^oLe@OJ7aPx4OzMW^8p+Erjr z5`?p?UDA<5t7uV^aQ1N`n3q7fB`xYDk^PoF`@)2x@8@vEN zfJRFa7e^lLno>M8F)Bt}Hq%RJf1JZNq>KviQf=s$QCh()4xFzL_eeO7`ZE%ApgypJ z0TxhhF36(NK~SL(kequYc1_5hl)W_-htn_VLw)NY{M;A!=own?v3YaOzR77#gFC;% z#6v~D>FbKue|Db!@e@6n#t=*cdYyq@CMPnPUdzQvUfKeb%i~xW!@RdFCfXoja|co4 zo!#z#Pgjm>3VNw-!|U|DaHDFY*zv@=$Rli90Umzp=gV6~{OU({@w4)#me)4naM|J& z_1(G2%Ld}Ivu_=pKjJX3Ig~~1LL0ETFCf#@nS$h3UA5Ut=V^zNN zGJP);(gzq-0=Jxny^{23z(|0N(Z{M(aXJg{yx`)vvAJTaV%=9O?Pg(bT?=hLdW3eY zy@xO3_G4?ANoF$5_ShHFOUZw+4fG$RDM<2Tj8PhQIkU)|IVdQM_%oyI;HnxLKnnhR z=bfwmxyE)~e7nD~|KeGt$E&N3i*sT;U)Z+nyJ2&NIysFf9g;lnnGt2f60)AnOkb4= zzuApxc*~MA^XI*1`?A<=fLr{kxg~E*FL+~NWwKvU>Z`9-!bXA z2|26Nv!Bn(Sj|}9yL^Ah5r9e}Y0Hy{6iz0A(FOk@vNq4eiMW3r4C&nchmkbtD@;By9-pZCJz6&d>=iPwWa;Sl^kz${E zus6KhJMVNI0=omlj?>%tS!ooQAjc@M_aMNq50bSzeOl!cH^|*pF;wqnbwGBf437#3 zaP#n;q?PPlJ^CDM>rRO5VFql0!pC%p6S)0$C9ZlAZ`q00wb2WJtR8RWL%4tUE=dPN zL0&?-CULu={JXW4X6)Pv!nGVGjDBiDY~iE3CXoNwm7HQHEq)P?!EtRcU#X76VaZyb|qE{bhXQ#E^V@=V;sS_GA7w&csi!lrg z&n<2$Sbn*dHt*-nvtKEWi4P3b>r)2K&D$7j%AY-Aq&Q*wYEI_rvUKx!@1nh3vVD+N zCa9LqlJ6HzL4K(KY@$iV>$CwxRGL8@Vs%E|L#1(dgCGa&0LXQJ({dvh*^Ezn3?7SvLZmeG}Z(C32&>uk`6MipvW$pt!Yd4O#-8il7T4k}euVjANNjcyhqdB6UpoaTLbwmo?*Zvj_C=F^05FpF~LL`{0; z*B~H<1enB!i$_VoCnVtL8}_!_hw+2MZUeo%1~P|(Pmx7bf$xWn89to(8ng>``3B6R zMBY*?$xN(H37&>U3UXfp)+!kCOaAEM(lP`FoYZn*T z_2t^NLi<{(T5G@815geC>{QePpjYzcUAM_Td**I7(08pp3kJa0THryea8hEtQpW53 z16WKMU^4Qaa?mSgg^5Oi*eM!9DxtNCUTOOmJ+}9Nh*Q42jkU?^ePa^B=e+pFFE(uG zp8rc0ts@sGp0T(CkNN)JIP=JdpM;Lfi}xP(0=<8j-lFg4regoKjzvPyE>Xq86Be?W z;8#%W?z+EwHwRshbI36}Fw*`ana-99_6*km1dE}RdQpjMjVFlw9?!j;iAytnU+9m|4C=Xn%6D^3AE2FL{*KnODt)Pb8R$pfI3kF>r#B zON+rKa-K}QM#1 zt7nWdVc^mJuAjwM_j76qYR3~0^CvTS_?kr|nLY4yi~u=&bGY}$LI_S@}SzOSqOZu|CcYsruB9((N$&N})&-FxF8 zcH6px{&b|BJ`y)=#(f>q&i@Eum9wNqps;Kwby`qb1IQ`p>W>fKr$M_(D*o;5=__bo ze6ap?UU{XH*k2af=*;5sK>J<3i7maPdz0`PEZrN$13%dzE=bSp>7Nn_c9uxd0;59w zlZ@Cn5LB?VaO6lL!e@Q@_ib(^##0N<(vS87T~{w+^WM^`@Qp82cfR<-_e<-4SRWjh zY;qel&eK)JXKn~i8SBUSC3uXO;~#$tr+;<}PdNGkee?6T>4U1^iR8dRtbTDD{m-F; z^w-UT#!C^b$u;>5M3 z^?;zuVh#*|_&tzUGfOA;fW>(7{0%=Uvwsn}J`&eBt6cV-r6u(76CeC7zUQ+gknX2v zeYqXu4@}3K@jALh>w+&2pxZFUiq#9=6|-W`Z^Fw|Dq7kXd-v`0)5>_C2sJaSDPXVK zfFDv=BJsh(w^8kD)DKM0z0( z29ys0RVZW}^I)87&p2r)jFz?UquX!M4%%^xZr_JPan2{0!Q=>iAO9CrO2hy3L<8`{ z08bRag8|m*F#xjvBGlY2K_Xan2|R1lC8{LKOEic4OitRbk#PHPyP8Y}VCE&G0T@2P z0vJdI{PIN~+t2T_pZ^#`ma1!?y^Z8?nf7O3bRzJs6-I-;gRQq1?F@rL0&tk%J)hImsOw%w#(Es_sk^k_F5rRu&5htE^Y zaH@g!XYu}OnjxHe94UOlP|{iWc+VVQ;!R3810Schn>U5_hbI=v@}(^$?{Kxk35nC- ziTgJb9kpve}?#9={D=2Sm(% ztMwetwl#G^k`BJ8Ff9T{#NFnNphLg|hxR+7DVD*3gDZrqj%W`wh(&vF{?b79%V1$K zp~fA|SuA&Z;7}i}8_8=e{>R>>E5ajU@^hyR2rAEC&=%ko9PgC1eADQuuNS*`wY%4C zY49oPOf9pzJE{AQ%$DV)E?v>^@&IQiC$(C`HD{&Omdjk6hE`h>Ad;ZE%BC;AmG>X$ z*Uvn+!90O2w_TJ@XYH`R{y>kz;~0SdCZ&{x_JA`1v$cO6VQ}RKOS5dF8ym+h&8qug zVN*s^R>tzNsmmwkG>s=t8-L$0bo4@C2Oc+QOV{R#cNQ)_U0Qautl}7O4gwYKD)5G3 z>Wwf(N3vTA=AXg?R*<`D`h3UI^9w58uWRTWtT2agDXXUEJ(n?YU4H4N2=@uN;H{G_ zzpmd*x4pU1)uS)2s;m8=a^CTZH7jKvk{Q0soq=sqJ7NO8g~hhLM;#AOH9M>ULh(<^ zxHC<$IXQ`SXBR9uTbEro4&za_?5w7YiK{cR#Z;zGi(&_RzVOGoja^%ZjKSSqg;giZ z7r#?F|7h9#V}KB-<1tXDg>S4ZU~!xQfe=X7v8Wp2YIbe}BgSHULD!3)$6b%In{(!$ z)DDdE3I1*8%u%D0Q_^&PLk7P(yWvVr*CQfM+)$X)oJ}S-O@F0meu;~_OLJ>z_%o^R zt}2){J$-zx?bGE2TMLS|0gHjPq!y?iz?J|hT~JiW^O_+i#IUmPM-H2b^S}MpcJ!#A z(D{g?wz)-WochX~7S{ywFWJPdB5tQRt9FDz9YrvQbK2O7p0vu!o+IN9ytN) z%chL$Wi2}{cz9Zrf0G&RJjQcRFMZ`JADjD@Ikqi?q-3YXFF9K|yn3fNIin`a!RUGt z>4Ud*wN##3Q2oxldB^61!E~tI8Q7^_8>Z~Fn*X1oooO2KeCE=#6`)v?vp1R?dX=?0 zUDB(^sYEtp_~zf6%g%3~G;ZWl`<<#&#uqMKOkoT?57^DwkVg~t9ZY#_N(PXb* zahzlzh%*E@J_0%XAB&LL_i-?lu<2XpA1mK=(X?1Uwq*QpTlOCMiE7Wxy`=@aOKh&| zbBkJ{pI@_~IT8n?ugl-GU7ML75StTiHRrozzcpgG2;mCR)qBZu;9#~8_mtO^XF$o4|eCB6j#U(B6g>DMSH{) z%>>37pydLnxffFzJtF{S0(&lnddvpGv68#cnZ6w-$1s|oU#1D6~4-5=k2Uh4|qq7zi22XiLuxc$){)y26u5`UbK$ny4!$m%!9$8)kM$an?6%L>I6l~a5tlUuVQr^rx6@>i{#MfWaQ5xR8Lln3+H%rqPGs-|Mm znDflif!W&{DNU$Wdiu*h|#&jhE-QC8k#h3)X3^F zrsYjbA}!BzxhEo`)lq|^634vhF*pJ$<6%B<*t}Y}&rTUw!}Lt1(LmmXojLgOf8LK8_HfE5U6INwpG-gV_Jxh5-xGrfCtU&s>C0Yz10U%89 zAC@H7@bl>O3-EclH4DC=JJI(};W}LV4t*EuZ)cH|I+}pb)tR=}kumlW0UqpXa4>@lw41K6jyRM{&}y+`QN+F_X$xpQw0uXWH-)xjCMJeYGRVbV?aY1lLpn zCC6l$&8P;7lqUO!A09p|T&J|_xV?g`!!ucK5XQ>#5rrE2+KhnnjQgyJ8uHaOeEs^P z&j5t|F&Qv+-{Mya|CBzRJB%abBjh^RId>1>kxmi=i7H4LfZRa_+$5!r`IW&*8^+GN zw8oW`DeWy7lLD3fL#Ndrm5tvp__@us-yN=WSz1!E(5>#|4^>$&3-!lEOH9#$szzt; zP>q%}EsGn%KE0|mz&cJKxIF;q5u~(d7u-nDl&Rl9mAP7v!_lVH#DuM z&OvK=Pn~~ii~u6|ZcjVAvi6l!pX>}Q$wys19Ztv}=k(N_Q9Q2csk@*uxT@wr+y^BS z-=4bbQ}w?7i^ Date: Fri, 22 Sep 2023 15:07:25 -0500 Subject: [PATCH 010/107] =?UTF-8?q?chore(resources):=20ldml=20update=20key?= =?UTF-8?q?board=20->=20keyboard3=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For: #9403 - unicode-org/cldr:f16d66601f309f29a64a897282fdcab440d42661 - No local modifications neded1 --- .../ldml-keyboards/techpreview/3.0/pcm.xml | 7 ++-- .../ldml-keyboards/techpreview/cldr_info.json | 6 +-- .../techpreview/import/scanCodes-implied.xml | 37 ++++++++++++++++--- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/resources/standards-data/ldml-keyboards/techpreview/3.0/pcm.xml b/resources/standards-data/ldml-keyboards/techpreview/3.0/pcm.xml index f175fbd039..5ef43e5d68 100644 --- a/resources/standards-data/ldml-keyboards/techpreview/3.0/pcm.xml +++ b/resources/standards-data/ldml-keyboards/techpreview/3.0/pcm.xml @@ -11,6 +11,7 @@ + @@ -34,15 +35,15 @@ - + - - + + diff --git a/resources/standards-data/ldml-keyboards/techpreview/cldr_info.json b/resources/standards-data/ldml-keyboards/techpreview/cldr_info.json index 601f341a25..c481be521b 100644 --- a/resources/standards-data/ldml-keyboards/techpreview/cldr_info.json +++ b/resources/standards-data/ldml-keyboards/techpreview/cldr_info.json @@ -1,5 +1,5 @@ { - "sha": "f3daab445e2e3ee88f8b94c6b46d380777035051", - "description": "release-44-alpha3-4-gf3daab445e", - "date": "Wed, 20 Sep 2023 22:27:35 +0000" + "sha": "f16d66601f309f29a64a897282fdcab440d42661", + "description": "release-44-alpha3-6-gf16d66601f", + "date": "Fri, 22 Sep 2023 20:06:24 +0000" } diff --git a/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml b/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml index 2ebb0ac85a..73414c54c7 100644 --- a/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml +++ b/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml @@ -9,6 +9,7 @@ Values are space separated hex bytes. Frame keys are not included. --> +
@@ -16,13 +17,37 @@ - -
- - + + + + + + + +
+ + + + + + +
+ + + + + + +
+ + + + + + - \ No newline at end of file + From 6a54ebdd57aa751767feedee7d30c2a80a189e79 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 22 Sep 2023 15:20:20 -0500 Subject: [PATCH 011/107] =?UTF-8?q?feat(developer):=20ldml=20scancodes=20?= =?UTF-8?q?=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For: #9403 - read implied imports for scancodes --- .../ldml-keyboard/ldml-keyboard-xml-reader.ts | 16 ++++++++++++++++ core/include/ldml/keyboardprocessor_ldml.h | 1 + core/include/ldml/keyboardprocessor_ldml.ts | 4 ++++ 3 files changed, 21 insertions(+) diff --git a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts index 3fdd9a7402..5bec1cde01 100644 --- a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts +++ b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts @@ -49,6 +49,14 @@ export class LDMLKeyboardXMLSourceFileReader { if (!source.keyboard3.keys.import) { source.keyboard3.keys.import = []; } + if (!source.keyboard3.forms) { + source.keyboard3.forms = { + form: [], + }; + } + if (!source.keyboard3.forms.import) { + source.keyboard3.forms.import = []; + } } boxXmlArray(source?.keyboard3, 'layers'); boxXmlArray(source?.keyboard3?.displays, 'display'); @@ -152,6 +160,14 @@ export class LDMLKeyboardXMLSourceFileReader { })) { return false; } + } else if (subtag === 'forms') { + // + if (!this.resolveOneImport(obj, subtag, { + base: constants.cldr_import_base, + path: constants.cldr_implied_forms_import + })) { + return false; + } } return true; } diff --git a/core/include/ldml/keyboardprocessor_ldml.h b/core/include/ldml/keyboardprocessor_ldml.h index ae244ffbe7..4c629ae77b 100644 --- a/core/include/ldml/keyboardprocessor_ldml.h +++ b/core/include/ldml/keyboardprocessor_ldml.h @@ -16,6 +16,7 @@ #pragma once #define LDML_BKSP_FLAGS_ERROR 0x1 +#define LDML_CLDR_IMPLIED_FORMS_IMPORT "techpreview/scanCodes-implied.xml" #define LDML_CLDR_IMPLIED_KEYS_IMPORT "techpreview/keys-Latn-implied.xml" #define LDML_CLDR_IMPORT_BASE "cldr" #define LDML_CLDR_VERSION_LATEST "techpreview" diff --git a/core/include/ldml/keyboardprocessor_ldml.ts b/core/include/ldml/keyboardprocessor_ldml.ts index ed9ad899ed..d19784b110 100644 --- a/core/include/ldml/keyboardprocessor_ldml.ts +++ b/core/include/ldml/keyboardprocessor_ldml.ts @@ -74,6 +74,10 @@ class Constants { * implied keys file */ readonly cldr_implied_keys_import = `${this.cldr_version_techpreview}/keys-Latn-implied.xml`; + /** + * implied scancodes file + */ + readonly cldr_implied_forms_import = `${this.cldr_version_techpreview}/scanCodes-implied.xml`; /** * Length of a raw section header, in bytes */ From 3a677da0c6e76e7812264ea34ff7b0a1c2d40208 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 22 Sep 2023 16:48:07 -0500 Subject: [PATCH 012/107] =?UTF-8?q?feat(common):=20ldml=20scancodes=20?= =?UTF-8?q?=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For: #9403 - use Symbols to track import status --- .../ldml-keyboard/ldml-keyboard-xml-reader.ts | 17 ++++++++++---- .../src/ldml-keyboard/ldml-keyboard-xml.ts | 22 ++++++++++++++++++- .../test-ldml-keyboard-xml-reader.ts | 14 +++++++++++- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts index 5bec1cde01..87f2cbbdba 100644 --- a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts +++ b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts @@ -1,5 +1,5 @@ import * as xml2js from 'xml2js'; -import { LDMLKeyboardXMLSourceFile, LKImport } from './ldml-keyboard-xml.js'; +import { LDMLKeyboardXMLSourceFile, LKImport, ImportStatus } from './ldml-keyboard-xml.js'; import { default as AjvModule } from 'ajv'; const Ajv = AjvModule.default; // The actual expected Ajv type. import { boxXmlArray } from '../util/util.js'; @@ -157,7 +157,7 @@ export class LDMLKeyboardXMLSourceFileReader { if (!this.resolveOneImport(obj, subtag, { base: constants.cldr_import_base, path: constants.cldr_implied_keys_import - })) { + }, true)) { return false; } } else if (subtag === 'forms') { @@ -165,7 +165,7 @@ export class LDMLKeyboardXMLSourceFileReader { if (!this.resolveOneImport(obj, subtag, { base: constants.cldr_import_base, path: constants.cldr_implied_forms_import - })) { + }, true)) { return false; } } @@ -176,9 +176,10 @@ export class LDMLKeyboardXMLSourceFileReader { * @param obj the object being imported into * @param subtag obj's element tag, e.g. `keys` * @param asImport the import structure + * @param implied true if it is an implied import * @returns true on success, false on failure */ - private resolveOneImport(obj: any, subtag: string, asImport: LKImport) : boolean { + private resolveOneImport(obj: any, subtag: string, asImport: LKImport, implied? : boolean) : boolean { const { base, path } = asImport; if (base !== constants.cldr_import_base) { this.callbacks.reportMessage(CommonTypesMessages.Error_ImportInvalidBase({base, path, subtag})); @@ -205,12 +206,20 @@ export class LDMLKeyboardXMLSourceFileReader { // pull all children of importXml[subtag] into obj for (const subsubtag of Object.keys(importRootNode).reverse()) { // e.g. const subsubval = importRootNode[subsubtag]; + const basePath = `${base}/${path}`; if (!Array.isArray(subsubval)) { // This is somewhat of an internal error, indicating that a non-mergeable XML file was imported // Not exercisable with the standard LDML imports. this.callbacks.reportMessage(CommonTypesMessages.Error_ImportMergeFail({base, path, subtag, subsubtag})); return false; } + // Mark all children as an import + subsubval.forEach(o => o[ImportStatus.import] = basePath); + if (implied) { + // mark all children as an implied import + subsubval.forEach(o => o[ImportStatus.impliedImport] = basePath); + } + if (!obj[subsubtag]) { obj[subsubtag] = []; // start with empty array } diff --git a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts index 629b8e8aa2..0a6b2b0924 100644 --- a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts +++ b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts @@ -12,7 +12,7 @@ export interface LDMLKeyboardXMLSourceFile { * -- the root element. */ keyboard3: LKKeyboard; -} +}; export interface LKKeyboard { locale?: string; @@ -193,3 +193,23 @@ export interface LKDisplays { display?: LKDisplay[]; displayOptions?: LKDisplayOptions; }; + +/** + * Utilities for determining the import status of items + */ +export class ImportStatus { + /** item came in via implied (spec based) import, such as keys-Latn-implied.xml */ + static impliedImport = Symbol.for('@keymanapp:implied_import'); + /** item came in via import */ + static import = Symbol.for('@keymanapp:import'); + + /** @returns true if the object was loaded through an implied import */ + static isImpliedImport(o : any) : boolean { + return o && !!o[ImportStatus.impliedImport]; + } + /** @returns true if the object was loaded through an explicit import */ + static isImport(o : any) : boolean { + return o && !!o[ImportStatus.import]; + } +}; + diff --git a/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts b/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts index 4da7a00663..296e36a8cc 100644 --- a/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts +++ b/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts @@ -1,4 +1,4 @@ -import { LKKey } from './../../src/ldml-keyboard/ldml-keyboard-xml.js'; +import { LKKey, ImportStatus } from './../../src/ldml-keyboard/ldml-keyboard-xml.js'; import 'mocha'; import {assert} from 'chai'; import { CommonTypesMessages } from '../../src/util/common-events.js'; @@ -40,6 +40,9 @@ describe('ldml keyboard xml reader tests', function () { {id: 'b', to: 'b'}, {id: 'c', to: 'c'}, ]); + // all of the keys are implied imports here + assert.isTrue(ImportStatus.isImpliedImport(source?.keyboard3?.keys.key.find(({id}) => id === 'a'))); + assert.isTrue(ImportStatus.isImport(source?.keyboard3?.keys.key.find(({id}) => id === 'a'))); }, }, { @@ -81,6 +84,15 @@ describe('ldml keyboard xml reader tests', function () { {id: 'zz', to: 'zz'}, // new key {id: 'hash', to: '##'}, // override ]); + // 'a' is an implied import + assert.isTrue(ImportStatus.isImpliedImport(k.find(({id}) => id === 'a'))); + assert.isTrue(ImportStatus.isImport(k.find(({id}) => id === 'a'))); + // 'hash' is an import but not implied + assert.isFalse(ImportStatus.isImpliedImport(k.find(({id}) => id === 'hash'))); + assert.isTrue(ImportStatus.isImport(k.find(({id}) => id === 'hash'))); + // 'zz' is not imported + assert.isFalse(ImportStatus.isImpliedImport(k.find(({id}) => id === 'zz'))); + assert.isFalse(ImportStatus.isImport(k.find(({id}) => id === 'zz'))); }, }, { From 44f061f293ece3da5e17845841c6cbadde402598 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 22 Sep 2023 17:33:20 -0500 Subject: [PATCH 013/107] =?UTF-8?q?feat(common):=20ldml=20scancodes=20?= =?UTF-8?q?=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For: #9403 - improve how forms are read in the XML structure - warnings when custom (non-default-import) scancodes are loaded - error, as usual, when an unknown form is present --- .../ldml-keyboard/ldml-keyboard-xml-reader.ts | 6 +++++ .../src/ldml-keyboard/ldml-keyboard-xml.ts | 14 +++++++++++ developer/src/kmc-ldml/src/compiler/layr.ts | 8 +++++- .../src/kmc-ldml/src/compiler/messages.ts | 4 +++ .../sections/layr/error-custom-form.xml | 24 ++++++++++++++++++ .../sections/layr/hint-custom-form.xml | 25 +++++++++++++++++++ developer/src/kmc-ldml/test/test-layr.ts | 19 +++++++++++++- 7 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 developer/src/kmc-ldml/test/fixtures/sections/layr/error-custom-form.xml create mode 100644 developer/src/kmc-ldml/test/fixtures/sections/layr/hint-custom-form.xml diff --git a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts index 87f2cbbdba..60c77acc22 100644 --- a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts +++ b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts @@ -76,6 +76,12 @@ export class LDMLKeyboardXMLSourceFileReader { } } } + if(source?.keyboard3?.forms?.form) { + boxXmlArray(source?.keyboard3?.forms, 'form'); + for(let form of source?.keyboard3?.forms?.form) { + boxXmlArray(form, 'scanCodes'); + } + } if(source?.keyboard3?.keys?.flicks) { for(let flicks of source?.keyboard3?.keys?.flicks) { boxXmlArray(flicks, 'flick'); diff --git a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts index 0a6b2b0924..80bbb2e4d4 100644 --- a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts +++ b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts @@ -24,6 +24,7 @@ export interface LKKeyboard { names?: LKNames; settings?: LKSettings; keys?: LKKeys; + forms?: LKForms; displays?: LKDisplays; layers?: LKLayers[]; vkeys?: LKVkeys; @@ -194,6 +195,19 @@ export interface LKDisplays { displayOptions?: LKDisplayOptions; }; +export interface LKForms { + form?: LKForm[]; +}; + +export interface LKForm { + id?: string; + scanCodes?: LKScanCodes[]; +}; + +export interface LKScanCodes { + codes?: string; +}; + /** * Utilities for determining the import status of items */ diff --git a/developer/src/kmc-ldml/src/compiler/layr.ts b/developer/src/kmc-ldml/src/compiler/layr.ts index 281ca8d5db..07dfbcf92d 100644 --- a/developer/src/kmc-ldml/src/compiler/layr.ts +++ b/developer/src/kmc-ldml/src/compiler/layr.ts @@ -1,5 +1,5 @@ import { constants } from '@keymanapp/ldml-keyboard-constants'; -import { KMXPlus } from '@keymanapp/common-types'; +import { KMXPlus, LDMLKeyboard } from '@keymanapp/common-types'; import { CompilerMessages } from './messages.js'; import { SectionCompiler } from "./section-compiler.js"; import { translateLayerAttrToModifier, validModifier } from '../util/util.js'; @@ -22,6 +22,12 @@ export class LayrCompiler extends SectionCompiler { let totalLayerCount = 0; let hardwareLayers = 0; // let touchLayers = 0; + this.keyboard3.forms?.form?.forEach((form) => { + // Just check whether it's NOT an implied import + if (!LDMLKeyboard.ImportStatus.isImpliedImport(form)) { + this.callbacks.reportMessage(CompilerMessages.Hint_UnsupportedCustomForm({id: form.id})); + } + }); this.keyboard3.layers?.forEach((layers) => { const { form } = layers; if (form === 'touch') { diff --git a/developer/src/kmc-ldml/src/compiler/messages.ts b/developer/src/kmc-ldml/src/compiler/messages.ts index 804ec1d02d..37dfd7772c 100644 --- a/developer/src/kmc-ldml/src/compiler/messages.ts +++ b/developer/src/kmc-ldml/src/compiler/messages.ts @@ -149,5 +149,9 @@ export class CompilerMessages { m(this.ERROR_DisplayNeedsToOrId, `display ${CompilerMessages.toOrId(o)} needs to= or id=, but not both`); static ERROR_DisplayNeedsToOrId = SevError | 0x0022; + static Hint_UnsupportedCustomForm = (o:{id: string}) => + m(this.HINT_UnsupportedCustomForm, `Custom
element is not supported.`); + static HINT_UnsupportedCustomForm = SevHint | 0x0023; } + diff --git a/developer/src/kmc-ldml/test/fixtures/sections/layr/error-custom-form.xml b/developer/src/kmc-ldml/test/fixtures/sections/layr/error-custom-form.xml new file mode 100644 index 0000000000..5aa93783de --- /dev/null +++ b/developer/src/kmc-ldml/test/fixtures/sections/layr/error-custom-form.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/developer/src/kmc-ldml/test/fixtures/sections/layr/hint-custom-form.xml b/developer/src/kmc-ldml/test/fixtures/sections/layr/hint-custom-form.xml new file mode 100644 index 0000000000..813a2dbf2e --- /dev/null +++ b/developer/src/kmc-ldml/test/fixtures/sections/layr/hint-custom-form.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + +
+ + +
+ + + + + + +
diff --git a/developer/src/kmc-ldml/test/test-layr.ts b/developer/src/kmc-ldml/test/test-layr.ts index 86c7e2729b..97b11799c3 100644 --- a/developer/src/kmc-ldml/test/test-layr.ts +++ b/developer/src/kmc-ldml/test/test-layr.ts @@ -121,6 +121,23 @@ describe('layr', function () { errors: [ CompilerMessages.Error_MustBeAtLeastOneLayerElement(), ], - } + }, + { + // warning on custom form + subpath: 'sections/layr/hint-custom-form.xml', + warnings: [ + CompilerMessages.Hint_UnsupportedCustomForm({id: "us"}), + ], + }, + { + // error on unknown form + subpath: 'sections/layr/error-custom-form.xml', + warnings: [ + CompilerMessages.Hint_UnsupportedCustomForm({id: "zzz"}), + ], + errors: [CompilerMessages.Error_InvalidHardware({ + form: 'zzz', + }),], + }, ]); }); From f56e4ffa8514efcb57b684eb72f0fa98a21027e0 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 22 Sep 2023 17:56:35 -0500 Subject: [PATCH 014/107] =?UTF-8?q?feat(common):=20ldml=20scancodes=20?= =?UTF-8?q?=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For: #9403 - unit test the set and row count for codes - fix errors! --- .../types/src/consts/virtual-key-constants.ts | 18 +++++- .../test-ldml-keyboard-xml-reader.ts | 29 ++++++++++ developer/src/kmc-ldml/test/test-layr.ts | 56 +++++++++---------- 3 files changed, 70 insertions(+), 33 deletions(-) diff --git a/common/web/types/src/consts/virtual-key-constants.ts b/common/web/types/src/consts/virtual-key-constants.ts index f93155f1ff..39eb4d6d70 100644 --- a/common/web/types/src/consts/virtual-key-constants.ts +++ b/common/web/types/src/consts/virtual-key-constants.ts @@ -159,6 +159,19 @@ export const USVirtualKeyMap: KeyMap = [ [ k.K_SPACE ], ]; +export const KSVirtualKeyMap: KeyMap = [ + // ` 1 2 3 4 5 6 7 8 9 0 - = [bksp] + [ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL, k.K_BKSLASH /* YEN */ ], + // [tab] Q W E R T Y U I O P [ ] \ + [ k.K_Q, k.K_W, k.K_E, k.K_R, k.K_T, k.K_Y, k.K_U, k.K_I, k.K_O, k.K_P, k.K_LBRKT, k.K_RBRKT, k.K_BKSLASH ], + // [caps] A S D F G H J K L ; ' [enter] + [ k.K_A, k.K_S, k.K_D, k.K_F, k.K_G, k.K_H, k.K_J, k.K_K, k.K_L, k.K_COLON, k.K_QUOTE ], + // [shift] Z X C V B N M , . / [shift] *=oE2 + [ k.K_Z, k.K_X, k.K_C, k.K_V, k.K_B, k.K_N, k.K_M, k.K_COMMA, k.K_PERIOD, k.K_SLASH ], + // space + [ k.K_SPACE ], +]; + export const ISOVirtualKeyMap: KeyMap = [ // ` 1 2 3 4 5 6 7 8 9 0 - = [bksp] [ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL ], @@ -174,13 +187,13 @@ export const ISOVirtualKeyMap: KeyMap = [ export const JISVirtualKeyMap: KeyMap = [ // [Hankaku/Zenkaku] 1 2 3 4 5 6 7 8 9 0 - ^ ¥ [bksp] - [ k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL, k.K_BKSLASH /* YEN */ ], + [ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL, k.K_BKSLASH /* YEN */ ], // [tab] Q W E R T Y U I O P @«`» [ [enter] [ k.K_Q, k.K_W, k.K_E, k.K_R, k.K_T, k.K_Y, k.K_U, k.K_I, k.K_O, k.K_P, k.K_BKQUOTE, k.K_LBRKT ], // [caps] A S D F G H J K L ; : ] [enter] [ k.K_A, k.K_S, k.K_D, k.K_F, k.K_G, k.K_H, k.K_J, k.K_K, k.K_L, k.K_COLON, k.K_QUOTE, k.K_RBRKT ], // [shift] Z X C V B N M , . / _ [shift] - [ k.K_Z, k.K_X, k.K_C, k.K_V, k.K_B, k.K_N, k.K_M, k.K_COMMA, k.K_PERIOD, k.K_SLASH, k.K_oE2 /* ろ */ ], + [ k.K_oE2, k.K_Z, k.K_X, k.K_C, k.K_V, k.K_B, k.K_N, k.K_M, k.K_COMMA, k.K_PERIOD, k.K_SLASH, k.k_oC1 /* ろ */ ], // space [ k.K_SPACE ], ]; @@ -208,6 +221,7 @@ export const HardwareToKeymap: Map = new Map( ["iso", ISOVirtualKeyMap], ["jis", JISVirtualKeyMap], ["abnt2", ABNT2VirtualKeyMap], + ["ks", KSVirtualKeyMap], ] ); diff --git a/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts b/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts index 296e36a8cc..1fe589a98c 100644 --- a/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts +++ b/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts @@ -3,6 +3,7 @@ import 'mocha'; import {assert} from 'chai'; import { CommonTypesMessages } from '../../src/util/common-events.js'; import { testReaderCases } from '../helpers/reader-callback-test.js'; +import { HardwareToKeymap } from '../../src/consts/virtual-key-constants.js'; function pluckKeysFromKeybag(keys: LKKey[], ids: string[]) { return keys.filter(({id}) => ids.indexOf(id) !== -1); @@ -141,3 +142,31 @@ describe('ldml keyboard xml reader tests', function () { }, ]); }); + +describe('verify scancodes', function () { + this.slow(500); // 0.5 sec -- json schema validation takes a while + + testReaderCases([ + { + // We've read this above, but we're going to test for scancodes here + subpath: 'import-minimal.xml', + callback: (data, source, subpath, callbacks) => { + assert.ok(source?.keyboard3?.forms?.form); + + const ldmlFormIds = source?.keyboard3?.forms?.form.map(f => f.id); + const kmcFormIds = Array.from(HardwareToKeymap.keys()); + + assert.sameDeepMembers(ldmlFormIds, kmcFormIds, "LDML and kmc form ids"); + + source?.keyboard3?.forms?.form.forEach((form) => { + const {id, scanCodes} = form; + const km = HardwareToKeymap.get(id); + assert.ok(km, `kmc's ${id}`); + const ldmlRowCounts = scanCodes.map(o => o.codes.split(" ").length); + const kmcRowCounts = km.map(o => o.length); + assert.deepEqual(ldmlRowCounts, kmcRowCounts, `ldml/kmc counts for form ${id}`); + }); + }, + }, + ]); +}); diff --git a/developer/src/kmc-ldml/test/test-layr.ts b/developer/src/kmc-ldml/test/test-layr.ts index 97b11799c3..899d5d8666 100644 --- a/developer/src/kmc-ldml/test/test-layr.ts +++ b/developer/src/kmc-ldml/test/test-layr.ts @@ -2,7 +2,7 @@ import 'mocha'; import { assert } from 'chai'; import { LayrCompiler } from '../src/compiler/layr.js'; import { CompilerMessages } from '../src/compiler/messages.js'; -import { compilerTestCallbacks, loadSectionFixture, testCompilationCases } from './helpers/index.js'; +import { compilerTestCallbacks, testCompilationCases } from './helpers/index.js'; import { KMXPlus } from '@keymanapp/common-types'; import { constants } from '@keymanapp/ldml-keyboard-constants'; @@ -20,30 +20,31 @@ function allKeysOk(row : LayrRow, str : string, msg? : string) { describe('layr', function () { this.slow(500); // 0.5 sec -- json schema validation takes a while - // reuse the keys minimal file - it('should compile minimal keys data', async function () { - let layr = await loadSectionFixture(LayrCompiler, 'sections/keys/minimal.xml', compilerTestCallbacks) as Layr; - assert.ok(layr); - assert.equal(compilerTestCallbacks.messages.length, 0); - - assert.equal(layr.lists?.length, 1); - const list0 = layr.lists[0]; - assert.ok(list0); - assert.equal(list0.layers.length, 1); - assert.equal(list0.hardware, constants.layr_list_hardware_us); - const layer0 = list0.layers[0]; - assert.ok(layer0); - assert.equal(layer0.rows.length, 1); - const row0 = layer0.rows[0]; - assert.ok(row0); - assert.equal(row0.keys.length, 2); - - assert.equal(layer0.id.value, 'base'); - assert.equal(layer0.mod, constants.keys_mod_none); - assert.equal(row0.keys[0]?.value, 'grave'); - }); - testCompilationCases(LayrCompiler, [ + { + subpath: 'sections/keys/minimal.xml', + callback(sect) { + const layr = sect; + assert.ok(layr); + assert.equal(compilerTestCallbacks.messages.length, 0); + + assert.equal(layr.lists?.length, 1); + const list0 = layr.lists[0]; + assert.ok(list0); + assert.equal(list0.layers.length, 1); + assert.equal(list0.hardware, constants.layr_list_hardware_us); + const layer0 = list0.layers[0]; + assert.ok(layer0); + assert.equal(layer0.rows.length, 1); + const row0 = layer0.rows[0]; + assert.ok(row0); + assert.equal(row0.keys.length, 2); + + assert.equal(layer0.id.value, 'base'); + assert.equal(layer0.mod, constants.keys_mod_none); + assert.equal(row0.keys[0]?.value, 'grave'); + }, + }, { subpath: 'sections/keys/maximal.xml', callback(sect) { @@ -115,13 +116,6 @@ describe('layr', function () { subpath: 'sections/layr/invalid-missing-layer.xml', errors: [CompilerMessages.Error_MustBeAtLeastOneLayerElement()], }, - { - // missing layers element completely - subpath: 'sections/layr/invalid-missing-layer.xml', - errors: [ - CompilerMessages.Error_MustBeAtLeastOneLayerElement(), - ], - }, { // warning on custom form subpath: 'sections/layr/hint-custom-form.xml', From 20d5d551e7e6a60802120a77eac25a8cd4cc7a5e Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Sat, 23 Sep 2023 10:30:54 +0700 Subject: [PATCH 015/107] chore(web): Update comments --- web/src/engine/osk/src/specialCharacters.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/engine/osk/src/specialCharacters.ts b/web/src/engine/osk/src/specialCharacters.ts index 0a88283cb5..faa5fd697b 100644 --- a/web/src/engine/osk/src/specialCharacters.ts +++ b/web/src/engine/osk/src/specialCharacters.ts @@ -1,5 +1,5 @@ // Defines the PUA code mapping for the various 'special' modifier/control/non-printing keys on keyboards. -// `specialCharacters` must be kept in sync with the same variable in builder.js. See also CompileKeymanWeb.pas: CSpecialText10 +// `specialCharacters` must be kept in sync with the same variable in constants.js. See also CompileKeymanWeb.pas: CSpecialText10 let specialCharacters = { '*Shift*': 8, '*Enter*': 5, @@ -44,7 +44,7 @@ let specialCharacters = { '*ZWNJiOS*': 0x75, // The iOS version will be used by default, but the '*ZWNJAndroid*': 0x76, // Android platform has its own default glyph. // Added in Keyman 17.0. - // Reference: https://github.com/silnrsi/font-symchar/blob/v3.000/documentation/encoding.md + // Reference: https://github.com/silnrsi/font-symchar/blob/v4.000/documentation/encoding.md '*Sp*': 0x80, // Space '*NBSp*': 0x82, // No-break Space '*NarNBSp*': 0x83, // Narrow No-break Space From 87d1a4407dfa9846effbdce1d4bba45499237cc3 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Mon, 25 Sep 2023 10:54:34 +0700 Subject: [PATCH 016/107] fix(web): fixes toolbar refocus timing after a keyboard change --- web/src/app/ui/kmwuitoolbar.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/web/src/app/ui/kmwuitoolbar.ts b/web/src/app/ui/kmwuitoolbar.ts index 0be3f2cf0f..68799cd35c 100644 --- a/web/src/app/ui/kmwuitoolbar.ts +++ b/web/src/app/ui/kmwuitoolbar.ts @@ -824,10 +824,12 @@ if(!keyman?.ui?.name) { this.selectedLanguage = kbd.LanguageCode; // Return focus to input area and activate the selected keyboard - this.setLastFocus(); //*****this seems out of sequence??? this.addKeyboardToList(lang, kbd); if(updateKeyman) { - keymanweb.setActiveKeyboard(kbd.InternalName, kbd.LanguageCode); + keymanweb.setActiveKeyboard(kbd.InternalName, kbd.LanguageCode).then(() => { + // Restore focus _after_ the keyboard finishes loading. + this.setLastFocus(); + }); } this.listedKeyboards[this.findListedKeyboard(lang)].buttonNode.className = 'kmw_button_selected'; From 27266049f723aa28541643fce676fc0fa2e2f682 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 25 Sep 2023 15:58:05 -0500 Subject: [PATCH 017/107] =?UTF-8?q?feat(common):=20ldml=20import=20infrast?= =?UTF-8?q?ructure=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For: #9403 - Just use a local Symbol() instead of a named one, there's no reason for a namespace here. --- common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts index 80bbb2e4d4..5f954c1605 100644 --- a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts +++ b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts @@ -213,9 +213,9 @@ export interface LKScanCodes { */ export class ImportStatus { /** item came in via implied (spec based) import, such as keys-Latn-implied.xml */ - static impliedImport = Symbol.for('@keymanapp:implied_import'); + static impliedImport = Symbol('LDML implied import'); /** item came in via import */ - static import = Symbol.for('@keymanapp:import'); + static import = Symbol('LDML import'); /** @returns true if the object was loaded through an implied import */ static isImpliedImport(o : any) : boolean { From 87c18fdb42e4a1adf76997a71f49d3c2b303b5b3 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 25 Sep 2023 16:13:17 -0500 Subject: [PATCH 018/107] =?UTF-8?q?feat(developer):=20scancode=20hint=20to?= =?UTF-8?q?=20warning=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For: #9403 - fix a bad comment - Warn_UnsupportedCustomForm (formerly hint) --- developer/src/kmc-ldml/src/compiler/layr.ts | 4 ++-- developer/src/kmc-ldml/src/compiler/messages.ts | 8 ++++---- .../test/fixtures/sections/layr/hint-custom-form.xml | 4 ++-- developer/src/kmc-ldml/test/test-layr.ts | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/developer/src/kmc-ldml/src/compiler/layr.ts b/developer/src/kmc-ldml/src/compiler/layr.ts index 07dfbcf92d..879d362a04 100644 --- a/developer/src/kmc-ldml/src/compiler/layr.ts +++ b/developer/src/kmc-ldml/src/compiler/layr.ts @@ -23,9 +23,9 @@ export class LayrCompiler extends SectionCompiler { let hardwareLayers = 0; // let touchLayers = 0; this.keyboard3.forms?.form?.forEach((form) => { - // Just check whether it's NOT an implied import if (!LDMLKeyboard.ImportStatus.isImpliedImport(form)) { - this.callbacks.reportMessage(CompilerMessages.Hint_UnsupportedCustomForm({id: form.id})); + // If it's not an implied import, give a warning. + this.callbacks.reportMessage(CompilerMessages.Warn_UnsupportedCustomForm({ id: form.id })); } }); this.keyboard3.layers?.forEach((layers) => { diff --git a/developer/src/kmc-ldml/src/compiler/messages.ts b/developer/src/kmc-ldml/src/compiler/messages.ts index 37dfd7772c..5bc3fba784 100644 --- a/developer/src/kmc-ldml/src/compiler/messages.ts +++ b/developer/src/kmc-ldml/src/compiler/messages.ts @@ -2,7 +2,7 @@ import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m const SevInfo = CompilerErrorSeverity.Info | CompilerErrorNamespace.LdmlKeyboardCompiler; const SevHint = CompilerErrorSeverity.Hint | CompilerErrorNamespace.LdmlKeyboardCompiler; -// const SevWarn = CompilerErrorSeverity.Warn | CompilerErrorNamespace.LdmlKeyboardCompiler; +const SevWarn = CompilerErrorSeverity.Warn | CompilerErrorNamespace.LdmlKeyboardCompiler; const SevError = CompilerErrorSeverity.Error | CompilerErrorNamespace.LdmlKeyboardCompiler; const SevFatal = CompilerErrorSeverity.Fatal | CompilerErrorNamespace.LdmlKeyboardCompiler; @@ -149,9 +149,9 @@ export class CompilerMessages { m(this.ERROR_DisplayNeedsToOrId, `display ${CompilerMessages.toOrId(o)} needs to= or id=, but not both`); static ERROR_DisplayNeedsToOrId = SevError | 0x0022; - static Hint_UnsupportedCustomForm = (o:{id: string}) => - m(this.HINT_UnsupportedCustomForm, `Custom
element is not supported.`); - static HINT_UnsupportedCustomForm = SevHint | 0x0023; + static Warn_UnsupportedCustomForm = (o:{id: string}) => + m(this.WARN_UnsupportedCustomForm, `Custom element is ignored. Key layout may not be as expected.`); + static WARN_UnsupportedCustomForm = SevWarn | 0x0023; } diff --git a/developer/src/kmc-ldml/test/fixtures/sections/layr/hint-custom-form.xml b/developer/src/kmc-ldml/test/fixtures/sections/layr/hint-custom-form.xml index 813a2dbf2e..f7122d10a8 100644 --- a/developer/src/kmc-ldml/test/fixtures/sections/layr/hint-custom-form.xml +++ b/developer/src/kmc-ldml/test/fixtures/sections/layr/hint-custom-form.xml @@ -11,12 +11,12 @@ - + - + diff --git a/developer/src/kmc-ldml/test/test-layr.ts b/developer/src/kmc-ldml/test/test-layr.ts index 899d5d8666..86f16ff27b 100644 --- a/developer/src/kmc-ldml/test/test-layr.ts +++ b/developer/src/kmc-ldml/test/test-layr.ts @@ -120,14 +120,14 @@ describe('layr', function () { // warning on custom form subpath: 'sections/layr/hint-custom-form.xml', warnings: [ - CompilerMessages.Hint_UnsupportedCustomForm({id: "us"}), + CompilerMessages.Warn_UnsupportedCustomForm({id: "us"}), ], }, { // error on unknown form subpath: 'sections/layr/error-custom-form.xml', warnings: [ - CompilerMessages.Hint_UnsupportedCustomForm({id: "zzz"}), + CompilerMessages.Warn_UnsupportedCustomForm({id: "zzz"}), ], errors: [CompilerMessages.Error_InvalidHardware({ form: 'zzz', From 71aee7a7fad1528ace5e99d30c77e8b2b843f72e Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 25 Sep 2023 17:08:19 -0500 Subject: [PATCH 019/107] =?UTF-8?q?feat(common):=20scancode=20fixes=20for?= =?UTF-8?q?=20ks=20and=20iso=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For: #9403 - per review comments - track CLDR PR 3282 --- common/web/types/src/consts/virtual-key-constants.ts | 10 +++++----- .../techpreview/import/scanCodes-implied.xml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/common/web/types/src/consts/virtual-key-constants.ts b/common/web/types/src/consts/virtual-key-constants.ts index 39eb4d6d70..3971329edd 100644 --- a/common/web/types/src/consts/virtual-key-constants.ts +++ b/common/web/types/src/consts/virtual-key-constants.ts @@ -160,13 +160,13 @@ export const USVirtualKeyMap: KeyMap = [ ]; export const KSVirtualKeyMap: KeyMap = [ - // ` 1 2 3 4 5 6 7 8 9 0 - = [bksp] + // ` 1 2 3 4 5 6 7 8 9 0 - = YEN [bksp] [ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL, k.K_BKSLASH /* YEN */ ], // [tab] Q W E R T Y U I O P [ ] \ - [ k.K_Q, k.K_W, k.K_E, k.K_R, k.K_T, k.K_Y, k.K_U, k.K_I, k.K_O, k.K_P, k.K_LBRKT, k.K_RBRKT, k.K_BKSLASH ], + [ k.K_Q, k.K_W, k.K_E, k.K_R, k.K_T, k.K_Y, k.K_U, k.K_I, k.K_O, k.K_P, k.K_LBRKT, k.K_RBRKT, k.k_oC1 ], // [caps] A S D F G H J K L ; ' [enter] [ k.K_A, k.K_S, k.K_D, k.K_F, k.K_G, k.K_H, k.K_J, k.K_K, k.K_L, k.K_COLON, k.K_QUOTE ], - // [shift] Z X C V B N M , . / [shift] *=oE2 + // [shift] Z X C V B N M , . / [shift] [ k.K_Z, k.K_X, k.K_C, k.K_V, k.K_B, k.K_N, k.K_M, k.K_COMMA, k.K_PERIOD, k.K_SLASH ], // space [ k.K_SPACE ], @@ -188,12 +188,12 @@ export const ISOVirtualKeyMap: KeyMap = [ export const JISVirtualKeyMap: KeyMap = [ // [Hankaku/Zenkaku] 1 2 3 4 5 6 7 8 9 0 - ^ ¥ [bksp] [ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL, k.K_BKSLASH /* YEN */ ], - // [tab] Q W E R T Y U I O P @«`» [ [enter] + // [tab] Q W E R T Y U I O P @ [ [enter] [ k.K_Q, k.K_W, k.K_E, k.K_R, k.K_T, k.K_Y, k.K_U, k.K_I, k.K_O, k.K_P, k.K_BKQUOTE, k.K_LBRKT ], // [caps] A S D F G H J K L ; : ] [enter] [ k.K_A, k.K_S, k.K_D, k.K_F, k.K_G, k.K_H, k.K_J, k.K_K, k.K_L, k.K_COLON, k.K_QUOTE, k.K_RBRKT ], // [shift] Z X C V B N M , . / _ [shift] - [ k.K_oE2, k.K_Z, k.K_X, k.K_C, k.K_V, k.K_B, k.K_N, k.K_M, k.K_COMMA, k.K_PERIOD, k.K_SLASH, k.k_oC1 /* ろ */ ], + [ k.K_Z, k.K_X, k.K_C, k.K_V, k.K_B, k.K_N, k.K_M, k.K_COMMA, k.K_PERIOD, k.K_SLASH, k.k_oC1 /* ろ */ ], // space [ k.K_SPACE ], ]; diff --git a/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml b/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml index 73414c54c7..23ee29d2cb 100644 --- a/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml +++ b/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml @@ -35,7 +35,7 @@ - +
From 2c588edbba9fbb08ff47c60fa1aec1080542c59d Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 25 Sep 2023 17:35:44 -0500 Subject: [PATCH 020/107] =?UTF-8?q?feat(common):=20scancode=20fixes=20for?= =?UTF-8?q?=20ks=20and=20jis=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - use vkey k.K_oE2 for 0x7D in KS and JIS keyboards For: #9403 --- common/web/types/src/consts/virtual-key-constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/web/types/src/consts/virtual-key-constants.ts b/common/web/types/src/consts/virtual-key-constants.ts index 3971329edd..929182c481 100644 --- a/common/web/types/src/consts/virtual-key-constants.ts +++ b/common/web/types/src/consts/virtual-key-constants.ts @@ -161,7 +161,7 @@ export const USVirtualKeyMap: KeyMap = [ export const KSVirtualKeyMap: KeyMap = [ // ` 1 2 3 4 5 6 7 8 9 0 - = YEN [bksp] - [ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL, k.K_BKSLASH /* YEN */ ], + [ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL, k.K_oE2 /* YEN */ ], // [tab] Q W E R T Y U I O P [ ] \ [ k.K_Q, k.K_W, k.K_E, k.K_R, k.K_T, k.K_Y, k.K_U, k.K_I, k.K_O, k.K_P, k.K_LBRKT, k.K_RBRKT, k.k_oC1 ], // [caps] A S D F G H J K L ; ' [enter] @@ -187,7 +187,7 @@ export const ISOVirtualKeyMap: KeyMap = [ export const JISVirtualKeyMap: KeyMap = [ // [Hankaku/Zenkaku] 1 2 3 4 5 6 7 8 9 0 - ^ ¥ [bksp] - [ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL, k.K_BKSLASH /* YEN */ ], + [ k.K_BKQUOTE, k.K_1, k.K_2, k.K_3, k.K_4, k.K_5, k.K_6, k.K_7, k.K_8, k.K_9, k.K_0, k.K_HYPHEN, k.K_EQUAL, k.K_oE2 /* YEN */ ], // [tab] Q W E R T Y U I O P @ [ [enter] [ k.K_Q, k.K_W, k.K_E, k.K_R, k.K_T, k.K_Y, k.K_U, k.K_I, k.K_O, k.K_P, k.K_BKQUOTE, k.K_LBRKT ], // [caps] A S D F G H J K L ; : ] [enter] From 70a204131f75e4cee16df5c2f02b9c5ce10ebff7 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 27 Sep 2023 06:08:25 +0700 Subject: [PATCH 021/107] chore(web,android): Update test9469 keyboard --- .../app/src/main/assets/test9469.kmp | Bin 4416 -> 4416 bytes .../web/issue9469/test9469/build/test9469.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/android/Tests/KeyboardHarness/app/src/main/assets/test9469.kmp b/android/Tests/KeyboardHarness/app/src/main/assets/test9469.kmp index 76f3480fac8195ec553e2b17a88f93915299b63b..b83a0c509b5e08d0484358b273280c642eccb998 100644 GIT binary patch delta 2391 zcmV-d38?nKBETXIP)h>@6aWAS2mshHJFyK>0SMSIJ6E)y&PJd@7t2P8hUHvk`-eBweE|M1#`doJICAHc0cs66e8T)Lm=R16-p97eg`VUH0W`DqZKpu(OAg5Ctmz@sDSb>c(_Y+=7 zl#v9Gb+2UW>pu!QQzq~?RCM+*dVV^0Ju%6)joq_#JLdldP)h>@6aWAS2msA6J6D>YqM?)K z0w;eDR}U5G#?V$N1Y9(vo3v8F226|~>7SUAm{-!IH5)fY=+cEq2@2v)DFt1+DqZ*q z{1CeFBdEWbH%VV?LPK4N6Yk8p=iYPg%)HEOE<3N&()Y`WmKYHQ?1IBH2roK32R`NSL-0w5OW=PIho6G4Is5^9-QiD>gZ+F4Typp;_^QJ{ zz$Y9YrQo^Fe!y28{s~U2u4NU~U|y1^4XuF7pjnufo)D|yP2;U&Rry+Ft;4O`bq$4Y zbH+8PgvPLO-Bi+ISqs+^(J>b@UDueCx`j3g^PV~r#3rcVXYTrk`x>R-c*)vKPtk7pZWD%7Dnhj&Bh0)uc)pT!m{{zkxFAl-|G`&(&JMFLHt< zmuv2C1#Q!wqe_N{UxP9CyBJa~lCcW!+1(g@)t>(`Y~A)Zu_kj7ZW-*W)Kv#(*Z?oE zGoP#q=WFmQ+1u;)&9Zu=2fD90%}{?Q>}7P9uhPq(zni-fpW_-$+?#J$FUi=FWd5uQ!Ch~n|UDaV3$Hj2eD&&FM1Oozta{+IvWwy{*I zuBlYI$9A3)3kJyXL2RxMB6CcaBcp+q+wb z^!?7i*RJ>IP48`b|JiTY{yG1RU5}&RY@_oFee;LW=kkSt`A2a8ZaLOMInV^~O-o6gD;i*4LdYEG=rCoquk06xLn*M)p}*eyHRa z8I2jXh7H|hbAl>M`G1PE+8{)=*;SU|Yh6{iO#rwTemU1MgOnP^`a;wv6LY~?Gt(42 z0aq&Wyg1e;T-RHeIKj4KyNeg+x;aDbk-)ONfR)?6Fc%DAtlZ{EkaV)YIUzTFG)C^< zfrHJ>>#qNzhlt(vv#Z#J;y}=^j%>^s%2+g!_24}2%2ne~k$?}8`?8&fCB7m57a1X(>%*q(NCeg27A|2b=S{ioXbNvC~w5^SK_RF>@I(Y6p< zS+XPBa@Y#n(|;fBvCazY(3nn4eQ`xn51R`&wJIZ>q`JToDM|gx?UFTy#KMm{F~Rn8 zD3*zUWMC*zwO*}GgbsRf2iocB_dD!L@U=Zx+iZO3MG;LjascW|lcc-^Al(V2twHU1 zozmx}{0FGlaRNkwE*jP)t(KvB98>2b)^YEJh=ePtUw;r^X>cadA7Y<|*9d^~~~82>@%R6PtTpDgwkYDP#$deF)Jf(*y|2 z!dm?}0ReYPzaPXAa^#>c#`ku@Tx2=AppQ5K1CLZQan(gQ-%c_FPPmyInG&3GCj}!@ zvvFbmp2e_vYFb&?LNpR-usv#j({RP8yDVslT7OX*Zl79B8t#CObQ-WshdTvW&L^Kk z58ku~Pdnh?#Ec6W#%LHdN5jZjUNdL1y{mBze||k=DFZ^f={82Yn_{+M=v331HN>_t zjG23-5f;{)>rYhWjHEWDl?r>Xt{#7cYE^56x-pbrG&*N(Fsew^ELA&hw_1R11kXC9 z9)E&k^)3t7ZPvP{A@&H)=<=%F1N@ZB@}yM z>)9AOk8b7n+Kq771olecn7tH^v1Vh0jRDaH{)@o>`BkggK30>4kn@H0rU!<3VAyP5 zByv>?S+l5Fu?)<*7q#OC3`S?|Ct!GEh?5-(X#us9hYD2z)05o_Wq*{R91xF`Mpr3G zx|c{_-)H4Dh}JJzI1s(>vTz`3KV;!RwBBdoPQP57Ho#HRvJYP4@~Q?{OUZH_s{pTG zS24mqJ4kXVjr=wTt=>_4!Dh+ucZ^%A=k$Kj0`zh>^WHN{RiteHoQ2&?#K$iEd8eR3 z%5qs=!E*RW4;dY;pMS8_I>UuAs0a|6%O`F_TveF$35zJClnHTmwxSE3@hhZvg{M8Y{D04p9LE*f2Yjun#f_*f2X+ zwm}#(lj;vH2+c4%SDK%qp_3pGG6>EvJ693qY$=mk5HSPTFgufu5H|x&8Y`2?5H@6aWAS2mtd!E3pkx0SNO#D_6OX%~_LX0VNeVCi6{DVInFF ze9=8*?XAt)Bqd3!lb``3f5L(hehVdJA_w^jQc=N8fENs~kAr@Ieea?Up3w}Ph$|ym zWwq8lk!vF;2QGm`4DL;q4X;)>(ag=Fd?uU}P8hUHvk`#`C0(N}M1#`9{$S`;0js99 zP~;0q<3t}yelL9gW{7%z?-Gqik7&d-NKULwvRxu6bRy&-+>eNIe>1DSi~t8smNOJP zXgkQaN@}y~@odI`Q})?h&v*DvKL;>#^&gb9O#guSfGiZXK~ASQE;}8PvK$*@?kBvE zFeNb{>t4y$*MAgru1w%>sOaor{QPw8dSp_0#Jt?8ATm12Cr(Wo?GZ}n?HgCNLPmI8 zn7*7!Th+EI-tjo2B`RstoubeTX>%6)P296}JLdldP)h>@6aWAS2mpLRD_0#HcXgBI z0w;fO`OqTWSlTKD!9_#5Nh=j>z{CiW{)s6`^GceuX5*#^S-KDjK|$PEN|0D}DL2J1RyI89yAYA(>k#d-Yni0R+O&|)-v3dT{ltq zHfK`P8rK9isau%AvKFi*A`>oVx^6PxCV!e)dQY7xVpF;aT2w-JSrh0gwp+>WwcUR) z%Wh=*OtPBVwLUe+$zCSEU!=ep3IigCJHA20SCuMxa1pL%{R+yYQ+fk)JXdQ8Kg$VL zT&}slHMCWGjv^TzehJ3h?{Yx7OvVPhXLn=tMSK1yuw~od#H!3$xK*&PTvy#b!!~${ zo%v)HIA4Wd&fZ?XZP^_TKn~GeyM4=c$e#!6RaJK?U`Qb`ib?Xcgc_UaKq|N?-WkG8~gPm z`hMqcHOoDE)4M_MKl=^aKjpu%>q+!GO>};yZ~id)R5~*-|G4jOVmoQ>GC5$_IdNi{Jj$vC#>ZL;l7qz((jng}Y4c5TEe;?6_bA+eFouaT) z2OHJ{%O6j4JVj@g!$l#2Eb-;TiZ_OOrm(RIu)gkGVQEq8?EG`1qp`=f$x;;kw?!#0jfe!FC$)@n#KTeyh!qTpgSDqD;PO5Y%zGnb0A2(AEJ{h;(Psgs^oH; z=m)~udKW}F*q9nozDVTXCdlfE!uGVA>+?^{`p;Rr>pxY`Pde?hlVAhYrm|!wkG6%_ z@{%3dmcy3Wo`3#mk9AgHhsJbb>WeFqde~gJsZ}27B-I6$NJ;9KZ)u`r~>_ITn+c=<~pu#0DZI9Y0-KZ;7+gEqBrOSZr^Dn1*G*lg2_cwWSjS% zMg%prdqE)6iJyXNtY2A=SMO>^OfD2N(wL;-wiwm-D+C{iQ1+YODvGvaj z>(v&b^M6l6_w>xmc4{0F6c@MSYM#PPUe7Eql>o46I_dn?nI=GB z7FKKZ1O(hE{eBQf$dQA(7~k6obCKoffuUWYRI6Gm)QzG1qR}~PgHc7QW~o}e-D&~45j^XZ zdVdIx)w?WQw^{9;hS*~`qsyyy5Aahi%MXRUW1%BLBhg{*?y`K<+s*cQ2rffcl&<2Z z*RwHn9^K0CwHx8E3G9`?F?%T-W6j108v~*Z{1<`$^Q%^~U00Kakn@H0rU!<3VAyP5 zByv>?S+l5F@er7GFRJwh3`S?|Ct!GEh?5-(X#v%fhYD2z(UaW@Wq%w(IUpV>jjmFX zbT5&uzonyB&uqQLl=TvDje(y`C^GDcp{hi zC053YTp@syI+IrnF$42LE0c>1Tmwiv60_=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='';this.KM=0;this.KBVER="1.1";this.KMBM=0x0000;this.KVKD="T_ZWNJ T_ZWNJIOS T_ZWNJANDROID";this.KVKL={"phone":{"font":"Tahoma","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_TAB","text":"*Tab*"},{"id":"T_TABLEFT","text":"*TabLeft*"},{"id":"U_0020","text":"*Sp*"},{"id":"U_00A0","text":"*NBSp*"},{"id":"U_202F","text":"*NarNBSp*"},{"id":"U_2000","text":"*EnQ*"},{"id":"U_2001","text":"*EmQ*"},{"id":"U_2002","text":"*EnSp*"},{"id":"U_2003","text":"*EmSp*"},{"id":"U_2008","text":"*PunctSp*"}]},{"id":"2","key":[{"id":"U_2009","pad":"50","text":"*ThSp*"},{"id":"U_200A","text":"*HSp*"},{"id":"U_200B","text":"*ZWSp*"},{"id":"U_200E","text":"*LTRM*"},{"id":"U_200F","text":"*RTLM*"},{"id":"U_00AD","text":"*SH*"},{"id":"T_0009","text":"*HTab*"},{"id":"U_200F","text":"*RTLM*"},{"id":"T_RTLBKSP","sp":"1","text":this._v>13?"*RTLBkSp*":"*BkSp*"},{"id":"T_new_338","sp":"1","text":this._v>13?"*LTRBkSp*":"*BkSp*"}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*","sk":[{"id":"T_new_206","text":"*Alt*"},{"id":"T_new_205","text":"*Ctrl*"},{"id":"T_new_207","text":"*Caps*"},{"id":"T_new_208","text":"*ABC*"},{"id":"T_new_209","text":"*abc*"},{"id":"T_new_210","text":"*Symbol*"},{"id":"T_new_211","text":"*AltGr*"},{"id":"T_new_212","text":"*LAlt*"},{"id":"T_new_258","text":"*RAlt*"},{"id":"T_new_259","text":"*LCtrl*"},{"id":"T_new_260","text":"*RCtrl*"},{"id":"T_new_261","text":"*LAltCtrlShift*"},{"id":"T_new_262","text":"*RAltCtrlShift*"},{"id":"T_new_263","text":"*AltShift*"},{"id":"T_new_264","text":"*CtrlShift*"},{"id":"T_new_265","text":"*AltCtrlShift*"},{"id":"T_new_266","text":"*LAltShift*"},{"id":"T_new_267","text":"*RAltShift*"},{"id":"T_new_268","text":"*LCtrlShift*"},{"id":"T_new_269","text":"*RCtrlShift*"},{"id":"T_new_292","text":this._v>13?"*ShiftLock*":"*Shift*"},{"id":"T_new_293","text":this._v>13?"*ShiftedLock*":"*Shifted*"}]},{"id":"T_ZWNJ","text":this._v>13?"*ZWNJ*":"<|>"},{"id":"T_ZWNJIOS","text":this._v>13?"*ZWNJiOS*":"<|>"},{"id":"T_ZWNJANDROID","text":this._v>13?"*ZWNJAndroid*":"<|>"},{"id":"U_200D","text":"*ZWJ*"},{"id":"U_2060","text":"*WJ*"},{"id":"U_034F","text":"*CGJ*"},{"id":"K_M","text":"m"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"590","id":"K_SPACE"},{"id":"K_ROPT","text":"*Hide*"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*","sk":[{"id":"T_new_270","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"T_new_295","text":this._v>13?"*LTREnter*":"*Enter*"}]}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_Q","text":"*Alt*"},{"id":"K_W","text":"*Ctrl*"},{"id":"K_E","text":"*Caps*"},{"id":"K_R","text":"*ABC*"},{"id":"K_T","text":"*abc*"},{"id":"K_Y","text":"*123*"},{"id":"K_U","text":"*Symbol*"},{"id":"K_I","text":"*Currency*"},{"id":"K_O","text":"*Shifted*"},{"id":"K_P","text":"*AltGr*"}]},{"id":"2","key":[{"id":"K_A","pad":"50","text":"*LAlt*"},{"id":"K_S","text":"*RAlt*"},{"id":"K_D","text":"*LCtrl*"},{"id":"K_F","text":"*RCtrl*"},{"id":"K_G","text":"*LAltCtrl*"},{"id":"K_H","text":"*RAltCtrl*"},{"id":"K_J","text":"*LAltCtrlShift*"},{"id":"K_K","text":"*RAltCtrlShift*"},{"id":"K_L","text":"*AltShift*"},{"id":"T_new_232","text":"*CtrlShift*"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shifted*"},{"id":"K_Z","text":"*AltCtrlShift*"},{"id":"K_X","text":"*LAltShift*"},{"id":"K_C","text":"*RAltShift*"},{"id":"K_V","text":"*RAltShift*"},{"id":"K_B","text":"*RCtrlShift*"},{"id":"K_N","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"K_M","text":this._v>13?"*LTREnter*":"*Enter*"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","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":"2","key":[{"layer":"shift","id":"K_4","pad":"50","text":"$"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_LBRKT","pad":"110","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_LBRKT","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_RBRKT","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"id":"K_SLASH","text":"\/"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.141.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,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,257)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,258)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}return r;};} \ No newline at end of file +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_test9469());}function Keyboard_test9469(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_test9469";this.KN="test9469";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={};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='';this.KM=0;this.KBVER="1.1";this.KMBM=0x0000;this.KVKD="T_ZWNJ T_ZWNJIOS T_ZWNJANDROID";this.KVKL={"phone":{"font":"Tahoma","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_TAB","text":"*Tab*"},{"id":"T_TABLEFT","text":"*TabLeft*"},{"id":"U_0020","text":"*Sp*"},{"id":"U_00A0","text":"*NBSp*"},{"id":"U_202F","text":"*NarNBSp*"},{"id":"U_2000","text":"*EnQ*"},{"id":"U_2001","text":"*EmQ*"},{"id":"U_2002","text":"*EnSp*"},{"id":"U_2003","text":"*EmSp*"},{"id":"U_2008","text":"*PunctSp*"}]},{"id":"2","key":[{"id":"U_2009","pad":"50","text":"*ThSp*"},{"id":"U_200A","text":"*HSp*"},{"id":"U_200B","text":"*ZWSp*"},{"id":"U_200E","text":"*LTRM*"},{"id":"U_200F","text":"*RTLM*"},{"id":"U_00AD","text":"*SH*"},{"id":"T_0009","text":"*HTab*"},{"id":"U_200F","text":"*RTLM*"},{"id":"T_RTLBKSP","sp":"1","text":this._v>13?"*RTLBkSp*":"*BkSp*"},{"id":"T_new_338","sp":"1","text":this._v>13?"*LTRBkSp*":"*BkSp*"}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*","sk":[{"id":"T_new_206","text":"*Alt*"},{"id":"T_new_205","text":"*Ctrl*"},{"id":"T_new_207","text":"*Caps*"},{"id":"T_new_208","text":"*ABC*"},{"id":"T_new_209","text":"*abc*"},{"id":"T_new_210","text":"*Symbol*"},{"id":"T_new_211","text":"*AltGr*"},{"id":"T_new_212","text":"*LAlt*"},{"id":"T_new_258","text":"*RAlt*"},{"id":"T_new_259","text":"*LCtrl*"},{"id":"T_new_260","text":"*RCtrl*"},{"id":"T_new_261","text":"*LAltCtrlShift*"},{"id":"T_new_262","text":"*RAltCtrlShift*"},{"id":"T_new_263","text":"*AltShift*"},{"id":"T_new_264","text":"*CtrlShift*"},{"id":"T_new_265","text":"*AltCtrlShift*"},{"id":"T_new_266","text":"*LAltShift*"},{"id":"T_new_267","text":"*RAltShift*"},{"id":"T_new_268","text":"*LCtrlShift*"},{"id":"T_new_269","text":"*RCtrlShift*"},{"id":"T_new_292","text":this._v>13?"*ShiftLock*":"*Shift*"},{"id":"T_new_293","text":this._v>13?"*ShiftedLock*":"*Shifted*"}]},{"id":"T_ZWNJ","text":this._v>13?"*ZWNJ*":"<|>"},{"id":"T_ZWNJIOS","text":this._v>13?"*ZWNJiOS*":"<|>"},{"id":"T_ZWNJANDROID","text":this._v>13?"*ZWNJAndroid*":"<|>"},{"id":"U_200D","text":"*ZWJ*"},{"id":"U_2060","text":"*WJ*"},{"id":"U_034F","text":"*CGJ*"},{"id":"K_M","text":"m"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"590","id":"K_SPACE"},{"id":"K_ROPT","text":"*Hide*"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*","sk":[{"id":"T_new_270","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"T_new_295","text":this._v>13?"*LTREnter*":"*Enter*"}]}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_Q","text":"*Alt*"},{"id":"K_W","text":"*Ctrl*"},{"id":"K_E","text":"*Caps*"},{"id":"K_R","text":"*ABC*"},{"id":"K_T","text":"*abc*"},{"id":"K_Y","text":"*123*"},{"id":"K_U","text":"*Symbol*"},{"id":"K_I","text":"*Currency*"},{"id":"K_O","text":"*Shifted*"},{"id":"K_P","text":"*AltGr*"}]},{"id":"2","key":[{"id":"K_A","pad":"50","text":"*LAlt*"},{"id":"K_S","text":"*RAlt*"},{"id":"K_D","text":"*LCtrl*"},{"id":"K_F","text":"*RCtrl*"},{"id":"K_G","text":"*LAltCtrl*"},{"id":"K_H","text":"*RAltCtrl*"},{"id":"K_J","text":"*LAltCtrlShift*"},{"id":"K_K","text":"*RAltCtrlShift*"},{"id":"K_L","text":"*AltShift*"},{"id":"T_new_232","text":"*CtrlShift*"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shifted*"},{"id":"K_Z","text":"*AltCtrlShift*"},{"id":"K_X","text":"*LAltShift*"},{"id":"K_C","text":"*RAltShift*"},{"id":"K_V","text":"*RAltShift*"},{"id":"K_B","text":"*RCtrlShift*"},{"id":"K_N","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"K_M","text":this._v>13?"*LTREnter*":"*Enter*"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","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":"2","key":[{"layer":"shift","id":"K_4","pad":"50","text":"$"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_LBRKT","pad":"110","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_LBRKT","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_RBRKT","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"id":"K_SLASH","text":"\/"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.139.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,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,257)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,258)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}return r;};} \ No newline at end of file From ff81276d10f54c77cfe2fa793958b3a6c3d778e1 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 28 Sep 2023 15:30:30 +0700 Subject: [PATCH 022/107] chore(web): Add ZWNJGeneric --- web/src/engine/osk/src/specialCharacters.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/src/engine/osk/src/specialCharacters.ts b/web/src/engine/osk/src/specialCharacters.ts index faa5fd697b..ebd17ab06c 100644 --- a/web/src/engine/osk/src/specialCharacters.ts +++ b/web/src/engine/osk/src/specialCharacters.ts @@ -40,11 +40,12 @@ let specialCharacters = { '*RTLBkSp*': 0x72, '*ShiftLock*': 0x73, '*ShiftedLock*': 0x74, - '*ZWNJ*': 0x79, // If this one is specified, auto-detection will kick in. + '*ZWNJ*': 0x75, // If this one is specified, auto-detection will kick in. '*ZWNJiOS*': 0x75, // The iOS version will be used by default, but the '*ZWNJAndroid*': 0x76, // Android platform has its own default glyph. // Added in Keyman 17.0. // Reference: https://github.com/silnrsi/font-symchar/blob/v4.000/documentation/encoding.md + '*ZWNJGeneric*': 0x79, // Generic version of ZWNJ (no override) '*Sp*': 0x80, // Space '*NBSp*': 0x82, // No-break Space '*NarNBSp*': 0x83, // Narrow No-break Space From 5beaf32ad4fac54d681f673069ec66ab83746692 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 28 Sep 2023 15:35:48 +0700 Subject: [PATCH 023/107] chore(web): Update test9469 to use ZWNJGeneric --- web/src/test/manual/web/issue9469/test9469/build/test9469.js | 2 +- .../web/issue9469/test9469/source/test9469.keyman-touch-layout | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/test/manual/web/issue9469/test9469/build/test9469.js b/web/src/test/manual/web/issue9469/test9469/build/test9469.js index f081026931..45ed85b545 100644 --- a/web/src/test/manual/web/issue9469/test9469/build/test9469.js +++ b/web/src/test/manual/web/issue9469/test9469/build/test9469.js @@ -1 +1 @@ -if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_test9469());}function Keyboard_test9469(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_test9469";this.KN="test9469";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={};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='';this.KM=0;this.KBVER="1.1";this.KMBM=0x0000;this.KVKD="T_ZWNJ T_ZWNJIOS T_ZWNJANDROID";this.KVKL={"phone":{"font":"Tahoma","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_TAB","text":"*Tab*"},{"id":"T_TABLEFT","text":"*TabLeft*"},{"id":"U_0020","text":"*Sp*"},{"id":"U_00A0","text":"*NBSp*"},{"id":"U_202F","text":"*NarNBSp*"},{"id":"U_2000","text":"*EnQ*"},{"id":"U_2001","text":"*EmQ*"},{"id":"U_2002","text":"*EnSp*"},{"id":"U_2003","text":"*EmSp*"},{"id":"U_2008","text":"*PunctSp*"}]},{"id":"2","key":[{"id":"U_2009","pad":"50","text":"*ThSp*"},{"id":"U_200A","text":"*HSp*"},{"id":"U_200B","text":"*ZWSp*"},{"id":"U_200E","text":"*LTRM*"},{"id":"U_200F","text":"*RTLM*"},{"id":"U_00AD","text":"*SH*"},{"id":"T_0009","text":"*HTab*"},{"id":"U_200F","text":"*RTLM*"},{"id":"T_RTLBKSP","sp":"1","text":this._v>13?"*RTLBkSp*":"*BkSp*"},{"id":"T_new_338","sp":"1","text":this._v>13?"*LTRBkSp*":"*BkSp*"}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*","sk":[{"id":"T_new_206","text":"*Alt*"},{"id":"T_new_205","text":"*Ctrl*"},{"id":"T_new_207","text":"*Caps*"},{"id":"T_new_208","text":"*ABC*"},{"id":"T_new_209","text":"*abc*"},{"id":"T_new_210","text":"*Symbol*"},{"id":"T_new_211","text":"*AltGr*"},{"id":"T_new_212","text":"*LAlt*"},{"id":"T_new_258","text":"*RAlt*"},{"id":"T_new_259","text":"*LCtrl*"},{"id":"T_new_260","text":"*RCtrl*"},{"id":"T_new_261","text":"*LAltCtrlShift*"},{"id":"T_new_262","text":"*RAltCtrlShift*"},{"id":"T_new_263","text":"*AltShift*"},{"id":"T_new_264","text":"*CtrlShift*"},{"id":"T_new_265","text":"*AltCtrlShift*"},{"id":"T_new_266","text":"*LAltShift*"},{"id":"T_new_267","text":"*RAltShift*"},{"id":"T_new_268","text":"*LCtrlShift*"},{"id":"T_new_269","text":"*RCtrlShift*"},{"id":"T_new_292","text":this._v>13?"*ShiftLock*":"*Shift*"},{"id":"T_new_293","text":this._v>13?"*ShiftedLock*":"*Shifted*"}]},{"id":"T_ZWNJ","text":this._v>13?"*ZWNJ*":"<|>"},{"id":"T_ZWNJIOS","text":this._v>13?"*ZWNJiOS*":"<|>"},{"id":"T_ZWNJANDROID","text":this._v>13?"*ZWNJAndroid*":"<|>"},{"id":"U_200D","text":"*ZWJ*"},{"id":"U_2060","text":"*WJ*"},{"id":"U_034F","text":"*CGJ*"},{"id":"K_M","text":"m"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"590","id":"K_SPACE"},{"id":"K_ROPT","text":"*Hide*"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*","sk":[{"id":"T_new_270","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"T_new_295","text":this._v>13?"*LTREnter*":"*Enter*"}]}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_Q","text":"*Alt*"},{"id":"K_W","text":"*Ctrl*"},{"id":"K_E","text":"*Caps*"},{"id":"K_R","text":"*ABC*"},{"id":"K_T","text":"*abc*"},{"id":"K_Y","text":"*123*"},{"id":"K_U","text":"*Symbol*"},{"id":"K_I","text":"*Currency*"},{"id":"K_O","text":"*Shifted*"},{"id":"K_P","text":"*AltGr*"}]},{"id":"2","key":[{"id":"K_A","pad":"50","text":"*LAlt*"},{"id":"K_S","text":"*RAlt*"},{"id":"K_D","text":"*LCtrl*"},{"id":"K_F","text":"*RCtrl*"},{"id":"K_G","text":"*LAltCtrl*"},{"id":"K_H","text":"*RAltCtrl*"},{"id":"K_J","text":"*LAltCtrlShift*"},{"id":"K_K","text":"*RAltCtrlShift*"},{"id":"K_L","text":"*AltShift*"},{"id":"T_new_232","text":"*CtrlShift*"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shifted*"},{"id":"K_Z","text":"*AltCtrlShift*"},{"id":"K_X","text":"*LAltShift*"},{"id":"K_C","text":"*RAltShift*"},{"id":"K_V","text":"*RAltShift*"},{"id":"K_B","text":"*RCtrlShift*"},{"id":"K_N","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"K_M","text":this._v>13?"*LTREnter*":"*Enter*"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","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":"2","key":[{"layer":"shift","id":"K_4","pad":"50","text":"$"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_LBRKT","pad":"110","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_LBRKT","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_RBRKT","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"id":"K_SLASH","text":"\/"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.139.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,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,257)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,258)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}return r;};} \ No newline at end of file +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_test9469());}function Keyboard_test9469(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_test9469";this.KN="test9469";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={};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='';this.KM=0;this.KBVER="1.1";this.KMBM=0x0000;this.KVKD="T_ZWNJ T_ZWNJIOS T_ZWNJANDROID";this.KVKL={"phone":{"font":"Tahoma","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_TAB","text":"*Tab*"},{"id":"T_TABLEFT","text":"*TabLeft*"},{"id":"U_0020","text":"*Sp*"},{"id":"U_00A0","text":"*NBSp*"},{"id":"U_202F","text":"*NarNBSp*"},{"id":"U_2000","text":"*EnQ*"},{"id":"U_2001","text":"*EmQ*"},{"id":"U_2002","text":"*EnSp*"},{"id":"U_2003","text":"*EmSp*"},{"id":"U_2008","text":"*PunctSp*"}]},{"id":"2","key":[{"id":"U_2009","pad":"50","text":"*ThSp*"},{"id":"U_200A","text":"*HSp*"},{"id":"U_200B","text":"*ZWSp*"},{"id":"U_200E","text":"*LTRM*"},{"id":"U_200F","text":"*RTLM*"},{"id":"U_00AD","text":"*SH*"},{"id":"T_0009","text":"*HTab*"},{"id":"U_200F","text":"*RTLM*"},{"id":"T_RTLBKSP","sp":"1","text":this._v>13?"*RTLBkSp*":"*BkSp*"},{"id":"T_new_338","sp":"1","text":this._v>13?"*LTRBkSp*":"*BkSp*"}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*","sk":[{"id":"T_new_206","text":"*Alt*"},{"id":"T_new_205","text":"*Ctrl*"},{"id":"T_new_207","text":"*Caps*"},{"id":"T_new_208","text":"*ABC*"},{"id":"T_new_209","text":"*abc*"},{"id":"T_new_210","text":"*Symbol*"},{"id":"T_new_211","text":"*AltGr*"},{"id":"T_new_212","text":"*LAlt*"},{"id":"T_new_258","text":"*RAlt*"},{"id":"T_new_259","text":"*LCtrl*"},{"id":"T_new_260","text":"*RCtrl*"},{"id":"T_new_261","text":"*LAltCtrlShift*"},{"id":"T_new_262","text":"*RAltCtrlShift*"},{"id":"T_new_263","text":"*AltShift*"},{"id":"T_new_264","text":"*CtrlShift*"},{"id":"T_new_265","text":"*AltCtrlShift*"},{"id":"T_new_266","text":"*LAltShift*"},{"id":"T_new_267","text":"*RAltShift*"},{"id":"T_new_268","text":"*LCtrlShift*"},{"id":"T_new_269","text":"*RCtrlShift*"},{"id":"T_new_292","text":this._v>13?"*ShiftLock*":"*Shift*"},{"id":"T_new_293","text":this._v>13?"*ShiftedLock*":"*Shifted*"}]},{"id":"T_ZWNJ","text":"*ZWNJGeneric*"},{"id":"T_ZWNJIOS","text":this._v>13?"*ZWNJiOS*":"<|>"},{"id":"T_ZWNJANDROID","text":this._v>13?"*ZWNJAndroid*":"<|>"},{"id":"U_200D","text":"*ZWJ*"},{"id":"U_2060","text":"*WJ*"},{"id":"U_034F","text":"*CGJ*"},{"id":"K_M","text":"m"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"590","id":"K_SPACE"},{"id":"K_ROPT","text":"*Hide*"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*","sk":[{"id":"T_new_270","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"T_new_295","text":this._v>13?"*LTREnter*":"*Enter*"}]}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_Q","text":"*Alt*"},{"id":"K_W","text":"*Ctrl*"},{"id":"K_E","text":"*Caps*"},{"id":"K_R","text":"*ABC*"},{"id":"K_T","text":"*abc*"},{"id":"K_Y","text":"*123*"},{"id":"K_U","text":"*Symbol*"},{"id":"K_I","text":"*Currency*"},{"id":"K_O","text":"*Shifted*"},{"id":"K_P","text":"*AltGr*"}]},{"id":"2","key":[{"id":"K_A","pad":"50","text":"*LAlt*"},{"id":"K_S","text":"*RAlt*"},{"id":"K_D","text":"*LCtrl*"},{"id":"K_F","text":"*RCtrl*"},{"id":"K_G","text":"*LAltCtrl*"},{"id":"K_H","text":"*RAltCtrl*"},{"id":"K_J","text":"*LAltCtrlShift*"},{"id":"K_K","text":"*RAltCtrlShift*"},{"id":"K_L","text":"*AltShift*"},{"id":"T_new_232","text":"*CtrlShift*"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shifted*"},{"id":"K_Z","text":"*AltCtrlShift*"},{"id":"K_X","text":"*LAltShift*"},{"id":"K_C","text":"*RAltShift*"},{"id":"K_V","text":"*RAltShift*"},{"id":"K_B","text":"*RCtrlShift*"},{"id":"K_N","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"K_M","text":this._v>13?"*LTREnter*":"*Enter*"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","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":"2","key":[{"layer":"shift","id":"K_4","pad":"50","text":"$"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_LBRKT","pad":"110","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_LBRKT","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_RBRKT","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"id":"K_SLASH","text":"\/"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.138.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,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,257)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,258)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}return r;};} \ No newline at end of file diff --git a/web/src/test/manual/web/issue9469/test9469/source/test9469.keyman-touch-layout b/web/src/test/manual/web/issue9469/test9469/source/test9469.keyman-touch-layout index 5edff50120..5f8ac2101a 100644 --- a/web/src/test/manual/web/issue9469/test9469/source/test9469.keyman-touch-layout +++ b/web/src/test/manual/web/issue9469/test9469/source/test9469.keyman-touch-layout @@ -199,7 +199,7 @@ }, { "id": "T_ZWNJ", - "text": "*ZWNJ*" + "text": "*ZWNJGeneric*" }, { "id": "T_ZWNJIOS", From 2d8013360ff0ba6f3da97b7b775454de28d43189 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 28 Sep 2023 15:36:04 +0700 Subject: [PATCH 024/107] chore(android): Update test9469 to use ZWNJGeneric --- .../app/src/main/assets/test9469.kmp | Bin 4416 -> 4417 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/android/Tests/KeyboardHarness/app/src/main/assets/test9469.kmp b/android/Tests/KeyboardHarness/app/src/main/assets/test9469.kmp index b83a0c509b5e08d0484358b273280c642eccb998..f09531b5651019e83d56cc684f04cdb8f88feae7 100644 GIT binary patch delta 3778 zcmZvf2T&8tw#P${^dh3tq)P7w6i`AB9jT#%)L^JVX_5e!q9n8+MT*j;m(T?xiqg9v z9U_AC-s{DC-@Nbp-n=ujv$H$r%8>FG2W-EfKv~0{yk=J86`vH+&byA@uBmz@MPoqWGPoYvlZEjK)!ELK~ z`);7^&g9f#Mb!J>hbOKIfl55(U>^sk#C66_tGmh@U(TZiR-m;~#B9dUK7+M)>vwFm zi#lh}g&ZV$<1T)Rvjq9`wbq{RNP{8nbCN}pYJ;cLJ_=vG$G78?7RGMkGPiU-C$*tU zgZM0Mk(c0sG^tR0b`JJ*dw9NRH372BuN%vkAP|JL)T=z`$yMPFIoNp+N`Z?c~z4b0JsAL0H^@~0K&-^abE^> zU(6luzkmh18-cG!=)ZY~TX6-VjI1#<=?rw9uEZG`qYZCWJ2 z_SuoItLGzIz;E^o@{dbfbX$^9?E?MR7*f94SDoB2iy?IWmO<(g0Ld09@`xNlO&)>gN~Vu&x1Q!M(PfB(j}CGCSVI(y+d z{L7J4oR_ej?QvFBp6Av~5EEhJbos(9K%xK6+b7w8Lt=achO{B&sG`a!iz^H#$nscb!kaRoPoDKl zPO8him}Jh2+?LaQd_Dh-7!w($n8WddVKgQ`y7u|)mNTDjuWb%lfxG7NHzz?YLl~Y_ z-OXyw&3Rg6iEN9}p2vpF!7@cAe!6&XS$C7a<#O%$*oENbYwNh2Sy=Y2G|4Vqu719> z$}Zi>1%KV^#fQ%xv5#%q;_&QvqJKU+m&W{G%oG3soE-q5`unqk`A$R6eJ0fDk<4oF z@LyfUq~wzZU&)Z^M=HT%sCj-+ZUUk5-VH`YQc!r>GRdCcDX-!+t};E&2DgG?x1Ff` z>Di6-E8A?l#nT7XiC1*U8gMAJMCSmv+;Zk?)EWeNvzA0h9#G!~N9{fA&b~ z7|Jp{ldC&))tNq;0ZDb6nNmv?MnlPghU;E80-ZqwcSnWaUKNOrZBoTIP?Gk_GT!|m zuJD)%tCx$*nV-ph?Pl?DOKtZ*8~xNX94iW^Sq)u? zGY6DbAl(H;L}6L=4@cxFSM@@8PV+<_CHtb$->5CWMtW4=2fxk_hFZYsb0(IAy0>Zz zgr@k3rl{~4tEpfu<|i+>R$)%mFrRt4!sqx;hzllU385F}~9o*$0|- zP@7L(aNAU>NC{I9UtY)q=xj!O`or5ihnt^Tk&BCdKahheZ5t=!CTq&xcb3f5L5tK* zB5yhZy*QpPyxImQ2z}cS(}%^T3yas!TjtLGwzaK_BUF9vjazhTi!mC$c_)?yVoisL z`VvgW;}R)KUg1y6`|{8T;iDT|!P%c=<$*m{GPkS<6QH0n;^|^}c{a%lRWuySI#?+1 zL$;P)X4HSUFsk(%a(nxhlz+_}=g&q2` z_*t}UNAqsJSf#3#7C!icBZjML3#X@3dCvCAiTe)oO-kc3voeP4aGR;nXMrc@v>zCQ z;r%0^70w_-RT2yvs%ey0P@G8fxw2b{0dlg~@T58E61e|B52ZPvHrSAbGlp~K5wS#a_EK%XkT-tDFh@1^V(;1MR;2Lh152mCye5BpO*c3um z?Zf0-)Uh`2m>Pmz5*Xu0cY$Fs$sM3gMGO!IJ4{q6V8WCBFvsIU;;A&UpzEE;Ocw8| z5P+EG>L_JIxTsi1vl|P6nE4Yiv~6@&y!3}NLtcZWqp?k+~%A>}TtAX0uu<4bpasRi00K{p_^A2E??p!IU^SHMC4R_Ep zszg_kOSL(?-}KX(xDjL?*RNpvmZea8j+>x~l$X>as-q$>Qw37z>FyP8cK%%40n=8K zr0Vzg5>tUCW}Cb;mh~O7W|Wc}Q4xCB7S9_GqVGjJREydlH^664@!OR}(Qu8~65|Qe z+H}Nc{!Yz8SmF=kMETr`xy^BWITE} z?^OaD`Gtjt>pfu+kgs8U26=O8BI@%V?WWIk^pIFCS3QEh=6%sUz>S<`P z1{_55fx;n1aOA~34_(aMTO7Q2)w30UD^1(+*CicA$}d&g3!zv{yp>!nT!uoS)2kg- zo)G1;)oFzC*}~u`7Ut3mfD3aZ1*8je;ZB@gtrT5EN#UCbDgqR3Jo$qrS_vC`Lq86o zel*ql+Baw&H$RB5bxhDf<>Jc@p$)kH6c@kB*EMSxq#3@coOtwcwN?9rPpd!t&|4Yo z*Bg`6L((y(tM6OvsvM72zl!=T?uE1y@A=5?&PZFDw5YxT6VU@OLxSeEt#3(%sn+ol4_$Dpd8)Q1xKErNtlGC-_cM~!0mae zk6LsxnVQ;?B)e7y_3q`7vLJ{}dF|J1exe)h8k(fDG5&f?u+#5g(N<_>YU~lOk}~~8 zNtD6nn>e?%@g#lnHJOIp<=Hvi;fm*i^*LX|IO`?IgZ3gTy?2_ivu#EEAH@_KLv4jr zG7&cGvKyvXCjtP3uKKw@MfJJU({^YahwPhaVGkHA~BCb%`9x&Hn0J;NpB{&=*ex^TdC>;yi`80VT zK3|*XC~)JZ$b(YeS* z2)YHs3P5x$m@>f`LB6{RmnWsoN?M{m-^-*_1N#}YRmtIj;J zG~duN-yPjp(qWY%7oL|)I$c1$UStleq}>3~xxXLek{IRt`l2Ls@CAnMFYteW%PO^- z30wgu5Fr5o$}8eNPWF!f1KjXGz?%<+lfC$KjZB!~SSyqYA8-6pMDFTSM(vPJ=n4JL z@FSX!XkBIPuSB+`2+6J{s+vkaj%-X5@vG{aM2_ST)KgX0 zgqeYEj36~UVf|I2g2PB5UCCz57 z9i<&IHg6n>Pzb#(N)9$xX3nth^Y8WQ2@6R*KKWP5K2PcWc{?&emxv24Y%6;IlM!ZHLML|Zj}H8gOu=%|OLG2M{on5Kiu{$`xf<$NZ~EILS3cNS xdRC%;VT3S0z~YLqGv zsu+q?FAxOjQeN)7&s?2no}Jm~C>*+1P zR2RE#lNP6Zh8I{E5Z*H}ce^S^hZ@oJ*sLD>A}G{b;l9y|t=fEUqO{r|Ep#+@N<KoqUa*;RUWhQG9|;0ZMUvX+(S>EmZbh^;-d^xg zT(Lm~qfqS^>yGnjhdzK4`r*6eVOnmwNOpD8jU;7L~SOn%gd}~!YKz-B|rC5#2v0cHFB`; zUl=-!H;K(|3zmr?@VSMtTH`Pu2& zwxh+0Jjyz2qjCDwG~Y}`$(>rnoDQi^m|C_4%G-044P4+iZ#gBg5(nO{&IWG{v<<+e z)NAph2mMJ|oXq5lRo#|To8`NYUk-;+9!Lo1hMp;J#B|G3Nvmm4UR(Zg>jz+vU^LI1 zkRMa4dIClf7R=Jnrzi?X{M(_Z4qM(cYSYRZPxf(F=kzlA>gfIg zSawz(Q{{rmVzs;Vk-cYiclFFY`nZ5#oZ_okTwM^sYV;0_c9La8mP6iYGCQLsPKo+w zo*HY9aQVECGZ(>au)uH1A5d(aEO1XFWc!xp!#8d6pHsi)=-uLY6&T+a{i!oGfN6WY z*pSOH&JWi9P;NbQwuATcxP6B-GDhf`A2EO&fzK;4j8AYu%O13H-j+(Qr`eh&a7K>j zoy)=r`^xpg!OZ?#8j#6c!;2|ffLhf-bLfU=$g|qf z{*vsndl>zAMb7E9PHf`+S+iBM{>2C2BbLXp&9;XKxM0sa9Pl`In~piptH*3Y_AmP2wlPb`I=CPJZh!Lv9 zaSvzynN3LvJTaLIh)YQN=H>$aA#4*)C%XGESXB8ECsztrQ#?JvBREFP=;%?y7l?M_ zv~|{kpOba738s!6NyzJV)ho)83cAF(hv-3IaJ}ZdFd>n!_oi|x?%R#w z+En-eSD&3i+TOedvCn$ZJgovplrlr6V#THZT68FyTXk`%$1K!$4PsWKleX8Z~Wa;HWhnW)lS@=x@V};x;k}fx4txYZG{oJGxqOLRmf;M4}xd#XTWZo%J%D z*K$>0B4{fv@qr@%+T|enY(q{#nPsHwu%}5Og{`$ZDyOsVsA%rteB5{-#=mCqm||Et zBKJ~t0+_h_TrwPOI=`Q*d;5lctw6S;f=<(eEgx-j+g1)Tx!gn1X58`9J##7E2VQ&7 zP{66@!!fuSQsN-a#?aIZSub^p<*@?scrZJhx79f#uBe?WgqVG9gO}m1XaxnS*Q|(s zUD_MixlIl7D`mw-IE#_=$clPUKZ&Fof#S)i2DhH%#zC#aL#4MFp7G0rwnnyJsv_axJD;qG!O>UDpDIm>&$ zepeYp4@7Bth?3rH`L3kfioMh1wq}KYuGrHgo17C-!hC50yKZK+oLsC_@{}e5sH@=z zVtuXs;#y=gT@=*35i%9};}X{D{(sp=`;&cEE8&lE-;<)9L`<}lUD>A^THC20ke+1r z@7!|RvRg|W)(^>UZIy8OxasvvgUq%-+|YIpzdp^WhVfrM_>vMhMYeA^pZ$(4wcg7; zHU&IFarU_5{K&d;`kGBf{F9$?7w;cs`~%l1xQigtnilq^99B;^(8AHUNI|FTy$N*< zb5AU{SP0=+eWwfcnTpqW|NgcJ^15-z^Zm#-!&+5VY#9jZxsQlnv*#%ZCc1FH7->st z$MG8cD=e8nZi9iN<@e_egjd?tzAou<9g|L;BY#!ob{-AL=uWsYgB!l*0l3QQ0+gT( zpo^{aZCv92%OIhiHj~eux>ArpUT$CfF4^b0una&JXqduFiZc9h1D{p#DqxNKQx3|q z-TafKL1QN(z^+@mwKz+$-7_Mf>ELq3{(9CBI`gxnW*W84JJBX6*vb}ngyZAAGSg8*rl!#M3L&eK|GYg zDn%m`jmam;MAznOicq>J>xfY1%L!d9Qoqa@u30k_@S<`uU-B|xGIec54O*V*yUckn zD<)1z!&I2wZM_bJ_+Ix|xY01{yZ+!oB()A-X3OY_S;j+f#H+qG;tXH8TvfhPvvo;E4Bz5+hiw8$Vppl457rk44q@uxh0BpRkC#>(sDx z^vXi18Mdx9y>)^GlI?$TH!|wJ!Srz}X3mYf7N=0cHY5D5 z+_k>YRWs}>ytKFLS{HGbxo3;G;wDK>=$H9*z7@a^mum*zIsk3gZWtI!NlB**$9S~p zla6Ucpd}8NAr|^{VZBwi4AGK^t{Grnd&Jm{dxMN9?k)=QS9rNU^zPFu++HJKP7nEP_GXx&th2>Mv;_AqsqEr3Pa@)q@t2%;hyG%`Q@%uWwU9=ABSD zYMHC2`;qIQVbK)td$q=74ARSkVSA~kJ4N9>g{?cFl8?UA#H2Prmu4Z)X$>R@c!k7s zouYl_1TAJl-VB$|-A&JF+pnJvI{7&4e3#z(IsrqnJ;+2ec9+YIfyXa%(n=^Y96wf` zIuEUq?}jso+h8S6X>kK|=mWK>kRt6x*9l96==ZJ~6%1 z)c8SmOlflW&IqWblt)QT_DL$vJnag`m^^d#?+%|b65hrZqQb#X`hazByM%#vT3HhX zYWQAPp5$ZT?81(KN!URDI=_s1M!Db4Z=F$!`d^olag|9{<9~IJ7wj(v|^N+~?%MdP{&>toAr_3Lb|2OczFPdfWGxJfrWc=sk{{UP& B@YMhS From a5cbf6aab864b822a3a589f30cee96c33bd2fc41 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Thu, 28 Sep 2023 16:40:29 +0700 Subject: [PATCH 025/107] fix(web): test page path on the index page --- web/src/test/manual/web/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/test/manual/web/index.html b/web/src/test/manual/web/index.html index 6d5c4bb466..2597d8caac 100644 --- a/web/src/test/manual/web/index.html +++ b/web/src/test/manual/web/index.html @@ -64,7 +64,7 @@

Test Start of Sentence (#3621)

Test start of sentence keyboard rules (#5963)

Tests predictive text & other handling of rule matching when the final rule group does not match (#6005)

-

Tests handling of new default-subkey feature (#9430)

+

Tests handling of new default-subkey feature (#9430)

Test special characters rendering with keymanweb-osk.ttf (#9469)

Other

Keystroke processing regression test engine.

From 08f0b4dfed7efefb23db3007be3daf7aa723fdec Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 19 Sep 2023 19:08:22 +0200 Subject: [PATCH 026/107] =?UTF-8?q?chore(linux):=20Extract=20free=5Finfo?= =?UTF-8?q?=20method=20in=20kmpdetails.c=20=F0=9F=8F=98=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also add guard to kmpdetails.h. --- linux/ibus-keyman/src/kmpdetails.c | 28 ++++++++++++++++++++-------- linux/ibus-keyman/src/kmpdetails.h | 7 ++++++- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/linux/ibus-keyman/src/kmpdetails.c b/linux/ibus-keyman/src/kmpdetails.c index eba95f4ef9..18ffde73ac 100644 --- a/linux/ibus-keyman/src/kmpdetails.c +++ b/linux/ibus-keyman/src/kmpdetails.c @@ -455,6 +455,24 @@ kmp_json_status free_keyboard_details(keyboard_details *kbd_details) return JSON_OK; } +void free_info(gpointer data) { + kmp_info *info = (kmp_info *)data; + if (info->name) + g_free(info->name); + if (info->version) + g_free(info->version); + if (info->copyright) + g_free(info->copyright); + if (info->author_desc) + g_free(info->author_desc); + if (info->author_url) + g_free(info->author_url); + if (info->website_desc) + g_free(info->website_desc); + if (info->website_url) + g_free(info->website_url); +} + kmp_json_status free_kmp_details(kmp_details * details) { g_assert(details != NULL); @@ -462,15 +480,9 @@ kmp_json_status free_kmp_details(kmp_details * details) g_free(details->system.keymanDeveloperVersion); g_free(details->options.readmeFile); g_free(details->options.graphicFile); - g_free(details->info.name); - g_free(details->info.version); - g_free(details->info.copyright); - g_free(details->info.author_desc); - g_free(details->info.author_url); - g_free(details->info.website_desc); - g_free(details->info.website_url); + free_info(&details->info); if (details->keyboards != NULL) { - g_list_free_full(details->keyboards, (GDestroyNotify)free_keyboard); + g_list_free_full(details->keyboards, (GDestroyNotify)free_keyboard); } if (details->files != NULL) { g_list_free_full(details->files, (GDestroyNotify)free_fileinfo); diff --git a/linux/ibus-keyman/src/kmpdetails.h b/linux/ibus-keyman/src/kmpdetails.h index 3bcf6a9739..586f815bae 100644 --- a/linux/ibus-keyman/src/kmpdetails.h +++ b/linux/ibus-keyman/src/kmpdetails.h @@ -1,3 +1,6 @@ +#ifndef __KMPDETAILS_H__ +#define __KMPDETAILS_H__ + // kmp details from json #include @@ -75,4 +78,6 @@ kmp_json_status get_kmp_details(const gchar *kmp_dir, kmp_details *details); kmp_json_status free_kmp_details(kmp_details * details); kmp_json_status get_keyboard_details(const gchar *kmp_dir, const gchar *id, keyboard_details *details); kmp_json_status free_keyboard_details(keyboard_details * details); -kmp_json_status print_kmp_details(kmp_details * details); \ No newline at end of file +kmp_json_status print_kmp_details(kmp_details * details); + +#endif // __KMPDETAILS_H__ From f8866fea9537a4e8c680c4d0f3d639a9b6645f8c Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 28 Sep 2023 21:35:51 +0700 Subject: [PATCH 027/107] chore(web): Update test keyboard again --- web/src/test/manual/web/issue9469/test9469/build/test9469.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/test/manual/web/issue9469/test9469/build/test9469.js b/web/src/test/manual/web/issue9469/test9469/build/test9469.js index 45ed85b545..10e028fdd6 100644 --- a/web/src/test/manual/web/issue9469/test9469/build/test9469.js +++ b/web/src/test/manual/web/issue9469/test9469/build/test9469.js @@ -1 +1 @@ -if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_test9469());}function Keyboard_test9469(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_test9469";this.KN="test9469";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={};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='';this.KM=0;this.KBVER="1.1";this.KMBM=0x0000;this.KVKD="T_ZWNJ T_ZWNJIOS T_ZWNJANDROID";this.KVKL={"phone":{"font":"Tahoma","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_TAB","text":"*Tab*"},{"id":"T_TABLEFT","text":"*TabLeft*"},{"id":"U_0020","text":"*Sp*"},{"id":"U_00A0","text":"*NBSp*"},{"id":"U_202F","text":"*NarNBSp*"},{"id":"U_2000","text":"*EnQ*"},{"id":"U_2001","text":"*EmQ*"},{"id":"U_2002","text":"*EnSp*"},{"id":"U_2003","text":"*EmSp*"},{"id":"U_2008","text":"*PunctSp*"}]},{"id":"2","key":[{"id":"U_2009","pad":"50","text":"*ThSp*"},{"id":"U_200A","text":"*HSp*"},{"id":"U_200B","text":"*ZWSp*"},{"id":"U_200E","text":"*LTRM*"},{"id":"U_200F","text":"*RTLM*"},{"id":"U_00AD","text":"*SH*"},{"id":"T_0009","text":"*HTab*"},{"id":"U_200F","text":"*RTLM*"},{"id":"T_RTLBKSP","sp":"1","text":this._v>13?"*RTLBkSp*":"*BkSp*"},{"id":"T_new_338","sp":"1","text":this._v>13?"*LTRBkSp*":"*BkSp*"}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*","sk":[{"id":"T_new_206","text":"*Alt*"},{"id":"T_new_205","text":"*Ctrl*"},{"id":"T_new_207","text":"*Caps*"},{"id":"T_new_208","text":"*ABC*"},{"id":"T_new_209","text":"*abc*"},{"id":"T_new_210","text":"*Symbol*"},{"id":"T_new_211","text":"*AltGr*"},{"id":"T_new_212","text":"*LAlt*"},{"id":"T_new_258","text":"*RAlt*"},{"id":"T_new_259","text":"*LCtrl*"},{"id":"T_new_260","text":"*RCtrl*"},{"id":"T_new_261","text":"*LAltCtrlShift*"},{"id":"T_new_262","text":"*RAltCtrlShift*"},{"id":"T_new_263","text":"*AltShift*"},{"id":"T_new_264","text":"*CtrlShift*"},{"id":"T_new_265","text":"*AltCtrlShift*"},{"id":"T_new_266","text":"*LAltShift*"},{"id":"T_new_267","text":"*RAltShift*"},{"id":"T_new_268","text":"*LCtrlShift*"},{"id":"T_new_269","text":"*RCtrlShift*"},{"id":"T_new_292","text":this._v>13?"*ShiftLock*":"*Shift*"},{"id":"T_new_293","text":this._v>13?"*ShiftedLock*":"*Shifted*"}]},{"id":"T_ZWNJ","text":"*ZWNJGeneric*"},{"id":"T_ZWNJIOS","text":this._v>13?"*ZWNJiOS*":"<|>"},{"id":"T_ZWNJANDROID","text":this._v>13?"*ZWNJAndroid*":"<|>"},{"id":"U_200D","text":"*ZWJ*"},{"id":"U_2060","text":"*WJ*"},{"id":"U_034F","text":"*CGJ*"},{"id":"K_M","text":"m"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"590","id":"K_SPACE"},{"id":"K_ROPT","text":"*Hide*"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*","sk":[{"id":"T_new_270","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"T_new_295","text":this._v>13?"*LTREnter*":"*Enter*"}]}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_Q","text":"*Alt*"},{"id":"K_W","text":"*Ctrl*"},{"id":"K_E","text":"*Caps*"},{"id":"K_R","text":"*ABC*"},{"id":"K_T","text":"*abc*"},{"id":"K_Y","text":"*123*"},{"id":"K_U","text":"*Symbol*"},{"id":"K_I","text":"*Currency*"},{"id":"K_O","text":"*Shifted*"},{"id":"K_P","text":"*AltGr*"}]},{"id":"2","key":[{"id":"K_A","pad":"50","text":"*LAlt*"},{"id":"K_S","text":"*RAlt*"},{"id":"K_D","text":"*LCtrl*"},{"id":"K_F","text":"*RCtrl*"},{"id":"K_G","text":"*LAltCtrl*"},{"id":"K_H","text":"*RAltCtrl*"},{"id":"K_J","text":"*LAltCtrlShift*"},{"id":"K_K","text":"*RAltCtrlShift*"},{"id":"K_L","text":"*AltShift*"},{"id":"T_new_232","text":"*CtrlShift*"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shifted*"},{"id":"K_Z","text":"*AltCtrlShift*"},{"id":"K_X","text":"*LAltShift*"},{"id":"K_C","text":"*RAltShift*"},{"id":"K_V","text":"*RAltShift*"},{"id":"K_B","text":"*RCtrlShift*"},{"id":"K_N","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"K_M","text":this._v>13?"*LTREnter*":"*Enter*"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","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":"2","key":[{"layer":"shift","id":"K_4","pad":"50","text":"$"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_LBRKT","pad":"110","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_LBRKT","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_RBRKT","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"id":"K_SLASH","text":"\/"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.138.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,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,257)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,258)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}return r;};} \ No newline at end of file +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_test9469());}function Keyboard_test9469(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_test9469";this.KN="test9469";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={};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='';this.KM=0;this.KBVER="1.1";this.KMBM=0x0000;this.KVKD="T_ZWNJ T_ZWNJIOS T_ZWNJANDROID";this.KVKL={"phone":{"font":"Tahoma","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_TAB","text":"*Tab*"},{"id":"T_TABLEFT","text":"*TabLeft*"},{"id":"U_0020","text":"*Sp*"},{"id":"U_00A0","text":"*NBSp*"},{"id":"U_202F","text":"*NarNBSp*"},{"id":"U_2000","text":"*EnQ*"},{"id":"U_2001","text":"*EmQ*"},{"id":"U_2002","text":"*EnSp*"},{"id":"U_2003","text":"*EmSp*"},{"id":"U_2008","text":"*PunctSp*"}]},{"id":"2","key":[{"id":"U_2009","pad":"50","text":"*ThSp*"},{"id":"U_200A","text":"*HSp*"},{"id":"U_200B","text":"*ZWSp*"},{"id":"U_200E","text":"*LTRM*"},{"id":"U_200F","text":"*RTLM*"},{"id":"U_00AD","text":"*SH*"},{"id":"T_0009","text":"*HTab*"},{"id":"U_200F","text":"*RTLM*"},{"id":"T_RTLBKSP","sp":"1","text":this._v>13?"*RTLBkSp*":"*BkSp*"},{"id":"T_new_338","sp":"1","text":this._v>13?"*LTRBkSp*":"*BkSp*"}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*","sk":[{"id":"T_new_206","text":"*Alt*"},{"id":"T_new_205","text":"*Ctrl*"},{"id":"T_new_207","text":"*Caps*"},{"id":"T_new_208","text":"*ABC*"},{"id":"T_new_209","text":"*abc*"},{"id":"T_new_210","text":"*Symbol*"},{"id":"T_new_211","text":"*AltGr*"},{"id":"T_new_212","text":"*LAlt*"},{"id":"T_new_258","text":"*RAlt*"},{"id":"T_new_259","text":"*LCtrl*"},{"id":"T_new_260","text":"*RCtrl*"},{"id":"T_new_261","text":"*LAltCtrlShift*"},{"id":"T_new_262","text":"*RAltCtrlShift*"},{"id":"T_new_263","text":"*AltShift*"},{"id":"T_new_264","text":"*CtrlShift*"},{"id":"T_new_265","text":"*AltCtrlShift*"},{"id":"T_new_266","text":"*LAltShift*"},{"id":"T_new_267","text":"*RAltShift*"},{"id":"T_new_268","text":"*LCtrlShift*"},{"id":"T_new_269","text":"*RCtrlShift*"},{"id":"T_new_292","text":this._v>13?"*ShiftLock*":"*Shift*"},{"id":"T_new_293","text":this._v>13?"*ShiftedLock*":"*Shifted*"}]},{"id":"T_ZWNJ","text":"*ZWNJGeneric*"},{"id":"T_ZWNJIOS","text":this._v>13?"*ZWNJiOS*":"<|>"},{"id":"T_ZWNJANDROID","text":this._v>13?"*ZWNJAndroid*":"<|>"},{"id":"U_200D","text":"*ZWJ*"},{"id":"U_2060","text":"*WJ*"},{"id":"U_034F","text":"*CGJ*"},{"id":"K_M","text":"m"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"590","id":"K_SPACE"},{"id":"K_ROPT","text":"*Hide*"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*","sk":[{"id":"T_new_270","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"T_new_295","text":this._v>13?"*LTREnter*":"*Enter*"}]}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_Q","text":"*Alt*"},{"id":"K_W","text":"*Ctrl*"},{"id":"K_E","text":"*Caps*"},{"id":"K_R","text":"*ABC*"},{"id":"K_T","text":"*abc*"},{"id":"K_Y","text":"*123*"},{"id":"K_U","text":"*Symbol*"},{"id":"K_I","text":"*Currency*"},{"id":"K_O","text":"*Shifted*"},{"id":"K_P","text":"*AltGr*"}]},{"id":"2","key":[{"id":"K_A","pad":"50","text":"*LAlt*"},{"id":"K_S","text":"*RAlt*"},{"id":"K_D","text":"*LCtrl*"},{"id":"K_F","text":"*RCtrl*"},{"id":"K_G","text":"*LAltCtrl*"},{"id":"K_H","text":"*RAltCtrl*"},{"id":"K_J","text":"*LAltCtrlShift*"},{"id":"K_K","text":"*RAltCtrlShift*"},{"id":"K_L","text":"*AltShift*"},{"id":"T_new_232","text":"*CtrlShift*"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shifted*"},{"id":"K_Z","text":"*AltCtrlShift*"},{"id":"K_X","text":"*LAltShift*"},{"id":"K_C","text":"*RAltShift*"},{"id":"K_V","text":"*RAltShift*"},{"id":"K_B","text":"*RCtrlShift*"},{"id":"K_N","text":this._v>13?"*RTLEnter*":"*Enter*"},{"id":"K_M","text":this._v>13?"*LTREnter*":"*Enter*"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","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":"2","key":[{"layer":"shift","id":"K_4","pad":"50","text":"$"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"width":"10","sp":"10"}]},{"id":"3","key":[{"id":"K_LBRKT","pad":"110","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_LBRKT","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_RBRKT","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"id":"K_SLASH","text":"\/"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.141.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,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,257)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,258)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}return r;};} \ No newline at end of file From ffd428da21b2854349992ac4c63eccc881fff64a Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 28 Sep 2023 21:36:00 +0700 Subject: [PATCH 028/107] chore(android): Update test keyboard again --- .../app/src/main/assets/test9469.kmp | Bin 4417 -> 4421 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/android/Tests/KeyboardHarness/app/src/main/assets/test9469.kmp b/android/Tests/KeyboardHarness/app/src/main/assets/test9469.kmp index f09531b5651019e83d56cc684f04cdb8f88feae7..8390d5dee317ad8a78b8ee4d33805019846f9907 100644 GIT binary patch delta 2073 zcmZvdcT|&E8pc0BBtU=!14`3O5Ev8bMMyx5A`(cbDntPZ9VwwiK?3=Ztc#3FFAnyy zNE3(($?^*?+nXcn>s{({JJR6{MZI8@+@gY~2Zxll9a@{sWTd5v z?<(KqL$6=N=#oR&uk3Oob$^sII`04#k&2XRj$8A4`|hUbUq`s^*bsrAR{-_=?io5T zUvk$1J{^;)EM>b-DiS6fb~!VQQ`SQ-CNspUSB_+dcUn5RRuLchq4v;FlRpTuFUFf! zwp<3}NJZudTsZF8W9QR#GqX|MXu4vQIU)@J zNC*Hx0RW(dB+zUutZa-Tqmw@7yG4585nXO2;B6F&ETJwApx*hsMayyyA8I0C)S}uu zA$e<=dk9~hOX@=>N+IMXm^>aYAUoqZR~jLH68RNa^$O%ORX=~OOW$Is(0aW8I$dP9 z(BIqB`ylTU7L&SIk3%~;3FAh`HNLp|EOogDG&AYyxklJ^+*#hZ&0mUj{DE6>5)dw_ z=i2=JBG-*`Pg$H^gIh7BHQsuWhEWD(P9;d>Bn8|cMDxI~ill;T&xtE!S5%>UF~8S8 zw2a+pq2e`&WvPzt9aTSGP^0w9Oi<*v&qHDr<~gYOdW%*0$*Y`4>Q#EEZAPI@F=k`> zU*9)c@N@ZC$&5*{5+ho)mgjYs7}HeC9=qhhU+`l4Wu+1Ok8P|O!W@o7 zW0X?YOqPyf%}v%D#neDtglOVDm$kZPxjZtf_1|6h8{dsx=Og=gD|pUrtGA=y$A&fr z<0_g%%F#vMBromLjeIyMkEyJYaR5}NFpu85VwSj^YYiqZ z>D_#v={r^Iqk)OP0Jvt^5Mq-SSbf6h>AJPx+FAyE{_*eCYpQ}Tpw>P)@I~KLOlEN4 z{Pu63krr0u=Ro~Hk|xHx(C63B1StSGv|$Iu4J#yuL{(W!YZF5CmKr{eT6 zie^o>#orJk`YmMvth)hrNrI?SUdR3p(Hy)}ESjPi%D(F{SzZ@YcSe~tf=^C@&HE1! zoQ;f(^Yqh$o1A2Z@O0+h1vt{f37W*KI^@hWjP4i#-#hS$6wNPNM3|sGK#awmKl)pq zl@k*L@>!H?zRZF2E%|pQh=H05+N!(bW*vJ~n{js(ku(b(w^G7T#KS%hLwH$rid~1y zVZoCuz@1|dmGV)ellxOZpYy#p+O1gj(>FV>* zboZ}ety16EZ!))KnFOJw01#N*0I#qCJwAjI{4eGnJ+536ShMb|ic4c&X?ev@4Fu!% zJF2Qqa~*LrQK~Ks9(f7&fhkdHg--J;KBO5}4$t-{Jss|w=;2PS&dZ;Eb^1(dAzKYm zg3f;C;FnPgQ9}-PLhd?_!KV3g#j~k2&W@piBRB#*4759ftfH8WPx-6+PRk1K-)@vi zL|zHbM8|AFKOe+r=wVKnTH4;~pCZ4U$T}@4gGfH5%MG62#?V=L!dE5gOqfqb zZwtQY)ott`FF@<^61cW8)1{;lz`x@&zgETkTYS!_7|CyD=|3lZJ_=@v+dOSLP)!a1 zqILdk_6_tK3%Rim%YK&vrxX51It!*P#mujSY5Dv=%WP`=sq$eXOujSF_bT7j{Xb>@ R_V8%_PPoq2QkBh{e*oj8p(_9Y delta 2079 zcmZuy3pCU1AOCGkOEN?^*JyLiy;1aLb6vA6w~ee(mP^#wl%j@S-B2-?Od6G z268gQ6K7657PAD$mA<_}hXoF*`48OYx&<{un-am6>1X3Xr6og%zt+h0b5P4Fi-TN5 z>>ewsu4!s;RTPfAkHmJ*_!$sDJkx5TuE3MrF zd$r23T7l?OnXF58+pK?z{O#?#+3NEppJx|B?N2%ARiUB}QZl}(v<2v+h0i1x495H( zS%NjZ{W|f28(($E*wVJa)Vo?Td$}PoyFT#jB!cGlHw^r1U5U(y%maLcLbQEr6nFA! z=5YT;R)NU>|rob2J3j;CWrm8YUVK+?NWe?*19E^#)< zuQ?XLg>K?azMCHQ9w=k`OlEU7`Cynr)#Pxu89#wd)T_R)*OoW@3bZ|;rE+xK4GaJ} zPykQ>0Dw-R(RWxQcbFcDj2&j8j(DL|lRd68Zs_Xzg~rU|(~p`&s@)$d+VZ|QOCA|` zP!`kkJhP=f15wGXHAH8dI-&7O5L79IR3}fGTO(Gk60aV!VPX~zuJa$;lTQul+%;Pm z7cxQ_@oIA}$aLA=7-#I_RuDD7+ax$lTxi7y)+ffPq<8LIwnL7IG@jBF%@RCpZq9I+ zSNRY)RO?QaYs-sRR;)S^)7VEerm7z&x$@rTV@UthBJN>Gy=zk_+lW{v{eX5lDWtG( z`@$AGH^~u(iF~0h;_Zg1R=>`F?2n!E+j~zC-65$gs^ro#{}zc}nva~Jfhd<#x5vH` zKL3LKE`|jevzspVUSm;>1IhD+b+mIhk&4|^n^AP5QB!?G1L}iG>8d)$-6#HC8Zk)+ z&^7Z$l7Q5cz9%khCEDq28jM@V6E2P}g`Kp2rSqRdH-TAjQ*xSYZO&ZveXqhTNi4$+ zp4J0V^68y+>d%Ulv0j%l%l+Pyns)obqZ6AO#L+LQlUgr0l&4!sxGFT0s;UdDIeBIxp0CKap+hi#Wa*2c{=0e-e=}Y z&a;wBVf`QPl$Kp$V~`0>&dP3?5G*GbkuAO;7}Z0I?e;o?wj|nQe;(X1b+w1r!JiqK z8C@U#+DN*iJQA(E+2{@Sx13c4OP;cIyEH)YF&L%m3U?lN2vqH@#yNIsJ&?8Ws zxmGYH#`og^`QW=8xSJj(y0v~to>k1bx;1&;D#}&#@pfrKS5N%Tyt`4=F{U1s=o{?S zz0fPFYbHGAfwlF`$V`%hB&3AdqD@dV0_K@K zHh2b%=$K@<=ZcHmmu}Jx!{Wnj1s1{$x$D^xQ>gwU-#8U0Xmrmjx}u}yX2)bXO?{J~ z@e0N3N4;Y&gX`y=1`q8g3ilAF`h;KH)h*?W`4*Xr!wFdtMRYi@G%r@5N}{OsfN5daw}`EQd*m za0*TT_9d-s4!HoYFu&$%mmD_%cGf9?KYUk9fNwu}(GG4QY+h?n?zUR9#xt~?(Stgt z8fF6B@83R>VzP?dfYD2L=8 z5O5N(XZrcx=jir{o43iKh-fwQ{GiU*4r+VSnQQY4f9A~SRqWsgLJUKam$opQQ)d=o z5;;5;1Xcz9CzH&FFsq+3IRP_Wy`q`_c625}$>Lwv3elKkrS&^qAip&CaN6&g> Date: Mon, 18 Sep 2023 11:48:41 +0200 Subject: [PATCH 029/107] =?UTF-8?q?refactor(linux):=20Add=20more=20tests?= =?UTF-8?q?=20for=20keymanutil.c=20=F0=9F=8F=98=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- linux/ibus-keyman/src/keymanutil.c | 331 ++++----- linux/ibus-keyman/src/keymanutil_internal.h | 39 ++ linux/ibus-keyman/src/test/keymanutil_tests.c | 641 +++++++++++++++++- linux/ibus-keyman/src/test/meson.build | 4 +- linux/ibus-keyman/src/test/run-tests.sh | 2 +- linux/ibus-keyman/src/test/setup-tests.sh | 2 +- .../src/test/{ => testdata}/kmp.json | 534 +++++++-------- linux/ibus-keyman/src/test/testdata/kmp1.json | 123 ++++ linux/ibus-keyman/src/test/testdata/kmp2.json | 127 ++++ 9 files changed, 1343 insertions(+), 460 deletions(-) create mode 100644 linux/ibus-keyman/src/keymanutil_internal.h rename linux/ibus-keyman/src/test/{ => testdata}/kmp.json (95%) create mode 100644 linux/ibus-keyman/src/test/testdata/kmp1.json create mode 100644 linux/ibus-keyman/src/test/testdata/kmp2.json diff --git a/linux/ibus-keyman/src/keymanutil.c b/linux/ibus-keyman/src/keymanutil.c index 9eb42c173b..4e2608f246 100644 --- a/linux/ibus-keyman/src/keymanutil.c +++ b/linux/ibus-keyman/src/keymanutil.c @@ -58,15 +58,16 @@ #include #include "bcp47util.h" -#include "keymanutil.h" #include "kmpdetails.h" #include "keyman-version.h" +#include "keymanutil.h" +#include "keymanutil_internal.h" #define N_(text) text // change to keyman_get_kmpdirs_fromdir // returns list of directories with kmp.json -GList * keyman_get_kmpdirs_fromdir( GList *keyboard_list, const gchar * path) +GList * keyman_get_kmpdirs_fromdir(GList *kmpdir_list, const gchar * path) { DIR *dir = opendir(path); @@ -80,13 +81,13 @@ GList * keyman_get_kmpdirs_fromdir( GList *keyboard_list, const gchar * path) if (S_ISDIR(filestat.st_mode)) { if(g_strcmp0(file->d_name, ".") != 0 && g_strcmp0(file->d_name, "..") != 0) - keyboard_list = keyman_get_kmpdirs_fromdir(keyboard_list, absfn); + kmpdir_list = keyman_get_kmpdirs_fromdir(kmpdir_list, absfn); } // Looking for kmp.json else if (S_ISREG(filestat.st_mode) && g_strcmp0(file->d_name, "kmp.json") == 0) { g_message("adding kmp path %s", path); - keyboard_list=g_list_append(keyboard_list, g_strdup(path)); + kmpdir_list=g_list_append(kmpdir_list, g_strdup(path)); } g_free(absfn); @@ -94,7 +95,7 @@ GList * keyman_get_kmpdirs_fromdir( GList *keyboard_list, const gchar * path) } closedir(dir); } - return keyboard_list; + return kmpdir_list; } gchar * keyman_get_icon_file(const gchar *kmx_file) @@ -115,7 +116,7 @@ gchar * keyman_get_icon_file(const gchar *kmx_file) return full_path_to_icon_file; } -static IBusEngineDesc * +IBusEngineDesc * ibus_keyman_engine_desc_new (gchar * file_name, gchar *name, gchar *description, @@ -152,127 +153,157 @@ ibus_keyman_engine_desc_new (gchar * file_name, return engine_desc; } -GList * -ibus_keyman_add_engines(GList * engines, GList * kmpdir_list) -{ - GList *p, *k, *l, *e; +IBusEngineDesc * +get_engine_for_language( + kmp_keyboard *keyboard, + kmp_info *info, + keyboard_details *kbd_details, + gchar *kmp_dir, + gchar *lang_id, + gchar *lang_name) { + IBusEngineDesc* engine_desc = NULL; + if (!lang_id || !strlen(lang_id)) + return engine_desc; - for (p=kmpdir_list; p != NULL; p = p->next) { - gchar * kmp_dir = (gchar *) p->data; + int capacity = 255; + gchar *name_with_lang = NULL; + gchar *minimized_tag = g_new0(gchar, capacity); + int result = bcp47_minimize(lang_id, minimized_tag, capacity); + if (result < 0) { + g_strlcpy(minimized_tag, lang_id, capacity); + } - kmp_details *details = g_new0(kmp_details, 1); - get_kmp_details(kmp_dir, details); + gchar *lang_code = g_new0(gchar, capacity); + if (!bcp47_get_language_code(minimized_tag, lang_code, capacity)) { + g_strlcpy(lang_code, minimized_tag, capacity); + } - for (k=details->keyboards; k != NULL; k = k->next) { - kmp_keyboard *keyboard = (kmp_keyboard *) k->data; - gboolean alreadyexists = FALSE; - - for (e=engines; e != NULL && alreadyexists == FALSE; e = e->next) { - IBusEngineDesc *engine_desc = (IBusEngineDesc *) e->data; - const gchar *version = ibus_engine_desc_get_version(engine_desc); - const gchar *engine_name = ibus_engine_desc_get_name(engine_desc); - gchar *kmx_file = g_path_get_basename(engine_name); - if (g_strcmp0(kmx_file, keyboard->kmx_file) == 0 && g_strcmp0(version, keyboard->version) >= 0) { - alreadyexists = TRUE; - g_debug("keyboard %s already exists at version %s which is newer or same as %s", kmx_file, version, keyboard->version); - } - g_free(kmx_file); - } - - if (!alreadyexists) { - gchar *abs_kmx = g_strjoin("/", kmp_dir, keyboard->kmx_file, NULL); - gchar *json_file = g_strjoin(".", keyboard->id, "json", NULL); - keyboard_details *kbd_details = g_new0(keyboard_details, 1); - get_keyboard_details(kmp_dir, json_file, kbd_details); - g_free(json_file); - - if (keyboard->languages != NULL) { - for (l=keyboard->languages; l != NULL; l = l->next) { - kmp_language *language = (kmp_language *) l->data; - if (language->id != NULL) { - int capacity = 255; - gchar *name_with_lang = NULL; - gchar *minimized_tag = g_new0(gchar, capacity); - int result = bcp47_minimize(language->id, minimized_tag, capacity); - if (result < 0) { - g_strlcpy(minimized_tag, language->id, capacity); - } - - gchar *lang_code = g_new0(gchar, capacity); - if (!bcp47_get_language_code(minimized_tag, lang_code, capacity)) { - g_strlcpy(lang_code, minimized_tag, capacity); - } - - // If ibus doesn't know about the language then append the - // language name to the keyboard name - if (language->name != NULL) { - gchar *ibus_lang = ibus_get_untranslated_language_name(lang_code); - g_debug("%s: untranslated ibus language for %s: %s", __FUNCTION__, minimized_tag, ibus_lang); - if (g_strcmp0(ibus_lang, "Other") == 0) { - name_with_lang = g_strjoin(" - ", keyboard->name, language->name, NULL); - } - g_free(ibus_lang); - } - - gchar *id_with_lang = g_strjoin(":", minimized_tag, abs_kmx, NULL); - - g_message("adding engine %s", id_with_lang); - engines = g_list_append( - engines, - ibus_keyman_engine_desc_new( - id_with_lang, // lang:kmx full path - name_with_lang ? name_with_lang : keyboard->name, // longname - kbd_details->description, // description - details->info.copyright, // copyright if available - lang_code, // language, most are ignored by ibus except major languages - kbd_details->license, // license - details->info.author_desc, // author name only, not email - keyman_get_icon_file(abs_kmx), // icon full path - "us", // layout defaulting to us (en-US) - keyboard->version)); - g_free(lang_code); - g_free(minimized_tag); - g_free(id_with_lang); - g_free(name_with_lang); - } - } - } - else { - g_message("adding engine %s", abs_kmx); - engines = g_list_append (engines, - ibus_keyman_engine_desc_new (abs_kmx, // kmx full path - keyboard->name, // longname - kbd_details->description, // description - details->info.copyright, // copyright if available - NULL, // language, most are ignored by ibus except major languages - kbd_details->license, // license - details->info.author_desc, // author name only, not email - keyman_get_icon_file(abs_kmx), // icon full path - "us", // layout defaulting to us (en-US) - keyboard->version)); - } - free_keyboard_details(kbd_details); - g_free(kbd_details); - g_free(abs_kmx); - } - } - free_kmp_details(details); - g_free(details); + // If ibus doesn't know about the language then append the + // language name to the keyboard name + if (lang_name != NULL) { + gchar *ibus_lang = ibus_get_untranslated_language_name(lang_code); + g_debug("%s: untranslated ibus language for %s: %s", __FUNCTION__, minimized_tag, ibus_lang); + if (g_strcmp0(ibus_lang, "Other") == 0) { + name_with_lang = g_strjoin(" - ", keyboard->name, lang_name, NULL); } - return engines; + g_free(ibus_lang); + } + + gchar *abs_kmx = g_strjoin("/", kmp_dir, keyboard->kmx_file, NULL); + gchar *id_with_lang = g_strjoin(":", minimized_tag, abs_kmx, NULL); + + g_message("adding engine %s", id_with_lang); + engine_desc = ibus_keyman_engine_desc_new( + id_with_lang, // lang:kmx full path + name_with_lang ? name_with_lang : keyboard->name, // longname + kbd_details->description, // description + info->copyright, // copyright if available + lang_code, // language, most are ignored by ibus except major languages + kbd_details->license, // license + info->author_desc, // author name only, not email + keyman_get_icon_file(abs_kmx), // icon full path + "us", // layout defaulting to us (en-US) + keyboard->version); + g_free(abs_kmx); + g_free(lang_code); + g_free(minimized_tag); + g_free(id_with_lang); + g_free(name_with_lang); + return engine_desc; +} + +// Add a keyboard (ibus engine) to the list of engines +void +keyman_add_keyboard(gpointer data, gpointer user_data) { + kmp_keyboard *keyboard = (kmp_keyboard *)data; + add_keyboard_data *kb_data = (add_keyboard_data *)user_data; + gboolean alreadyexists = FALSE; + + for (GList *e = kb_data->engines_list; e != NULL && alreadyexists == FALSE; e = e->next) { + IBusEngineDesc *engine_desc = (IBusEngineDesc *)e->data; + const gchar *version = ibus_engine_desc_get_version(engine_desc); + const gchar *engine_name = ibus_engine_desc_get_name(engine_desc); + gchar *kmx_file = g_path_get_basename(engine_name); + // If we already have an engine for this keyboard (in a different area), we + // don't want to add it again since we wouldn't add anything new + // if it's the same version + // TODO: fix version comparison (#9593) + if (g_strcmp0(kmx_file, keyboard->kmx_file) == 0 && g_strcmp0(version, keyboard->version) >= 0) { + alreadyexists = TRUE; + g_debug("keyboard %s already exists at version %s which is newer or same as %s", kmx_file, version, keyboard->version); + } + g_free(kmx_file); + } + + if (!alreadyexists) { + gchar *json_file = g_strjoin(".", keyboard->id, "json", NULL); + keyboard_details *kbd_details = g_new0(keyboard_details, 1); + get_keyboard_details(kb_data->kmp_dir, json_file, kbd_details); + g_free(json_file); + + if (keyboard->languages != NULL) { + for (GList *l = keyboard->languages; l != NULL; l = l->next) { + kmp_language *language = (kmp_language *)l->data; + IBusEngineDesc *engine_desc = + get_engine_for_language(keyboard, kb_data->info, kbd_details, kb_data->kmp_dir, language->id, language->name); + if (engine_desc) { + kb_data->engines_list = g_list_append(kb_data->engines_list, engine_desc); + } + } + } else { + gchar *abs_kmx = g_strjoin("/", kb_data->kmp_dir, keyboard->kmx_file, NULL); + g_message("adding engine %s", abs_kmx); + kb_data->engines_list = g_list_append( + kb_data->engines_list, + ibus_keyman_engine_desc_new( + abs_kmx, // kmx full path + keyboard->name, // longname + kbd_details->description, // description + kb_data->info->copyright, // copyright if available + NULL, // language, most are ignored by ibus except major languages + kbd_details->license, // license + kb_data->info->author_desc, // author name only, not email + keyman_get_icon_file(abs_kmx), // icon full path + "us", // layout defaulting to us (en-US) + keyboard->version)); + g_free(abs_kmx); + } + free_keyboard_details(kbd_details); + g_free(kbd_details); + } +} + +// Add keyboards found in {kmp_dir}/kmp.json to engines_list +void +keyman_add_keyboards_from_dir(gpointer data, gpointer user_data) { + gchar * kmp_dir = (gchar *) data; + GList ** engines_list = (GList **)user_data; + + kmp_details *details = g_new0(kmp_details, 1); + if (get_kmp_details(kmp_dir, details) == JSON_OK) { + add_keyboard_data kb_data; + kb_data.engines_list = *engines_list; + kb_data.info = &details->info; + kb_data.kmp_dir = kmp_dir; + + g_list_foreach(details->keyboards, keyman_add_keyboard, &kb_data); + *engines_list = kb_data.engines_list; + } + free_kmp_details(details); + g_free(details); } GList * ibus_keyman_list_engines (void) { GList *engines = NULL; - GList *keyboard_list; + GList *kmpdir_list; gchar *local_keyboard_path, *xdgenv; g_debug("adding from /usr/share/keyman"); - keyboard_list = keyman_get_kmpdirs_fromdir(NULL, "/usr/share/keyman"); + kmpdir_list = keyman_get_kmpdirs_fromdir(NULL, "/usr/share/keyman"); g_debug("adding from /usr/local/share/keyman"); - keyboard_list = keyman_get_kmpdirs_fromdir(keyboard_list, "/usr/local/share/keyman"); + kmpdir_list = keyman_get_kmpdirs_fromdir(kmpdir_list, "/usr/local/share/keyman"); xdgenv = getenv("XDG_DATA_HOME"); if (xdgenv != NULL){ local_keyboard_path= g_strdup_printf("%s/keyman", xdgenv); @@ -282,10 +313,10 @@ ibus_keyman_list_engines (void) local_keyboard_path= g_strdup_printf("%s/.local/share/keyman", xdgenv); } g_debug("adding from %s", local_keyboard_path); - keyboard_list = keyman_get_kmpdirs_fromdir(keyboard_list, local_keyboard_path); + kmpdir_list = keyman_get_kmpdirs_fromdir(kmpdir_list, local_keyboard_path); g_free(local_keyboard_path); - engines = ibus_keyman_add_engines(engines, keyboard_list); - g_list_free(keyboard_list); + g_list_foreach(kmpdir_list, keyman_add_keyboards_from_dir, &engines); + g_list_free(kmpdir_list); return engines; } @@ -335,7 +366,7 @@ keyman_get_options_fromdconf(gchar *package_id, g_message("keyman_get_options_fromdconf"); // Obtain keyboard options from DConf - gchar *path = g_strdup_printf("%s%s/%s/", KEYMAN_DCONF_OPTIONS_PATH, package_id, keyboard_id); + g_autofree gchar *path = g_strdup_printf("%s%s/%s/", KEYMAN_DCONF_OPTIONS_PATH, package_id, keyboard_id); GSettings *child_settings = g_settings_new_with_path(KEYMAN_DCONF_OPTIONS_CHILD_NAME, path); gchar **options = NULL; if (child_settings != NULL) @@ -344,7 +375,6 @@ keyman_get_options_fromdconf(gchar *package_id, } g_object_unref(G_OBJECT(child_settings)); - g_free(path); return options; } @@ -364,7 +394,7 @@ keyman_get_options_queue_fromdconf(gchar *package_id, GQueue *queue_options = g_queue_new(); // Obtain keyboard options from DConf - gchar **options = keyman_get_options_fromdconf(package_id, keyboard_id); + g_auto(GStrv) options = keyman_get_options_fromdconf(package_id, keyboard_id); // Parse options into queue_options if (options != NULL) @@ -372,7 +402,7 @@ keyman_get_options_queue_fromdconf(gchar *package_id, int index = 0; while (options[index] != NULL) { - gchar **option_tokens = g_strsplit(options[index], "=", 2); + g_auto(GStrv) option_tokens = g_strsplit(options[index], "=", 2); if (option_tokens != NULL && option_tokens[0] != NULL && option_tokens[1] != NULL) { g_message("Keyboard Option [%d], %s=%s", index, option_tokens[0], option_tokens[1]); @@ -386,7 +416,6 @@ keyman_get_options_queue_fromdconf(gchar *package_id, } index++; } - g_strfreev(options); } return queue_options; @@ -416,47 +445,37 @@ keyman_put_options_todconf(gchar *package_id, // Obtain keyboard options from DConf gchar **options = keyman_get_options_fromdconf(package_id, keyboard_id); - gchar *needle = g_strdup_printf("%s=", option_key); + g_autofree gchar *needle = g_strdup_printf("%s=", option_key); gchar *kvp = g_strdup_printf("%s=%s", option_key, option_value); - if (options != NULL) - { - int index = 0; - gboolean option_updated = FALSE; - while (options[index] != NULL) - { - // If option_key already exists, update value with option_value - if (g_strrstr(options[index], needle) != NULL) - { - g_free(options[index]); - options[index] = kvp; - option_updated = TRUE; - break; - } - index++; - } + g_assert(options != NULL); - if (!option_updated) - { - // Resize to add new option and null-terminate - int size = index + 2; // old size: index + 1, plus 1 new - options = g_renew(gchar*, options, size); - options[index] = kvp; - options[index+1] = NULL; - } - } - else + int index = 0; + gboolean option_updated = FALSE; + while (options[index] != NULL) { - // we never should come here - keyman_get_options_fromdconf will create empty - // options if they don't yet exist. - // Allocate space for new option and null-terminate - options = g_new(gchar *, 2); - options[0] = kvp; - options[1] = NULL; + // If option_key already exists, update value with option_value + if (g_strrstr(options[index], needle) != NULL) + { + g_free(options[index]); + options[index] = kvp; + option_updated = TRUE; + break; + } + index++; + } + + if (!option_updated) + { + // Resize to add new option and null-terminate + int size = index + 2; // old size: index + 1, plus 1 new + options = g_renew(gchar*, options, size); + options[index] = kvp; + options[index+1] = NULL; } // Write to DConf - gchar *path = g_strdup_printf("%s%s/%s/", KEYMAN_DCONF_OPTIONS_PATH, package_id, keyboard_id); + g_autofree gchar *path = g_strdup_printf("%s%s/%s/", KEYMAN_DCONF_OPTIONS_PATH, package_id, keyboard_id); GSettings *child_settings = g_settings_new_with_path(KEYMAN_DCONF_OPTIONS_CHILD_NAME, path); if (child_settings != NULL) { @@ -465,8 +484,6 @@ keyman_put_options_todconf(gchar *package_id, } g_object_unref(G_OBJECT(child_settings)); - g_free(path); - g_free(needle); g_strfreev(options); // kvp got assigned to options[x] and so got freed by g_strfreev() } diff --git a/linux/ibus-keyman/src/keymanutil_internal.h b/linux/ibus-keyman/src/keymanutil_internal.h new file mode 100644 index 0000000000..112f7abd16 --- /dev/null +++ b/linux/ibus-keyman/src/keymanutil_internal.h @@ -0,0 +1,39 @@ +// Internal data structures used in the implementation of keymanutil methods +// and exposed for unit testing. + +#ifndef __KEYMANUTIL_INTERNAL_H__ +#define __KEYMANUTIL_INTERNAL_H__ + +#include +#include "kmpdetails.h" + +typedef struct { + GList *engines_list; + kmp_info *info; + gchar *kmp_dir; +} add_keyboard_data; + +IBusEngineDesc *ibus_keyman_engine_desc_new( + gchar *file_name, + gchar *name, + gchar *description, + gchar *copyright, + gchar *lang, + gchar *license, + gchar *author, + gchar *icon, + gchar *layout, + gchar *version); + +IBusEngineDesc *get_engine_for_language( + kmp_keyboard *keyboard, + kmp_info *info, + keyboard_details *kbd_details, + gchar *kmp_dir, + gchar *lang_id, + gchar *lang_name); + +void keyman_add_keyboard(gpointer data, gpointer user_data); +void keyman_add_keyboards_from_dir(gpointer data, gpointer user_data); + +#endif // __KEYMANUTIL_INTERNAL_H__ diff --git a/linux/ibus-keyman/src/test/keymanutil_tests.c b/linux/ibus-keyman/src/test/keymanutil_tests.c index 80f77a72ea..924215f77d 100644 --- a/linux/ibus-keyman/src/test/keymanutil_tests.c +++ b/linux/ibus-keyman/src/test/keymanutil_tests.c @@ -1,59 +1,139 @@ #include #include #include +#include +#include "kmpdetails.h" #include "keymanutil.h" +#include "keymanutil_internal.h" #define TEST_FIXTURE "keymanutil-test" void delete_options_key(gchar* testname) { - gchar *path = g_strdup_printf("%s%s/%s/", KEYMAN_DCONF_OPTIONS_PATH, TEST_FIXTURE, testname); - GSettings *settings = g_settings_new_with_path(KEYMAN_DCONF_OPTIONS_CHILD_NAME, path); + g_autofree gchar *path = g_strdup_printf("%s%s/%s/", KEYMAN_DCONF_OPTIONS_PATH, TEST_FIXTURE, testname); + g_autoptr(GSettings) settings = g_settings_new_with_path(KEYMAN_DCONF_OPTIONS_CHILD_NAME, path); g_settings_reset(settings, KEYMAN_DCONF_OPTIONS_KEY); - g_object_unref(G_OBJECT(settings)); - g_free(path); } void set_options_key(gchar* testname, gchar** options) { - gchar *path = g_strdup_printf("%s%s/%s/", KEYMAN_DCONF_OPTIONS_PATH, TEST_FIXTURE, testname); - GSettings *settings = g_settings_new_with_path(KEYMAN_DCONF_OPTIONS_CHILD_NAME, path); + g_autofree gchar* path = g_strdup_printf("%s%s/%s/", KEYMAN_DCONF_OPTIONS_PATH, TEST_FIXTURE, testname); + g_autoptr(GSettings) settings = g_settings_new_with_path(KEYMAN_DCONF_OPTIONS_CHILD_NAME, path); g_settings_set_strv(settings, KEYMAN_DCONF_OPTIONS_KEY, (const gchar* const*)options); - g_object_unref(G_OBJECT(settings)); - g_free(path); } gchar** get_options_key(gchar* testname) { - gchar* path = g_strdup_printf("%s%s/%s/", KEYMAN_DCONF_OPTIONS_PATH, TEST_FIXTURE, testname); - GSettings* settings = g_settings_new_with_path(KEYMAN_DCONF_OPTIONS_CHILD_NAME, path); + g_autofree gchar* path = g_strdup_printf("%s%s/%s/", KEYMAN_DCONF_OPTIONS_PATH, TEST_FIXTURE, testname); + g_autoptr(GSettings) settings = g_settings_new_with_path(KEYMAN_DCONF_OPTIONS_CHILD_NAME, path); gchar** result = g_settings_get_strv(settings, KEYMAN_DCONF_OPTIONS_KEY); - g_object_unref(G_OBJECT(settings)); - g_free(path); return result; } +kmp_keyboard* +_get_kmp_keyboard(gchar* version, gchar** languages) { + kmp_keyboard* keyboard = g_new0(kmp_keyboard, 1); + keyboard->name = g_strdup("Testing"); + keyboard->id = g_strdup("tst"); + keyboard->version = g_strdup(version); + keyboard->kmx_file = g_strdup("tst.kmx"); + keyboard->kvk_file = g_strdup(""); + keyboard->languages = NULL; + for (gchar* lang = *languages++; lang; lang = *languages++) { + gchar** tokens = g_strsplit(lang, ":", 2); + kmp_language* kmp_lang = g_new0(kmp_language, 1); + kmp_lang->id = g_strdup(tokens[0]); + kmp_lang->name = g_strdup(tokens[1]); + g_strfreev(tokens); + keyboard->languages = g_list_append(keyboard->languages, kmp_lang); + } + return keyboard; +} + +kmp_info* +_get_kmp_info(gchar * copyright, gchar * author_desc, gchar * author_url) { + kmp_info* info = g_new0(kmp_info, 1); + info->copyright = g_strdup(copyright); + info->author_desc = g_strdup(author_desc); + info->author_url = g_strdup(author_url); + return info; +} + +keyboard_details* +_get_keyboard_details(gchar * description, gchar * license) { + keyboard_details* details = g_new0(keyboard_details, 1); + details->id = g_strdup("tst"); + details->description = g_strdup(description); + details->license = g_strdup(license); + return details; +} + +add_keyboard_data* +_get_keyboard_data() { + add_keyboard_data* kb_data = g_new0(add_keyboard_data, 1); + kb_data->engines_list = NULL; + kb_data->info = _get_kmp_info(NULL, NULL, NULL); + kb_data->kmp_dir = "/tmp"; + return kb_data; +} + +void +free_kb_data(add_keyboard_data* kb_data) { + if (kb_data->engines_list) + g_list_free(kb_data->engines_list); + if (kb_data->info) + g_free(kb_data->info); + g_free(kb_data); +} + +// defined in kmpdetails +void free_keyboard(gpointer data); +void free_info(gpointer data); +kmp_json_status free_keyboard_details(keyboard_details* kbd_details); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(add_keyboard_data, free_kb_data) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(kmp_keyboard, free_keyboard) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(kmp_info, free_info) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(keyboard_details, free_keyboard_details) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(IBusEngineDesc, g_object_unref) + +//---------------------------------------------------------------------------------------------- +void +test_keyman_put_options_todconf__invalid() { + // Initialize + gchar* testname = "test_keyman_put_options_todconf__test_keyman_put_options_todconf__invalid"; + delete_options_key(testname); + + // Execute + keyman_put_options_todconf(TEST_FIXTURE, testname, "new_key", NULL); + + // Verify + g_auto(GStrv) options = get_options_key(testname); + g_assert_nonnull(options); + g_assert_null(options[0]); + + // Cleanup + delete_options_key(testname); +} + void test_keyman_put_options_todconf__new_key() { // Initialize gchar* testname = "test_keyman_put_options_todconf__new_key"; delete_options_key(testname); - gchar* value = g_strdup_printf("%d", g_test_rand_int()); + g_autofree gchar* value = g_strdup_printf("%d", g_test_rand_int()); // Execute keyman_put_options_todconf(TEST_FIXTURE, testname, "new_key", value); // Verify - gchar** options = get_options_key(testname); - gchar* expected = g_strdup_printf("new_key=%s", value); + g_auto(GStrv) options = get_options_key(testname); + g_autofree gchar* expected = g_strdup_printf("new_key=%s", value); g_assert_nonnull(options); g_assert_cmpstr(options[0], ==, expected); g_assert_null(options[1]); // Cleanup - g_free(expected); - g_free(value); - g_strfreev(options); delete_options_key(testname); } @@ -64,14 +144,14 @@ test_keyman_put_options_todconf__other_keys() { delete_options_key(testname); gchar* existingKeys[] = {"key1=val1", "key2=val2", NULL}; set_options_key(testname, existingKeys); - gchar* value = g_strdup_printf("%d", g_test_rand_int()); + g_autofree gchar* value = g_strdup_printf("%d", g_test_rand_int()); // Execute keyman_put_options_todconf(TEST_FIXTURE, testname, "new_key", value); // Verify - gchar** options = get_options_key(testname); - gchar* expected = g_strdup_printf("new_key=%s", value); + g_auto(GStrv) options = get_options_key(testname); + g_autofree gchar* expected = g_strdup_printf("new_key=%s", value); g_assert_nonnull(options); g_assert_cmpstr(options[0], ==, "key1=val1"); g_assert_cmpstr(options[1], ==, "key2=val2"); @@ -79,9 +159,6 @@ test_keyman_put_options_todconf__other_keys() { g_assert_null(options[3]); // Cleanup - g_free(expected); - g_free(value); - g_strfreev(options); delete_options_key(testname); } @@ -92,37 +169,537 @@ test_keyman_put_options_todconf__existing_key() { delete_options_key(testname); gchar* existingKeys[] = {"key1=val1", "new_key=val2", NULL}; set_options_key(testname, existingKeys); - gchar* value = g_strdup_printf("%d", g_test_rand_int()); + g_autofree gchar* value = g_strdup_printf("%d", g_test_rand_int()); // Execute keyman_put_options_todconf(TEST_FIXTURE, testname, "new_key", value); // Verify - gchar** options = get_options_key(testname); - gchar* expected = g_strdup_printf("new_key=%s", value); + g_auto(GStrv) options = get_options_key(testname); + g_autofree gchar* expected = g_strdup_printf("new_key=%s", value); g_assert_nonnull(options); g_assert_cmpstr(options[0], ==, "key1=val1"); g_assert_cmpstr(options[1], ==, expected); g_assert_null(options[2]); // Cleanup - g_free(expected); - g_free(value); - g_strfreev(options); delete_options_key(testname); } -int -main(int argc, char* argv[]) { +//---------------------------------------------------------------------------------------------- +void +test_ibus_keyman_engine_desc_new__all_set() { + // Execute + g_autoptr(IBusEngineDesc) desc = ibus_keyman_engine_desc_new("name", "longname", "description", "copyright", "lang", "license", "author", "icon", "layout", "version"); + + // Verify + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "name"); + g_assert_cmpstr(ibus_engine_desc_get_longname(desc), ==, "longname"); + g_assert_cmpstr(ibus_engine_desc_get_description(desc), ==, "description\ncopyright"); + g_assert_cmpstr(ibus_engine_desc_get_language(desc), ==, "lang"); + g_assert_cmpstr(ibus_engine_desc_get_license(desc), ==, "license"); + g_assert_cmpstr(ibus_engine_desc_get_author(desc), ==, "author"); + g_assert_cmpstr(ibus_engine_desc_get_icon(desc), ==, "icon"); + g_assert_cmpstr(ibus_engine_desc_get_layout(desc), ==, "layout"); + g_assert_cmpstr(ibus_engine_desc_get_version(desc), ==, "version"); +} + +void +test_ibus_keyman_engine_desc_new__only_description() { + // Execute + g_autoptr(IBusEngineDesc) desc = ibus_keyman_engine_desc_new( + "name", "longname", "description", NULL, "lang", "license", "author", "icon", "layout", "version"); + + // Verify + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "name"); + g_assert_cmpstr(ibus_engine_desc_get_longname(desc), ==, "longname"); + g_assert_cmpstr(ibus_engine_desc_get_description(desc), ==, "description\n(null)"); + g_assert_cmpstr(ibus_engine_desc_get_language(desc), ==, "lang"); + g_assert_cmpstr(ibus_engine_desc_get_license(desc), ==, "license"); + g_assert_cmpstr(ibus_engine_desc_get_author(desc), ==, "author"); + g_assert_cmpstr(ibus_engine_desc_get_icon(desc), ==, "icon"); + g_assert_cmpstr(ibus_engine_desc_get_layout(desc), ==, "layout"); + g_assert_cmpstr(ibus_engine_desc_get_version(desc), ==, "version"); +} + +void +test_ibus_keyman_engine_desc_new__only_copyright() { + // Execute + g_autoptr(IBusEngineDesc) desc = ibus_keyman_engine_desc_new( + "name", "longname", NULL, "copyright", "lang", "license", "author", "icon", "layout", "version"); + + // Verify + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "name"); + g_assert_cmpstr(ibus_engine_desc_get_longname(desc), ==, "longname"); + g_assert_cmpstr(ibus_engine_desc_get_description(desc), ==, "copyright"); + g_assert_cmpstr(ibus_engine_desc_get_language(desc), ==, "lang"); + g_assert_cmpstr(ibus_engine_desc_get_license(desc), ==, "license"); + g_assert_cmpstr(ibus_engine_desc_get_author(desc), ==, "author"); + g_assert_cmpstr(ibus_engine_desc_get_icon(desc), ==, "icon"); + g_assert_cmpstr(ibus_engine_desc_get_layout(desc), ==, "layout"); + g_assert_cmpstr(ibus_engine_desc_get_version(desc), ==, "version"); +} + +void +test_ibus_keyman_engine_desc_new__no_language_license_author_version() { + // Execute + g_autoptr(IBusEngineDesc) desc = ibus_keyman_engine_desc_new( + "name", "longname", "description", "copyright", NULL, NULL, NULL, "icon", "layout", NULL); + + // Verify + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "name"); + g_assert_cmpstr(ibus_engine_desc_get_longname(desc), ==, "longname"); + g_assert_cmpstr(ibus_engine_desc_get_description(desc), ==, "description\ncopyright"); + g_assert_cmpstr(ibus_engine_desc_get_language(desc), ==, "other"); + g_assert_cmpstr(ibus_engine_desc_get_license(desc), ==, ""); + g_assert_cmpstr(ibus_engine_desc_get_author(desc), ==, ""); + g_assert_cmpstr(ibus_engine_desc_get_icon(desc), ==, "icon"); + g_assert_cmpstr(ibus_engine_desc_get_layout(desc), ==, "layout"); + g_assert_cmpstr(ibus_engine_desc_get_version(desc), ==, ""); +} + +//---------------------------------------------------------------------------------------------- +void +test_get_engine_for_language__null_language() { + // Initialize + gchar* languages[] = {"en:English", NULL}; + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.0", languages); + g_autoptr(kmp_info) info = _get_kmp_info("Copyright by me", "My Author", "myauthor@example.com"); + g_autoptr(keyboard_details) details = _get_keyboard_details("my description", "MIT"); + + // Execute + g_autoptr(IBusEngineDesc) desc = get_engine_for_language(keyboard, info, details, "/tmp", NULL, NULL); + + // Verify + g_assert_null(desc); +} + +void +test_get_engine_for_language__empty_language() { + // Initialize + gchar* languages[] = {"en:English", NULL}; + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.0", languages); + g_autoptr(kmp_info) info = _get_kmp_info("Copyright by me", "My Author", "myauthor@example.com"); + g_autoptr(keyboard_details) details = _get_keyboard_details("my description", "MIT"); + + // Execute + g_autoptr(IBusEngineDesc) desc = get_engine_for_language(keyboard, info, details, "/tmp", "", ""); + + // Verify + g_assert_null(desc); +} + +void +test_get_engine_for_language__one_language() { + // Initialize + gchar* languages[] = {"en:English", NULL}; + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.0", languages); + g_autoptr(kmp_info) info = _get_kmp_info("Copyright by me", "My Author", "myauthor@example.com"); + g_autoptr(keyboard_details) details = _get_keyboard_details("my description", "MIT"); + + // Execute + g_autoptr(IBusEngineDesc) desc = get_engine_for_language(keyboard, info, details, "/tmp", "en", "English"); + + // Verify + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "en:/tmp/tst.kmx"); + g_assert_cmpstr(ibus_engine_desc_get_longname(desc), ==, "Testing"); + g_assert_cmpstr(ibus_engine_desc_get_language(desc), ==, "en"); +} + +void +test_get_engine_for_language__one_unknown_language() { + // Initialize + gchar* languages[] = {"foo:Foo", NULL}; + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.0", languages); + g_autoptr(kmp_info) info = _get_kmp_info("Copyright by me", "My Author", "myauthor@example.com"); + g_autoptr(keyboard_details) details = _get_keyboard_details("my description", "MIT"); + + // Execute + g_autoptr(IBusEngineDesc) desc = get_engine_for_language(keyboard, info, details, "/tmp", "foo", "Foo"); + + // Verify + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "foo:/tmp/tst.kmx"); + g_assert_cmpstr(ibus_engine_desc_get_longname(desc), ==, "Testing - Foo"); + g_assert_cmpstr(ibus_engine_desc_get_language(desc), ==, "foo"); +} + +void +test_get_engine_for_language__different_languages() { + // Initialize + gchar* languages[] = {"en:English", NULL}; + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.0", languages); + g_autoptr(kmp_info) info = _get_kmp_info("Copyright by me", "My Author", "myauthor@example.com"); + g_autoptr(keyboard_details) details = _get_keyboard_details("my description", "MIT"); + + // Execute + g_autoptr(IBusEngineDesc) desc = get_engine_for_language(keyboard, info, details, "/tmp", "foo", "Foo"); + + // Verify + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "foo:/tmp/tst.kmx"); + g_assert_cmpstr(ibus_engine_desc_get_longname(desc), ==, "Testing - Foo"); + g_assert_cmpstr(ibus_engine_desc_get_language(desc), ==, "foo"); +} + +void +test_get_engine_for_language__no_kbd_language() { + // Initialize + gchar* languages[] = {NULL}; + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.0", languages); + g_autoptr(kmp_info) info = _get_kmp_info("Copyright by me", "My Author", "myauthor@example.com"); + g_autoptr(keyboard_details) details = _get_keyboard_details("my description", "MIT"); + + // Execute + g_autoptr(IBusEngineDesc) desc = get_engine_for_language(keyboard, info, details, "/tmp", "en", "English"); + + // Verify + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "en:/tmp/tst.kmx"); + g_assert_cmpstr(ibus_engine_desc_get_longname(desc), ==, "Testing"); + g_assert_cmpstr(ibus_engine_desc_get_language(desc), ==, "en"); +} + +//---------------------------------------------------------------------------------------------- +void +test_keyman_add_keyboard__no_language() { + // Initialize + gchar* languages[] = {NULL}; + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.0", languages); + g_autoptr(add_keyboard_data) kb_data = _get_keyboard_data(); + + // Execute + keyman_add_keyboard(keyboard, kb_data); + + // Verify + g_assert_nonnull(kb_data->engines_list->data); + IBusEngineDesc* desc = (IBusEngineDesc*)kb_data->engines_list->data; + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "/tmp/tst.kmx"); + g_assert_null(kb_data->engines_list->next); +} + +void +test_keyman_add_keyboard__one_language() { + // Initialize + gchar* languages[] = {"en:English", NULL}; + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.0", languages); + g_autoptr(add_keyboard_data) kb_data = _get_keyboard_data(); + + // Execute + keyman_add_keyboard(keyboard, kb_data); + + // Verify + g_assert_nonnull(kb_data->engines_list->data); + IBusEngineDesc* desc = (IBusEngineDesc*)kb_data->engines_list->data; + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "en:/tmp/tst.kmx"); + g_assert_null(kb_data->engines_list->next); +} + +void +test_keyman_add_keyboard__two_languages() { + // Initialize + gchar* languages[] = {"en:English", "fr:French", NULL}; + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.0", languages); + g_autoptr(add_keyboard_data) kb_data = _get_keyboard_data(); + + // Execute + keyman_add_keyboard(keyboard, kb_data); + + // Verify + g_assert_nonnull(kb_data->engines_list->data); + IBusEngineDesc* desc = (IBusEngineDesc*)kb_data->engines_list->data; + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "en:/tmp/tst.kmx"); + g_assert_nonnull(kb_data->engines_list->next); + g_assert_nonnull(kb_data->engines_list->next->data); + desc = (IBusEngineDesc*)kb_data->engines_list->next->data; + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, "fr:/tmp/tst.kmx"); + g_assert_null(kb_data->engines_list->next->next); +} + +void +test_keyman_add_keyboard__prev_engine_adding_same_version() { + // Initialize + gchar* languages[] = {"en:English", NULL}; + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.0", languages); + g_autoptr(add_keyboard_data) kb_data = _get_keyboard_data(); + IBusEngineDesc* desc = ibus_keyman_engine_desc_new("en:/usr/share/keyman/tst.kmx", "Testing", NULL, NULL, "en", NULL, NULL, "", "us", "1.0"); + kb_data->engines_list = g_list_append(kb_data->engines_list, desc); + + // Execute + keyman_add_keyboard(keyboard, kb_data); + + // Verify + GList* list = kb_data->engines_list; + g_assert_nonnull(list->data); + g_assert_cmpstr(ibus_engine_desc_get_name((IBusEngineDesc*)list->data), ==, "en:/usr/share/keyman/tst.kmx"); + g_assert_null(list->next); +} + +void +test_keyman_add_keyboard__prev_engine_adding_newer_version() { + // Initialize + gchar* languages[] = {"en:English", "fr:French", NULL}; // New version adds French + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.1", languages); + g_autoptr(add_keyboard_data) kb_data = _get_keyboard_data(); + IBusEngineDesc* desc = + ibus_keyman_engine_desc_new("en:/usr/share/keyman/tst.kmx", "Testing", NULL, NULL, "en", NULL, NULL, "", "us", "1.0"); + kb_data->engines_list = g_list_append(kb_data->engines_list, desc); + + // Execute + keyman_add_keyboard(keyboard, kb_data); + + // Verify + GList* list = kb_data->engines_list; + g_assert_nonnull(list->data); + g_assert_cmpstr(ibus_engine_desc_get_name((IBusEngineDesc*)list->data), ==, "en:/usr/share/keyman/tst.kmx"); + g_assert_nonnull(list->next); + list = list->next; + g_assert_nonnull(list->data); + g_assert_cmpstr(ibus_engine_desc_get_name((IBusEngineDesc*)list->data), ==, "en:/tmp/tst.kmx"); + g_assert_nonnull(list->next); + list = list->next; + g_assert_nonnull(list->data); + g_assert_cmpstr(ibus_engine_desc_get_name((IBusEngineDesc*)list->data), ==, "fr:/tmp/tst.kmx"); + g_assert_null(list->next); +} + +void +test_keyman_add_keyboard__prev_engine_adding_newer_version_9593() { + // This tests bug #9593: We add keyboard version 1.10 while 1.9 is already in + // the list. + + // Initialize + gchar* languages[] = {"en:English", "fr:French", NULL}; // New version adds French + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("1.10", languages); + g_autoptr(add_keyboard_data) kb_data = _get_keyboard_data(); + IBusEngineDesc* desc = + ibus_keyman_engine_desc_new("en:/usr/share/keyman/tst.kmx", "Testing", NULL, NULL, "en", NULL, NULL, "", "us", "1.9"); + kb_data->engines_list = g_list_append(kb_data->engines_list, desc); + + // Execute + keyman_add_keyboard(keyboard, kb_data); + + // Verify + GList* list = kb_data->engines_list; + g_assert_nonnull(list->data); + g_assert_cmpstr(ibus_engine_desc_get_name((IBusEngineDesc*)list->data), ==, "en:/usr/share/keyman/tst.kmx"); + g_assert_nonnull(list->next); + list = list->next; + g_assert_nonnull(list->data); + g_assert_cmpstr(ibus_engine_desc_get_name((IBusEngineDesc*)list->data), ==, "en:/tmp/tst.kmx"); + g_assert_nonnull(list->next); + list = list->next; + g_assert_nonnull(list->data); + g_assert_cmpstr(ibus_engine_desc_get_name((IBusEngineDesc*)list->data), ==, "fr:/tmp/tst.kmx"); + g_assert_null(list->next); +} + +void +test_keyman_add_keyboard__prev_engine_adding_older_version() { + // Initialize + gchar* languages[] = {"en:English", "fr:French", NULL}; // Old version has additional French + g_autoptr(kmp_keyboard) keyboard = _get_kmp_keyboard("0.9", languages); + g_autoptr(add_keyboard_data) kb_data = _get_keyboard_data(); + IBusEngineDesc* desc = + ibus_keyman_engine_desc_new("en:/usr/share/keyman/tst.kmx", "Testing", NULL, NULL, "en", NULL, NULL, "", "us", "1.0"); + kb_data->engines_list = g_list_append(kb_data->engines_list, desc); + + // Execute + keyman_add_keyboard(keyboard, kb_data); + + // Verify + GList* list = kb_data->engines_list; + g_assert_nonnull(list->data); + g_assert_cmpstr(ibus_engine_desc_get_name((IBusEngineDesc*)list->data), ==, "en:/usr/share/keyman/tst.kmx"); + g_assert_null(list->next); +} + +//---------------------------------------------------------------------------------------------- +gchar* testdata_dir; + +gboolean +delete_directory(gchar* path) { + g_autoptr(GFile) file = g_file_new_for_path(path); + if (g_file_test(path, G_FILE_TEST_IS_DIR)) { + g_autoptr(GFileEnumerator) enumerator = NULL; + + enumerator = g_file_enumerate_children(file, G_FILE_ATTRIBUTE_STANDARD_NAME, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL); + + while (enumerator != NULL) { + GFile* child; + + if (!g_file_enumerator_iterate(enumerator, NULL, &child, NULL, NULL)) + return FALSE; + if (child == NULL) + break; + if (!delete_directory(g_file_get_path(child))) + return FALSE; + } + } + + return g_file_delete(file, NULL, NULL); +} + +void clear_kmpdir(gchar* dir) { + delete_directory(dir); + g_free(dir); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(gchar, clear_kmpdir); + +void copy_test_data(gchar* kmp_dir, gchar* name) { + g_autofree gchar* oldfile = g_strdup_printf("%s/%s", testdata_dir, name); + g_autoptr(GFile) source = g_file_new_for_path(oldfile); + g_autofree gchar* newfile = g_strdup_printf("%s/kmp.json", kmp_dir); + g_autoptr(GFile) dest = g_file_new_for_path(newfile); + g_file_copy(source, dest, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL); +} + +void +test_keyman_add_keyboards_from_dir__no_kmpjson() { + // Initialize + g_autolist(GList) keyboards = NULL; + g_autoptr(gchar) kmp_dir = g_dir_make_tmp(NULL, NULL); + + // Execute + keyman_add_keyboards_from_dir(kmp_dir, &keyboards); + + // Verify + g_assert_cmpint(g_list_length(keyboards), ==, 0); +} + +void +test_keyman_add_keyboards_from_dir__one_dir() { + // Initialize + g_autoptr(GList) keyboards = NULL; + g_autoptr(gchar) kmp_dir = g_dir_make_tmp(NULL, NULL); + copy_test_data(kmp_dir, "kmp1.json"); + + // Execute + keyman_add_keyboards_from_dir(kmp_dir, &keyboards); + + // Verify + g_assert_cmpint(g_list_length(keyboards), ==, 1); + + IBusEngineDesc* desc = IBUS_ENGINE_DESC(keyboards->data); + g_autofree gchar* expected_name = g_strdup_printf("bza:%s/test1.kmx", kmp_dir); + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, expected_name); +} + +void +test_keyman_add_keyboards_from_dir__two_langs() { + // Initialize + g_autoptr(GList) keyboards = NULL; + g_autoptr(gchar) kmp_dir = g_dir_make_tmp(NULL, NULL); + copy_test_data(kmp_dir, "kmp2.json"); + + // Execute + keyman_add_keyboards_from_dir(kmp_dir, &keyboards); + + // Verify + g_assert_cmpint(g_list_length(keyboards), ==, 2); + + IBusEngineDesc* desc = IBUS_ENGINE_DESC(keyboards->data); + g_autofree gchar* expected_name1 = g_strdup_printf("bmf-Latn:%s/test2.kmx", kmp_dir); + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, expected_name1); + desc = IBUS_ENGINE_DESC(keyboards->next->data); + g_autofree gchar* expected_name2 = g_strdup_printf("bun-Latn:%s/test2.kmx", kmp_dir); + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, expected_name2); +} + +void +test_keyman_add_keyboards_from_dir__prev_keyboards() { + // Initialize + g_autoptr(GList) keyboards = NULL; + g_autoptr(gchar) kmp_dir = g_dir_make_tmp(NULL, NULL); + copy_test_data(kmp_dir, "kmp2.json"); + keyman_add_keyboards_from_dir(kmp_dir, &keyboards); + copy_test_data(kmp_dir, "kmp1.json"); + + // Execute + keyman_add_keyboards_from_dir(kmp_dir, &keyboards); + + // Verify + g_assert_cmpint(g_list_length(keyboards), ==, 3); + + IBusEngineDesc* desc = IBUS_ENGINE_DESC(keyboards->data); + g_autofree gchar* expected_name1 = g_strdup_printf("bmf-Latn:%s/test2.kmx", kmp_dir); + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, expected_name1); + desc = IBUS_ENGINE_DESC(keyboards->next->data); + g_autofree gchar* expected_name2 = g_strdup_printf("bun-Latn:%s/test2.kmx", kmp_dir); + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, expected_name2); + desc = IBUS_ENGINE_DESC(keyboards->next->next->data); + g_autofree gchar* expected_name = g_strdup_printf("bza:%s/test1.kmx", kmp_dir); + g_assert_cmpstr(ibus_engine_desc_get_name(desc), ==, expected_name); +} + +//---------------------------------------------------------------------------------------------- +void +print_usage() { + printf( + "Usage: %s --testdata \n\n", + g_get_prgname()); + printf("Arguments:\n"); + printf("\t--testdata \tThe directory containing test kmp.json files for the tests.\n\n"); +} + +int main(int argc, char* argv[]) { gtk_init(&argc, &argv); g_test_init(&argc, &argv, NULL); g_test_set_nonfatal_assertions(); + if (argc < 3 || strcmp(argv[1], "--testdata") != 0) { + print_usage(); + return 1; + } + + testdata_dir = argv[2]; + + if (!g_file_test(testdata_dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { + printf("ERROR: Testdata directory %s does not exist\n\n", testdata_dir); + print_usage(); + return 2; + } + // Add tests + g_test_add_func("/keymanutil/keyman_put_options_todconf/invalid", test_keyman_put_options_todconf__invalid); g_test_add_func("/keymanutil/keyman_put_options_todconf/new_key", test_keyman_put_options_todconf__new_key); g_test_add_func("/keymanutil/keyman_put_options_todconf/other_keys", test_keyman_put_options_todconf__other_keys); g_test_add_func("/keymanutil/keyman_put_options_todconf/existing_key", test_keyman_put_options_todconf__existing_key); + g_test_add_func("/keymanutil/ibus_keyman_engine_desc_new/all_set", test_ibus_keyman_engine_desc_new__all_set); + g_test_add_func("/keymanutil/ibus_keyman_engine_desc_new/only_description", test_ibus_keyman_engine_desc_new__only_description); + g_test_add_func("/keymanutil/ibus_keyman_engine_desc_new/only_copyright", test_ibus_keyman_engine_desc_new__only_copyright); + g_test_add_func( + "/keymanutil/ibus_keyman_engine_desc_new/no_language_license_author_version", + test_ibus_keyman_engine_desc_new__no_language_license_author_version); + + g_test_add_func("/keymanutil/get_engine_for_language/null_language", test_get_engine_for_language__null_language); + g_test_add_func("/keymanutil/get_engine_for_language/empty_language", test_get_engine_for_language__empty_language); + g_test_add_func("/keymanutil/get_engine_for_language/one_language", test_get_engine_for_language__one_language); + g_test_add_func("/keymanutil/get_engine_for_language/one_unknown_language", test_get_engine_for_language__one_unknown_language); + g_test_add_func("/keymanutil/get_engine_for_language/different_languages", test_get_engine_for_language__different_languages); + g_test_add_func("/keymanutil/get_engine_for_language/no_kbd_language", test_get_engine_for_language__no_kbd_language); + + g_test_add_func("/keymanutil/keyman_add_keyboard/no_language", test_keyman_add_keyboard__no_language); + g_test_add_func("/keymanutil/keyman_add_keyboard/one_language", test_keyman_add_keyboard__one_language); + g_test_add_func("/keymanutil/keyman_add_keyboard/two_languages", test_keyman_add_keyboard__two_languages); + g_test_add_func( + "/keymanutil/keyman_add_keyboard/prev_engine_adding_same_version", + test_keyman_add_keyboard__prev_engine_adding_same_version); + g_test_add_func( + "/keymanutil/keyman_add_keyboard/prev_engine_adding_newer_version", + test_keyman_add_keyboard__prev_engine_adding_newer_version); + // #9593 + // g_test_add_func( + // "/keymanutil/keyman_add_keyboard/prev_engine_adding_newer_version_versioncompare", + // test_keyman_add_keyboard__prev_engine_adding_newer_version_9593); + g_test_add_func( + "/keymanutil/keyman_add_keyboard/prev_engine_adding_older_version", + test_keyman_add_keyboard__prev_engine_adding_older_version); + + g_test_add_func("/keymanutil/keyman_add_keyboards_from_dir/no_kmpjson", test_keyman_add_keyboards_from_dir__no_kmpjson); + g_test_add_func("/keymanutil/keyman_add_keyboards_from_dir/one_dir", test_keyman_add_keyboards_from_dir__one_dir); + g_test_add_func("/keymanutil/keyman_add_keyboards_from_dir/two_langs", test_keyman_add_keyboards_from_dir__two_langs); + g_test_add_func("/keymanutil/keyman_add_keyboards_from_dir/prev_keyboards", test_keyman_add_keyboards_from_dir__prev_keyboards); + // Run tests int retVal = g_test_run(); diff --git a/linux/ibus-keyman/src/test/meson.build b/linux/ibus-keyman/src/test/meson.build index 3c8c1044c0..02631e27f7 100644 --- a/linux/ibus-keyman/src/test/meson.build +++ b/linux/ibus-keyman/src/test/meson.build @@ -84,7 +84,7 @@ test( test( 'keymanutil-tests', run_src_test, - args: [ '--tap', '-k', '--env', env_file, '--', keymanutil_tests], + args: [ '--tap', '-k', '--env', env_file, '--', keymanutil_tests, '--testdata', meson.current_source_dir() / 'testdata'], env: test_env, priority: -2, is_parallel: false, @@ -103,7 +103,7 @@ test( test( 'print-kmp-test', run_src_test, - args: [ '--', print_kmp_test, meson.current_source_dir() / 'kmp.json' ], + args: [ '--', print_kmp_test, meson.current_source_dir() / 'testdata/kmp.json' ], env: test_env, priority: -2, protocol: 'exitcode', diff --git a/linux/ibus-keyman/src/test/run-tests.sh b/linux/ibus-keyman/src/test/run-tests.sh index efeb747ddc..ae005fcbd6 100755 --- a/linux/ibus-keyman/src/test/run-tests.sh +++ b/linux/ibus-keyman/src/test/run-tests.sh @@ -58,4 +58,4 @@ glib-compile-schemas "$SCHEMA_DIR" export GSETTINGS_BACKEND=memory -"${G_TEST_BUILDDIR:-.}/keymanutil-tests" "$@" +"${G_TEST_BUILDDIR:-.}/keymanutil-tests" "$@" --testdata "${SRCDIR}/src/test/testdata" diff --git a/linux/ibus-keyman/src/test/setup-tests.sh b/linux/ibus-keyman/src/test/setup-tests.sh index 07e7d5462b..79bb765f50 100755 --- a/linux/ibus-keyman/src/test/setup-tests.sh +++ b/linux/ibus-keyman/src/test/setup-tests.sh @@ -3,4 +3,4 @@ set -eu . "$(dirname "$0")/../../tests/scripts/test-helper.inc.sh" -setup_display_server_only "$1" "$2" "$3" "$4" +setup_display_server_only "${1:-x11}" "${2:-/tmp/env-src-test.txt}" "${3:-/tmp/ibus-keyman-src-test-pids}" "${4:-/tmp/ibus-keyman-src-test-pids.pids}" diff --git a/linux/ibus-keyman/src/test/kmp.json b/linux/ibus-keyman/src/test/testdata/kmp.json similarity index 95% rename from linux/ibus-keyman/src/test/kmp.json rename to linux/ibus-keyman/src/test/testdata/kmp.json index dc659d324e..d2ee4fa9e1 100644 --- a/linux/ibus-keyman/src/test/kmp.json +++ b/linux/ibus-keyman/src/test/testdata/kmp.json @@ -1,267 +1,267 @@ -{ - "system": { - "keymanDeveloperVersion": "10.0.1202.0", - "fileVersion": "7.0" - }, - "options": { - "readmeFile": "readme.htm" - }, - "info": { - "version": { - "description": "1.6.1" - }, - "name": { - "description": "LIBTRALO" - }, - "copyright": { - "description": "\u00A9 2008-2018 SIL International" - }, - "author": { - "description": "support@keyman.com", - "url": "mailto:support@keyman.com" - } - }, - "files": [ - { - "name": "libtralo.kmx", - "description": "Keyboard LIBTRALO" - }, - { - "name": "readme.htm", - "description": "File readme.htm" - }, - { - "name": "libtralo.png", - "description": "File libtralo.png" - }, - { - "name": "welcome.htm", - "description": "File welcome.htm" - }, - { - "name": "Charis_SIL_README.txt", - "description": "File Charis_SIL_README.txt" - }, - { - "name": "CharisSIL-B.ttf", - "description": "Font Charis SIL Bold" - }, - { - "name": "CharisSIL-BI.ttf", - "description": "Font Charis SIL Bold Italic" - }, - { - "name": "CharisSIL-I.ttf", - "description": "Font Charis SIL Italic" - }, - { - "name": "CharisSIL-R.ttf", - "description": "Font Charis SIL" - }, - { - "name": "FONTLOG.txt", - "description": "File FONTLOG.txt" - }, - { - "name": "OFL.txt", - "description": "File OFL.txt" - }, - { - "name": "OFL-FAQ.txt", - "description": "File OFL-FAQ.txt" - }, - { - "name": "CharisSILDan-Bold.ttf", - "description": "Font Charis SIL Dan Bold" - }, - { - "name": "CharisSILDan-BoldItalic.ttf", - "description": "Font Charis SIL Dan Bold Italic" - }, - { - "name": "CharisSILDan-Italic.ttf", - "description": "Font Charis SIL Dan Italic" - }, - { - "name": "CharisSILDan-Regular.ttf", - "description": "Font Charis SIL Dan" - }, - { - "name": "libtralo.js", - "description": "File libtralo.js" - }, - { - "name": "libtralo.kvk", - "description": "File libtralo.kvk" - }, - { - "name": "CharisSILDan_FONTLOG.txt", - "description": "File CharisSILDan_FONTLOG.txt" - }, - { - "name": "kmp.inf", - "description": "Package information" - }, - { - "name": "kmp.json", - "description": "Package information (JSON)" - } - ], - "keyboards": [ - { - "name": "LIBTRALO", - "id": "libtralo", - "version": "1.6.1", - "languages": [ - { - "name": "Bandi", - "id": "bza-Latn" - }, - { - "name": "Bassa", - "id": "bsq-Latn" - }, - { - "name": "Glio-Oubi", - "id": "oub-Latn" - }, - { - "name": "Gola", - "id": "gol-Latn" - }, - { - "name": "Northern Grebo", - "id": "gbo-Latn" - }, - { - "name": "Southern Kisi", - "id": "kss-Latn" - }, - { - "name": "Klao", - "id": "klu-Latn" - }, - { - "name": "Liberia Kpelle (Latin)", - "id": "xpe-Latn" - }, - { - "name": "Eastern Krahn", - "id": "kqo-Latn" - }, - { - "name": "Western Krahn", - "id": "krw-Latn" - }, - { - "name": "Kuwaa", - "id": "blh-Latn" - }, - { - "name": "Loma (Liberia) (Latin)", - "id": "lom-Latn" - }, - { - "name": "Mano", - "id": "mev-Latn" - }, - { - "name": "Manya", - "id": "mzj-Latn" - }, - { - "name": "Sapo", - "id": "krn-Latn" - }, - { - "name": "Bullom So", - "id": "buy-Latn" - }, - { - "name": "Kono (Sierra Leone)", - "id": "kno-Latn" - }, - { - "name": "Krio", - "id": "kri-Latn" - }, - { - "name": "Kuranko", - "id": "knk-Latn" - }, - { - "name": "West-Central Limba", - "id": "lia-Latn" - }, - { - "name": "Loko", - "id": "lok-Latn" - }, - { - "name": "Mende (Sierra Leone)", - "id": "men" - }, - { - "name": "Timne", - "id": "tem" - }, - { - "name": "Vai (Latin)", - "id": "vai-Latn" - }, - { - "name": "Dewoin (Latin)", - "id": "dee-Latn" - }, - { - "name": "Dan (Western) (Latin)", - "id": "dnj-Latn-LR" - }, - { - "name": "Gbii (Latin)", - "id": "ggb-Latn" - }, - { - "name": "Glaro-Twabo (Latin)", - "id": "glr-Latn" - }, - { - "name": "Grebo (Latin)", - "id": "grb-Latn" - }, - { - "name": "Barclayville Grebo (Latin)", - "id": "gry-Latn" - }, - { - "name": "Central Grebo (Latin)", - "id": "grv-Latn" - }, - { - "name": "Gboloo Grebo (Latin)", - "id": "gec-Latn" - }, - { - "name": "Southern Grebo (Latin)", - "id": "grj-Latn" - }, - { - "name": "Kpelle (Latin)", - "id": "kpe-Latn" - }, - { - "name": "Tajuasohn (Latin)", - "id": "tja-Latn" - }, - { - "name": "Bom-Kim (Latin)", - "id": "bmf-Latn" - }, - { - "name": "Sherbro (Latin)", - "id": "bun-Latn" - } - ] - } - ] -} +{ + "system": { + "keymanDeveloperVersion": "10.0.1202.0", + "fileVersion": "7.0" + }, + "options": { + "readmeFile": "readme.htm" + }, + "info": { + "version": { + "description": "1.6.1" + }, + "name": { + "description": "LIBTRALO" + }, + "copyright": { + "description": "\u00A9 2008-2018 SIL International" + }, + "author": { + "description": "support@keyman.com", + "url": "mailto:support@keyman.com" + } + }, + "files": [ + { + "name": "libtralo.kmx", + "description": "Keyboard LIBTRALO" + }, + { + "name": "readme.htm", + "description": "File readme.htm" + }, + { + "name": "libtralo.png", + "description": "File libtralo.png" + }, + { + "name": "welcome.htm", + "description": "File welcome.htm" + }, + { + "name": "Charis_SIL_README.txt", + "description": "File Charis_SIL_README.txt" + }, + { + "name": "CharisSIL-B.ttf", + "description": "Font Charis SIL Bold" + }, + { + "name": "CharisSIL-BI.ttf", + "description": "Font Charis SIL Bold Italic" + }, + { + "name": "CharisSIL-I.ttf", + "description": "Font Charis SIL Italic" + }, + { + "name": "CharisSIL-R.ttf", + "description": "Font Charis SIL" + }, + { + "name": "FONTLOG.txt", + "description": "File FONTLOG.txt" + }, + { + "name": "OFL.txt", + "description": "File OFL.txt" + }, + { + "name": "OFL-FAQ.txt", + "description": "File OFL-FAQ.txt" + }, + { + "name": "CharisSILDan-Bold.ttf", + "description": "Font Charis SIL Dan Bold" + }, + { + "name": "CharisSILDan-BoldItalic.ttf", + "description": "Font Charis SIL Dan Bold Italic" + }, + { + "name": "CharisSILDan-Italic.ttf", + "description": "Font Charis SIL Dan Italic" + }, + { + "name": "CharisSILDan-Regular.ttf", + "description": "Font Charis SIL Dan" + }, + { + "name": "libtralo.js", + "description": "File libtralo.js" + }, + { + "name": "libtralo.kvk", + "description": "File libtralo.kvk" + }, + { + "name": "CharisSILDan_FONTLOG.txt", + "description": "File CharisSILDan_FONTLOG.txt" + }, + { + "name": "kmp.inf", + "description": "Package information" + }, + { + "name": "kmp.json", + "description": "Package information (JSON)" + } + ], + "keyboards": [ + { + "name": "LIBTRALO", + "id": "libtralo", + "version": "1.6.1", + "languages": [ + { + "name": "Bandi", + "id": "bza-Latn" + }, + { + "name": "Bassa", + "id": "bsq-Latn" + }, + { + "name": "Glio-Oubi", + "id": "oub-Latn" + }, + { + "name": "Gola", + "id": "gol-Latn" + }, + { + "name": "Northern Grebo", + "id": "gbo-Latn" + }, + { + "name": "Southern Kisi", + "id": "kss-Latn" + }, + { + "name": "Klao", + "id": "klu-Latn" + }, + { + "name": "Liberia Kpelle (Latin)", + "id": "xpe-Latn" + }, + { + "name": "Eastern Krahn", + "id": "kqo-Latn" + }, + { + "name": "Western Krahn", + "id": "krw-Latn" + }, + { + "name": "Kuwaa", + "id": "blh-Latn" + }, + { + "name": "Loma (Liberia) (Latin)", + "id": "lom-Latn" + }, + { + "name": "Mano", + "id": "mev-Latn" + }, + { + "name": "Manya", + "id": "mzj-Latn" + }, + { + "name": "Sapo", + "id": "krn-Latn" + }, + { + "name": "Bullom So", + "id": "buy-Latn" + }, + { + "name": "Kono (Sierra Leone)", + "id": "kno-Latn" + }, + { + "name": "Krio", + "id": "kri-Latn" + }, + { + "name": "Kuranko", + "id": "knk-Latn" + }, + { + "name": "West-Central Limba", + "id": "lia-Latn" + }, + { + "name": "Loko", + "id": "lok-Latn" + }, + { + "name": "Mende (Sierra Leone)", + "id": "men" + }, + { + "name": "Timne", + "id": "tem" + }, + { + "name": "Vai (Latin)", + "id": "vai-Latn" + }, + { + "name": "Dewoin (Latin)", + "id": "dee-Latn" + }, + { + "name": "Dan (Western) (Latin)", + "id": "dnj-Latn-LR" + }, + { + "name": "Gbii (Latin)", + "id": "ggb-Latn" + }, + { + "name": "Glaro-Twabo (Latin)", + "id": "glr-Latn" + }, + { + "name": "Grebo (Latin)", + "id": "grb-Latn" + }, + { + "name": "Barclayville Grebo (Latin)", + "id": "gry-Latn" + }, + { + "name": "Central Grebo (Latin)", + "id": "grv-Latn" + }, + { + "name": "Gboloo Grebo (Latin)", + "id": "gec-Latn" + }, + { + "name": "Southern Grebo (Latin)", + "id": "grj-Latn" + }, + { + "name": "Kpelle (Latin)", + "id": "kpe-Latn" + }, + { + "name": "Tajuasohn (Latin)", + "id": "tja-Latn" + }, + { + "name": "Bom-Kim (Latin)", + "id": "bmf-Latn" + }, + { + "name": "Sherbro (Latin)", + "id": "bun-Latn" + } + ] + } + ] +} diff --git a/linux/ibus-keyman/src/test/testdata/kmp1.json b/linux/ibus-keyman/src/test/testdata/kmp1.json new file mode 100644 index 0000000000..5d9954c330 --- /dev/null +++ b/linux/ibus-keyman/src/test/testdata/kmp1.json @@ -0,0 +1,123 @@ +{ + "system": { + "keymanDeveloperVersion": "10.0.1202.0", + "fileVersion": "7.0" + }, + "options": { + "readmeFile": "readme.htm" + }, + "info": { + "version": { + "description": "1.6.1" + }, + "name": { + "description": "LIBTRALO" + }, + "copyright": { + "description": "\u00A9 2008-2018 SIL International" + }, + "author": { + "description": "support@keyman.com", + "url": "mailto:support@keyman.com" + } + }, + "files": [ + { + "name": "libtralo.kmx", + "description": "Keyboard LIBTRALO" + }, + { + "name": "readme.htm", + "description": "File readme.htm" + }, + { + "name": "libtralo.png", + "description": "File libtralo.png" + }, + { + "name": "welcome.htm", + "description": "File welcome.htm" + }, + { + "name": "Charis_SIL_README.txt", + "description": "File Charis_SIL_README.txt" + }, + { + "name": "CharisSIL-B.ttf", + "description": "Font Charis SIL Bold" + }, + { + "name": "CharisSIL-BI.ttf", + "description": "Font Charis SIL Bold Italic" + }, + { + "name": "CharisSIL-I.ttf", + "description": "Font Charis SIL Italic" + }, + { + "name": "CharisSIL-R.ttf", + "description": "Font Charis SIL" + }, + { + "name": "FONTLOG.txt", + "description": "File FONTLOG.txt" + }, + { + "name": "OFL.txt", + "description": "File OFL.txt" + }, + { + "name": "OFL-FAQ.txt", + "description": "File OFL-FAQ.txt" + }, + { + "name": "CharisSILDan-Bold.ttf", + "description": "Font Charis SIL Dan Bold" + }, + { + "name": "CharisSILDan-BoldItalic.ttf", + "description": "Font Charis SIL Dan Bold Italic" + }, + { + "name": "CharisSILDan-Italic.ttf", + "description": "Font Charis SIL Dan Italic" + }, + { + "name": "CharisSILDan-Regular.ttf", + "description": "Font Charis SIL Dan" + }, + { + "name": "libtralo.js", + "description": "File libtralo.js" + }, + { + "name": "libtralo.kvk", + "description": "File libtralo.kvk" + }, + { + "name": "CharisSILDan_FONTLOG.txt", + "description": "File CharisSILDan_FONTLOG.txt" + }, + { + "name": "kmp.inf", + "description": "Package information" + }, + { + "name": "kmp.json", + "description": "Package information (JSON)" + } + ], + "keyboards": [ + { + "name": "TEST1", + "id": "test1", + "version": "1.6.1", + "languages": [ + { + "name": "Bandi", + "id": "bza-Latn" + } + ] + } + ] +} diff --git a/linux/ibus-keyman/src/test/testdata/kmp2.json b/linux/ibus-keyman/src/test/testdata/kmp2.json new file mode 100644 index 0000000000..5e889091f7 --- /dev/null +++ b/linux/ibus-keyman/src/test/testdata/kmp2.json @@ -0,0 +1,127 @@ +{ + "system": { + "keymanDeveloperVersion": "10.0.1202.0", + "fileVersion": "7.0" + }, + "options": { + "readmeFile": "readme.htm" + }, + "info": { + "version": { + "description": "1.6.1" + }, + "name": { + "description": "LIBTRALO" + }, + "copyright": { + "description": "\u00A9 2008-2018 SIL International" + }, + "author": { + "description": "support@keyman.com", + "url": "mailto:support@keyman.com" + } + }, + "files": [ + { + "name": "libtralo.kmx", + "description": "Keyboard LIBTRALO" + }, + { + "name": "readme.htm", + "description": "File readme.htm" + }, + { + "name": "libtralo.png", + "description": "File libtralo.png" + }, + { + "name": "welcome.htm", + "description": "File welcome.htm" + }, + { + "name": "Charis_SIL_README.txt", + "description": "File Charis_SIL_README.txt" + }, + { + "name": "CharisSIL-B.ttf", + "description": "Font Charis SIL Bold" + }, + { + "name": "CharisSIL-BI.ttf", + "description": "Font Charis SIL Bold Italic" + }, + { + "name": "CharisSIL-I.ttf", + "description": "Font Charis SIL Italic" + }, + { + "name": "CharisSIL-R.ttf", + "description": "Font Charis SIL" + }, + { + "name": "FONTLOG.txt", + "description": "File FONTLOG.txt" + }, + { + "name": "OFL.txt", + "description": "File OFL.txt" + }, + { + "name": "OFL-FAQ.txt", + "description": "File OFL-FAQ.txt" + }, + { + "name": "CharisSILDan-Bold.ttf", + "description": "Font Charis SIL Dan Bold" + }, + { + "name": "CharisSILDan-BoldItalic.ttf", + "description": "Font Charis SIL Dan Bold Italic" + }, + { + "name": "CharisSILDan-Italic.ttf", + "description": "Font Charis SIL Dan Italic" + }, + { + "name": "CharisSILDan-Regular.ttf", + "description": "Font Charis SIL Dan" + }, + { + "name": "libtralo.js", + "description": "File libtralo.js" + }, + { + "name": "libtralo.kvk", + "description": "File libtralo.kvk" + }, + { + "name": "CharisSILDan_FONTLOG.txt", + "description": "File CharisSILDan_FONTLOG.txt" + }, + { + "name": "kmp.inf", + "description": "Package information" + }, + { + "name": "kmp.json", + "description": "Package information (JSON)" + } + ], + "keyboards": [ + { + "name": "TEST2", + "id": "test2", + "version": "1.6.1", + "languages": [ + { + "name": "Bom-Kim (Latin)", + "id": "bmf-Latn" + }, + { + "name": "Sherbro (Latin)", + "id": "bun-Latn" + } + ] + } + ] +} From 1236ded7cd1c6bb8fa5fed1b57b26e950d428f11 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 28 Sep 2023 12:50:25 -0500 Subject: [PATCH 030/107] =?UTF-8?q?chore(resources):=20ldml=20update=20=20?= =?UTF-8?q?=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For: #9403 - unicode-org/cldr:2aa2275158c29e8e41c7f0b67c8fb786a453b89c --- .../techpreview/3.0/fr-t-k0-azerty.xml | 16 ------- .../ldml-keyboards/techpreview/cldr_info.json | 6 +-- .../techpreview/dtd/ldmlKeyboard3.dtd | 13 +----- .../techpreview/dtd/ldmlKeyboard3.xsd | 21 --------- .../techpreview/import/scanCodes-implied.xml | 6 +-- .../techpreview/ldml-keyboard3.schema.json | 43 ------------------- 6 files changed, 7 insertions(+), 98 deletions(-) diff --git a/resources/standards-data/ldml-keyboards/techpreview/3.0/fr-t-k0-azerty.xml b/resources/standards-data/ldml-keyboards/techpreview/3.0/fr-t-k0-azerty.xml index 4ccedc062f..190700d496 100644 --- a/resources/standards-data/ldml-keyboards/techpreview/3.0/fr-t-k0-azerty.xml +++ b/resources/standards-data/ldml-keyboards/techpreview/3.0/fr-t-k0-azerty.xml @@ -23,22 +23,6 @@ - - - - - - - - - - - - - - - - - + @@ -77,17 +77,6 @@ Please view the subcommittee page for the most recent information. - - - - - - - - - - - diff --git a/resources/standards-data/ldml-keyboards/techpreview/dtd/ldmlKeyboard3.xsd b/resources/standards-data/ldml-keyboards/techpreview/dtd/ldmlKeyboard3.xsd index f3a7b8bed8..47f299571b 100644 --- a/resources/standards-data/ldml-keyboards/techpreview/dtd/ldmlKeyboard3.xsd +++ b/resources/standards-data/ldml-keyboards/techpreview/dtd/ldmlKeyboard3.xsd @@ -25,7 +25,6 @@ Note: DTD @-annotations are not currently converted to .xsd. For full CLDR file - @@ -148,26 +147,6 @@ Note: DTD @-annotations are not currently converted to .xsd. For full CLDR file - - - - - - - - - - - - - - - - - - - - diff --git a/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml b/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml index 23ee29d2cb..e1ba3309d6 100644 --- a/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml +++ b/resources/standards-data/ldml-keyboards/techpreview/import/scanCodes-implied.xml @@ -35,12 +35,12 @@ - +
- - + + diff --git a/resources/standards-data/ldml-keyboards/techpreview/ldml-keyboard3.schema.json b/resources/standards-data/ldml-keyboards/techpreview/ldml-keyboard3.schema.json index c5d13311ef..6d6ba9d2a9 100644 --- a/resources/standards-data/ldml-keyboards/techpreview/ldml-keyboard3.schema.json +++ b/resources/standards-data/ldml-keyboards/techpreview/ldml-keyboard3.schema.json @@ -635,46 +635,6 @@ } }, "type": "object" - }, - "vkey": { - "additionalProperties": false, - "properties": { - "from": { - "type": "string" - }, - "to": { - "type": "string" - } - }, - "required": [ - "from", - "to" - ], - "type": "object" - }, - "vkeys": { - "additionalProperties": false, - "properties": { - "import": { - "items": { - "$ref": "#/definitions/import" - }, - "type": "array" - }, - "special": { - "items": { - "$ref": "#/definitions/special" - }, - "type": "array" - }, - "vkey": { - "items": { - "$ref": "#/definitions/vkey" - }, - "type": "array" - } - }, - "type": "object" } }, "properties": { @@ -740,9 +700,6 @@ }, "version": { "$ref": "#/definitions/version" - }, - "vkeys": { - "$ref": "#/definitions/vkeys" } }, "required": [ From bdef1c48d3ebe01e53f222edf8ae7573e14d7d1c Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 28 Sep 2023 13:03:44 -0500 Subject: [PATCH 031/107] =?UTF-8?q?fix(common):=20update=20keyman=20for=20?= =?UTF-8?q?removal=20of=20vkeys=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dropped in upstream CLDR-17093 See #7135 --- .../src/kmx/kmx-plus-builder/build-vkey.ts | 43 ------------ .../kmx/kmx-plus-builder/kmx-plus-builder.ts | 5 -- common/web/types/src/kmx/kmx-plus.ts | 12 ---- .../src/ldml-keyboard/ldml-keyboard-xml.ts | 10 --- core/include/ldml/keyboardprocessor_ldml.h | 4 -- core/include/ldml/keyboardprocessor_ldml.ts | 17 +---- core/src/kmx/kmx_plus.cpp | 22 +----- core/src/kmx/kmx_plus.h | 27 +------- .../src/kmc-ldml/src/compiler/compiler.ts | 2 - .../src/kmc-ldml/src/compiler/messages.ts | 18 +---- developer/src/kmc-ldml/src/compiler/vkey.ts | 69 ------------------- .../src/kmc-ldml/test/fixtures/basic.txt | 12 ---- .../src/kmc-ldml/test/fixtures/basic.xml | 5 -- .../sections/vkey/invalid-from-vkey.xml | 18 ----- .../sections/vkey/invalid-repeated-vkey.xml | 16 ----- .../sections/vkey/invalid-to-vkey.xml | 15 ---- .../test/fixtures/sections/vkey/minimal.xml | 17 ----- .../test/fixtures/sections/vkey/redundant.xml | 15 ---- .../fixtures/sections/vkey/same-target.xml | 16 ----- developer/src/kmc-ldml/test/test-vkey.ts | 62 ----------------- 20 files changed, 5 insertions(+), 400 deletions(-) delete mode 100644 common/web/types/src/kmx/kmx-plus-builder/build-vkey.ts delete mode 100644 developer/src/kmc-ldml/src/compiler/vkey.ts delete mode 100644 developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-from-vkey.xml delete mode 100644 developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-repeated-vkey.xml delete mode 100644 developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-to-vkey.xml delete mode 100644 developer/src/kmc-ldml/test/fixtures/sections/vkey/minimal.xml delete mode 100644 developer/src/kmc-ldml/test/fixtures/sections/vkey/redundant.xml delete mode 100644 developer/src/kmc-ldml/test/fixtures/sections/vkey/same-target.xml delete mode 100644 developer/src/kmc-ldml/test/test-vkey.ts diff --git a/common/web/types/src/kmx/kmx-plus-builder/build-vkey.ts b/common/web/types/src/kmx/kmx-plus-builder/build-vkey.ts deleted file mode 100644 index 0a4863beab..0000000000 --- a/common/web/types/src/kmx/kmx-plus-builder/build-vkey.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { constants } from '@keymanapp/ldml-keyboard-constants'; -import { KMXPlusData } from "../kmx-plus.js"; -import { BUILDER_SECTION } from './builder-section.js'; - -/* ------------------------------------------------------------------ - * vkey section - ------------------------------------------------------------------ */ - -/** - * Builder for the 'vkey' section - */ -interface BUILDER_VKEY_ITEM { - vkey: number; - target: number; -}; - -export interface BUILDER_VKEY extends BUILDER_SECTION { - count: number; - items: BUILDER_VKEY_ITEM[]; -}; - -export function build_vkey(kmxplus: KMXPlusData): BUILDER_VKEY { - if(!kmxplus.vkey.vkeys.length) { - return null; - } - - let vkey: BUILDER_VKEY = { - ident: constants.hex_section_id(constants.section.vkey), - size: constants.length_vkey + constants.length_vkey_item * kmxplus.vkey.vkeys.length, - _offset: 0, - count: kmxplus.vkey.vkeys.length, - items: [] - }; - - for(let item of kmxplus.vkey.vkeys) { - vkey.items.push({ - vkey: item.vkey, - target: item.target - }); - } - - return vkey; -} diff --git a/common/web/types/src/kmx/kmx-plus-builder/kmx-plus-builder.ts b/common/web/types/src/kmx/kmx-plus-builder/kmx-plus-builder.ts index 3cc58c9fe7..e77c60fbe7 100644 --- a/common/web/types/src/kmx/kmx-plus-builder/kmx-plus-builder.ts +++ b/common/web/types/src/kmx/kmx-plus-builder/kmx-plus-builder.ts @@ -15,7 +15,6 @@ import { BUILDER_STRS, build_strs } from './build-strs.js'; import { BUILDER_TRAN, build_tran } from './build-tran.js'; import { BUILDER_USET, build_uset } from './build-uset.js'; import { BUILDER_VARS, build_vars } from './build-vars.js'; -import { BUILDER_VKEY, build_vkey } from './build-vkey.js'; type BUILDER_BKSP = BUILDER_TRAN; // type BUILDER_FINL = BUILDER_TRAN; @@ -36,7 +35,6 @@ type SectionBuilders = { tran?: BUILDER_TRAN; uset?: BUILDER_USET; vars?: BUILDER_VARS; - vkey?: BUILDER_VKEY; }; export default class KMXPlusBuilder { @@ -73,7 +71,6 @@ export default class KMXPlusBuilder { this.emitSection(file, this.file.COMP_PLUS_TRAN, this.sect.tran); this.emitSection(file, this.file.COMP_PLUS_USET, this.sect.uset); this.emitSection(file, this.file.COMP_PLUS_VARS, this.sect.vars); - this.emitSection(file, this.file.COMP_PLUS_VKEY, this.sect.vkey); return file; } @@ -100,7 +97,6 @@ export default class KMXPlusBuilder { this.sect.tran = build_tran(this.file.kmxplus.tran, this.sect.strs, this.sect.elem); this.sect.uset = build_uset(this.file.kmxplus, this.sect.strs); this.sect.vars = build_vars(this.file.kmxplus, this.sect.strs, this.sect.elem, this.sect.list); - this.sect.vkey = build_vkey(this.file.kmxplus); // Finalize the sect (index) section @@ -138,7 +134,6 @@ export default class KMXPlusBuilder { offset = this.finalize_sect_item(this.sect.tran, offset); offset = this.finalize_sect_item(this.sect.uset, offset); offset = this.finalize_sect_item(this.sect.vars, offset); - offset = this.finalize_sect_item(this.sect.vkey, offset); this.sect.sect.total = offset; } diff --git a/common/web/types/src/kmx/kmx-plus.ts b/common/web/types/src/kmx/kmx-plus.ts index eba1324b85..1c022a7803 100644 --- a/common/web/types/src/kmx/kmx-plus.ts +++ b/common/web/types/src/kmx/kmx-plus.ts @@ -404,17 +404,6 @@ export class Bksp extends Tran { } }; -// 'vkey' - -export class VkeyItem { - vkey: number; - target: number; -} - -export class Vkey extends Section { - vkeys: VkeyItem[] = []; -}; - // 'disp' export class DispItem { to: StrsItem; @@ -569,7 +558,6 @@ export interface KMXPlusData { tran?: Tran; uset?: Uset; // uset is ignored in-memory vars?: Vars; - vkey?: Vkey; }; export class KMXPlusFile extends KMXFile { diff --git a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts index 5f954c1605..83720312dd 100644 --- a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts +++ b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml.ts @@ -27,7 +27,6 @@ export interface LKKeyboard { forms?: LKForms; displays?: LKDisplays; layers?: LKLayers[]; - vkeys?: LKVkeys; variables?: LKVariables; transforms?: LKTransforms[]; }; @@ -129,15 +128,6 @@ export interface LKRow { keys?: string; }; -export interface LKVkeys { - vkey?: LKVkey[]; -}; - -export interface LKVkey { - from?: string; - to?: string; -}; - export interface LKVariables { string?: LKString[]; set?: LKSet[]; diff --git a/core/include/ldml/keyboardprocessor_ldml.h b/core/include/ldml/keyboardprocessor_ldml.h index 4c629ae77b..641382a4ff 100644 --- a/core/include/ldml/keyboardprocessor_ldml.h +++ b/core/include/ldml/keyboardprocessor_ldml.h @@ -92,8 +92,6 @@ #define LDML_LENGTH_USET_USET 0xC #define LDML_LENGTH_VARS 0x10 #define LDML_LENGTH_VARS_ITEM 0x10 -#define LDML_LENGTH_VKEY 0xC -#define LDML_LENGTH_VKEY_ITEM 0x8 #define LDML_MARKER_ANY_INDEX 0xD7FF #define LDML_MARKER_CODE 0x8 #define LDML_MARKER_MAX_COUNT 0xD7FE @@ -130,8 +128,6 @@ #define LDML_SECTIONNAME_USET "uset" #define LDML_SECTIONID_VARS 0x73726176 /* "vars" */ #define LDML_SECTIONNAME_VARS "vars" -#define LDML_SECTIONID_VKEY 0x79656B76 /* "vkey" */ -#define LDML_SECTIONNAME_VKEY "vkey" #define LDML_TRAN_FLAGS_ERROR 0x1 #define LDML_TRAN_GROUP_TYPE_REORDER 0x1 #define LDML_TRAN_GROUP_TYPE_TRANSFORM 0x0 diff --git a/core/include/ldml/keyboardprocessor_ldml.ts b/core/include/ldml/keyboardprocessor_ldml.ts index d19784b110..90882024b3 100644 --- a/core/include/ldml/keyboardprocessor_ldml.ts +++ b/core/include/ldml/keyboardprocessor_ldml.ts @@ -37,8 +37,7 @@ export type SectionIdent = 'strs' | 'tran' | 'uset' | - 'vars' | - 'vkey'; + 'vars'; type SectionMap = { @@ -508,19 +507,6 @@ class Constants { */ readonly tran_group_type_reorder = 1; - /* ------------------------------------------------------------------ - * vkey section - ------------------------------------------------------------------ */ - - /** - * Minimum length of the 'vkey' section not including variable parts - */ - readonly length_vkey = 12; - /** - * Length of each item in the 'vkey' section variable part - */ - readonly length_vkey_item = 8; - /* ------------------------------------------------------------------ * vars section * ------------------------------------------------------------------ */ @@ -585,7 +571,6 @@ class Constants { tran: 'tran', uset: 'uset', vars: 'vars', - vkey: 'vkey', }; /** diff --git a/core/src/kmx/kmx_plus.cpp b/core/src/kmx/kmx_plus.cpp index b20b826cc2..950febfa9b 100644 --- a/core/src/kmx/kmx_plus.cpp +++ b/core/src/kmx/kmx_plus.cpp @@ -215,25 +215,6 @@ COMP_KMXPLUS_META::valid(KMX_DWORD _kmn_unused(length)) const { return true; } -bool -COMP_KMXPLUS_VKEY::valid(KMX_DWORD _kmn_unused(length)) const { - DebugLog("vkey: count 0x%X\n", count); - if (header.size < sizeof(*this)+(sizeof(entries[0])*count)) { - DebugLog("header.size < expected size"); - assert(false); - return false; - } - for (KMX_DWORD i = 0; i < count; i++) { - DebugLog("vkey #0x%X: 0x%X->0x%X", i, entries[i].vkey, entries[i].target); - if (entries[i].vkey > 0xFF || entries[i].target > 0xFF) { - DebugLog("vkey source or target out of range [0x00…0xFF]"); - assert(false); - return false; - } - } - return true; -} - bool COMP_KMXPLUS_DISP::valid(KMX_DWORD _kmn_unused(length)) const { DebugLog("disp: count 0x%X\n", count); @@ -1183,7 +1164,7 @@ COMP_KMXPLUS_USET_Helper::getRange(KMX_DWORD i) const { kmx_plus::kmx_plus(const COMP_KEYBOARD *keyboard, size_t length) : bksp(nullptr), disp(nullptr), elem(nullptr), key2(nullptr), layr(nullptr), list(nullptr), loca(nullptr), meta(nullptr), - sect(nullptr), strs(nullptr), tran(nullptr), vars(nullptr), vkey(nullptr), valid(false) { + sect(nullptr), strs(nullptr), tran(nullptr), vars(nullptr), valid(false) { DebugLog("kmx_plus: Got a COMP_KEYBOARD at %p\n", keyboard); #if !KMXPLUS_DEBUG_LOAD DebugLog("Note: define KMXPLUS_DEBUG_LOAD=1 at compile time for more verbosity in loading"); @@ -1232,7 +1213,6 @@ kmx_plus::kmx_plus(const COMP_KEYBOARD *keyboard, size_t length) tran = section_from_sect(sect); uset = section_from_sect(sect); vars = section_from_sect(sect); - vkey = section_from_sect(sect); // Initialize the helper objects for sections with dynamic parts. // Note: all of these setters will be passed 'nullptr' diff --git a/core/src/kmx/kmx_plus.h b/core/src/kmx/kmx_plus.h index b75fcf2bd0..ec269668f8 100644 --- a/core/src/kmx/kmx_plus.h +++ b/core/src/kmx/kmx_plus.h @@ -348,7 +348,7 @@ struct COMP_KMXPLUS_BKSP : public COMP_KMXPLUS_TRAN { /* ------------------------------------------------------------------ - * vkey section + * vars section ------------------------------------------------------------------ */ struct COMP_KMXPLUS_VARS_ITEM { @@ -376,30 +376,6 @@ static_assert(sizeof(struct COMP_KMXPLUS_VARS) % 0x4 == 0, "Structs prior to var static_assert(sizeof(struct COMP_KMXPLUS_VARS) == LDML_LENGTH_VARS, "mismatched size of section vars"); static_assert(sizeof(struct COMP_KMXPLUS_VARS_ITEM) == LDML_LENGTH_VARS_ITEM, "mismatched size of vars item"); -/* ------------------------------------------------------------------ - * vkey section - ------------------------------------------------------------------ */ - -struct COMP_KMXPLUS_VKEY_ENTRY { - KMX_DWORD_unaligned vkey; - KMX_DWORD_unaligned target; -}; - -struct COMP_KMXPLUS_VKEY { - static const KMXPLUS_IDENT IDENT = LDML_SECTIONID_VKEY; - COMP_KMXPLUS_HEADER header; - KMX_DWORD_unaligned count; - COMP_KMXPLUS_VKEY_ENTRY entries[]; - /** - * @brief True if section is valid. - */ - bool valid(KMX_DWORD length) const; -}; - -static_assert(sizeof(struct COMP_KMXPLUS_VKEY) % 0x4 == 0, "Structs prior to variable part should align to 32-bit boundary"); -static_assert(sizeof(struct COMP_KMXPLUS_VKEY) == LDML_LENGTH_VKEY, "mismatched size of section vkey"); - - /* ------------------------------------------------------------------ * disp section ------------------------------------------------------------------ */ @@ -787,7 +763,6 @@ class kmx_plus { const COMP_KMXPLUS_TRAN *tran; const COMP_KMXPLUS_USET *uset; const COMP_KMXPLUS_VARS *vars; - const COMP_KMXPLUS_VKEY *vkey; inline bool is_valid() { return valid; } COMP_KMXPLUS_BKSP_Helper bkspHelper; COMP_KMXPLUS_KEYS_Helper key2Helper; diff --git a/developer/src/kmc-ldml/src/compiler/compiler.ts b/developer/src/kmc-ldml/src/compiler/compiler.ts index ad0340ed82..c29aa9fa93 100644 --- a/developer/src/kmc-ldml/src/compiler/compiler.ts +++ b/developer/src/kmc-ldml/src/compiler/compiler.ts @@ -8,7 +8,6 @@ import { LayrCompiler } from './layr.js'; import { LocaCompiler } from './loca.js'; import { MetaCompiler } from './meta.js'; import { NameCompiler } from './name.js'; -import { VkeyCompiler } from './vkey.js'; import { VarsCompiler } from './vars.js'; import { StrsCompiler, ElemCompiler, ListCompiler, UsetCompiler } from './empty-compiler.js'; @@ -38,7 +37,6 @@ export const SECTION_COMPILERS = [ MetaCompiler, NameCompiler, TranCompiler, - VkeyCompiler, ]; export class LdmlKeyboardCompiler { diff --git a/developer/src/kmc-ldml/src/compiler/messages.ts b/developer/src/kmc-ldml/src/compiler/messages.ts index 5bc3fba784..28783d0f85 100644 --- a/developer/src/kmc-ldml/src/compiler/messages.ts +++ b/developer/src/kmc-ldml/src/compiler/messages.ts @@ -1,6 +1,6 @@ import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m } from "@keymanapp/common-types"; -const SevInfo = CompilerErrorSeverity.Info | CompilerErrorNamespace.LdmlKeyboardCompiler; +// const SevInfo = CompilerErrorSeverity.Info | CompilerErrorNamespace.LdmlKeyboardCompiler; const SevHint = CompilerErrorSeverity.Hint | CompilerErrorNamespace.LdmlKeyboardCompiler; const SevWarn = CompilerErrorSeverity.Warn | CompilerErrorNamespace.LdmlKeyboardCompiler; const SevError = CompilerErrorSeverity.Error | CompilerErrorNamespace.LdmlKeyboardCompiler; @@ -35,21 +35,7 @@ export class CompilerMessages { m(this.HINT_LocaleIsNotMinimalAndClean, `Locale '${o.sourceLocale}' is not minimal or correctly formatted and should be '${o.locale}'`); static HINT_LocaleIsNotMinimalAndClean = SevHint | 0x0008; - static Hint_VkeyIsNotValid = (o:{vkey: string}) => - m(this.HINT_VkeyIsNotValid, `Virtual key '${o.vkey}' is not found in the CLDR VKey Enum table.`); - static HINT_VkeyIsNotValid = SevHint | 0x0009; - - static Hint_VkeyIsRedundant = (o:{vkey: string}) => - m(this.HINT_VkeyIsRedundant, `Virtual key '${o.vkey}' is mapped to itself, which is redundant.`); - static HINT_VkeyIsRedundant = SevHint | 0x000A; - - static Error_VkeyIsRepeated = (o:{vkey: string}) => - m(this.ERROR_VkeyIsRepeated, `Virtual key '${o.vkey}' has more than one vkey entry.`); - static ERROR_VkeyIsRepeated = SevError | 0x000B; - - static Info_MultipleVkeysHaveSameTarget = (o:{vkey: string}) => - m(this.INFO_MultipleVkeysHaveSameTarget, `Target virtual key '${o.vkey}' has multiple source mappings, which may be an error.`); - static INFO_MultipleVkeysHaveSameTarget = SevInfo | 0x000C; + // gap: 0x0009 … 0x000C were for vkeys static Error_InvalidVersion = (o:{version: string}) => m(this.ERROR_InvalidVersion, `Version number '${o.version}' must be a semantic version format string.`); diff --git a/developer/src/kmc-ldml/src/compiler/vkey.ts b/developer/src/kmc-ldml/src/compiler/vkey.ts deleted file mode 100644 index 1c4c69403b..0000000000 --- a/developer/src/kmc-ldml/src/compiler/vkey.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { constants } from "@keymanapp/ldml-keyboard-constants"; -import { KMXPlus, Constants } from '@keymanapp/common-types'; -import { CompilerMessages } from "./messages.js"; -import { SectionCompiler } from "./section-compiler.js"; - -import Vkey = KMXPlus.Vkey; -import LdmlVkeyNames = Constants.LdmlVkeyNames; - -export class VkeyCompiler extends SectionCompiler { - - public get id() { - return constants.section.vkey; - } - - public validate(): boolean { - let valid = true; - if(this.keyboard3.vkeys) { - let from: string[] = [], to: string[] = []; - - this.keyboard3.vkeys.vkey.forEach(vk => { - if(LdmlVkeyNames[vk.from] === undefined) { - // TODO-LDML: When we do #7135 this may need to change back to an error. - this.callbacks.reportMessage(CompilerMessages.Hint_VkeyIsNotValid({vkey: vk.from})); - return; - } - - if(LdmlVkeyNames[vk.to] === undefined) { - // TODO-LDML: When we do #7135 this may need to change back to an error. - this.callbacks.reportMessage(CompilerMessages.Hint_VkeyIsNotValid({vkey: vk.to})); - return; - } - - if(vk.from == vk.to) { - this.callbacks.reportMessage(CompilerMessages.Hint_VkeyIsRedundant({vkey: vk.from})); - } - - if(from.find(svk => svk == vk.from)) { - this.callbacks.reportMessage(CompilerMessages.Error_VkeyIsRepeated({vkey: vk.from})); - valid = false; - } - from.push(vk.from); - - if(to.find(svk => svk == vk.to)) { - this.callbacks.reportMessage(CompilerMessages.Info_MultipleVkeysHaveSameTarget({vkey: vk.to})); - } - to.push(vk.to); - }); - } - return valid; - } - - public compile(): Vkey { - let result = new Vkey(); - if(!this.keyboard3.vkeys) { - /* c8 ignore next 2 */ - return result; // not hit due to boxing - } - - result.vkeys = this.keyboard3.vkeys?.vkey.map(vk => { - return { - vkey: LdmlVkeyNames[vk.from], - target: LdmlVkeyNames[vk.to] - }; - }); - // Sort according to vkey binary order, per C7043 - result.vkeys.sort((a,b) => a.vkey - b.vkey); - return result; - } -} diff --git a/developer/src/kmc-ldml/test/fixtures/basic.txt b/developer/src/kmc-ldml/test/fixtures/basic.txt index 74280b3ecf..9282894633 100644 --- a/developer/src/kmc-ldml/test/fixtures/basic.txt +++ b/developer/src/kmc-ldml/test/fixtures/basic.txt @@ -137,9 +137,6 @@ block(sectitems) 76 61 72 73 diff(sect,vars) - 76 6b 65 79 - diff(sect,vkey) - block(endsect) # ---------------------------------------------------------------------------------------------------- @@ -579,13 +576,4 @@ block(vars) # struct COMP_KMXPLUS_VARS { 00 00 00 00 # KMXPLUS_ELEM elem block(varsEnd) -block(vkey) # struct COMP_KMXPLUS_VKEY { - 76 6b 65 79 # KMX_DWORD header.ident; // 0000 Section name - vkey - sizeof(vkey) # KMX_DWORD header.size; // 0004 Section length - 02 00 00 00 # KMX_DWORD count; // 0008 Number of vkey maps - - 41 00 00 00 51 00 00 00 # KMX_DWORD vkey; KMX_DWORD target; // K_A => K_Q - 51 00 00 00 41 00 00 00 # KMX_DWORD vkey; KMX_DWORD target; // K_Q => K_A - # }; - block(eof) # end of file diff --git a/developer/src/kmc-ldml/test/fixtures/basic.xml b/developer/src/kmc-ldml/test/fixtures/basic.xml index 9c45f5e07f..144bcb4924 100644 --- a/developer/src/kmc-ldml/test/fixtures/basic.xml +++ b/developer/src/kmc-ldml/test/fixtures/basic.xml @@ -14,11 +14,6 @@ - - - - - diff --git a/developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-from-vkey.xml b/developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-from-vkey.xml deleted file mode 100644 index 9ed1d1b63f..0000000000 --- a/developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-from-vkey.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-repeated-vkey.xml b/developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-repeated-vkey.xml deleted file mode 100644 index 36deceb4d8..0000000000 --- a/developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-repeated-vkey.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-to-vkey.xml b/developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-to-vkey.xml deleted file mode 100644 index 58b573adc2..0000000000 --- a/developer/src/kmc-ldml/test/fixtures/sections/vkey/invalid-to-vkey.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/developer/src/kmc-ldml/test/fixtures/sections/vkey/minimal.xml b/developer/src/kmc-ldml/test/fixtures/sections/vkey/minimal.xml deleted file mode 100644 index 4af6dd3032..0000000000 --- a/developer/src/kmc-ldml/test/fixtures/sections/vkey/minimal.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/developer/src/kmc-ldml/test/fixtures/sections/vkey/redundant.xml b/developer/src/kmc-ldml/test/fixtures/sections/vkey/redundant.xml deleted file mode 100644 index 612d12c014..0000000000 --- a/developer/src/kmc-ldml/test/fixtures/sections/vkey/redundant.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/developer/src/kmc-ldml/test/fixtures/sections/vkey/same-target.xml b/developer/src/kmc-ldml/test/fixtures/sections/vkey/same-target.xml deleted file mode 100644 index 9dd34420eb..0000000000 --- a/developer/src/kmc-ldml/test/fixtures/sections/vkey/same-target.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/developer/src/kmc-ldml/test/test-vkey.ts b/developer/src/kmc-ldml/test/test-vkey.ts deleted file mode 100644 index dec24125e2..0000000000 --- a/developer/src/kmc-ldml/test/test-vkey.ts +++ /dev/null @@ -1,62 +0,0 @@ -import 'mocha'; -import { assert } from 'chai'; -import { VkeyCompiler } from '../src/compiler/vkey.js'; -import { compilerTestCallbacks, loadSectionFixture } from './helpers/index.js'; -import { KMXPlus, Constants } from '@keymanapp/common-types'; -import { CompilerMessages } from '../src/compiler/messages.js'; - -import Vkey = KMXPlus.Vkey; -import USVirtualKeyCodes = Constants.USVirtualKeyCodes; - -describe('vkey compiler', function () { - this.slow(500); // 0.5 sec -- json schema validation takes a while - - it('should compile minimal vkey data', async function() { - let vkey = await loadSectionFixture(VkeyCompiler, 'sections/vkey/minimal.xml', compilerTestCallbacks) as Vkey; - assert.equal(compilerTestCallbacks.messages.length, 0); - - assert.equal(vkey.vkeys.length, 4); - // Note, final order is sorted by `vkey` member - assert.deepEqual(vkey.vkeys[0], {vkey: USVirtualKeyCodes.K_A, target: USVirtualKeyCodes.K_Q}); - assert.deepEqual(vkey.vkeys[1], {vkey: USVirtualKeyCodes.K_Q, target: USVirtualKeyCodes.K_A}); - assert.deepEqual(vkey.vkeys[2], {vkey: USVirtualKeyCodes.K_W, target: USVirtualKeyCodes.K_Z}); - assert.deepEqual(vkey.vkeys[3], {vkey: USVirtualKeyCodes.K_Z, target: USVirtualKeyCodes.K_W}); - }); - - it('should hint on redundant data', async function() { - let vkey = await loadSectionFixture(VkeyCompiler, 'sections/vkey/redundant.xml', compilerTestCallbacks) as Vkey; - assert.isNotNull(vkey); - assert.equal(compilerTestCallbacks.messages.length, 1); - assert.deepEqual(compilerTestCallbacks.messages[0], CompilerMessages.Hint_VkeyIsRedundant({vkey: 'A'})); - }); - - it('should report an info message if same target found', async function() { - let vkey = await loadSectionFixture(VkeyCompiler, 'sections/vkey/same-target.xml', compilerTestCallbacks) as Vkey; - assert.isNotNull(vkey); - assert.equal(compilerTestCallbacks.messages.length, 1); - assert.deepEqual(compilerTestCallbacks.messages[0], CompilerMessages.Info_MultipleVkeysHaveSameTarget({vkey: 'Q'})); - }); - - it('should hint on invalid "from" vkey', async function() { - let vkey = await loadSectionFixture(VkeyCompiler, 'sections/vkey/invalid-from-vkey.xml', compilerTestCallbacks) as Vkey; - assert.isNotNull(vkey); - assert.equal(compilerTestCallbacks.messages.length, 2); - assert.deepEqual(compilerTestCallbacks.messages[0], CompilerMessages.Hint_VkeyIsNotValid({vkey: 'q'})); - assert.deepEqual(compilerTestCallbacks.messages[1], CompilerMessages.Hint_VkeyIsNotValid({vkey: 'HYFEN'})); - }); - - it('should hint on invalid "to" vkey', async function() { - let vkey = await loadSectionFixture(VkeyCompiler, 'sections/vkey/invalid-to-vkey.xml', compilerTestCallbacks) as Vkey; - assert.isNotNull(vkey); - assert.equal(compilerTestCallbacks.messages.length, 1); - assert.deepEqual(compilerTestCallbacks.messages[0], CompilerMessages.Hint_VkeyIsNotValid({vkey: 'A-ACUTE'})); - }); - - it('should error on repeated vkeys', async function() { - let vkey = await loadSectionFixture(VkeyCompiler, 'sections/vkey/invalid-repeated-vkey.xml', compilerTestCallbacks) as Vkey; - assert.isNull(vkey); - assert.equal(compilerTestCallbacks.messages.length, 1); - assert.deepEqual(compilerTestCallbacks.messages[0], CompilerMessages.Error_VkeyIsRepeated({vkey: 'A'})); - }); -}); - From 5fa99f53144dfa678f97823aa28da538e47aebc1 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 28 Sep 2023 13:32:02 -0500 Subject: [PATCH 032/107] =?UTF-8?q?fix(common):=20update=20keyman=20for=20?= =?UTF-8?q?removal=20of=20vkeys=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dropped in upstream CLDR-17093 - missed changes See #7135 --- .../ldml-keyboard/ldml-keyboard-xml-reader.ts | 1 - core/tests/unit/ldml/keyboards/k_020_fr.xml | 18 ------------------ 2 files changed, 19 deletions(-) diff --git a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts index 60c77acc22..66f8fdbe56 100644 --- a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts +++ b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts @@ -61,7 +61,6 @@ export class LDMLKeyboardXMLSourceFileReader { boxXmlArray(source?.keyboard3, 'layers'); boxXmlArray(source?.keyboard3?.displays, 'display'); boxXmlArray(source?.keyboard3?.names, 'name'); - boxXmlArray(source?.keyboard3?.vkeys, 'vkey'); boxXmlArray(source?.keyboard3?.keys, 'key'); boxXmlArray(source?.keyboard3?.keys, 'flicks'); boxXmlArray(source?.keyboard3?.locales, 'locale'); diff --git a/core/tests/unit/ldml/keyboards/k_020_fr.xml b/core/tests/unit/ldml/keyboards/k_020_fr.xml index 843ad80ede..42b7e1826f 100644 --- a/core/tests/unit/ldml/keyboards/k_020_fr.xml +++ b/core/tests/unit/ldml/keyboards/k_020_fr.xml @@ -17,24 +17,6 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + diff --git a/developer/src/kmc-ldml/test/fixtures/sections/layr/error-custom-zzz-form.xml b/developer/src/kmc-ldml/test/fixtures/sections/layr/error-custom-zzz-form.xml new file mode 100644 index 0000000000..0ab10f3d03 --- /dev/null +++ b/developer/src/kmc-ldml/test/fixtures/sections/layr/error-custom-zzz-form.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
diff --git a/developer/src/kmc-ldml/test/fixtures/sections/layr/hint-custom-form.xml b/developer/src/kmc-ldml/test/fixtures/sections/layr/warn-custom-us-form.xml similarity index 75% rename from developer/src/kmc-ldml/test/fixtures/sections/layr/hint-custom-form.xml rename to developer/src/kmc-ldml/test/fixtures/sections/layr/warn-custom-us-form.xml index f7122d10a8..d3a0573b21 100644 --- a/developer/src/kmc-ldml/test/fixtures/sections/layr/hint-custom-form.xml +++ b/developer/src/kmc-ldml/test/fixtures/sections/layr/warn-custom-us-form.xml @@ -7,19 +7,20 @@ - + +
- + +
- - + diff --git a/developer/src/kmc-ldml/test/fixtures/sections/layr/error-custom-form.xml b/developer/src/kmc-ldml/test/fixtures/sections/layr/warn-custom-zzz-form.xml similarity index 74% rename from developer/src/kmc-ldml/test/fixtures/sections/layr/error-custom-form.xml rename to developer/src/kmc-ldml/test/fixtures/sections/layr/warn-custom-zzz-form.xml index 5aa93783de..502b254135 100644 --- a/developer/src/kmc-ldml/test/fixtures/sections/layr/error-custom-form.xml +++ b/developer/src/kmc-ldml/test/fixtures/sections/layr/warn-custom-zzz-form.xml @@ -7,18 +7,19 @@ - + +
- +
- + - + diff --git a/developer/src/kmc-ldml/test/test-keys.ts b/developer/src/kmc-ldml/test/test-keys.ts index 9429b33979..fb36f9a96f 100644 --- a/developer/src/kmc-ldml/test/test-keys.ts +++ b/developer/src/kmc-ldml/test/test-keys.ts @@ -241,6 +241,90 @@ describe('keys.kmap', function () { CompilerMessages.Error_MissingFlicks({flicks:'an-undefined-flick-id',id:'Q'}), ] }, + { + subpath: 'sections/layr/invalid-invalid-form.xml', + errors: [CompilerMessages.Error_InvalidHardware({ + form: 'holographic', + }),], + }, + { + // warning on custom form + subpath: 'sections/layr/warn-custom-us-form.xml', + warnings: [ + CompilerMessages.Warn_CustomForm({id: "us"}), + ], + callback: (sect, subpath, callbacks) => { + const keys = sect as Keys; + assert.isNotNull(keys); + assert.equal(compilerTestCallbacks.messages.length, 0); + assert.equal(keys.keys.length, 3); + assert.sameDeepMembers(keys.kmap, [ + { + vkey: K.K_K, + key: 'one', + mod: constants.keys_mod_none, + }, + { + vkey: K.K_E, + key: 'two', + mod: constants.keys_mod_none, + }, + { + vkey: K.K_Y, + key: 'three', + mod: constants.keys_mod_none, + }, + ]); + }, + }, + { + // warning on a custom unknown form - but no error! + subpath: 'sections/layr/warn-custom-zzz-form.xml', + warnings: [ + CompilerMessages.Warn_CustomForm({id: "zzz"}), + ], + callback: (sect, subpath, callbacks) => { + const keys = sect as Keys; + assert.isNotNull(keys); + assert.equal(compilerTestCallbacks.messages.length, 0); + assert.equal(keys.keys.length, 3); + assert.sameDeepMembers(keys.kmap, [ + { + vkey: K.K_K, + key: 'one', + mod: constants.keys_mod_none, + }, + { + vkey: K.K_E, + key: 'two', + mod: constants.keys_mod_none, + }, + { + vkey: K.K_Y, + key: 'three', + mod: constants.keys_mod_none, + }, + ]); + }, + }, + { + subpath: 'sections/layr/error-custom-us-form.xml', + warnings: [ + CompilerMessages.Warn_CustomForm({id: "us"}), + ], + errors: [ + CompilerMessages.Error_InvalidScanCode({ form: "us", codes: ['ff'] }), + ], + }, + { + subpath: 'sections/layr/error-custom-zzz-form.xml', + warnings: [ + CompilerMessages.Warn_CustomForm({id: "zzz"}), + ], + errors: [ + CompilerMessages.Error_InvalidScanCode({ form: "zzz", codes: ['ff'] }), + ], + }, ]); it('should reject layouts with too many hardware rows', async function() { diff --git a/developer/src/kmc-ldml/test/test-layr.ts b/developer/src/kmc-ldml/test/test-layr.ts index 86f16ff27b..126935c33b 100644 --- a/developer/src/kmc-ldml/test/test-layr.ts +++ b/developer/src/kmc-ldml/test/test-layr.ts @@ -32,7 +32,7 @@ describe('layr', function () { const list0 = layr.lists[0]; assert.ok(list0); assert.equal(list0.layers.length, 1); - assert.equal(list0.hardware, constants.layr_list_hardware_us); + assert.equal(list0.hardware.value, 'us'); const layer0 = list0.layers[0]; assert.ok(layer0); assert.equal(layer0.rows.length, 1); @@ -51,7 +51,7 @@ describe('layr', function () { const layr = sect; assert.equal(layr.lists?.length, 2); - const listHardware = layr.lists.find(v => v.hardware === constants.layr_list_hardware_iso); + const listHardware = layr.lists.find(v => v.hardware.value === 'iso'); assert.ok(listHardware); assert.equal(listHardware.minDeviceWidth, 0); assert.equal(listHardware.layers.length, 2); @@ -73,7 +73,7 @@ describe('layr', function () { assert.equal(hardware1row0.keys.length, 2); allKeysOk(hardware1row0,'q w', 'hardware1row0'); - const listTouch = layr.lists.find(v => v.hardware === constants.layr_list_hardware_touch); + const listTouch = layr.lists.find(v => v.hardware.value === constants.layr_list_hardware_touch); assert.ok(listTouch); assert.equal(listTouch.minDeviceWidth, 300); assert.equal(listTouch.layers.length, 1); @@ -105,33 +105,10 @@ describe('layr', function () { subpath: 'sections/layr/invalid-multi-hardware.xml', errors: [CompilerMessages.Error_ExcessHardware({ form: 'iso' })], }, - { - subpath: 'sections/layr/invalid-invalid-form.xml', - errors: [CompilerMessages.Error_InvalidHardware({ - form: 'holographic', - }),], - }, { // missing layer element subpath: 'sections/layr/invalid-missing-layer.xml', errors: [CompilerMessages.Error_MustBeAtLeastOneLayerElement()], }, - { - // warning on custom form - subpath: 'sections/layr/hint-custom-form.xml', - warnings: [ - CompilerMessages.Warn_UnsupportedCustomForm({id: "us"}), - ], - }, - { - // error on unknown form - subpath: 'sections/layr/error-custom-form.xml', - warnings: [ - CompilerMessages.Warn_UnsupportedCustomForm({id: "zzz"}), - ], - errors: [CompilerMessages.Error_InvalidHardware({ - form: 'zzz', - }),], - }, ]); }); From c168ef01cb5b4fd9476cf65537931276c65b4796 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 2 Oct 2023 12:36:54 +0700 Subject: [PATCH 044/107] feat(developer): show an INFO message when warnings have failed a build Fixes #9610. If a build fails when "treat warnings as errors" is on, but there are only warnings and no error messages, it can be confusing for the developer. Adds the following `INFO_WarningsHaveFailedBuild` message: `The build failed because option "treat warnings as errors" is enabled and there are one or more warnings.` --- developer/src/kmc/src/commands/build.ts | 3 +++ .../src/messages/infrastructureMessages.ts | 4 ++++ .../kmc/test/test-infrastructureMessages.ts | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/developer/src/kmc/src/commands/build.ts b/developer/src/kmc/src/commands/build.ts index 1047dd8208..62fbb95031 100644 --- a/developer/src/kmc/src/commands/build.ts +++ b/developer/src/kmc/src/commands/build.ts @@ -129,6 +129,9 @@ async function build(filename: string, parentCallbacks: NodeCompilerCallbacks, o : InfrastructureMessages.Info_FileBuiltSuccessfully({filename:buildFilename}) ); } else { + if(!callbacks.hasFailureMessage(false)) { // false == check only for error+fatal messages + callbacks.reportMessage(InfrastructureMessages.Info_WarningsHaveFailedBuild()); + } callbacks.reportMessage(builder instanceof BuildProject ? InfrastructureMessages.Info_ProjectNotBuiltSuccessfully({filename:buildFilename}) : InfrastructureMessages.Info_FileNotBuiltSuccessfully({filename:buildFilename}) diff --git a/developer/src/kmc/src/messages/infrastructureMessages.ts b/developer/src/kmc/src/messages/infrastructureMessages.ts index ee828dae75..25032152a5 100644 --- a/developer/src/kmc/src/messages/infrastructureMessages.ts +++ b/developer/src/kmc/src/messages/infrastructureMessages.ts @@ -71,5 +71,9 @@ export class InfrastructureMessages { static Error_NotAProjectFile = (o:{filename:string}) => m(this.ERROR_NotAProjectFile, `File ${o.filename} must have a .kpj extension to be treated as a project.`); static ERROR_NotAProjectFile = SevError | 0x000F; + + static Info_WarningsHaveFailedBuild = () => m(this.INFO_WarningsHaveFailedBuild, + `The build failed because option "treat warnings as errors" is enabled and there are one or more warnings.`); + static INFO_WarningsHaveFailedBuild = SevInfo | 0x0010; } diff --git a/developer/src/kmc/test/test-infrastructureMessages.ts b/developer/src/kmc/test/test-infrastructureMessages.ts index a9b55d075d..fde352f3dd 100644 --- a/developer/src/kmc/test/test-infrastructureMessages.ts +++ b/developer/src/kmc/test/test-infrastructureMessages.ts @@ -6,6 +6,7 @@ import { makePathToFixture } from './helpers/index.js'; import { NodeCompilerCallbacks } from '../src/util/NodeCompilerCallbacks.js'; import { CompilerErrorNamespace } from '@keymanapp/common-types'; import { unitTestEndpoints } from '../src/commands/build.js'; +import { KmnCompilerMessages } from '@keymanapp/kmc-kmn'; describe('InfrastructureMessages', function () { it('should have a valid InfrastructureMessages object', function() { @@ -65,4 +66,22 @@ describe('InfrastructureMessages', function () { assert.isTrue(ncb.hasMessage(InfrastructureMessages.HINT_FilenameHasDifferingCase), `HINT_FilenameHasDifferingCase not generated, instead got: `+JSON.stringify(ncb.messages,null,2)); }); + + // INFO_WarningsHaveFailedBuild + + it('should generate INFO_WarningsHaveFailedBuild if only warnings failed the build', async function() { + // NOTE: we can probably re-use this format for most other message tests in the future + const ncb = new NodeCompilerCallbacks({logLevel: 'silent'}); + const filename = makePathToFixture('compiler-warnings-as-errors', 'keyboard.kmn'); + const expectedMessages = [ + InfrastructureMessages.INFO_BuildingFile, + KmnCompilerMessages.WARN_HeaderStatementIsDeprecated, + InfrastructureMessages.INFO_WarningsHaveFailedBuild, + InfrastructureMessages.INFO_FileNotBuiltSuccessfully + ]; + await unitTestEndpoints.build(filename, ncb, {compilerWarningsAsErrors: true}); + assert.deepEqual(ncb.messages.map(m => m.code), expectedMessages, + `actual callbacks.messages:\n${JSON.stringify(ncb.messages,null,2)}\n\n`+ + `did not match expected:\n${JSON.stringify(expectedMessages,null,2)}\n\n`); + }); }); From d4fb7cd23429b9d5bf538c4224e9a1c59c6457df Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 2 Oct 2023 12:48:10 +0700 Subject: [PATCH 045/107] chore(developer): reduce duplicate words warning to hint Fixes #9597. --- developer/src/kmc-model/src/build-trie.ts | 12 +++++++----- developer/src/kmc-model/src/model-compiler-errors.ts | 12 ++++++------ developer/src/kmc-model/test/test-parse-wordlist.ts | 8 ++++---- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/developer/src/kmc-model/src/build-trie.ts b/developer/src/kmc-model/src/build-trie.ts index 5f5ae99f85..7a9b8873f4 100644 --- a/developer/src/kmc-model/src/build-trie.ts +++ b/developer/src/kmc-model/src/build-trie.ts @@ -112,8 +112,10 @@ function _parseWordList(wordlist: WordList, source: WordListSource): void { wordform = wordform.normalize('NFC'); if (original !== wordform) { - // Mixed normalization forms are yucky! Warn about it. - callbacks.reportMessage(ModelCompilerMessages.Warn_MixedNormalizationForms({wordform: wordform})); + // Mixed normalization forms are yucky! Hint about it, because it may + // result in unexpected counts where multiple normalization forms for one + // word + callbacks.reportMessage(ModelCompilerMessages.Hint_MixedNormalizationForms({wordform: wordform})); } wordform = wordform.trim() @@ -129,9 +131,9 @@ function _parseWordList(wordlist: WordList, source: WordListSource): void { } if (wordsSeenInThisFile.has(wordform)) { - // The same word seen across multiple files is fine, - // but a word seen multiple times in one file is a problem! - callbacks.reportMessage(ModelCompilerMessages.Warn_DuplicateWordInSameFile({wordform: wordform})); + // The same word seen across multiple files is fine, but a word seen + // multiple times in one file may be a problem + callbacks.reportMessage(ModelCompilerMessages.Hint_DuplicateWordInSameFile({wordform: wordform})); } wordsSeenInThisFile.add(wordform); diff --git a/developer/src/kmc-model/src/model-compiler-errors.ts b/developer/src/kmc-model/src/model-compiler-errors.ts index beb3398caa..5d112eb96b 100644 --- a/developer/src/kmc-model/src/model-compiler-errors.ts +++ b/developer/src/kmc-model/src/model-compiler-errors.ts @@ -2,8 +2,8 @@ import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerEvent, CompilerM const Namespace = CompilerErrorNamespace.ModelCompiler; // const SevInfo = CompilerErrorSeverity.Info | Namespace; -// const SevHint = CompilerErrorSeverity.Hint | Namespace; -const SevWarn = CompilerErrorSeverity.Warn | Namespace; +const SevHint = CompilerErrorSeverity.Hint | Namespace; +// const SevWarn = CompilerErrorSeverity.Warn | Namespace; const SevError = CompilerErrorSeverity.Error | Namespace; const SevFatal = CompilerErrorSeverity.Fatal | Namespace; @@ -24,13 +24,13 @@ export class ModelCompilerMessages { static Fatal_UnexpectedException = (o:{e: any}) => m(this.FATAL_UnexpectedException, null, o.e ?? 'unknown error'); static FATAL_UnexpectedException = SevFatal | 0x0001; - static Warn_MixedNormalizationForms = (o:{wordform: string}) => m(this.WARN_MixedNormalizationForms, + static Hint_MixedNormalizationForms = (o:{wordform: string}) => m(this.HINT_MixedNormalizationForms, `“${o.wordform}” is not in Unicode NFC. Automatically converting to NFC.`); - static WARN_MixedNormalizationForms = SevWarn | 0x0002; + static HINT_MixedNormalizationForms = SevHint | 0x0002; - static Warn_DuplicateWordInSameFile = (o:{wordform: string}) => m(this.WARN_DuplicateWordInSameFile, + static Hint_DuplicateWordInSameFile = (o:{wordform: string}) => m(this.HINT_DuplicateWordInSameFile, `duplicate word “${o.wordform}” found in same file; summing counts`); - static WARN_DuplicateWordInSameFile = SevWarn | 0x0003; + static HINT_DuplicateWordInSameFile = SevHint | 0x0003; static Error_UnimplementedModelFormat = (o:{format: string}) => m(this.ERROR_UnimplementedModelFormat, `Unimplemented model format: ${o.format}`); diff --git a/developer/src/kmc-model/test/test-parse-wordlist.ts b/developer/src/kmc-model/test/test-parse-wordlist.ts index ab610f5e80..93269e243d 100644 --- a/developer/src/kmc-model/test/test-parse-wordlist.ts +++ b/developer/src/kmc-model/test/test-parse-wordlist.ts @@ -108,9 +108,9 @@ describe('parsing a word list', function () { assert.lengthOf(testCallbacks.messages, 4); // hello has been seen multiple times: - assert.isTrue(testCallbacks.hasMessage(ModelCompilerMessages.WARN_DuplicateWordInSameFile)); + assert.isTrue(testCallbacks.hasMessage(ModelCompilerMessages.HINT_DuplicateWordInSameFile)); // helló and hello + U+0301 have both been seen: - assert.isTrue(testCallbacks.hasMessage(ModelCompilerMessages.WARN_MixedNormalizationForms)); + assert.isTrue(testCallbacks.hasMessage(ModelCompilerMessages.HINT_MixedNormalizationForms)); // Let's parse another file: @@ -119,9 +119,9 @@ describe('parsing a word list', function () { parseWordListFromContents(repeatedWords, "hello\u0301\t5\n"); assert.lengthOf(testCallbacks.messages, 1); // hello + U+0301 (NFD) has been seen, but... - assert.isTrue(testCallbacks.hasMessage(ModelCompilerMessages.WARN_MixedNormalizationForms)); + assert.isTrue(testCallbacks.hasMessage(ModelCompilerMessages.HINT_MixedNormalizationForms)); // BUT! We have not seen a duplicate **within the same file** - assert.isFalse(testCallbacks.hasMessage(ModelCompilerMessages.WARN_DuplicateWordInSameFile)); + assert.isFalse(testCallbacks.hasMessage(ModelCompilerMessages.HINT_DuplicateWordInSameFile)); assert.deepEqual(repeatedWords, { hello: expected['hello'], From 7adc9b5d955961c6cf3e6901923ab118e72adba7 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 2 Oct 2023 15:30:07 +0700 Subject: [PATCH 046/107] feat(developer): support `store(&version) '17.0'` Fixes #9541. Also adds version 16.0 support to the kmcmplib compiler constants, and unit tests for both versions. Does not add any support for automatic version feature detection, because that forces an inverted dependency on the touch layout compilation phase (done in kmc-kmw), which would be a significant refactor. This may be something we need to support in the future. --- common/include/kmx_file.h | 3 +- common/web/types/src/kmx/kmx.ts | 3 +- common/windows/cpp/include/legacy_kmx_file.h | 3 +- .../delphi/keyboards/kmxfileconsts.pas | 3 +- .../test/fixtures/features/version_160.kmn | 8 ++++ .../test/fixtures/features/version_170.kmn | 8 ++++ developer/src/kmc-kmn/test/test-features.ts | 44 +++++++++++++++++++ developer/src/kmcmplib/src/Compiler.cpp | 2 + .../KeymanEngine4Mac/KME/KMBinaryFileFormat.h | 3 +- 9 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 developer/src/kmc-kmn/test/fixtures/features/version_160.kmn create mode 100644 developer/src/kmc-kmn/test/fixtures/features/version_170.kmn create mode 100644 developer/src/kmc-kmn/test/test-features.ts diff --git a/common/include/kmx_file.h b/common/include/kmx_file.h index b689ba685a..243e5e0d63 100644 --- a/common/include/kmx_file.h +++ b/common/include/kmx_file.h @@ -68,9 +68,10 @@ namespace kmx { #define VERSION_150 0x00000F00 #define VERSION_160 0x00001000 +#define VERSION_170 0x00001100 #define VERSION_MIN VERSION_50 -#define VERSION_MAX VERSION_160 +#define VERSION_MAX VERSION_170 // // Backspace types diff --git a/common/web/types/src/kmx/kmx.ts b/common/web/types/src/kmx/kmx.ts index 8a2c3e47aa..6102a69cf5 100644 --- a/common/web/types/src/kmx/kmx.ts +++ b/common/web/types/src/kmx/kmx.ts @@ -144,9 +144,10 @@ export class KMXFile { public static readonly VERSION_150 = 0x00000F00; public static readonly VERSION_160 = 0x00001000; + public static readonly VERSION_170 = 0x00001100; public static readonly VERSION_MIN = this.VERSION_50; - public static readonly VERSION_MAX = this.VERSION_160; + public static readonly VERSION_MAX = this.VERSION_170; // // Backspace types diff --git a/common/windows/cpp/include/legacy_kmx_file.h b/common/windows/cpp/include/legacy_kmx_file.h index 6be4b3b986..9b8f6a59fb 100644 --- a/common/windows/cpp/include/legacy_kmx_file.h +++ b/common/windows/cpp/include/legacy_kmx_file.h @@ -74,8 +74,9 @@ #define VERSION_140 0x00000E00 #define VERSION_150 0x00000F00 #define VERSION_160 0x00001000 +#define VERSION_170 0x00001100 #define VERSION_MIN VERSION_50 -#define VERSION_MAX VERSION_160 +#define VERSION_MAX VERSION_170 /* Special flag for WM_CHAR/WM_KEY???/WM_SYSKEY???: says that key has been diff --git a/common/windows/delphi/keyboards/kmxfileconsts.pas b/common/windows/delphi/keyboards/kmxfileconsts.pas index e08feb6564..966dada882 100644 --- a/common/windows/delphi/keyboards/kmxfileconsts.pas +++ b/common/windows/delphi/keyboards/kmxfileconsts.pas @@ -99,9 +99,10 @@ const VERSION_140 = $00000E00; VERSION_150 = $00000F00; VERSION_160 = $00001000; + VERSION_170 = $00001100; VERSION_MIN = VERSION_50; - VERSION_MAX = VERSION_160; + VERSION_MAX = VERSION_170; VERSION_MASK_MINOR = $00FF; VERSION_MASK_MAJOR = $FF00; diff --git a/developer/src/kmc-kmn/test/fixtures/features/version_160.kmn b/developer/src/kmc-kmn/test/fixtures/features/version_160.kmn new file mode 100644 index 0000000000..43ba17e6af --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/features/version_160.kmn @@ -0,0 +1,8 @@ +c Description: Verifies that kmcmplib can compile a v16.0 keyboard + +store(&NAME) 'version_160' +store(&VERSION) '16.0' + +begin unicode > use(main) + +group(main) using keys diff --git a/developer/src/kmc-kmn/test/fixtures/features/version_170.kmn b/developer/src/kmc-kmn/test/fixtures/features/version_170.kmn new file mode 100644 index 0000000000..b9779d0734 --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/features/version_170.kmn @@ -0,0 +1,8 @@ +c Description: Verifies that kmcmplib can compile a v17.0 keyboard + +store(&NAME) 'version_170' +store(&VERSION) '17.0' + +begin unicode > use(main) + +group(main) using keys diff --git a/developer/src/kmc-kmn/test/test-features.ts b/developer/src/kmc-kmn/test/test-features.ts new file mode 100644 index 0000000000..aa3b050a9f --- /dev/null +++ b/developer/src/kmc-kmn/test/test-features.ts @@ -0,0 +1,44 @@ +import 'mocha'; +import { assert } from 'chai'; +import { KmnCompiler } from '../src/main.js'; +import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; +import { makePathToFixture } from './helpers/index.js'; +import { KMX, KmxFileReader } from '@keymanapp/common-types'; + +describe('Keyboard compiler features', async function() { + let compiler: KmnCompiler = null; + let callbacks: TestCompilerCallbacks = null; + + this.beforeAll(async function() { + compiler = new KmnCompiler(); + callbacks = new TestCompilerCallbacks(); + assert(await compiler.init(callbacks)); + assert(compiler.verifyInitialized()); + }); + + beforeEach(function() { + callbacks.clear(); + }); + + // Test each Keyman file version target + + const versions = [ + // TODO(lowpri): we should add a test for each version + also test automatic feature detection + ['16.0', '160', KMX.KMXFile.VERSION_160], + ['17.0', '170', KMX.KMXFile.VERSION_170], + ]; + + for(const v of versions) { + it(`should build a version ${v[0]} keyboard`, function() { + const fixtureName = makePathToFixture('features', `version_${v[1]}.kmn`); + + const result = compiler.runCompiler(fixtureName, `version_${v[1]}.kmx`, {saveDebug: true}); + if(result === null) callbacks.printMessages(); + assert.isNotNull(result); + + const reader = new KmxFileReader(); + const keyboard = reader.read(result.kmx.data); + assert.equal(keyboard.fileVersion, v[2]); + }); + } +}); diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index 02990bc324..b09b9d60e4 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -1029,6 +1029,8 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE else if (u16ncmp(p, u"10.0", 4) == 0) fk->version = VERSION_100; else if (u16ncmp(p, u"14.0", 4) == 0) fk->version = VERSION_140; // Adds support for #917 -- context() with notany() for KeymanWeb else if (u16ncmp(p, u"15.0", 4) == 0) fk->version = VERSION_150; // Adds support for U_xxxx_yyyy #2858 + else if (u16ncmp(p, u"16.0", 4) == 0) fk->version = VERSION_160; // KMXPlus + else if (u16ncmp(p, u"17.0", 4) == 0) fk->version = VERSION_170; // Flicks and gestures else return CERR_InvalidVersion; diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/KMBinaryFileFormat.h b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/KMBinaryFileFormat.h index 97907c67c1..d91f9b4f40 100644 --- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/KMBinaryFileFormat.h +++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/KMBinaryFileFormat.h @@ -45,8 +45,9 @@ struct COMP_KEYBOARD { #define VERSION_140 0x00000E00 #define VERSION_150 0x00000F00 #define VERSION_160 0x00001000 +#define VERSION_170 0x00001100 #define VERSION_MIN VERSION_50 -#define VERSION_MAX VERSION_160 +#define VERSION_MAX VERSION_170 struct COMP_GROUP { DWORD dpName; // string (only debug) From a2fa1f918edfa4997a36dd466042d3bbdf20860a Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 2 Oct 2023 15:55:00 +0700 Subject: [PATCH 047/107] feat(developer): issue hint if package includes keyboard source files Fixes #9325. Also tweaks test for error_package_must_contain_a_model_or_a_keyboard as the fixture had a .kmn, triggering the new hint, which was unhelpful in this case. --- .../src/kmc-package/src/compiler/messages.ts | 6 ++- .../src/compiler/package-validation.ts | 24 +++++++++++- ...age_must_contain_a_model_or_a_keyboard.kps | 9 ++--- .../test/fixtures/invalid/example.txt | 1 + ...t_source_file_should_not_be_in_package.kps | 38 +++++++++++++++++++ .../src/kmc-package/test/test-messages.ts | 9 ++++- 6 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 developer/src/kmc-package/test/fixtures/invalid/example.txt create mode 100644 developer/src/kmc-package/test/fixtures/invalid/hint_source_file_should_not_be_in_package.kps diff --git a/developer/src/kmc-package/src/compiler/messages.ts b/developer/src/kmc-package/src/compiler/messages.ts index c230c69772..86f088ab69 100644 --- a/developer/src/kmc-package/src/compiler/messages.ts +++ b/developer/src/kmc-package/src/compiler/messages.ts @@ -2,7 +2,7 @@ import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m const Namespace = CompilerErrorNamespace.PackageCompiler; const SevInfo = CompilerErrorSeverity.Info | Namespace; -// const SevHint = CompilerErrorSeverity.Hint | Namespace; +const SevHint = CompilerErrorSeverity.Hint | Namespace; const SevWarn = CompilerErrorSeverity.Warn | Namespace; const SevError = CompilerErrorSeverity.Error | Namespace; const SevFatal = CompilerErrorSeverity.Fatal | Namespace; @@ -116,5 +116,9 @@ export class CompilerMessages { `The keyboard ${o.id} should have at least one language specified.`); static WARN_KeyboardShouldHaveAtLeastOneLanguage = SevWarn | 0x001B; + static Hint_PackageContainsSourceFile = (o:{filename:string}) => m(this.HINT_PackageContainsSourceFile, + `The source file ${o.filename} should not be included in the package; instead include the compiled result.`); + static HINT_PackageContainsSourceFile = SevHint | 0x001C; + } diff --git a/developer/src/kmc-package/src/compiler/package-validation.ts b/developer/src/kmc-package/src/compiler/package-validation.ts index 94e180a465..f0463e8f53 100644 --- a/developer/src/kmc-package/src/compiler/package-validation.ts +++ b/developer/src/kmc-package/src/compiler/package-validation.ts @@ -1,4 +1,4 @@ -import { KmpJsonFile, CompilerCallbacks, CompilerOptions } from '@keymanapp/common-types'; +import { KmpJsonFile, CompilerCallbacks, CompilerOptions, KeymanFileTypes } from '@keymanapp/common-types'; import { CompilerMessages } from './messages.js'; import { keymanEngineForWindowsFiles, keymanForWindowsInstallerFiles, keymanForWindowsRedistFiles } from './redist-files.js'; @@ -167,15 +167,35 @@ export class PackageValidation { } private checkIfContentFileIsDangerous(file: KmpJsonFile.KmpJsonFileContentFile): boolean { - let filename = this.callbacks.path.basename(file.name).toLowerCase(); + const filename = this.callbacks.path.basename(file.name).toLowerCase(); + + // # Test for inclusion of redistributable files + if(keymanForWindowsInstallerFiles.includes(filename) || keymanForWindowsRedistFiles.includes(filename) || keymanEngineForWindowsFiles.includes(filename)) { this.callbacks.reportMessage(CompilerMessages.Warn_RedistFileShouldNotBeInPackage({filename})); } + + // # Test for inclusion of .doc or .docx files + if(filename.match(/\.doc(x?)$/)) { this.callbacks.reportMessage(CompilerMessages.Warn_DocFileDangerous({filename})); } + + // # Test for inclusion of keyboard source files + // + // We treat this as a hint, because it's not a dangerous problem, just + // something that suggests that perhaps they are trying to distribute the + // wrong files. + // + // Note: we allow .xml in the package because there are other files + // which may be valid, not just LDML keyboards + const fileType = KeymanFileTypes.sourceTypeFromFilename(file.name); + if(fileType !== null && fileType !== KeymanFileTypes.Source.LdmlKeyboard) { + this.callbacks.reportMessage(CompilerMessages.Hint_PackageContainsSourceFile({filename: file.name})); + } + return true; } diff --git a/developer/src/kmc-package/test/fixtures/invalid/error_package_must_contain_a_model_or_a_keyboard.kps b/developer/src/kmc-package/test/fixtures/invalid/error_package_must_contain_a_model_or_a_keyboard.kps index 335201a6e5..51b3e3f363 100644 --- a/developer/src/kmc-package/test/fixtures/invalid/error_package_must_contain_a_model_or_a_keyboard.kps +++ b/developer/src/kmc-package/test/fixtures/invalid/error_package_must_contain_a_model_or_a_keyboard.kps @@ -10,12 +10,11 @@ - - khmer_angkor.kmn - Keyboard Khmer Angkor + + example.txt + Example text file 0 - .kmn + .txt diff --git a/developer/src/kmc-package/test/fixtures/invalid/example.txt b/developer/src/kmc-package/test/fixtures/invalid/example.txt new file mode 100644 index 0000000000..0f8c58ac58 --- /dev/null +++ b/developer/src/kmc-package/test/fixtures/invalid/example.txt @@ -0,0 +1 @@ +This is a sample text file \ No newline at end of file diff --git a/developer/src/kmc-package/test/fixtures/invalid/hint_source_file_should_not_be_in_package.kps b/developer/src/kmc-package/test/fixtures/invalid/hint_source_file_should_not_be_in_package.kps new file mode 100644 index 0000000000..8de72f2a82 --- /dev/null +++ b/developer/src/kmc-package/test/fixtures/invalid/hint_source_file_should_not_be_in_package.kps @@ -0,0 +1,38 @@ + + + + 15.0.266.0 + 7.0 + + + SENĆOŦEN (Saanich Dialect) Keyboard + © 2019 National Research Council Canada + Eddie Antonio Santos + 1.0 + + + + basic.kmx + Keyboard Basic + 0 + .kmx + + + + basic.kmn + Keyboard Source Basic + 0 + .kmn + + + + + Basic + basic + 1.0 + + Khmer + + + + diff --git a/developer/src/kmc-package/test/test-messages.ts b/developer/src/kmc-package/test/test-messages.ts index e1d463dc4f..477fc8f700 100644 --- a/developer/src/kmc-package/test/test-messages.ts +++ b/developer/src/kmc-package/test/test-messages.ts @@ -182,7 +182,7 @@ describe('CompilerMessages', function () { // ERROR_PackageMustContainAPackageOrAKeyboard - it('should generate ERROR_PackageMustContainAModelOrAKeyboard if package contains a .doc file', async function() { + it('should generate ERROR_PackageMustContainAModelOrAKeyboard if package contains no keyboard or model', async function() { testForMessage(this, ['invalid', 'error_package_must_contain_a_model_or_a_keyboard.kps'], CompilerMessages.ERROR_PackageMustContainAModelOrAKeyboard); }); @@ -201,4 +201,11 @@ describe('CompilerMessages', function () { CompilerMessages.WARN_KeyboardShouldHaveAtLeastOneLanguage); }); + // HINT_PackageContainsSourceFile + + it('should generate HINT_PackageContainsSourceFile if package contains a source file', async function() { + testForMessage(this, ['invalid', 'hint_source_file_should_not_be_in_package.kps'], + CompilerMessages.HINT_PackageContainsSourceFile); + }); + }); From 1b8516652b282676300cede7629688b323fe4d58 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 2 Oct 2023 09:23:48 -0500 Subject: [PATCH 048/107] Actualizar virtual-key-constants.ts Co-authored-by: Marc Durdin --- common/web/types/src/consts/virtual-key-constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/web/types/src/consts/virtual-key-constants.ts b/common/web/types/src/consts/virtual-key-constants.ts index 5624afb572..447c26e2c2 100644 --- a/common/web/types/src/consts/virtual-key-constants.ts +++ b/common/web/types/src/consts/virtual-key-constants.ts @@ -199,9 +199,9 @@ export const CLDRScanToUSVirtualKeyCodes = { 0x39: k.K_SPACE, - 0x56: k.K_oE2, // << Dup + 0x56: k.K_oE2, // << Same as 0x7D; found on iso, abnt2 0x73: k.k_oC1, - 0x7D: k.K_oE2, // << Dup + 0x7D: k.K_oE2, // << Same as 0x56; found on jis }; export type KeyMap = number[][]; From 8200f84418005ca63528979faa8acac257a07a17 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 2 Oct 2023 12:30:36 -0500 Subject: [PATCH 049/107] =?UTF-8?q?feat(developer):=20scancode=20and=20for?= =?UTF-8?q?ms=20=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix casing of k_oC1 - allow vkey 226 to be doubly defined - drop LdmlVkeyNames table and test, not needed anymore (was for vkey #7135) Fixes: #9403 --- .../types/src/consts/virtual-key-constants.ts | 62 +--------------- .../test-ldml-keyboard-xml-reader.ts | 6 +- .../test/test-virtual-key-constants.ts | 70 ------------------- 3 files changed, 6 insertions(+), 132 deletions(-) delete mode 100644 developer/src/kmc-ldml/test/test-virtual-key-constants.ts diff --git a/common/web/types/src/consts/virtual-key-constants.ts b/common/web/types/src/consts/virtual-key-constants.ts index 447c26e2c2..798dd95ead 100644 --- a/common/web/types/src/consts/virtual-key-constants.ts +++ b/common/web/types/src/consts/virtual-key-constants.ts @@ -122,8 +122,8 @@ export const USVirtualKeyCodes = { */ K_oE2:226, K_OE2:226, - k_oC1:193, // ISO B11, ABNT-2 key to left of right shift, not on US keyboard - k_OC1:193, + K_oC1:193, // ISO B11, ABNT-2 key to left of right shift, not on US keyboard + K_OC1:193, 'K_?C1':193, 'k_?C1':193, K_oDF:0xDF, @@ -200,7 +200,7 @@ export const CLDRScanToUSVirtualKeyCodes = { 0x39: k.K_SPACE, 0x56: k.K_oE2, // << Same as 0x7D; found on iso, abnt2 - 0x73: k.k_oC1, + 0x73: k.K_oC1, 0x7D: k.K_oE2, // << Same as 0x56; found on jis }; @@ -230,59 +230,3 @@ export function CLDRScanToVkey(scan: number, badScans?: Set): number { } } - -/** - * Maps LDML VKey Names from CLDR VKey Enum in TR35 to Keyman virtual key codes - */ -export const LdmlVkeyNames: Record = { - 'SPACE': k.K_SPACE, // 0x20, // A03 - '0': k.K_0, // 0x30, // E10 - '1': k.K_1, // 0x31, // E01 - '2': k.K_2, // 0x32, // E02 - '3': k.K_3, // 0x33, // E03 - '4': k.K_4, // 0x34, // E04 - '5': k.K_5, // 0x35, // E05 - '6': k.K_6, // 0x36, // E06 - '7': k.K_7, // 0x37, // E07 - '8': k.K_8, // 0x38, // E08 - '9': k.K_9, // 0x39, // E09 - 'A': k.K_A, // 0x41, // C01 - 'B': k.K_B, // 0x42, // B05 - 'C': k.K_C, // 0x43, // B03 - 'D': k.K_D, // 0x44, // C03 - 'E': k.K_E, // 0x45, // D03 - 'F': k.K_F, // 0x46, // C04 - 'G': k.K_G, // 0x47, // C05 - 'H': k.K_H, // 0x48, // C06 - 'I': k.K_I, // 0x49, // D08 - 'J': k.K_J, // 0x4A, // C07 - 'K': k.K_K, // 0x4B, // C08 - 'L': k.K_L, // 0x4C, // C09 - 'M': k.K_M, // 0x4D, // B07 - 'N': k.K_N, // 0x4E, // B06 - 'O': k.K_O, // 0x4F, // D09 - 'P': k.K_P, // 0x50, // D10 - 'Q': k.K_Q, // 0x51, // D01 - 'R': k.K_R, // 0x52, // D04 - 'S': k.K_S, // 0x53, // C02 - 'T': k.K_T, // 0x54, // D05 - 'U': k.K_U, // 0x55, // D07 - 'V': k.K_V, // 0x56, // B05 - 'W': k.K_W, // 0x57, // D02 - 'X': k.K_X, // 0x58, // B02 - 'Y': k.K_Y, // 0x59, // D06 - 'Z': k.K_Z, // 0x5A, // B01 - 'SEMICOLON': k.K_COLON, // 0xBA, // C10 - 'EQUAL': k.K_EQUAL, // 0xBB, // E12 - 'COMMA': k.K_COMMA, // 0xBC, // B08 - 'HYPHEN': k.K_HYPHEN, // 0xBD, // E11 - 'PERIOD': k.K_PERIOD, // 0xBE, // B09 - 'SLASH': k.K_SLASH, // 0xBF, // B10 - 'GRAVE': k.K_BKQUOTE, // 0xC0, // E00 - 'LBRACKET': k.K_LBRKT, // 0xDB, // D11 - 'BACKSLASH': k.K_BKSLASH, // 0xDC, // D13 - 'RBRACKET': k.K_RBRKT, // 0xDD, // D12 - 'QUOTE': k.K_QUOTE, // 0xDE, // C11 - 'LESS-THAN': k.K_oE2, // 0xE2, // B00 102nd key on European layouts, right of left shift. - 'ABNT2': k.k_oC1, // 0xC1, // B11 Extra key, left of right-shift, ABNT2 -}; diff --git a/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts b/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts index 8816ffce23..252f3e4319 100644 --- a/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts +++ b/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts @@ -158,14 +158,14 @@ describe('check scan code routines', () => { assert.equal(badScans.size, 1); assert.sameDeepMembers(Array.from(badScans.values()), [0xFF]); }); - it.skip('CLDRScanToUSVirtualKeyCodes should be 1:1', () => { + it('CLDRScanToUSVirtualKeyCodes should be 1:1', () => { const vkeyToScan = new Map(); // check all scancodes for (let scan = 0; scan <= 0xFF; scan++) { const vkey = CLDRScanToVkey(scan); - if (vkey !== undefined) { + if (vkey !== undefined && vkey !== 226) { assert.isFalse(vkeyToScan.has(vkey), - `vkey ${vkey} mapped from more than one scancode: ${Number(vkeyToScan.get(vkey)).toString(16)} and ${Number(scan).toString(16)}`); + `vkey ${vkey} (other than 226) mapped from more than one scancode: ${Number(vkeyToScan.get(vkey)).toString(16)} and ${Number(scan).toString(16)}`); vkeyToScan.set(vkey, scan); } } diff --git a/developer/src/kmc-ldml/test/test-virtual-key-constants.ts b/developer/src/kmc-ldml/test/test-virtual-key-constants.ts deleted file mode 100644 index 3ad5d3662c..0000000000 --- a/developer/src/kmc-ldml/test/test-virtual-key-constants.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { expect } from 'chai'; -import { Constants } from '@keymanapp/common-types'; - -import LdmlVkeyNames = Constants.LdmlVkeyNames; - -describe('virtual key constants', function () { - - it('should map the CLDR VKey Enum values to the right constants', function () { - - // These are copied-and-pasted from the table in TR35 - // We want to check that our constants match the ones in that table! - const CLDRVKeyEnumValues: Record = { - 'SPACE': 0x20, - '0': 0x30, - '1': 0x31, - '2': 0x32, - '3': 0x33, - '4': 0x34, - '5': 0x35, - '6': 0x36, - '7': 0x37, - '8': 0x38, - '9': 0x39, - 'A': 0x41, - 'B': 0x42, - 'C': 0x43, - 'D': 0x44, - 'E': 0x45, - 'F': 0x46, - 'G': 0x47, - 'H': 0x48, - 'I': 0x49, - 'J': 0x4A, - 'K': 0x4B, - 'L': 0x4C, - 'M': 0x4D, - 'N': 0x4E, - 'O': 0x4F, - 'P': 0x50, - 'Q': 0x51, - 'R': 0x52, - 'S': 0x53, - 'T': 0x54, - 'U': 0x55, - 'V': 0x56, - 'W': 0x57, - 'X': 0x58, - 'Y': 0x59, - 'Z': 0x5A, - 'SEMICOLON': 0xBA, - 'EQUAL': 0xBB, - 'COMMA': 0xBC, - 'HYPHEN': 0xBD, - 'PERIOD': 0xBE, - 'SLASH': 0xBF, - 'GRAVE': 0xC0, - 'LBRACKET': 0xDB, - 'BACKSLASH': 0xDC, - 'RBRACKET': 0xDD, - 'QUOTE': 0xDE, - 'LESS-THAN': 0xE2, - 'ABNT2': 0xC1 - }; - - const keys = Object.keys(CLDRVKeyEnumValues); - for (let key of keys) { - expect(CLDRVKeyEnumValues[key]).to.be.equal(LdmlVkeyNames[key]); - } - }); -}); From c33172a146d0920b6999bd8049e524d3e4c1a6b0 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Mon, 2 Oct 2023 14:08:15 -0400 Subject: [PATCH 050/107] auto: increment master version to 17.0.185 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 277c080391..b23206e773 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 17.0.184 alpha 2023-10-02 + +* fix(web): fixes toolbar refocus timing after a keyboard change (#9618) + ## 17.0.183 alpha 2023-09-29 * feat(web): browser-KMW support for default subkeys (#9496) diff --git a/VERSION.md b/VERSION.md index 8d2ab4f96c..10aedf6d36 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.184 \ No newline at end of file +17.0.185 \ No newline at end of file From 2b2661bb1bea711a13454ad568d00aefeddc8e4a Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 2 Oct 2023 18:00:48 -0500 Subject: [PATCH 051/107] =?UTF-8?q?feat(developer):=20scancode=20and=20for?= =?UTF-8?q?ms=20=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fixes to the special case test Fixes: #9403 --- .../types/src/consts/virtual-key-constants.ts | 1 + .../test-ldml-keyboard-xml-reader.ts | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/common/web/types/src/consts/virtual-key-constants.ts b/common/web/types/src/consts/virtual-key-constants.ts index 798dd95ead..3347660f01 100644 --- a/common/web/types/src/consts/virtual-key-constants.ts +++ b/common/web/types/src/consts/virtual-key-constants.ts @@ -202,6 +202,7 @@ export const CLDRScanToUSVirtualKeyCodes = { 0x56: k.K_oE2, // << Same as 0x7D; found on iso, abnt2 0x73: k.K_oC1, 0x7D: k.K_oE2, // << Same as 0x56; found on jis + }; export type KeyMap = number[][]; diff --git a/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts b/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts index 252f3e4319..43429676a0 100644 --- a/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts +++ b/common/web/types/test/ldml-keyboard/test-ldml-keyboard-xml-reader.ts @@ -3,7 +3,7 @@ import 'mocha'; import {assert} from 'chai'; import { CommonTypesMessages } from '../../src/util/common-events.js'; import { testReaderCases } from '../helpers/reader-callback-test.js'; -import { CLDRScanToVkey, CLDRScanToKeyMap } from '../../src/consts/virtual-key-constants.js'; +import { CLDRScanToVkey, CLDRScanToKeyMap, USVirtualKeyCodes } from '../../src/consts/virtual-key-constants.js'; function pluckKeysFromKeybag(keys: LKKey[], ids: string[]) { return keys.filter(({id}) => ids.indexOf(id) !== -1); @@ -163,11 +163,20 @@ describe('check scan code routines', () => { // check all scancodes for (let scan = 0; scan <= 0xFF; scan++) { const vkey = CLDRScanToVkey(scan); - if (vkey !== undefined && vkey !== 226) { - assert.isFalse(vkeyToScan.has(vkey), - `vkey ${vkey} (other than 226) mapped from more than one scancode: ${Number(vkeyToScan.get(vkey)).toString(16)} and ${Number(scan).toString(16)}`); - vkeyToScan.set(vkey, scan); + if (vkey === undefined) { + // not mapped, which is OK + continue; } + if (scan === 0x56 || scan === 0x7D) { + // These both can map to this scancode + assert.equal(vkey, USVirtualKeyCodes.K_oE2); + } else { + // don't check those exceptions + assert.isFalse(vkeyToScan.has(vkey), + `vkey ${vkey} mapped from more than one scancode: ${Number(vkeyToScan.get(vkey)).toString(16)} and ${Number(scan).toString(16)}`); + } + // do make sure nothing else maps to that vkey + vkeyToScan.set(vkey, scan); } }); }); From 886c64d1c3d241082734a78640db06587acfc8e6 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 3 Oct 2023 13:29:34 +0700 Subject: [PATCH 052/107] chore(developer): add test for checkFilenameConventions == false or unset Fixes #9317. --- .../src/kmc-package/test/fixtures/invalid/my_file.PDF | 1 + developer/src/kmc-package/test/test-messages.ts | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 developer/src/kmc-package/test/fixtures/invalid/my_file.PDF diff --git a/developer/src/kmc-package/test/fixtures/invalid/my_file.PDF b/developer/src/kmc-package/test/fixtures/invalid/my_file.PDF new file mode 100644 index 0000000000..8f8a5ee09e --- /dev/null +++ b/developer/src/kmc-package/test/fixtures/invalid/my_file.PDF @@ -0,0 +1 @@ +(Note: not a PDF file, just included as a sample file) \ No newline at end of file diff --git a/developer/src/kmc-package/test/test-messages.ts b/developer/src/kmc-package/test/test-messages.ts index e1d463dc4f..7dca440cee 100644 --- a/developer/src/kmc-package/test/test-messages.ts +++ b/developer/src/kmc-package/test/test-messages.ts @@ -128,6 +128,13 @@ describe('CompilerMessages', function () { CompilerMessages.WARN_FileInPackageDoesNotFollowFilenameConventions, {checkFilenameConventions: true}); }); + // Test the inverse -- no warning generated if checkFilenameConventions is false + + it('should not generate WARN_FileInPackageDoesNotFollowFilenameConventions if content filename has wrong conventions but checkFilenameConventions is false', async function() { + testForMessage(this, ['invalid', 'warn_file_in_package_does_not_follow_filename_conventions.kps'], null, {checkFilenameConventions: false}); + testForMessage(this, ['invalid', 'warn_file_in_package_does_not_follow_filename_conventions_2.kps'], null, {checkFilenameConventions: false}); + }); + // ERROR_PackageNameCannotBeBlank it('should generate ERROR_PackageNameCannotBeBlank if package info has empty name', async function() { From c66e8c1e8f967cb286028c8d62488b55403caa15 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 3 Oct 2023 13:56:21 +0700 Subject: [PATCH 053/107] chore(developer): switch on code coverage reporting for kmc Fixes #8661. --- developer/src/kmc/build.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/developer/src/kmc/build.sh b/developer/src/kmc/build.sh index e7c809419e..137098d6c4 100755 --- a/developer/src/kmc/build.sh +++ b/developer/src/kmc/build.sh @@ -74,9 +74,10 @@ fi if builder_start_action test; then eslint . tsc --build test/ - mocha - # TODO: enable c8 (disabled because no coverage at present) - # && c8 --reporter=lcov --reporter=text mocha + readonly C8_THRESHOLD=35 + c8 --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha + builder_echo warning "Coverage thresholds are currently $C8_THRESHOLD%, which is lower than ideal." + builder_echo warning "Please increase threshold in build.sh as test coverage improves." builder_finish_action success test fi From 1b9c6fba51a0a00d1848f94c13031d510ec82f76 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 3 Oct 2023 15:28:22 +0700 Subject: [PATCH 054/107] feat(developer): warn if .kps includes a .js which is not touch-capable Fixes #9324. As .js keyboards in packages are only used by the iOS and Android apps, it's kinda helpful if the keyboard itself includes a touch layout. While Keyman will fall back to a desktop vk layout if a touch layout is not present, this is less than ideal -- but that's why this is setup as a hint and not a warning. --- .../src/compiler/kmx-keyboard-metadata.ts | 3 +- .../src/kmc-package/src/compiler/messages.ts | 5 ++- .../package-keyboard-target-validator.ts | 16 ++++++-- .../src/compiler/web-keyboard-metadata.ts | 6 ++- ...t_js_keyboard_file_has_no_touch_targets.js | 1 + ..._js_keyboard_file_has_no_touch_targets.kmn | 7 ++++ ..._js_keyboard_file_has_no_touch_targets.kps | 40 +++++++++++++++++++ .../src/kmc-package/test/test-messages.ts | 11 +++++ 8 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.js create mode 100644 developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.kmn create mode 100644 developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.kps diff --git a/developer/src/kmc-package/src/compiler/kmx-keyboard-metadata.ts b/developer/src/kmc-package/src/compiler/kmx-keyboard-metadata.ts index 1fbefd7e94..75ada3a8ac 100644 --- a/developer/src/kmc-package/src/compiler/kmx-keyboard-metadata.ts +++ b/developer/src/kmc-package/src/compiler/kmx-keyboard-metadata.ts @@ -8,7 +8,8 @@ export function getCompiledKmxKeyboardMetadata(kmx: KMX.KEYBOARD): WebKeyboardMe keyboardName: getStoreFromKmx(kmx, KMX.KMXFile.TSS_NAME), keyboardVersion: getStoreFromKmx(kmx, KMX.KMXFile.TSS_KEYBOARDVERSION), minKeymanVersion: ((kmx.fileVersion & 0xFF00) >> 8).toString() + '.' + (kmx.fileVersion & 0xFF).toString(), - targets: getStoreFromKmx(kmx, KMX.KMXFile.TSS_TARGETS) ?? 'windows' + targets: getStoreFromKmx(kmx, KMX.KMXFile.TSS_TARGETS) ?? 'windows', + hasTouchLayout: !!getStoreFromKmx(kmx, KMX.KMXFile.TSS_LAYOUTFILE) }; } diff --git a/developer/src/kmc-package/src/compiler/messages.ts b/developer/src/kmc-package/src/compiler/messages.ts index c230c69772..79bae2d5b9 100644 --- a/developer/src/kmc-package/src/compiler/messages.ts +++ b/developer/src/kmc-package/src/compiler/messages.ts @@ -2,7 +2,7 @@ import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m const Namespace = CompilerErrorNamespace.PackageCompiler; const SevInfo = CompilerErrorSeverity.Info | Namespace; -// const SevHint = CompilerErrorSeverity.Hint | Namespace; +const SevHint = CompilerErrorSeverity.Hint | Namespace; const SevWarn = CompilerErrorSeverity.Warn | Namespace; const SevError = CompilerErrorSeverity.Error | Namespace; const SevFatal = CompilerErrorSeverity.Fatal | Namespace; @@ -116,5 +116,8 @@ export class CompilerMessages { `The keyboard ${o.id} should have at least one language specified.`); static WARN_KeyboardShouldHaveAtLeastOneLanguage = SevWarn | 0x001B; + static Hint_JsKeyboardFileHasNoTouchTargets = (o:{id:string}) => m(this.HINT_JsKeyboardFileHasNoTouchTargets, + `The keyboard ${o.id} has been included for touch platforms, but does not include a touch layout.`); + static HINT_JsKeyboardFileHasNoTouchTargets = SevHint | 0x001C; } diff --git a/developer/src/kmc-package/src/compiler/package-keyboard-target-validator.ts b/developer/src/kmc-package/src/compiler/package-keyboard-target-validator.ts index a79ec8f00a..96cb23686e 100644 --- a/developer/src/kmc-package/src/compiler/package-keyboard-target-validator.ts +++ b/developer/src/kmc-package/src/compiler/package-keyboard-target-validator.ts @@ -8,9 +8,14 @@ export class PackageKeyboardTargetValidator { public verifyAllTargets(kmp: KmpJsonFile.KmpJsonFile, metadata: KeyboardMetadataCollection): void { for(let keyboard of Object.keys(metadata)) { + let hasJS = true; + if(metadata[keyboard].data.targets) { - // get the targets from the .kmx - this.verifyTargets(metadata[keyboard].keyboard, metadata[keyboard].data.targets, kmp); + // get the targets from the .kmx (only the .kmx has the targets data) + hasJS = this.verifyTargets(metadata[keyboard].keyboard, metadata[keyboard].data.targets, kmp); + } + if(hasJS && !metadata[keyboard].data.hasTouchLayout) { + this.callbacks.reportMessage(CompilerMessages.Hint_JsKeyboardFileHasNoTouchTargets({id: metadata[keyboard].keyboard.id})); } } } @@ -23,7 +28,7 @@ export class PackageKeyboardTargetValidator { keyboard: KmpJsonFile.KmpJsonFileKeyboard, targetsText: string, kmp: KmpJsonFile.KmpJsonFile - ): void { + ): boolean { // Note, if we have gotten this far, we've already located and loaded a // .kmx, so no need to verify that the package includes a .kmx @@ -34,7 +39,12 @@ export class PackageKeyboardTargetValidator { if(!kmp.files.find(file => this.callbacks.path.basename(file.name, '.js') == keyboard.id)) { // .js version of the keyboard is not found, warn this.callbacks.reportMessage(CompilerMessages.Warn_JsKeyboardFileIsMissing({id: keyboard.id})); + return false; } + // A js file is included and targeted + return true; } + // js is not targeted + return false; } } \ No newline at end of file diff --git a/developer/src/kmc-package/src/compiler/web-keyboard-metadata.ts b/developer/src/kmc-package/src/compiler/web-keyboard-metadata.ts index 5800163ff9..eed412df1e 100644 --- a/developer/src/kmc-package/src/compiler/web-keyboard-metadata.ts +++ b/developer/src/kmc-package/src/compiler/web-keyboard-metadata.ts @@ -6,6 +6,7 @@ export interface WebKeyboardMetadata { isRtl: boolean; isMnemonic: boolean; targets?: string; + hasTouchLayout: boolean; }; /** @@ -24,12 +25,14 @@ export function getCompiledWebKeyboardMetadata(js: string): WebKeyboardMetadata const minverRegex = /this.KMINVER\s*=\s*([''"])(.*?)\1/; const rtlRegex = /this.KRTL\s*=\s*(.*?)\s*;/; const mnemonicRegex = /this.KM\s*=\s*(.*?)\s*;/; + const touchLayoutRegex = /this.KVKL\s*=\s*{/; const name = nameRegex.exec(js); const kbver = kbverRegex.exec(js); const minver = minverRegex.exec(js); const rtl = rtlRegex.exec(js); const mnemonic = mnemonicRegex.exec(js); + const touchLayout = touchLayoutRegex.exec(js); const SKeymanVersion70 = '7.0'; @@ -38,6 +41,7 @@ export function getCompiledWebKeyboardMetadata(js: string): WebKeyboardMetadata keyboardVersion: kbver ? kbver[2] : null, minKeymanVersion: minver ? minver[2] : SKeymanVersion70, isRtl: !!(rtl && rtl[1].match(/^(1|true)$/)), - isMnemonic: !!(mnemonic && mnemonic[1].match(/^(1|true)$/)) + isMnemonic: !!(mnemonic && mnemonic[1].match(/^(1|true)$/)), + hasTouchLayout: !!touchLayout }; } diff --git a/developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.js b/developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.js new file mode 100644 index 0000000000..5a6fff14f7 --- /dev/null +++ b/developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.js @@ -0,0 +1 @@ +KeymanWeb.KR(new Keyboard_hint_js_keyboard_file_has_no_touch_targets());function Keyboard_hint_js_keyboard_file_has_no_touch_targets(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_hint_js_keyboard_file_has_no_touch_targets";this.KN="hint_js_keyboard_file_has_no_touch_targets";this.KMINVER="9.0";this.KV=null;this.KDU=0;this.KH='';this.KM=0;this.KBVER="1.0";this.KMBM=0x0;this.KVER="17.0.184.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;return r;};} \ No newline at end of file diff --git a/developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.kmn b/developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.kmn new file mode 100644 index 0000000000..f5919a61c7 --- /dev/null +++ b/developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.kmn @@ -0,0 +1,7 @@ +store(&name) 'hint_js_keyboard_file_has_no_touch_targets' +store(&keyboardversion) '1.0' +store(&targets) 'web' + +begin unicode > use(main) + +group(main) using keys \ No newline at end of file diff --git a/developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.kps b/developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.kps new file mode 100644 index 0000000000..0a24a29deb --- /dev/null +++ b/developer/src/kmc-package/test/fixtures/invalid/hint_js_keyboard_file_has_no_touch_targets.kps @@ -0,0 +1,40 @@ + + + + 15.0.266.0 + 7.0 + + + + + + + + + + Khmer Angkor + © 2015-2022 SIL International + Makara Sok + + https://keyman.com/keyboards/khmer_angkor + + + + hint_js_keyboard_file_has_no_touch_targets.js + Keyboard + 0 + .js + + + + + hint_js_keyboard_file_has_no_touch_targets + hint_js_keyboard_file_has_no_touch_targets + 1.0 + + Central Khmer (Khmer, Cambodia) + + + + + diff --git a/developer/src/kmc-package/test/test-messages.ts b/developer/src/kmc-package/test/test-messages.ts index e1d463dc4f..95bb6adfd9 100644 --- a/developer/src/kmc-package/test/test-messages.ts +++ b/developer/src/kmc-package/test/test-messages.ts @@ -201,4 +201,15 @@ describe('CompilerMessages', function () { CompilerMessages.WARN_KeyboardShouldHaveAtLeastOneLanguage); }); + // HINT_JsKeyboardFileHasNoTouchTargets + + it('should generate HINT_JsKeyboardFileHasNoTouchTargets if keyboard has no touch targets', async function() { + testForMessage(this, ['invalid', 'hint_js_keyboard_file_has_no_touch_targets.kps'], + CompilerMessages.HINT_JsKeyboardFileHasNoTouchTargets); + }); + + it('should not generate HINT_JsKeyboardFileHasNoTouchTargets if keyboard has a touch target', async function() { + testForMessage(this, ['khmer_angkor', 'source', 'khmer_angkor.kps'], null); + }); + }); From 4c206e50a786b53a2b68b26d946505a163ebe6e2 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 3 Oct 2023 15:48:43 +0700 Subject: [PATCH 055/107] fix(core): clean cached ICU in core Fixes #9636. --- core/commands.inc.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/commands.inc.sh b/core/commands.inc.sh index 6916b61a9d..bff1e90f2d 100644 --- a/core/commands.inc.sh +++ b/core/commands.inc.sh @@ -11,7 +11,19 @@ do_clean() { # clean: note build/ will be left, but build// should be gone local target=$1 builder_start_action clean:$target || return 0 + rm -rf "$MESON_PATH" + + # Removes ICU cached components so it will be re-downloaded and built. Note: + # we could use `git clean`, but this clarifies exactly what is deleted, and + # but we try not to use git commands in build scripts, to maintain clear + # responsibility + rm -rf \ + "$THIS_SCRIPT_PATH/subprojects/packagecache" \ + "$THIS_SCRIPT_PATH/subprojects/icu" \ + "$THIS_SCRIPT_PATH/subprojects/*.tgz" \ + "$THIS_SCRIPT_PATH/subprojects/*.zip" + builder_finish_action success clean:$target } From 64e7606290b78fb7efad2554230fc6102f382a1b Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Tue, 3 Oct 2023 14:03:03 -0400 Subject: [PATCH 056/107] auto: increment master version to 17.0.186 --- HISTORY.md | 7 +++++++ VERSION.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index b23206e773..afc72e7a17 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,12 @@ # Keyman Version History +## 17.0.185 alpha 2023-10-03 + +* chore(web): Add non-printing characters to the OSK (#9547) +* feat(developer): support `store(&version) '17.0'` (#9656) +* chore(developer): add test for `checkFilenameConventions == false` or unset (#9661) +* feat(developer): ldml scan codes support (#9615) + ## 17.0.184 alpha 2023-10-02 * fix(web): fixes toolbar refocus timing after a keyboard change (#9618) diff --git a/VERSION.md b/VERSION.md index 10aedf6d36..e7118d25e1 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.185 \ No newline at end of file +17.0.186 \ No newline at end of file From 2fa8a09672eb7ccedb0e1c91121d08b8a345c504 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 12:44:56 +1100 Subject: [PATCH 057/107] chore: Update core/commands.inc.sh Co-authored-by: Steven R. Loomis --- core/commands.inc.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/core/commands.inc.sh b/core/commands.inc.sh index bff1e90f2d..2d3bccc4c0 100644 --- a/core/commands.inc.sh +++ b/core/commands.inc.sh @@ -19,7 +19,6 @@ do_clean() { # but we try not to use git commands in build scripts, to maintain clear # responsibility rm -rf \ - "$THIS_SCRIPT_PATH/subprojects/packagecache" \ "$THIS_SCRIPT_PATH/subprojects/icu" \ "$THIS_SCRIPT_PATH/subprojects/*.tgz" \ "$THIS_SCRIPT_PATH/subprojects/*.zip" From 8e23b11dfcb357e82f37d1b04dbcf14a3b9e745d Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 09:38:48 +0700 Subject: [PATCH 058/107] chore(developer): convert Server to ES Modules Fixes #9672. Also rewrote build.sh as a builder script in order to simplify some of the build changes. Makes /web a dependency of Keyman Developer Server, which is a significant improvement, but we need to consider if we want to use web's debug build as we did in the past. --- developer/src/server/build-addins.inc.sh | 2 +- developer/src/server/build.sh | 201 +++++++----------- developer/src/server/package.json | 12 +- developer/src/server/postbuild.sh | 25 --- developer/src/server/src/config.ts | 2 +- developer/src/server/src/data.ts | 4 +- developer/src/server/src/environment.ts | 4 +- .../src/handlers/api/debugobject/get.ts | 6 +- .../src/handlers/api/debugobject/register.ts | 12 +- .../handlers/api/debugobject/unregister.ts | 8 +- .../server/src/handlers/api/font/register.ts | 6 +- .../src/handlers/api/keyboard/register.ts | 6 +- .../src/handlers/api/package/register.ts | 6 +- .../server/src/handlers/inc/keyboards-css.ts | 6 +- .../server/src/handlers/inc/keyboards-js.ts | 4 +- .../server/src/handlers/inc/packages-json.ts | 6 +- developer/src/server/src/index.ts | 26 +-- developer/src/server/src/ngrok.d.ts | 1 + developer/src/server/src/routes.ts | 38 ++-- developer/src/server/src/tray.ts | 4 +- developer/src/server/src/version-data.test.ts | 2 +- developer/src/server/src/win32-tray.ts | 13 +- .../src/server/src/win32/console/index.d.ts | 5 - .../src/server/src/win32/console/index.js | 7 - .../src/server/src/win32/console/index.ts | 6 + .../src/win32/trayicon/{index.js => index.ts} | 23 +- developer/src/server/tsconfig.json | 9 +- 27 files changed, 183 insertions(+), 261 deletions(-) delete mode 100755 developer/src/server/postbuild.sh create mode 100644 developer/src/server/src/ngrok.d.ts delete mode 100644 developer/src/server/src/win32/console/index.d.ts delete mode 100644 developer/src/server/src/win32/console/index.js create mode 100644 developer/src/server/src/win32/console/index.ts rename developer/src/server/src/win32/trayicon/{index.js => index.ts} (68%) diff --git a/developer/src/server/build-addins.inc.sh b/developer/src/server/build-addins.inc.sh index cce1e9ae6f..3643ebffcd 100644 --- a/developer/src/server/build-addins.inc.sh +++ b/developer/src/server/build-addins.inc.sh @@ -11,7 +11,7 @@ isNodeX64() { # [[ $(file -b "$(which node)" | grep x86-64) ]] && echo 1 || echo 0 } -build_addins() { +do_build_addins() { local NODEX64=$(isNodeX64) local ARCH=x64 local TRAYICON_TARGET=addon.x64.node diff --git a/developer/src/server/build.sh b/developer/src/server/build.sh index c735e26fec..e609635b11 100755 --- a/developer/src/server/build.sh +++ b/developer/src/server/build.sh @@ -1,10 +1,4 @@ #!/usr/bin/env bash -# -# Compiles Keyman Developer Server for deployment -# - -# Exit on command failure and when using unset variables: -set -eu ## START STANDARD BUILD SCRIPT INCLUDE # adjust relative paths as necessary @@ -16,121 +10,64 @@ EX_USAGE=64 . "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" . "$KEYMAN_ROOT/resources/build/jq.inc.sh" -pushd "$(dirname "$THIS_SCRIPT")" +cd "$THIS_SCRIPT_PATH" -# Build the main script. -build () { - npm run build || builder_die "Could not build top-level JavaScript file." +builder_describe "Build Keyman Developer Server" \ + @/common/web/keyman-version \ + @/web \ + clean \ + configure \ + build \ + test \ + "installer Prepare for Keyman Developer installer" \ + "publish Publish to NPM" \ + ":server Keyman Developer Server main program" \ + ":addins Windows addins for GUI integration" + +builder_describe_outputs \ + configure:server /node_modules \ + configure:addins /node_modules \ + build:server /developer/src/server/build/src/index.js \ + build:addins /developer/src/server/build/src/win32/console/index.js + +builder_parse "$@" + +#------------------------------------------------------------------------------------------------------------------- + +function clean_server() { + rm -rf "$THIS_SCRIPT_PATH/build" + rm -rf "$THIS_SCRIPT_PATH/node_modules" + rm -rf "$THIS_SCRIPT_PATH/tsconfig.tsbuildinfo" + rm -rf "$THIS_SCRIPT_PATH/src/site/resource" + + # No longer in use, cleanup from previous versions: + rm -rf "$THIS_SCRIPT_PATH/dist" } -display_usage ( ) { - echo "Usage: $0 [--production|--watch] [--test|--tdd]" - echo " $0 --help" - echo - echo " --help displays this screen and exits" - echo " --production, -p builds production release in /developer/bin/server/" - echo " --skip-package-install, -S don't run npm install (not valid with --production)" - echo " --test, -t runs unit tests after building" - #echo " --watch, -w builds dev server in watch mode" - echo " --tdd runs unit tests WITHOUT building" - echo " --no-build-addins don't build/copy Win32 addins" - echo " --no-build-kmw don't build KeymanWeb" - echo " --no-copy-kmw don't copy KeymanWeb" -} - -################################ Main script ################################ - -run_tests=0 -production=0 -build=1 -install_dependencies=1 -build_keymanweb=1 -copy_keymanweb=1 -build_addins=1 - -# Process command-line arguments -while [[ $# -gt 0 ]] ; do - key="$1" - case $key in - --help|-h|-?) - display_usage - exit - ;; - --production|-p) - production=1 - ;; - --skip-package-install|-S) - install_dependencies=0 - ;; - --no-build-kmw) - build_keymanweb=0 - ;; - --no-build-addins) - build_addins=0 - ;; - --no-copy-kmw) - copy_keymanweb=0 - ;; - --test) - run_tests=1 - ;; - --tdd) - run_tests=1 - build=0 - install_dependencies=0 - ;; - *) - echo "$0: invalid option: $key" - display_usage - exit $EX_USAGE - esac - shift # past the processed argument -done - -# ---------------------------------------- -# Install dependencies -# ---------------------------------------- - -# Check if Node.JS/npm is installed. -type npm >/dev/null ||\ - builder_die "Build environment setup error detected! Please ensure Node.js is installed!" - -if (( install_dependencies )) ; then +function configure_server() { verify_npm_setup # See https://github.com/bubenshchykov/ngrok/issues/254, https://github.com/bubenshchykov/ngrok/pull/255 # TODO: this is horrible; is there a way we can avoid this? rm -f "$KEYMAN_ROOT"/node_modules/ngrok/bin/ngrok.exe -fi +} -# ---------------------------------------- -# Rebuild and bundle addins -# ---------------------------------------- - -if (( build_addins )); then - . ./build-addins.inc.sh +function build_addins() { + # Rebuild and bundle addins + source ./build-addins.inc.sh # If we have an x64 version of node installed if [[ $(isNodeX64) ]]; then - build_addins + do_build_addins fi # Build with the Keyman Developer x86 version of node - PATH="$KEYMAN_ROOT/developer/src/inst/node/dist:$PATH" build_addins -fi + PATH="$KEYMAN_ROOT/developer/src/inst/node/dist:$PATH" do_build_addins +} -# ---------------------------------------- -# Build and bundle KeymanWeb -# ---------------------------------------- - -if (( build_keymanweb )); then - pushd "$KEYMAN_ROOT/web/" - ./build.sh build --debug - popd -fi - -if (( copy_keymanweb )); then - WEB_SRC="$KEYMAN_ROOT/web/build/publish/debug" - DST="$(dirname "$THIS_SCRIPT")/src/site/resource" +function build_server() { + # Copy keymanweb build artifacts + local WEB_SRC="$KEYMAN_ROOT/web/build/publish/debug" + local DST="$THIS_SCRIPT_PATH/src/site/resource" rm -rf "$DST" mkdir -p "$DST/osk" @@ -140,33 +77,26 @@ if (( copy_keymanweb )); then cp -R "$WEB_SRC/ui/"* "$DST/ui/" cp "$KEYMAN_ROOT/web/LICENSE" "$DST/" cp "$KEYMAN_ROOT/web/README.md" "$DST/" -fi -# ---------------------------------------- -# Build the project -# ---------------------------------------- + # Build server + tsc --build -npm run build || builder_die "Compilation failed." -echo "Typescript compilation successful." + # Post build + mkdir -p "$THIS_SCRIPT_PATH/build/src/site/" + mkdir -p "$THIS_SCRIPT_PATH/build/src/win32/" + cp -r "$THIS_SCRIPT_PATH/src/site/"** "$THIS_SCRIPT_PATH/build/src/site/" + cp -r "$THIS_SCRIPT_PATH/src/win32/"** "$THIS_SCRIPT_PATH/build/src/win32/" -# ---------------------------------------- -# Unit tests -# ---------------------------------------- + replaceVersionStrings "$THIS_SCRIPT_PATH/build/src/site/lib/sentry/init.js.in" "$THIS_SCRIPT_PATH/build/src/site/lib/sentry/init.js" + rm "$THIS_SCRIPT_PATH/build/src/site/lib/sentry/init.js.in" +} -if (( run_tests )); then - npm test || builder_die "Tests failed" -fi - -# ---------------------------------------- -# Deploy to dist/ -# ---------------------------------------- - -if (( production )) ; then +function installer_server() { # We need to build in a tmp folder so that npm doesn't get confused by our # monorepo setup, and so we can copy the relevant node_modules in, because # we'll need them in order to build the deployable version. - PRODBUILDTEMP=`mktemp -d` + local PRODBUILDTEMP=`mktemp -d` echo "Preparing in $PRODBUILDTEMP" # Remove @keymanapp devDependencies because they won't install outside the # monorepo context @@ -180,14 +110,27 @@ if (( production )) ; then rm -f node_modules/ngrok/bin/ngrok.exe popd - # @keymanapp/keyman-version is required in dist now but we need to copy it in manually + # @keymanapp/keyman-version is required in build/ now but we need to copy it in manually mkdir -p "$PRODBUILDTEMP/node_modules/@keymanapp/" cp -R "$KEYMAN_ROOT/node_modules/@keymanapp/keyman-version/" "$PRODBUILDTEMP/node_modules/@keymanapp/" # We'll build in the $KEYMAN_ROOT/developer/bin/server/ folder rm -rf "$KEYMAN_ROOT/developer/bin/server/" - mkdir -p "$KEYMAN_ROOT/developer/bin/server/dist/" - cp -R dist/* "$KEYMAN_ROOT/developer/bin/server/dist/" + mkdir -p "$KEYMAN_ROOT/developer/bin/server/build/" + cp -R build/* "$KEYMAN_ROOT/developer/bin/server/build/" cp -R "$PRODBUILDTEMP"/* "$KEYMAN_ROOT/developer/bin/server/" rm -rf "$PRODBUILDTEMP" -fi +} +builder_run_action clean:server clean_server +builder_run_action configure:server configure_server +builder_run_action build:server build_server +builder_run_action build:addins build_addins +builder_run_action test:server mocha +# builder_run_action test:addins # no op +builder_run_action installer:server installer_server + +# TODO: consider 'watch' +# function watch_server() { +# tsc-watch --onSuccess "node --inspect ." --onFailure "node --inspect ." +# } +# builder_run_action watch:server watch_server diff --git a/developer/src/server/package.json b/developer/src/server/package.json index dd779db1a4..6d23e11bfb 100644 --- a/developer/src/server/package.json +++ b/developer/src/server/package.json @@ -1,13 +1,11 @@ { "name": "@keymanapp/developer-server", "description": "Keyman Developer backend server", - "main": "dist/index.js", + "main": "build/src/index.js", + "type": "module", "scripts": { - "build": "tsc -b", - "postbuild": "npx gosh ./postbuild.sh", - "prod": "node .", - "test": "mocha", - "watch": "npm run postbuild && tsc-watch --onSuccess \"node --inspect .\" --onFailure \"node --inspect .\"" + "build": "npx gosh ./build.sh build", + "test": "npx gosh ./build.sh test" }, "license": "MIT", "dependencies": { @@ -24,8 +22,8 @@ "node-windows-trayicon": "keymanapp/node-windows-trayicon#keyman-16.0" }, "devDependencies": { - "@keymanapp/resources-gosh": "*", "@keymanapp/keyman-version": "*", + "@keymanapp/resources-gosh": "*", "@types/chai": "^4.3.0", "@types/express": "^4.17.13", "@types/mocha": "^9.1.0", diff --git a/developer/src/server/postbuild.sh b/developer/src/server/postbuild.sh deleted file mode 100755 index e4b90e7e50..0000000000 --- a/developer/src/server/postbuild.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash -# -# postbuild script run by npm during/after a build -# - -# Exit on command failure and when using unset variables: -set -eu - -## START STANDARD BUILD SCRIPT INCLUDE -# adjust relative paths as necessary -THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" -. "${THIS_SCRIPT%/*}/../../../resources/build/build-utils.sh" -## END STANDARD BUILD SCRIPT INCLUDE - -. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" - -LOCAL_ROOT="$(dirname "$THIS_SCRIPT")" - -mkdir -p "$LOCAL_ROOT/dist/site/" -mkdir -p "$LOCAL_ROOT/dist/win32/" -cp -r "$LOCAL_ROOT/src/site/"** "$LOCAL_ROOT/dist/site/" -cp -r "$LOCAL_ROOT/src/win32/"** "$LOCAL_ROOT/dist/win32/" - -replaceVersionStrings "$LOCAL_ROOT/dist/site/lib/sentry/init.js.in" "$LOCAL_ROOT/dist/site/lib/sentry/init.js" -rm "$LOCAL_ROOT/dist/site/lib/sentry/init.js.in" diff --git a/developer/src/server/src/config.ts b/developer/src/server/src/config.ts index 5c67cd8c7e..6197cde05a 100644 --- a/developer/src/server/src/config.ts +++ b/developer/src/server/src/config.ts @@ -1,4 +1,4 @@ -import fs = require('fs'); +import * as fs from 'fs'; export class Configuration { public readonly appDataPath: string; diff --git a/developer/src/server/src/data.ts b/developer/src/server/src/data.ts index fcc750495d..58763f0701 100644 --- a/developer/src/server/src/data.ts +++ b/developer/src/server/src/data.ts @@ -1,5 +1,5 @@ -import fs = require('fs'); -import { configuration } from './config'; +import * as fs from 'fs'; +import { configuration } from './config.js'; export interface DebugObject { id: string; diff --git a/developer/src/server/src/environment.ts b/developer/src/server/src/environment.ts index be359f81d3..f3e0566024 100644 --- a/developer/src/server/src/environment.ts +++ b/developer/src/server/src/environment.ts @@ -1,5 +1,5 @@ -import { extractVersionData } from './version-data'; +import { extractVersionData } from './version-data.js'; // TODO: environment should be just KEYMAN_VERSION -const KEYMAN_VERSION = require("@keymanapp/keyman-version").KEYMAN_VERSION; +import KEYMAN_VERSION from "@keymanapp/keyman-version"; export const environment = extractVersionData(KEYMAN_VERSION.VERSION_WITH_TAG); diff --git a/developer/src/server/src/handlers/api/debugobject/get.ts b/developer/src/server/src/handlers/api/debugobject/get.ts index 3da2896d55..a701ca3a8f 100644 --- a/developer/src/server/src/handlers/api/debugobject/get.ts +++ b/developer/src/server/src/handlers/api/debugobject/get.ts @@ -1,6 +1,6 @@ -import chalk = require('chalk'); -import express = require('express'); -import { DebugObject, isValidId, simplifyId } from "../../../data"; +import * as express from 'express'; +import chalk from 'chalk'; +import { DebugObject, isValidId, simplifyId } from "../../../data.js"; export default function apiGet (data: { [id: string]: DebugObject }, req: express.Request, res: express.Response, next: express.NextFunction) { let id = req.query['id'] as string; diff --git a/developer/src/server/src/handlers/api/debugobject/register.ts b/developer/src/server/src/handlers/api/debugobject/register.ts index 9b52b577d8..a1f7a72cd4 100644 --- a/developer/src/server/src/handlers/api/debugobject/register.ts +++ b/developer/src/server/src/handlers/api/debugobject/register.ts @@ -1,9 +1,9 @@ -import express = require('express'); -import { DebugObject, isValidId, simplifyId } from "../../../data"; -import fs = require('fs'); -import crypto = require('crypto'); -import { configuration } from '../../../config'; -import chalk = require('chalk'); +import * as express from 'express'; +import { DebugObject, isValidId, simplifyId } from "../../../data.js"; +import * as fs from 'fs'; +import * as crypto from 'crypto'; +import { configuration } from '../../../config.js'; +import chalk from 'chalk'; // We allow only 12 objects of each type in the cache const MAX_OBJECTS = 12; diff --git a/developer/src/server/src/handlers/api/debugobject/unregister.ts b/developer/src/server/src/handlers/api/debugobject/unregister.ts index 6473c2edbd..59a846d135 100644 --- a/developer/src/server/src/handlers/api/debugobject/unregister.ts +++ b/developer/src/server/src/handlers/api/debugobject/unregister.ts @@ -1,7 +1,7 @@ -import express = require('express'); -import { DebugObject, isValidId, simplifyId } from "../../../data"; -import fs = require('fs'); -import chalk = require('chalk'); +import * as express from 'express'; +import { DebugObject, isValidId, simplifyId } from "../../../data.js"; +import * as fs from 'fs'; +import chalk from 'chalk'; export default function apiUnregister (root:{ [id: string]: O }, req: express.Request, res: express.Response, next: express.NextFunction) { let id = req.body['id']; diff --git a/developer/src/server/src/handlers/api/font/register.ts b/developer/src/server/src/handlers/api/font/register.ts index 14d60e8e12..8da3646a63 100644 --- a/developer/src/server/src/handlers/api/font/register.ts +++ b/developer/src/server/src/handlers/api/font/register.ts @@ -1,6 +1,6 @@ -import chalk = require('chalk'); -import express = require('express'); -import { data, DebugFont, simplifyId } from "../../../data"; +import chalk from 'chalk'; +import * as express from 'express'; +import { data, DebugFont, simplifyId } from "../../../data.js"; export default function apiKeyboardRegister (req: express.Request, res: express.Response, next: express.NextFunction) { const id = simplifyId(req.body['id']); diff --git a/developer/src/server/src/handlers/api/keyboard/register.ts b/developer/src/server/src/handlers/api/keyboard/register.ts index 02bdd3dde7..bb89d7b4c3 100644 --- a/developer/src/server/src/handlers/api/keyboard/register.ts +++ b/developer/src/server/src/handlers/api/keyboard/register.ts @@ -1,6 +1,6 @@ -import chalk = require('chalk'); -import express = require('express'); -import { data, DebugKeyboard } from "../../../data"; +import chalk from 'chalk'; +import * as express from 'express'; +import { data, DebugKeyboard } from "../../../data.js"; export default function apiKeyboardRegister (req: express.Request, res: express.Response, next: express.NextFunction) { const keyboard: DebugKeyboard = data.keyboards[req.body['id']]; diff --git a/developer/src/server/src/handlers/api/package/register.ts b/developer/src/server/src/handlers/api/package/register.ts index c21340c7fe..cf6e238846 100644 --- a/developer/src/server/src/handlers/api/package/register.ts +++ b/developer/src/server/src/handlers/api/package/register.ts @@ -1,6 +1,6 @@ -import chalk = require('chalk'); -import express = require('express'); -import { data, DebugPackage } from "../../../data"; +import chalk from 'chalk'; +import * as express from 'express'; +import { data, DebugPackage } from "../../../data.js"; export default function apiPackageRegister (req: express.Request, res: express.Response, next: express.NextFunction) { const kmp: DebugPackage = data.packages[req.body['id']]; diff --git a/developer/src/server/src/handlers/inc/keyboards-css.ts b/developer/src/server/src/handlers/inc/keyboards-css.ts index 9302fd1164..ed4cc7e15b 100644 --- a/developer/src/server/src/handlers/inc/keyboards-css.ts +++ b/developer/src/server/src/handlers/inc/keyboards-css.ts @@ -1,6 +1,6 @@ -import express = require('express'); -import path = require('path'); -import { data, SiteData } from "../../data"; +import * as express from 'express'; +import * as path from 'path'; +import { data, SiteData } from "../../data.js"; export default function handleIncKeyboardsCss (req: express.Request, res: express.Response) { let headers = {"Content-Type": "text/css"}; diff --git a/developer/src/server/src/handlers/inc/keyboards-js.ts b/developer/src/server/src/handlers/inc/keyboards-js.ts index ee09fa0f37..3c42702bf9 100644 --- a/developer/src/server/src/handlers/inc/keyboards-js.ts +++ b/developer/src/server/src/handlers/inc/keyboards-js.ts @@ -1,5 +1,5 @@ -import express = require('express'); -import { SiteData, data } from "../../data"; +import * as express from 'express'; +import { SiteData, data } from "../../data.js"; export default function handleIncKeyboardsJs (req: express.Request, res: express.Response) { let headers = {"Content-Type": "application/javascript"}; diff --git a/developer/src/server/src/handlers/inc/packages-json.ts b/developer/src/server/src/handlers/inc/packages-json.ts index a27fb00615..44449a5ef6 100644 --- a/developer/src/server/src/handlers/inc/packages-json.ts +++ b/developer/src/server/src/handlers/inc/packages-json.ts @@ -1,6 +1,6 @@ -import express = require('express'); -import { data } from "../../data"; -import { environment } from '../../environment'; +import * as express from 'express'; +import { data } from "../../data.js"; +import { environment } from '../../environment.js'; export default function handleIncPackagesJson (req: express.Request, res: express.Response) { const packages = Object.keys(data.packages).map(id => { return { id: id, filename: id+'.kmp', name: data.packages[id].name} }); diff --git a/developer/src/server/src/index.ts b/developer/src/server/src/index.ts index a6d109f1ba..a297554573 100644 --- a/developer/src/server/src/index.ts +++ b/developer/src/server/src/index.ts @@ -1,21 +1,21 @@ -import { environment } from './environment'; +import { environment } from './environment.js'; -const Sentry = require("@sentry/node"); +import * as Sentry from '@sentry/node'; Sentry.init({ dsn: 'https://39b25a09410349a58fe12aaf721565af@o1005580.ingest.sentry.io/5983519', // Keyman Developer environment: environment.versionEnvironment, release: environment.versionGitTag }); -import express = require('express'); -import ws = require('ws'); -import os = require('os'); -import multer = require('multer'); -import fs = require('fs'); -import setupRoutes from './routes'; -import { configuration } from './config'; -import tray from './tray'; -import chalk = require('chalk'); +import express from 'express'; +import * as ws from 'ws'; +import * as os from 'os'; +import multer from 'multer'; +import * as fs from 'fs'; +import setupRoutes from './routes.js'; +import { configuration } from './config.js'; +import tray from './tray.js'; +import chalk from 'chalk'; const options = { ngrokLog: false, // Set this to true if you need to see ngrok logs in the console @@ -58,7 +58,7 @@ const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 102 /* Websockets */ -const wsServer = new ws.Server({ noServer: true }); +const wsServer = new ws.WebSocketServer({ noServer: true }); wsServer.on('connection', socket => { socket.on('message', (message) => { console.debug('wsServer.socket.onmessage: '+message.toString()); @@ -87,7 +87,7 @@ server.on('upgrade', (request, socket, head) => { configuration.ngrokEndpoint = ''; if(configuration.useNgrok && os.platform() == 'win32' && fs.existsSync(configuration.ngrokBinPath)) { - const ngrok = require('ngrok'); + const ngrok: any = await import('ngrok'); (async function() { configuration.ngrokEndpoint = await ngrok.connect({ proto: 'http', diff --git a/developer/src/server/src/ngrok.d.ts b/developer/src/server/src/ngrok.d.ts new file mode 100644 index 0000000000..61f00d7a0b --- /dev/null +++ b/developer/src/server/src/ngrok.d.ts @@ -0,0 +1 @@ +declare module 'ngrok'; \ No newline at end of file diff --git a/developer/src/server/src/routes.ts b/developer/src/server/src/routes.ts index fdd2e421aa..20c09f838f 100644 --- a/developer/src/server/src/routes.ts +++ b/developer/src/server/src/routes.ts @@ -1,21 +1,21 @@ -import express = require('express'); -import multer = require('multer'); -import ws = require('ws'); -import handleIncKeyboardsJs from './handlers/inc/keyboards-js'; -import { data, DebugFont, DebugKeyboard, DebugModel, DebugObject, DebugPackage, isValidId } from './data'; -import apiGet from './handlers/api/debugobject/get'; -import apiRegister, { apiRegisterFile } from './handlers/api/debugobject/register'; -import apiKeyboardRegister from './handlers/api/keyboard/register'; -import apiFontRegister from './handlers/api/font/register'; -import apiUnregister from './handlers/api/debugobject/unregister'; -import handleIncPackagesJson from './handlers/inc/packages-json'; -import apiPackageRegister from './handlers/api/package/register'; -import handleIncKeyboardsCss from './handlers/inc/keyboards-css'; -import { Environment } from './version-data'; -import { configuration } from './config'; -import chalk = require('chalk'); +import * as express from 'express'; +import * as ws from 'ws'; +import * as multer from 'multer'; +import handleIncKeyboardsJs from './handlers/inc/keyboards-js.js'; +import { data, DebugFont, DebugKeyboard, DebugModel, DebugObject, DebugPackage, isValidId } from './data.js'; +import apiGet from './handlers/api/debugobject/get.js'; +import apiRegister, { apiRegisterFile } from './handlers/api/debugobject/register.js'; +import apiKeyboardRegister from './handlers/api/keyboard/register.js'; +import apiFontRegister from './handlers/api/font/register.js'; +import apiUnregister from './handlers/api/debugobject/unregister.js'; +import handleIncPackagesJson from './handlers/inc/packages-json.js'; +import apiPackageRegister from './handlers/api/package/register.js'; +import handleIncKeyboardsCss from './handlers/inc/keyboards-css.js'; +import { Environment } from './version-data.js'; +import { configuration } from './config.js'; +import chalk from 'chalk'; -export default function setupRoutes(app: express.Express, upload: multer.Multer, wsServer: ws.Server, environment: Environment ) { +export default function setupRoutes(app: express.Express, upload: multer.Multer, wsServer: ws.WebSocketServer, environment: Environment ) { /* Middleware - JSON and logging */ @@ -49,7 +49,7 @@ export default function setupRoutes(app: express.Express, upload: multer.Multer, /* All routes */ - app.use('/', express.static('dist/site')); + app.use('/', express.static('build/src/site')); app.post('/upload', localhostOnly, upload.single('file'), (req, res, next) => { const name = req.file.originalname; @@ -170,7 +170,7 @@ export default function setupRoutes(app: express.Express, upload: multer.Multer, /* Utility functions */ -function notifyClients(wsServer: ws.Server, res: express.Request, req: express.Response, next: express.NextFunction) { +function notifyClients(wsServer: ws.WebSocketServer, res: express.Request, req: express.Response, next: express.NextFunction) { wsServer.clients.forEach(c => { c.send('refresh', (err) => { if(err) console.error(chalk.red('Websocket send error '+err.message)); diff --git a/developer/src/server/src/tray.ts b/developer/src/server/src/tray.ts index 0c9c3bf2f6..780d9c792c 100644 --- a/developer/src/server/src/tray.ts +++ b/developer/src/server/src/tray.ts @@ -1,4 +1,4 @@ -import os = require('os'); +import * as os from 'os'; class TrayStub { public start(localPort: number, ngrokAddress: string) {} @@ -9,7 +9,7 @@ class TrayStub { let tray = new TrayStub(); if(os.platform() == 'win32') { - const Win32Tray = require('./win32-tray'); + const { Win32Tray } = await import('./win32-tray.js'); tray = new Win32Tray(); } diff --git a/developer/src/server/src/version-data.test.ts b/developer/src/server/src/version-data.test.ts index 5f33932b3b..9f7ebd385f 100644 --- a/developer/src/server/src/version-data.test.ts +++ b/developer/src/server/src/version-data.test.ts @@ -1,7 +1,7 @@ import {assert} from 'chai'; import 'mocha'; -import { extractVersionData } from './version-data'; +import { extractVersionData } from './version-data.js'; describe('extractVersionData', function() { diff --git a/developer/src/server/src/win32-tray.ts b/developer/src/server/src/win32-tray.ts index b17c775f00..02ef0a4db8 100644 --- a/developer/src/server/src/win32-tray.ts +++ b/developer/src/server/src/win32-tray.ts @@ -1,14 +1,15 @@ -import path = require("path"); +import * as path from "path"; +import * as url from 'url'; // TODO: this is a Windows-only tray icon. There are a number of // cross-platform solutions but none of them are wonderful. We // should replace this when we find a decent one. -const WindowsTrayicon = require("./win32/trayicon"); -const WindowsConsole = require("./win32/console"); -const open = require("open"); +import WindowsTrayicon from "./win32/trayicon/index.js"; +import WindowsConsole from "./win32/console/index.js"; +import open from 'open'; -module.exports = class Win32Tray { +export class Win32Tray { private myTrayApp: any; public restart(localPort: number, ngrokAddress: string) { @@ -55,7 +56,7 @@ module.exports = class Win32Tray { this.myTrayApp = new WindowsTrayicon({ title: "Keyman Developer Server", - icon: path.resolve(__dirname, "site", "favicon.ico"), + icon: path.resolve(url.fileURLToPath(new URL('.', import.meta.url)), "site", "favicon.ico"), menu: menu }); diff --git a/developer/src/server/src/win32/console/index.d.ts b/developer/src/server/src/win32/console/index.d.ts deleted file mode 100644 index ac9e647fa4..0000000000 --- a/developer/src/server/src/win32/console/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module "node-hide-console-window" { - function hideConsole(): void - - function showConsole(): void -} \ No newline at end of file diff --git a/developer/src/server/src/win32/console/index.js b/developer/src/server/src/win32/console/index.js deleted file mode 100644 index 26026657a0..0000000000 --- a/developer/src/server/src/win32/console/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const os = require('os'); -const {showConsole, hideConsole} = require(os.arch() == 'ia32' ? "./node-hide-console-window" : "./node-hide-console-window.x64"); - -module.exports = { - showConsole, - hideConsole -} \ No newline at end of file diff --git a/developer/src/server/src/win32/console/index.ts b/developer/src/server/src/win32/console/index.ts new file mode 100644 index 0000000000..1bee9ada87 --- /dev/null +++ b/developer/src/server/src/win32/console/index.ts @@ -0,0 +1,6 @@ +import * as os from 'os'; +import { createRequire } from 'node:module'; +const require = createRequire(import.meta.url); +const {showConsole, hideConsole} = require(os.arch() == 'ia32' ? "./node-hide-console-window" : "./node-hide-console-window.x64"); + +export default { showConsole, hideConsole }; diff --git a/developer/src/server/src/win32/trayicon/index.js b/developer/src/server/src/win32/trayicon/index.ts similarity index 68% rename from developer/src/server/src/win32/trayicon/index.js rename to developer/src/server/src/win32/trayicon/index.ts index 1e50cef3da..6b313af262 100644 --- a/developer/src/server/src/win32/trayicon/index.js +++ b/developer/src/server/src/win32/trayicon/index.ts @@ -1,8 +1,17 @@ -const os = require('os'); +import * as os from 'os'; +import { createRequire } from 'node:module'; +const require = createRequire(import.meta.url); const { CTrayIconContainer } = require(os.arch() == 'ia32' ? "./addon" : "./addon.x64"); class WindowsTrayicon { - constructor(options) { + __itemCallbacks: any[]; + __icon: any; + __trayTitle: any; + __menuItems: any; + __nativeTray: any; + + + constructor(options: any) { this.__itemCallbacks = []; this.__icon = options.icon; this.__trayTitle = options.title || ""; @@ -12,7 +21,7 @@ class WindowsTrayicon { for (const item of this.__menuItems) { this.__nativeTray.AddMenuItem(item.id, item.caption); } - this.__nativeTray.OnMenuItem((id) => { + this.__nativeTray.OnMenuItem((id: any) => { for (const cb of this.__itemCallbacks) { cb(id); } @@ -23,15 +32,15 @@ class WindowsTrayicon { } this.__nativeTray.Start(); } - item(cb) { + item(cb: any) { if ("function" === typeof cb) { this.__itemCallbacks.push(cb); } } - balloon(title, text, timeout = 5000) { + balloon(title: any, text: any, timeout = 5000) { return new Promise((resolve) => { this.__nativeTray.ShowBalloon(title, text, timeout, () => { - resolve(); + resolve(null); }) }); } @@ -40,4 +49,4 @@ class WindowsTrayicon { } } -module.exports = WindowsTrayicon; +export default WindowsTrayicon; diff --git a/developer/src/server/tsconfig.json b/developer/src/server/tsconfig.json index 280b535dd9..701a97af6c 100644 --- a/developer/src/server/tsconfig.json +++ b/developer/src/server/tsconfig.json @@ -1,13 +1,13 @@ { - "extends": "../../../tsconfig-base.json", + "extends": "../../../tsconfig.esm-base.json", "compilerOptions": { - "module": "commonjs", "target": "es2022", - "moduleResolution": "node", "sourceMap": true, - "outDir": "dist/", + "outDir": "build/src/", "rootDir": "src/", + "baseUrl": ".", + "declaration": true, "alwaysStrict": true, "noImplicitThis": true, @@ -16,6 +16,7 @@ "strictBindCallApply": true, "strictFunctionTypes": true, "noUnusedLocals": true, + "allowJs": true, "lib": ["es2022"] }, "include": [ From 81960a649606bc4dd380e86cc9d3fce9a0548b43 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 09:50:05 +0700 Subject: [PATCH 059/107] chore(developer): move server from cjs to esm tsconfig --- tsconfig.cjs.json | 2 -- tsconfig.esm.json | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json index 3dff61f8b6..2b8030ac76 100644 --- a/tsconfig.cjs.json +++ b/tsconfig.cjs.json @@ -9,8 +9,6 @@ { "path": "./common/predictive-text/testing/two-stage-embedded-webworker/tsconfig.json" }, { "path": "./common/predictive-text/testing/two-stage-embedded-webworker/worker/tsconfig.json" }, - { "path": "./developer/src/server/tsconfig.json" }, - { "path": "./resources/build/version/tsconfig.json" }, { "path": "./resources/build/version/tsconfig.production.json" }, // { "path": "./web/bulk_rendering/tsconfig.json" }, diff --git a/tsconfig.esm.json b/tsconfig.esm.json index e0f72d8f8d..c58550431a 100644 --- a/tsconfig.esm.json +++ b/tsconfig.esm.json @@ -26,6 +26,7 @@ { "path": "./developer/src/kmc-model-info/tsconfig.json" }, { "path": "./developer/src/kmc-package/test/tsconfig.json" }, { "path": "./developer/src/kmc-package/tsconfig.json" }, + { "path": "./developer/src/server/tsconfig.json" }, { "path": "./common/web/keyman-version" }, { "path": "./common/web/types/" }, From e7ac526c69610b918d9d6bfa09785da9ad24b981 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 11:50:03 +0700 Subject: [PATCH 060/107] chore(developer): fixup Makefile for server --- developer/src/server/Makefile | 2 +- developer/src/server/build.sh | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/developer/src/server/Makefile b/developer/src/server/Makefile index 0a580ea3d6..eef7390804 100644 --- a/developer/src/server/Makefile +++ b/developer/src/server/Makefile @@ -5,7 +5,7 @@ !include ..\Defines.mak build: .virtual - $(GIT_BASH_FOR_KEYMAN) build.sh --production --test + $(GIT_BASH_FOR_KEYMAN) build.sh configure build test installer clean: .virtual #TODO: move to build.sh `clean` target diff --git a/developer/src/server/build.sh b/developer/src/server/build.sh index e609635b11..44cdbe1ca7 100755 --- a/developer/src/server/build.sh +++ b/developer/src/server/build.sh @@ -24,6 +24,10 @@ builder_describe "Build Keyman Developer Server" \ ":server Keyman Developer Server main program" \ ":addins Windows addins for GUI integration" +builder_describe_internal_dependency \ + publish:server build:server \ + publish:server build:addins + builder_describe_outputs \ configure:server /node_modules \ configure:addins /node_modules \ From f69f28bbd579c1b6b532df764491508dcef97b9b Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 11:04:36 +0700 Subject: [PATCH 061/107] chore(common): convert hextobin to ES Modules Fixes #9675. --- common/tools/hextobin/build.sh | 26 ++++---------------------- common/tools/hextobin/hextobin.ts | 5 +---- common/tools/hextobin/package.json | 10 ++-------- common/tools/hextobin/tsconfig.json | 24 +++++++----------------- tsconfig.esm.json | 1 + 5 files changed, 15 insertions(+), 51 deletions(-) diff --git a/common/tools/hextobin/build.sh b/common/tools/hextobin/build.sh index 702e6610f0..48c8542510 100755 --- a/common/tools/hextobin/build.sh +++ b/common/tools/hextobin/build.sh @@ -1,11 +1,4 @@ #!/usr/bin/env bash -# -# Builds hextobin.js -# - -# Exit on command failure and when using unset variables: -set -eu - ## START STANDARD BUILD SCRIPT INCLUDE # adjust relative paths as necessary THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" @@ -23,20 +16,9 @@ builder_describe "Build hextobin" clean configure build builder_describe_outputs \ configure /node_modules \ build build/index.js + builder_parse "$@" -if builder_start_action clean; then - npm run clean - builder_finish_action success clean -fi - -if builder_start_action configure; then - verify_npm_setup - builder_finish_action success configure -fi - -if builder_start_action build; then - npm run build - builder_finish_action success build -fi - +builder_run_action clean rm -rf build/ node_modules/ +builder_run_action configure verify_npm_setup +builder_run_action build tsc --build diff --git a/common/tools/hextobin/hextobin.ts b/common/tools/hextobin/hextobin.ts index 503b18d4b1..e53e08ddbc 100644 --- a/common/tools/hextobin/hextobin.ts +++ b/common/tools/hextobin/hextobin.ts @@ -1,7 +1,6 @@ #!/usr/bin/env node -import * as fs from 'fs'; -import * as rd from 'readline'; import * as program from 'commander'; +import hextobin from './index.js'; let inputFilename: string = ""; let outputFilename: string = ""; @@ -43,6 +42,4 @@ function exitDueToUsageError(message: string): never { return process.exit(64); // SysExits.EX_USAGE } -import hextobin from './index'; - hextobin(inputFilename, outputFilename, {silent: false}); diff --git a/common/tools/hextobin/package.json b/common/tools/hextobin/package.json index 155f829759..2ebb0e9f4e 100644 --- a/common/tools/hextobin/package.json +++ b/common/tools/hextobin/package.json @@ -1,6 +1,8 @@ { "name": "@keymanapp/hextobin", "description": "hextobin conversion tool", + "type": "module", + "private": true, "keywords": [ "keyman", "hex", @@ -14,14 +16,6 @@ "bin": { "hextobin": "build/hextobin.js" }, - "scripts": { - "clean": "tsc -b --clean", - "build": "tsc -b" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/keymanapp/keyman.git" - }, "devDependencies": { "@types/node": "^18.7.18" } diff --git a/common/tools/hextobin/tsconfig.json b/common/tools/hextobin/tsconfig.json index e32831fe73..db0a65ae9d 100644 --- a/common/tools/hextobin/tsconfig.json +++ b/common/tools/hextobin/tsconfig.json @@ -1,19 +1,9 @@ { - "extends": "../../../tsconfig-base.json", - "compilerOptions": { - "composite": true, - "declaration": true, - "target": "ES2020", - "module": "CommonJS", - "moduleResolution": "node", - "rootDir": ".", - "outDir": "build/", - }, - "exclude": [ - "node_modules" - ], - "files": [ - "index.ts", - "hextobin.ts" - ] + "extends": "../../../tsconfig.esm-base.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "build/" + }, + "exclude": ["node_modules"], + "files": ["index.ts", "hextobin.ts"] } diff --git a/tsconfig.esm.json b/tsconfig.esm.json index c58550431a..47c0ef92e9 100644 --- a/tsconfig.esm.json +++ b/tsconfig.esm.json @@ -47,5 +47,6 @@ // { "path": "./web/tools/sourcemap-root/tsconfig.json" }, { "path": "./common/web/lm-message-types/" }, { "path": "./common/web/lm-worker/" }, + { "path": "./common/tools/hextobin/" } ] } \ No newline at end of file From fbd9a4b5e899923e8e734c8e50ee6518711b7b4b Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 11:46:49 +0700 Subject: [PATCH 062/107] chore(common): convert resources/build/version to ES Modules Fixes #9677. --- common/tools/hextobin/build.sh | 2 +- package-lock.json | 149 ++++++------------ resources/build/increment-version.sh | 4 +- resources/build/version/.gitignore | 1 + resources/build/version/build.sh | 24 +++ resources/build/version/package.json | 11 +- resources/build/version/src/fixupHistory.ts | 7 +- resources/build/version/src/index.ts | 15 +- resources/build/version/src/reportHistory.ts | 6 +- resources/build/version/tsconfig.json | 7 +- .../build/version/tsconfig.production.json | 25 --- tsconfig.esm.json | 4 +- 12 files changed, 106 insertions(+), 149 deletions(-) create mode 100755 resources/build/version/build.sh delete mode 100644 resources/build/version/tsconfig.production.json diff --git a/common/tools/hextobin/build.sh b/common/tools/hextobin/build.sh index 48c8542510..8df4f9b83a 100755 --- a/common/tools/hextobin/build.sh +++ b/common/tools/hextobin/build.sh @@ -15,7 +15,7 @@ cd "$THIS_SCRIPT_PATH" builder_describe "Build hextobin" clean configure build builder_describe_outputs \ configure /node_modules \ - build build/index.js + build /common/tools/hextobin/build/index.js builder_parse "$@" diff --git a/package-lock.json b/package-lock.json index 405d2154cf..dea220c34d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3830,6 +3830,21 @@ "@types/node": "*" } }, + "node_modules/@types/yargs": { + "version": "17.0.26", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.26.tgz", + "integrity": "sha512-Y3vDy2X6zw/ZCumcwLpdhM5L7jmyGpmBCTYMHDLqT2IKVMYRRLdv6ZakA+wxhra6Z/3bwhNbNl9bDGXaFU+6rw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==", + "dev": true + }, "node_modules/@types/yauzl": { "version": "2.9.2", "license": "MIT", @@ -4753,6 +4768,7 @@ }, "node_modules/camelcase": { "version": "5.3.1", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5148,6 +5164,7 @@ }, "node_modules/decamelize": { "version": "1.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5884,7 +5901,6 @@ }, "node_modules/escalade": { "version": "3.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -9573,6 +9589,7 @@ }, "node_modules/p-try": { "version": "2.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -9603,6 +9620,7 @@ }, "node_modules/path-exists": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9930,6 +9948,7 @@ }, "node_modules/require-main-filename": { "version": "2.0.0", + "dev": true, "license": "ISC" }, "node_modules/requirejs": { @@ -10170,6 +10189,7 @@ }, "node_modules/set-blocking": { "version": "2.0.0", + "devOptional": true, "license": "ISC" }, "node_modules/set-immediate-shim": { @@ -11172,6 +11192,7 @@ }, "node_modules/which-module": { "version": "2.0.0", + "dev": true, "license": "ISC" }, "node_modules/which-typed-array": { @@ -11231,7 +11252,6 @@ }, "node_modules/wrap-ansi": { "version": "7.0.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -11247,7 +11267,6 @@ }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "5.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11255,7 +11274,6 @@ }, "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11263,7 +11281,6 @@ }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "4.2.2", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -11276,7 +11293,6 @@ }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "6.0.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.0" @@ -11337,7 +11353,6 @@ }, "node_modules/y18n": { "version": "5.0.8", - "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -11497,16 +11512,14 @@ "@actions/core": "^1.9.1", "@actions/github": "^2.1.0", "typescript": "^4.9.5", - "yargs": "^15.1.0" + "yargs": "^17.7.2" }, "devDependencies": { "@types/node": "^13.7.0", "@types/semver": "^7.1.0", + "@types/yargs": "^17.0.26", "semver": "^7.5.2", "ts-node": "^10.9.1" - }, - "engines": { - "node": ">=16.0" } }, "resources/build/version/node_modules/@types/node": { @@ -11516,74 +11529,37 @@ }, "resources/build/version/node_modules/ansi-regex": { "version": "5.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "resources/build/version/node_modules/cliui": { - "version": "6.0.0", - "license": "ISC", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "resources/build/version/node_modules/find-up": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=12" } }, "resources/build/version/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "resources/build/version/node_modules/locate-path": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "resources/build/version/node_modules/p-limit": { - "version": "2.3.0", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "resources/build/version/node_modules/p-locate": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { "node": ">=8" } }, "resources/build/version/node_modules/string-width": { "version": "4.2.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -11595,7 +11571,8 @@ }, "resources/build/version/node_modules/strip-ansi": { "version": "6.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -11603,51 +11580,29 @@ "node": ">=8" } }, - "resources/build/version/node_modules/wrap-ansi": { - "version": "6.2.0", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "resources/build/version/node_modules/y18n": { - "version": "4.0.3", - "license": "ISC" - }, "resources/build/version/node_modules/yargs": { - "version": "15.4.1", - "license": "MIT", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=8" + "node": ">=12" } }, "resources/build/version/node_modules/yargs-parser": { - "version": "18.1.3", - "license": "ISC", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "engines": { - "node": ">=6" + "node": ">=12" } }, "resources/gosh": { diff --git a/resources/build/increment-version.sh b/resources/build/increment-version.sh index 445459da16..0f5e2d0608 100755 --- a/resources/build/increment-version.sh +++ b/resources/build/increment-version.sh @@ -88,9 +88,7 @@ echo "increment-version.sh: building resources/build/version" pushd "$KEYMAN_ROOT" npm ci -pushd "$KEYMAN_ROOT/resources/build/version" -npm run build:ts -popd +"$KEYMAN_ROOT/resources/build/version/build.sh" echo "increment-version.sh: running resources/build/version" pushd "$KEYMAN_ROOT" diff --git a/resources/build/version/.gitignore b/resources/build/version/.gitignore index 687e3299fe..3e42060cc6 100644 --- a/resources/build/version/.gitignore +++ b/resources/build/version/.gitignore @@ -47,3 +47,4 @@ coverage # Build output dist lib +build diff --git a/resources/build/version/build.sh b/resources/build/version/build.sh new file mode 100755 index 0000000000..64892803bc --- /dev/null +++ b/resources/build/version/build.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../resources/build/build-utils.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" + +# This script runs from its own folder +cd "$THIS_SCRIPT_PATH" + +################################ Main script ################################ + +builder_describe "Build version tooling" clean configure build +builder_describe_outputs \ + configure /resources/build/version/node_modules \ + build /resources/build/version/build/src/index.js + +builder_parse "$@" + +builder_run_action clean rm -rf build/ node_modules/ dist/ lib/ +builder_run_action configure verify_npm_setup +builder_run_action build tsc --build diff --git a/resources/build/version/package.json b/resources/build/version/package.json index 93911e7970..57264f02e4 100644 --- a/resources/build/version/package.json +++ b/resources/build/version/package.json @@ -1,25 +1,24 @@ { + "description": "Automatically updates HISTORY.md based on pull requests", + "type": "module", "dependencies": { "@actions/core": "^1.9.1", "@actions/github": "^2.1.0", "typescript": "^4.9.5", - "yargs": "^15.1.0" + "yargs": "^17.7.2" }, - "description": "Automatically updates HISTORY.md based on pull requests", "devDependencies": { "@types/node": "^13.7.0", "@types/semver": "^7.1.0", + "@types/yargs": "^17.0.26", "semver": "^7.5.2", "ts-node": "^10.9.1" }, - "engines": { - "node": ">=16.0" - }, "files": [ "src" ], "license": "MIT", - "main": "lib/index.js", + "main": "build/src/index.js", "name": "@keymanapp/auto-history-action", "private": true, "scripts": { diff --git a/resources/build/version/src/fixupHistory.ts b/resources/build/version/src/fixupHistory.ts index 2145fa9465..9f48f4851d 100644 --- a/resources/build/version/src/fixupHistory.ts +++ b/resources/build/version/src/fixupHistory.ts @@ -5,7 +5,7 @@ import { import { GitHub } from '@actions/github'; import { readFileSync, writeFileSync } from 'fs'; import { gt } from 'semver'; -import { reportHistory } from './reportHistory'; +import { reportHistory } from './reportHistory.js'; interface PRInformation { title: string; @@ -42,7 +42,8 @@ const splicePullsIntoHistory = async (pulls: PRInformation[]): Promise<{count: n const versionMatch = new RegExp(`^## ${version} ${tier}`, 'i'); let historyChunks: { heading: string[]; newer: string[]; current: string[]; older: string[] } = {heading:[], newer:[], current:[], older:[]}; - let state = "heading"; + type ChunkType = keyof typeof historyChunks; + let state: ChunkType = "heading"; for(const line of history) { if(line.match(versionMatch)) { // We are in the correct section of history @@ -90,7 +91,7 @@ const splicePullsIntoHistory = async (pulls: PRInformation[]): Promise<{count: n let found = false; // Look for the PR in any other chunk -- can be found with merges of master into PR or chained PRs - for(const chunk of ['newer','current','older']) { + for(const chunk of ['newer','current','older'] as ChunkType[]) { for(const line of historyChunks[chunk]) { if(line.match(pullNumberRe)) { found = true; diff --git a/resources/build/version/src/index.ts b/resources/build/version/src/index.ts index 3d5f896650..69776231c6 100644 --- a/resources/build/version/src/index.ts +++ b/resources/build/version/src/index.ts @@ -1,13 +1,14 @@ import { info as logInfo } from '@actions/core'; import { GitHub } from '@actions/github'; -import { sendCommentToPullRequestAndRelatedIssues, fixupHistory } from './fixupHistory'; -import { incrementVersion } from './incrementVersion'; -const yargs = require('yargs'); +import { sendCommentToPullRequestAndRelatedIssues, fixupHistory } from './fixupHistory.js'; +import { incrementVersion } from './incrementVersion.js'; +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; import { readFileSync } from 'fs'; -import { reportHistory } from './reportHistory'; +import { reportHistory } from './reportHistory.js'; -const argv = yargs +const argv = await yargs(hideBin(process.argv)) .command(['history'], 'Fixes up HISTORY.md with pull request data') .command(['version'], 'Increments the current patch version in VERSION.md') .command(['report-history'], 'Print list of outstanding PRs waiting for the next build') @@ -81,10 +82,10 @@ const main = async (): Promise => { if(argv._.includes('report-history')) { let pulls = await reportHistory(octokit, argv.base, argv.force, argv['github-pr'], argv.from, argv.to); - let versions = {}; + let versions: {[index:string]:any} = {}; pulls.forEach((item) => { if(typeof item.version == 'string') { - if(typeof versions[item.version] == 'undefined') { + if(typeof (versions)[item.version] == 'undefined') { versions[item.version] = {data: item.tag_data, pulls: []}; } // We want to invert the order of the pulls as we go to diff --git a/resources/build/version/src/reportHistory.ts b/resources/build/version/src/reportHistory.ts index bf72606333..2fae1ab628 100644 --- a/resources/build/version/src/reportHistory.ts +++ b/resources/build/version/src/reportHistory.ts @@ -2,8 +2,8 @@ import { warning as logWarning, info as logInfo } from '@actions/core'; import { GitHub } from '@actions/github'; -import { findLastHistoryPR, getAssociatedPR} from './graphql/queries'; -import { spawnChild } from './util/spawnAwait'; +import { findLastHistoryPR, getAssociatedPR} from './graphql/queries.js'; +import { spawnChild } from './util/spawnAwait.js'; const getPullRequestInformation = async ( octokit: GitHub, base: string @@ -67,7 +67,7 @@ const getAssociatedPRInformation = async ( } }: any = response; - const node = nodes.find(node => node.state == 'MERGED'); + const node = nodes.find((node:any) => node.state == 'MERGED'); return node ? { title: node.title, number: node.number } : undefined; }; diff --git a/resources/build/version/tsconfig.json b/resources/build/version/tsconfig.json index 655da5e8af..9f537c799d 100644 --- a/resources/build/version/tsconfig.json +++ b/resources/build/version/tsconfig.json @@ -1,7 +1,8 @@ { + "extends": "../../../tsconfig.esm-base.json", "compilerOptions": { - "rootDir": "." + "rootDir": ".", + "outDir": "build/", }, - "extends": "./tsconfig.production.json", - "include": ["./**/*"] + "include": ["./**/*.ts"] } diff --git a/resources/build/version/tsconfig.production.json b/resources/build/version/tsconfig.production.json deleted file mode 100644 index 2189a3042d..0000000000 --- a/resources/build/version/tsconfig.production.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "allowSyntheticDefaultImports": true, - "alwaysStrict": true, - "charset": "utf-8", - "declaration": true, - "declarationMap": true, - "downlevelIteration": true, - "forceConsistentCasingInFileNames": true, - "lib": ["es2017"], - "module": "commonjs", - "noImplicitAny": false, - "noImplicitReturns": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "outDir": "lib", - "pretty": true, - "rootDir": "src", - "sourceMap": true, - "strict": true, - "strictNullChecks": true, - "target": "es2017" - }, - "files": ["./src/index.ts"] -} diff --git a/tsconfig.esm.json b/tsconfig.esm.json index 47c0ef92e9..0252447c63 100644 --- a/tsconfig.esm.json +++ b/tsconfig.esm.json @@ -47,6 +47,8 @@ // { "path": "./web/tools/sourcemap-root/tsconfig.json" }, { "path": "./common/web/lm-message-types/" }, { "path": "./common/web/lm-worker/" }, - { "path": "./common/tools/hextobin/" } + { "path": "./common/tools/hextobin/" }, + + { "path": "./resources/build/version/" }, ] } \ No newline at end of file From f432cab85193ce5ace9c65ab06d328e0f7263854 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 12:06:46 +0700 Subject: [PATCH 063/107] chore(common): keyman-version now generates only es module --- common/web/keyman-version/build-bundler.js | 22 --------- common/web/keyman-version/build.sh | 53 ++++------------------ common/web/keyman-version/package.json | 13 +----- common/web/keyman-version/tsconfig.json | 10 +--- package-lock.json | 7 --- 5 files changed, 13 insertions(+), 92 deletions(-) delete mode 100644 common/web/keyman-version/build-bundler.js diff --git a/common/web/keyman-version/build-bundler.js b/common/web/keyman-version/build-bundler.js deleted file mode 100644 index a5f26a44df..0000000000 --- a/common/web/keyman-version/build-bundler.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Bundles @keymanapp/keyman-version as a single-file CommonJS module for components - * still in need of it. - */ - -import esbuild from 'esbuild'; - -// Bundles to a compact ESModule -esbuild.buildSync({ - entryPoints: ['build/version.inc.js'], - bundle: true, - sourcemap: true, - //minify: true, // No need to minify a module. - //keepNames: true, - format: "cjs", - // Sets 'common/web' as a root folder for module resolution; - // this allows the keyman-version import to resolve. - nodePaths: ['..'], - outfile: "build/version.inc.cjs", - tsconfig: 'tsconfig.json', - target: "es5" -}); \ No newline at end of file diff --git a/common/web/keyman-version/build.sh b/common/web/keyman-version/build.sh index 939709732c..28dd297211 100755 --- a/common/web/keyman-version/build.sh +++ b/common/web/keyman-version/build.sh @@ -1,11 +1,4 @@ #!/usr/bin/env bash -# -# Builds the include script for the current Keyman version. -# - -# Exit on command failure and when using unset variables: -set -eu - ## START STANDARD BUILD SCRIPT INCLUDE # adjust relative paths as necessary THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" @@ -13,6 +6,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" ## END STANDARD BUILD SCRIPT INCLUDE . "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" +. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" # This script runs from its own folder cd "$THIS_SCRIPT_PATH" @@ -24,9 +18,7 @@ builder_describe "Build the include script for current Keyman version" \ clean \ build \ "pack build a local .tgz pack for testing" \ - "publish publish to npm" \ - test \ - --dry-run + "publish publish to npm" builder_describe_outputs \ configure "/node_modules" \ @@ -34,21 +26,7 @@ builder_describe_outputs \ builder_parse "$@" - -if builder_start_action configure; then - verify_npm_setup - builder_finish_action success configure -fi - -if builder_start_action clean; then - npm run clean - rm -f ./version.inc.ts - rm -f ./keyman-version.mts - rm -rf build - builder_finish_action success clean -fi - -if builder_start_action build; then +function do_build() { # Generate version.inc.ts echo " // Generated by common/web/keyman-version/build.sh @@ -72,22 +50,11 @@ export class KEYMAN_VERSION { export default KEYMAN_VERSION; " > ./version.inc.ts - tsc -b $builder_verbose - # kmlmc (the lexical model compiler) relies on a Node-based import, but after some of the earlier - # ES-modularization work, our main output's an ES module. Fortunately, esbuild can provide an easy stopgap. + tsc --build $builder_verbose +} - # Generates a CommonJS variant (in case other modules still need it). - node ./build-bundler.js - - builder_finish_action success build -fi - -if builder_start_action publish; then - . "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" - builder_publish_to_npm - builder_finish_action success publish -elif builder_start_action pack; then - . "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" - builder_publish_to_pack - builder_finish_action success pack -fi +builder_run_action clean rm -rf version.inc.ts keyman-version.mts build/ +builder_run_action configure verify_npm_setup +builder_run_action build do_build +builder_run_action publish builder_publish_to_npm +builder_run_action pack builder_publish_to_pack diff --git a/common/web/keyman-version/package.json b/common/web/keyman-version/package.json index 0ec9c1322b..ded749528c 100644 --- a/common/web/keyman-version/package.json +++ b/common/web/keyman-version/package.json @@ -1,26 +1,15 @@ { "name": "@keymanapp/keyman-version", "description": "Keyman global version data", - "main": "./build/version.inc.cjs", "exports": { - ".": { - "import": "./build/version.inc.js", - "require": "./build/version.inc.cjs" - }, - "./build/version.inc.cjs": "./build/version.inc.cjs" + ".": "./build/version.inc.js" }, "files": [ "/build/" ], - "scripts": { - "build": "echo 'Building @keymanapp/keyman-version' && tsc -b", - "clean": "tsc -b --clean", - "tsc": "tsc" - }, "license": "MIT", "type": "module", "devDependencies": { - "@types/node": "^20.4.1", "typescript": "^4.9.5" } } diff --git a/common/web/keyman-version/tsconfig.json b/common/web/keyman-version/tsconfig.json index 8618c6dd92..03478f6021 100644 --- a/common/web/keyman-version/tsconfig.json +++ b/common/web/keyman-version/tsconfig.json @@ -1,17 +1,11 @@ { - "extends": "../../../tsconfig-base.json", + "extends": "../../../tsconfig.esm-base.json", "compilerOptions": { - "allowJs": false, - "declaration": true, - "module": "es6", - "sourceMap": true, "outDir": "./build", - "lib": ["es6"], - "target": "es5", - "downlevelIteration": true, "rootDir": "." }, + "include": [ "version.inc.ts" ] diff --git a/package-lock.json b/package-lock.json index dea220c34d..10b7dea423 100644 --- a/package-lock.json +++ b/package-lock.json @@ -271,16 +271,9 @@ "name": "@keymanapp/keyman-version", "license": "MIT", "devDependencies": { - "@types/node": "^20.4.1", "typescript": "^4.9.5" } }, - "common/web/keyman-version/node_modules/@types/node": { - "version": "20.4.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.1.tgz", - "integrity": "sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg==", - "dev": true - }, "common/web/lm-message-types": { "name": "@keymanapp/lm-message-types", "license": "MIT", From 253dea0ba66f2bb03bdde4787ea6972689813d20 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 12:21:10 +0700 Subject: [PATCH 064/107] chore(common): fixup Commander call --- common/tools/hextobin/hextobin.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/tools/hextobin/hextobin.ts b/common/tools/hextobin/hextobin.ts index e53e08ddbc..6bf56c7953 100644 --- a/common/tools/hextobin/hextobin.ts +++ b/common/tools/hextobin/hextobin.ts @@ -1,10 +1,11 @@ #!/usr/bin/env node -import * as program from 'commander'; +import { Command } from 'commander'; import hextobin from './index.js'; let inputFilename: string = ""; let outputFilename: string = ""; +const program = new Command(); program .description( `Will convert the input file which is a hex dump to the output file. Hex dump can contain From 8c28b96c9f40cc92d05b8b2d8a1b9e6bc41b5d96 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 11:46:49 +0700 Subject: [PATCH 065/107] chore(common): convert resources/build/version to ES Modules Fixes #9677. --- common/tools/hextobin/build.sh | 2 +- package-lock.json | 149 ++++++------------ resources/build/increment-version.sh | 4 +- resources/build/version/.gitignore | 1 + resources/build/version/build.sh | 24 +++ resources/build/version/package.json | 11 +- resources/build/version/src/fixupHistory.ts | 7 +- resources/build/version/src/index.ts | 15 +- resources/build/version/src/reportHistory.ts | 6 +- resources/build/version/tsconfig.json | 7 +- .../build/version/tsconfig.production.json | 25 --- tsconfig.esm.json | 4 +- 12 files changed, 106 insertions(+), 149 deletions(-) create mode 100755 resources/build/version/build.sh delete mode 100644 resources/build/version/tsconfig.production.json diff --git a/common/tools/hextobin/build.sh b/common/tools/hextobin/build.sh index 48c8542510..8df4f9b83a 100755 --- a/common/tools/hextobin/build.sh +++ b/common/tools/hextobin/build.sh @@ -15,7 +15,7 @@ cd "$THIS_SCRIPT_PATH" builder_describe "Build hextobin" clean configure build builder_describe_outputs \ configure /node_modules \ - build build/index.js + build /common/tools/hextobin/build/index.js builder_parse "$@" diff --git a/package-lock.json b/package-lock.json index 405d2154cf..dea220c34d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3830,6 +3830,21 @@ "@types/node": "*" } }, + "node_modules/@types/yargs": { + "version": "17.0.26", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.26.tgz", + "integrity": "sha512-Y3vDy2X6zw/ZCumcwLpdhM5L7jmyGpmBCTYMHDLqT2IKVMYRRLdv6ZakA+wxhra6Z/3bwhNbNl9bDGXaFU+6rw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==", + "dev": true + }, "node_modules/@types/yauzl": { "version": "2.9.2", "license": "MIT", @@ -4753,6 +4768,7 @@ }, "node_modules/camelcase": { "version": "5.3.1", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5148,6 +5164,7 @@ }, "node_modules/decamelize": { "version": "1.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5884,7 +5901,6 @@ }, "node_modules/escalade": { "version": "3.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -9573,6 +9589,7 @@ }, "node_modules/p-try": { "version": "2.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -9603,6 +9620,7 @@ }, "node_modules/path-exists": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9930,6 +9948,7 @@ }, "node_modules/require-main-filename": { "version": "2.0.0", + "dev": true, "license": "ISC" }, "node_modules/requirejs": { @@ -10170,6 +10189,7 @@ }, "node_modules/set-blocking": { "version": "2.0.0", + "devOptional": true, "license": "ISC" }, "node_modules/set-immediate-shim": { @@ -11172,6 +11192,7 @@ }, "node_modules/which-module": { "version": "2.0.0", + "dev": true, "license": "ISC" }, "node_modules/which-typed-array": { @@ -11231,7 +11252,6 @@ }, "node_modules/wrap-ansi": { "version": "7.0.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -11247,7 +11267,6 @@ }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "5.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11255,7 +11274,6 @@ }, "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11263,7 +11281,6 @@ }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "4.2.2", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -11276,7 +11293,6 @@ }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "6.0.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.0" @@ -11337,7 +11353,6 @@ }, "node_modules/y18n": { "version": "5.0.8", - "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -11497,16 +11512,14 @@ "@actions/core": "^1.9.1", "@actions/github": "^2.1.0", "typescript": "^4.9.5", - "yargs": "^15.1.0" + "yargs": "^17.7.2" }, "devDependencies": { "@types/node": "^13.7.0", "@types/semver": "^7.1.0", + "@types/yargs": "^17.0.26", "semver": "^7.5.2", "ts-node": "^10.9.1" - }, - "engines": { - "node": ">=16.0" } }, "resources/build/version/node_modules/@types/node": { @@ -11516,74 +11529,37 @@ }, "resources/build/version/node_modules/ansi-regex": { "version": "5.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "resources/build/version/node_modules/cliui": { - "version": "6.0.0", - "license": "ISC", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "resources/build/version/node_modules/find-up": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=12" } }, "resources/build/version/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "resources/build/version/node_modules/locate-path": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "resources/build/version/node_modules/p-limit": { - "version": "2.3.0", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "resources/build/version/node_modules/p-locate": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { "node": ">=8" } }, "resources/build/version/node_modules/string-width": { "version": "4.2.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -11595,7 +11571,8 @@ }, "resources/build/version/node_modules/strip-ansi": { "version": "6.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -11603,51 +11580,29 @@ "node": ">=8" } }, - "resources/build/version/node_modules/wrap-ansi": { - "version": "6.2.0", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "resources/build/version/node_modules/y18n": { - "version": "4.0.3", - "license": "ISC" - }, "resources/build/version/node_modules/yargs": { - "version": "15.4.1", - "license": "MIT", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=8" + "node": ">=12" } }, "resources/build/version/node_modules/yargs-parser": { - "version": "18.1.3", - "license": "ISC", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "engines": { - "node": ">=6" + "node": ">=12" } }, "resources/gosh": { diff --git a/resources/build/increment-version.sh b/resources/build/increment-version.sh index 445459da16..0f5e2d0608 100755 --- a/resources/build/increment-version.sh +++ b/resources/build/increment-version.sh @@ -88,9 +88,7 @@ echo "increment-version.sh: building resources/build/version" pushd "$KEYMAN_ROOT" npm ci -pushd "$KEYMAN_ROOT/resources/build/version" -npm run build:ts -popd +"$KEYMAN_ROOT/resources/build/version/build.sh" echo "increment-version.sh: running resources/build/version" pushd "$KEYMAN_ROOT" diff --git a/resources/build/version/.gitignore b/resources/build/version/.gitignore index 687e3299fe..3e42060cc6 100644 --- a/resources/build/version/.gitignore +++ b/resources/build/version/.gitignore @@ -47,3 +47,4 @@ coverage # Build output dist lib +build diff --git a/resources/build/version/build.sh b/resources/build/version/build.sh new file mode 100755 index 0000000000..64892803bc --- /dev/null +++ b/resources/build/version/build.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../resources/build/build-utils.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" + +# This script runs from its own folder +cd "$THIS_SCRIPT_PATH" + +################################ Main script ################################ + +builder_describe "Build version tooling" clean configure build +builder_describe_outputs \ + configure /resources/build/version/node_modules \ + build /resources/build/version/build/src/index.js + +builder_parse "$@" + +builder_run_action clean rm -rf build/ node_modules/ dist/ lib/ +builder_run_action configure verify_npm_setup +builder_run_action build tsc --build diff --git a/resources/build/version/package.json b/resources/build/version/package.json index 93911e7970..57264f02e4 100644 --- a/resources/build/version/package.json +++ b/resources/build/version/package.json @@ -1,25 +1,24 @@ { + "description": "Automatically updates HISTORY.md based on pull requests", + "type": "module", "dependencies": { "@actions/core": "^1.9.1", "@actions/github": "^2.1.0", "typescript": "^4.9.5", - "yargs": "^15.1.0" + "yargs": "^17.7.2" }, - "description": "Automatically updates HISTORY.md based on pull requests", "devDependencies": { "@types/node": "^13.7.0", "@types/semver": "^7.1.0", + "@types/yargs": "^17.0.26", "semver": "^7.5.2", "ts-node": "^10.9.1" }, - "engines": { - "node": ">=16.0" - }, "files": [ "src" ], "license": "MIT", - "main": "lib/index.js", + "main": "build/src/index.js", "name": "@keymanapp/auto-history-action", "private": true, "scripts": { diff --git a/resources/build/version/src/fixupHistory.ts b/resources/build/version/src/fixupHistory.ts index 2145fa9465..9f48f4851d 100644 --- a/resources/build/version/src/fixupHistory.ts +++ b/resources/build/version/src/fixupHistory.ts @@ -5,7 +5,7 @@ import { import { GitHub } from '@actions/github'; import { readFileSync, writeFileSync } from 'fs'; import { gt } from 'semver'; -import { reportHistory } from './reportHistory'; +import { reportHistory } from './reportHistory.js'; interface PRInformation { title: string; @@ -42,7 +42,8 @@ const splicePullsIntoHistory = async (pulls: PRInformation[]): Promise<{count: n const versionMatch = new RegExp(`^## ${version} ${tier}`, 'i'); let historyChunks: { heading: string[]; newer: string[]; current: string[]; older: string[] } = {heading:[], newer:[], current:[], older:[]}; - let state = "heading"; + type ChunkType = keyof typeof historyChunks; + let state: ChunkType = "heading"; for(const line of history) { if(line.match(versionMatch)) { // We are in the correct section of history @@ -90,7 +91,7 @@ const splicePullsIntoHistory = async (pulls: PRInformation[]): Promise<{count: n let found = false; // Look for the PR in any other chunk -- can be found with merges of master into PR or chained PRs - for(const chunk of ['newer','current','older']) { + for(const chunk of ['newer','current','older'] as ChunkType[]) { for(const line of historyChunks[chunk]) { if(line.match(pullNumberRe)) { found = true; diff --git a/resources/build/version/src/index.ts b/resources/build/version/src/index.ts index 3d5f896650..69776231c6 100644 --- a/resources/build/version/src/index.ts +++ b/resources/build/version/src/index.ts @@ -1,13 +1,14 @@ import { info as logInfo } from '@actions/core'; import { GitHub } from '@actions/github'; -import { sendCommentToPullRequestAndRelatedIssues, fixupHistory } from './fixupHistory'; -import { incrementVersion } from './incrementVersion'; -const yargs = require('yargs'); +import { sendCommentToPullRequestAndRelatedIssues, fixupHistory } from './fixupHistory.js'; +import { incrementVersion } from './incrementVersion.js'; +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; import { readFileSync } from 'fs'; -import { reportHistory } from './reportHistory'; +import { reportHistory } from './reportHistory.js'; -const argv = yargs +const argv = await yargs(hideBin(process.argv)) .command(['history'], 'Fixes up HISTORY.md with pull request data') .command(['version'], 'Increments the current patch version in VERSION.md') .command(['report-history'], 'Print list of outstanding PRs waiting for the next build') @@ -81,10 +82,10 @@ const main = async (): Promise => { if(argv._.includes('report-history')) { let pulls = await reportHistory(octokit, argv.base, argv.force, argv['github-pr'], argv.from, argv.to); - let versions = {}; + let versions: {[index:string]:any} = {}; pulls.forEach((item) => { if(typeof item.version == 'string') { - if(typeof versions[item.version] == 'undefined') { + if(typeof (versions)[item.version] == 'undefined') { versions[item.version] = {data: item.tag_data, pulls: []}; } // We want to invert the order of the pulls as we go to diff --git a/resources/build/version/src/reportHistory.ts b/resources/build/version/src/reportHistory.ts index bf72606333..2fae1ab628 100644 --- a/resources/build/version/src/reportHistory.ts +++ b/resources/build/version/src/reportHistory.ts @@ -2,8 +2,8 @@ import { warning as logWarning, info as logInfo } from '@actions/core'; import { GitHub } from '@actions/github'; -import { findLastHistoryPR, getAssociatedPR} from './graphql/queries'; -import { spawnChild } from './util/spawnAwait'; +import { findLastHistoryPR, getAssociatedPR} from './graphql/queries.js'; +import { spawnChild } from './util/spawnAwait.js'; const getPullRequestInformation = async ( octokit: GitHub, base: string @@ -67,7 +67,7 @@ const getAssociatedPRInformation = async ( } }: any = response; - const node = nodes.find(node => node.state == 'MERGED'); + const node = nodes.find((node:any) => node.state == 'MERGED'); return node ? { title: node.title, number: node.number } : undefined; }; diff --git a/resources/build/version/tsconfig.json b/resources/build/version/tsconfig.json index 655da5e8af..9f537c799d 100644 --- a/resources/build/version/tsconfig.json +++ b/resources/build/version/tsconfig.json @@ -1,7 +1,8 @@ { + "extends": "../../../tsconfig.esm-base.json", "compilerOptions": { - "rootDir": "." + "rootDir": ".", + "outDir": "build/", }, - "extends": "./tsconfig.production.json", - "include": ["./**/*"] + "include": ["./**/*.ts"] } diff --git a/resources/build/version/tsconfig.production.json b/resources/build/version/tsconfig.production.json deleted file mode 100644 index 2189a3042d..0000000000 --- a/resources/build/version/tsconfig.production.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "allowSyntheticDefaultImports": true, - "alwaysStrict": true, - "charset": "utf-8", - "declaration": true, - "declarationMap": true, - "downlevelIteration": true, - "forceConsistentCasingInFileNames": true, - "lib": ["es2017"], - "module": "commonjs", - "noImplicitAny": false, - "noImplicitReturns": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "outDir": "lib", - "pretty": true, - "rootDir": "src", - "sourceMap": true, - "strict": true, - "strictNullChecks": true, - "target": "es2017" - }, - "files": ["./src/index.ts"] -} diff --git a/tsconfig.esm.json b/tsconfig.esm.json index 47c0ef92e9..0252447c63 100644 --- a/tsconfig.esm.json +++ b/tsconfig.esm.json @@ -47,6 +47,8 @@ // { "path": "./web/tools/sourcemap-root/tsconfig.json" }, { "path": "./common/web/lm-message-types/" }, { "path": "./common/web/lm-worker/" }, - { "path": "./common/tools/hextobin/" } + { "path": "./common/tools/hextobin/" }, + + { "path": "./resources/build/version/" }, ] } \ No newline at end of file From 11e5cd3a47b90d4bab0c0bddbf77a14bbe4bf174 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 12:07:19 +0700 Subject: [PATCH 066/107] chore: update root tsconfig --- tsconfig.cjs.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json index 2b8030ac76..701d06ce3b 100644 --- a/tsconfig.cjs.json +++ b/tsconfig.cjs.json @@ -8,9 +8,5 @@ { "path": "./common/predictive-text/testing/one-stage-embedded-webworker/tsconfig.json" }, { "path": "./common/predictive-text/testing/two-stage-embedded-webworker/tsconfig.json" }, { "path": "./common/predictive-text/testing/two-stage-embedded-webworker/worker/tsconfig.json" }, - - { "path": "./resources/build/version/tsconfig.json" }, - { "path": "./resources/build/version/tsconfig.production.json" }, - // { "path": "./web/bulk_rendering/tsconfig.json" }, ] } \ No newline at end of file From d4e4992714b5f91d55dc52a88775bf8932309fb5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 12:55:51 +0700 Subject: [PATCH 067/107] chore(common): cleanup final Typescript non-ESM metadata Fixes #9262. --- common/models/templates/package.json | 4 +- common/models/wordbreakers/package.json | 3 +- common/predictive-text/testing/index.html | 28 -------- .../one-stage-embedded-webworker/.gitignore | 2 - .../one-stage-embedded-webworker/build.sh | 54 -------------- .../one-stage-embedded-webworker/index.html | 42 ----------- .../one-stage-embedded-webworker/main.ts | 52 -------------- .../tsconfig.json | 13 ---- .../post-blob-webworker/canaryWorker.js | 5 -- .../testing/post-blob-webworker/index.html | 72 ------------------- .../testing/simple-webworker/canaryWorker.js | 9 --- .../testing/simple-webworker/index.html | 55 -------------- .../two-stage-embedded-webworker/.gitignore | 2 - .../two-stage-embedded-webworker/build.sh | 68 ------------------ .../two-stage-embedded-webworker/index.html | 42 ----------- .../two-stage-embedded-webworker/main.ts | 30 -------- .../tsconfig.json | 13 ---- .../worker/canaryWorker.ts | 9 --- .../worker/tsconfig.json | 11 --- common/tools/hextobin/tsconfig.json | 2 +- .../sourcemap-path-remapper/tsconfig.json | 3 +- common/web/es-bundling/tsconfig.json | 2 +- common/web/keyman-version/tsconfig.json | 2 +- common/web/lm-message-types/tsconfig.json | 2 +- common/web/sentry-manager/src/tsconfig.json | 3 +- common/web/types/test/tsconfig.json | 2 +- common/web/types/tsconfig.json | 2 +- core/include/ldml/tsconfig.build.json | 2 +- core/include/ldml/tsconfig.json | 4 +- .../src/common/web/test-helpers/tsconfig.json | 2 +- developer/src/kmc-analyze/tsconfig.json | 2 +- .../src/kmc-keyboard-info/test/tsconfig.json | 1 - developer/src/kmc-kmn/tsconfig.json | 2 +- developer/src/kmc-ldml/tsconfig.json | 2 +- .../src/kmc-model-info/test/tsconfig.json | 1 - developer/src/kmc-model/test/tsconfig.json | 1 - developer/src/kmc/tsconfig.kmc-base.json | 2 +- developer/src/server/tsconfig.json | 2 +- resources/build/version/tsconfig.json | 2 +- tsconfig-base.json => tsconfig.base.json | 15 ++++ tsconfig.cjs.json | 12 ---- tsconfig.esm-base.json | 24 ------- tsconfig.esm.json => tsconfig.json | 44 +++++------- web/tsconfig.base.json | 3 +- 44 files changed, 53 insertions(+), 600 deletions(-) delete mode 100644 common/predictive-text/testing/index.html delete mode 100644 common/predictive-text/testing/one-stage-embedded-webworker/.gitignore delete mode 100755 common/predictive-text/testing/one-stage-embedded-webworker/build.sh delete mode 100644 common/predictive-text/testing/one-stage-embedded-webworker/index.html delete mode 100644 common/predictive-text/testing/one-stage-embedded-webworker/main.ts delete mode 100644 common/predictive-text/testing/one-stage-embedded-webworker/tsconfig.json delete mode 100644 common/predictive-text/testing/post-blob-webworker/canaryWorker.js delete mode 100644 common/predictive-text/testing/post-blob-webworker/index.html delete mode 100644 common/predictive-text/testing/simple-webworker/canaryWorker.js delete mode 100644 common/predictive-text/testing/simple-webworker/index.html delete mode 100644 common/predictive-text/testing/two-stage-embedded-webworker/.gitignore delete mode 100755 common/predictive-text/testing/two-stage-embedded-webworker/build.sh delete mode 100644 common/predictive-text/testing/two-stage-embedded-webworker/index.html delete mode 100644 common/predictive-text/testing/two-stage-embedded-webworker/main.ts delete mode 100644 common/predictive-text/testing/two-stage-embedded-webworker/tsconfig.json delete mode 100644 common/predictive-text/testing/two-stage-embedded-webworker/worker/canaryWorker.ts delete mode 100644 common/predictive-text/testing/two-stage-embedded-webworker/worker/tsconfig.json rename tsconfig-base.json => tsconfig.base.json (65%) delete mode 100644 tsconfig.cjs.json delete mode 100644 tsconfig.esm-base.json rename tsconfig.esm.json => tsconfig.json (87%) diff --git a/common/models/templates/package.json b/common/models/templates/package.json index 0bec0fc88f..33f89cca70 100644 --- a/common/models/templates/package.json +++ b/common/models/templates/package.json @@ -21,9 +21,7 @@ "exports": { ".": "./build/obj/index.js", "./lib": { - "types": "./build/lib/index.d.ts", - "import": "./build/lib/index.mjs", - "require": "./build/lib/index.cjs" + "types": "./build/lib/index.d.ts" }, "./obj/*.js": "./build/obj/*.js" }, diff --git a/common/models/wordbreakers/package.json b/common/models/wordbreakers/package.json index bd8d0157fb..7a03dc9e8f 100644 --- a/common/models/wordbreakers/package.json +++ b/common/models/wordbreakers/package.json @@ -19,8 +19,7 @@ "exports": { ".": "./build/obj/index.js", "./lib": { - "import": "./build/lib/index.mjs", - "require": "./build/lib/index.cjs" + "types": "./build/lib/index.d.ts" }, "./obj/*.js": "./build/obj/*.js" }, diff --git a/common/predictive-text/testing/index.html b/common/predictive-text/testing/index.html deleted file mode 100644 index 8a00094b70..0000000000 --- a/common/predictive-text/testing/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - LMLayer Testing - - - -

Language-Modeling Layer module testing

-

A simple basic WebWorker.

Designed as a baseline functionality test we can run against various platforms as a first-stage canary of sorts. -

An embedded WebWorker prototype.

A prototype for directly embedding a WebWorker's code within a "master" script. -

A better embedded WebWorker prototype.

A prototype for two-stage compilation of a master/slave main-script/WebWorker pair. -

Sending code via a Blob URI

A prototype for sending code over to a WebWorker via a Blob URI reference. - - diff --git a/common/predictive-text/testing/one-stage-embedded-webworker/.gitignore b/common/predictive-text/testing/one-stage-embedded-webworker/.gitignore deleted file mode 100644 index df6361deda..0000000000 --- a/common/predictive-text/testing/one-stage-embedded-webworker/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -main.js -main.js.map \ No newline at end of file diff --git a/common/predictive-text/testing/one-stage-embedded-webworker/build.sh b/common/predictive-text/testing/one-stage-embedded-webworker/build.sh deleted file mode 100755 index f1f727b8c0..0000000000 --- a/common/predictive-text/testing/one-stage-embedded-webworker/build.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash -# -# Compiles the Language Modeling Layer for common use in predictive text and autocorrective applications. -# Designed for optimal compatibility with the Keyman Suite. -# - -## START STANDARD BUILD SCRIPT INCLUDE -# adjust relative paths as necessary -THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" -. "${THIS_SCRIPT%/*}/../../../../resources/build/build-utils.sh" -. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" -## END STANDARD BUILD SCRIPT INCLUDE - -display_usage ( ) { - echo "build.sh [-clean]" - echo - echo " -clean to erase pre-existing build products before a re-build" -} - -SOURCE="testing/one-stage-embedded-webworker" - -echo "Node.js + dependencies check" -npm install --no-optional - -if [ $? -ne 0 ]; then - builder_die "Build environment setup error detected! Please ensure Node.js is installed!" -fi - -# A nice, extensible method for -clean operations. Add to this as necessary. -clean ( ) { - rm -rf "./*.js" - if [ $? -ne 0 ]; then - builder_die "Failed to erase the prior build." - fi -} - -# Process command-line arguments -while [[ $# -gt 0 ]] ; do - key="$1" - case $key in - -clean) - clean - ;; - esac - shift # past the processed argument -done - -npm run tsc -- -p $SOURCE/tsconfig.json - -if [ $? -ne 0 ]; then - builder_die "Compilation failed." -fi - -echo "Typescript compilation successful." \ No newline at end of file diff --git a/common/predictive-text/testing/one-stage-embedded-webworker/index.html b/common/predictive-text/testing/one-stage-embedded-webworker/index.html deleted file mode 100644 index 244f4aa283..0000000000 --- a/common/predictive-text/testing/one-stage-embedded-webworker/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - Embedded WebWorker test - - - - - - - - - -

LM Layer Testing - One-Stage Embedded WebWorkers

-

This page serves as a prototype for embedding a WebWorker's code within its "master" script - across the TypeScript transpilation boundary.

-
- - - -

Return to testing home page

- - diff --git a/common/predictive-text/testing/one-stage-embedded-webworker/main.ts b/common/predictive-text/testing/one-stage-embedded-webworker/main.ts deleted file mode 100644 index 5d15ae88b5..0000000000 --- a/common/predictive-text/testing/one-stage-embedded-webworker/main.ts +++ /dev/null @@ -1,52 +0,0 @@ -// Useful for passing class constructors -type Workable = { - new (...args: any[]): T; - // Requires a static implementation. - onmessage(e: any): void; -}; - -class A { - a(x: number, y: number):number { - return x + y; - } -} - -var WorkerGlobals = { - counter: 0, - a: A -} - -class WorkerCore { - static WorkerGlobals = WorkerGlobals; - //static counter: number; - - static onmessage(e: any) { - WorkerGlobals.counter++; - - console.log("Message received from main page: ", e.data); - - // Forces TypeScript to interpret this line as plain JavaScript, as it uses a non-Worker definition. - // @ts-ignore - postMessage(WorkerGlobals.counter); - } -} - -function createWorkerFromClasses(globals: object, fn: Workable): Worker { - var sep = ";\n"; - let glb = "var WorkerGlobals = " + JSON.stringify(globals); - let wc = "var onmessage = " + fn.onmessage.toString(); - var blob = new Blob([glb, sep, wc], { type: 'text/javascript' }); - let url = URL.createObjectURL(blob); - - return new Worker(url); -} - -var canaryWorker = createWorkerFromClasses(WorkerGlobals, WorkerCore); - -canaryWorker.onmessage = function(e) { - var counter = e.data; // Number of times the WebWorker has been messaged. - console.log("Received message from the WebWorker: " + e.data); - - var txtFeedback = document.getElementById("txtFeedback"); - txtFeedback.value = counter + " click(s)"; -} diff --git a/common/predictive-text/testing/one-stage-embedded-webworker/tsconfig.json b/common/predictive-text/testing/one-stage-embedded-webworker/tsconfig.json deleted file mode 100644 index f1e9be8600..0000000000 --- a/common/predictive-text/testing/one-stage-embedded-webworker/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "allowJs": false, - "module": "none", - "outDir": "./", - "inlineSources": true, - "sourceMap": true, - "target": "es5" - }, - "files" : [ - "main.ts" - ] -} diff --git a/common/predictive-text/testing/post-blob-webworker/canaryWorker.js b/common/predictive-text/testing/post-blob-webworker/canaryWorker.js deleted file mode 100644 index 5c69deace8..0000000000 --- a/common/predictive-text/testing/post-blob-webworker/canaryWorker.js +++ /dev/null @@ -1,5 +0,0 @@ -// receive a message and execute its uri -onmessage = function (e) { - let uri = e.data.uri; - importScripts(uri); -}; diff --git a/common/predictive-text/testing/post-blob-webworker/index.html b/common/predictive-text/testing/post-blob-webworker/index.html deleted file mode 100644 index a04b6be377..0000000000 --- a/common/predictive-text/testing/post-blob-webworker/index.html +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - Blob URI test - - - - - - - - - -

LM Layer Testing - Sending a function to a WebWorker via a Blob URI test

-

This page sends a function over to the Worker via a Blob URI, and - expects the function to reply back. -

-
- - - -

Return to testing home page

- - diff --git a/common/predictive-text/testing/simple-webworker/canaryWorker.js b/common/predictive-text/testing/simple-webworker/canaryWorker.js deleted file mode 100644 index cf8674d330..0000000000 --- a/common/predictive-text/testing/simple-webworker/canaryWorker.js +++ /dev/null @@ -1,9 +0,0 @@ -var counter = 0; - -onmessage = function(e) { - counter++; - - console.log("Message received from main page: ", e.data); - - postMessage(counter); -} \ No newline at end of file diff --git a/common/predictive-text/testing/simple-webworker/index.html b/common/predictive-text/testing/simple-webworker/index.html deleted file mode 100644 index adbcd30d3e..0000000000 --- a/common/predictive-text/testing/simple-webworker/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - Basic WebWorker test - - - - - - - - - -

LM Layer Testing - basic WebWorker canary

-

This page uses a simple WebWorker useful for ensuring functionality on various platforms.

-
- - - -

Return to testing home page

- - diff --git a/common/predictive-text/testing/two-stage-embedded-webworker/.gitignore b/common/predictive-text/testing/two-stage-embedded-webworker/.gitignore deleted file mode 100644 index 20efd1ec83..0000000000 --- a/common/predictive-text/testing/two-stage-embedded-webworker/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -**/*.js -**/*.js.map \ No newline at end of file diff --git a/common/predictive-text/testing/two-stage-embedded-webworker/build.sh b/common/predictive-text/testing/two-stage-embedded-webworker/build.sh deleted file mode 100755 index dd1854ec00..0000000000 --- a/common/predictive-text/testing/two-stage-embedded-webworker/build.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash -# -# Compiles the Language Modeling Layer for common use in predictive text and autocorrective applications. -# Designed for optimal compatibility with the Keyman Suite. -# - -## START STANDARD BUILD SCRIPT INCLUDE -# adjust relative paths as necessary -THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" -. "${THIS_SCRIPT%/*}/../../../../resources/build/build-utils.sh" -. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" -## END STANDARD BUILD SCRIPT INCLUDE - -display_usage ( ) { - echo "build.sh [-clean]" - echo - echo " -clean to erase pre-existing build products before a re-build" -} - -SOURCE="testing/two-stage-embedded-webworker" - -COMPILED_WORKER="worker.js" -EMBEDDED_WORKER="embedded_worker.js" - -echo "Node.js + dependencies check" -npm install --no-optional - -if [ $? -ne 0 ]; then - builder_die "Build environment setup error detected! Please ensure Node.js is installed!" -fi - -# A nice, extensible method for -clean operations. Add to this as necessary. -clean ( ) { - rm -rf "./*.js" - if [ $? -ne 0 ]; then - builder_die "Failed to erase the prior build." - fi -} - -# Process command-line arguments -while [[ $# -gt 0 ]] ; do - key="$1" - case $key in - -clean) - clean - ;; - esac - shift # past the processed argument -done - -npm run tsc -- -p $SOURCE/worker/tsconfig.json -if [ $? -ne 0 ]; then - builder_die "Worker compilation failed." -fi - -rm $EMBEDDED_WORKER &> /dev/null - -echo "var LMLayerWorker = function() {" >> $EMBEDDED_WORKER -cat $COMPILED_WORKER >> $EMBEDDED_WORKER -echo "" >> $EMBEDDED_WORKER -echo "}" >> $EMBEDDED_WORKER - -npm run tsc -- -p $SOURCE/tsconfig.json -if [ $? -ne 0 ]; then - builder_die "Final compilation failed." -fi - -echo "Typescript compilation successful." \ No newline at end of file diff --git a/common/predictive-text/testing/two-stage-embedded-webworker/index.html b/common/predictive-text/testing/two-stage-embedded-webworker/index.html deleted file mode 100644 index 244f4aa283..0000000000 --- a/common/predictive-text/testing/two-stage-embedded-webworker/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - Embedded WebWorker test - - - - - - - - - -

LM Layer Testing - One-Stage Embedded WebWorkers

-

This page serves as a prototype for embedding a WebWorker's code within its "master" script - across the TypeScript transpilation boundary.

-
- - - -

Return to testing home page

- - diff --git a/common/predictive-text/testing/two-stage-embedded-webworker/main.ts b/common/predictive-text/testing/two-stage-embedded-webworker/main.ts deleted file mode 100644 index 9eb276d379..0000000000 --- a/common/predictive-text/testing/two-stage-embedded-webworker/main.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Provides the final source for our compiled WebWorker within a wrapping function. -/// - -function createWorker(fn: Function): Worker { - var str_fn = fn.toString(); - - // We now unwrap our WebWorker from its function. - var str_lines = str_fn.split("\n"); - var blob_lines = [] - - for(var i=1; i < str_lines.length -1; i++) { - blob_lines.push(str_lines[i] + "\n"); - } - // Unwrapping complete. - - var blob = new Blob(blob_lines, { type: 'text/javascript' }); - let url = URL.createObjectURL(blob); - - return new Worker(url); -} - -var canaryWorker = createWorker(LMLayerWorker); - -canaryWorker.onmessage = function(e) { - var counter = e.data; // Number of times the WebWorker has been messaged. - console.log("Received message from the WebWorker: " + e.data); - - var txtFeedback = document.getElementById("txtFeedback"); - txtFeedback.value = counter + " click(s)"; -} diff --git a/common/predictive-text/testing/two-stage-embedded-webworker/tsconfig.json b/common/predictive-text/testing/two-stage-embedded-webworker/tsconfig.json deleted file mode 100644 index a25930a70e..0000000000 --- a/common/predictive-text/testing/two-stage-embedded-webworker/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "allowJs": true, - "module": "none", - "outFile": "./main.js", - "inlineSources": true, - "inlineSourceMap": true, - "target": "es5" - }, - "files" : [ - "main.ts" - ] -} diff --git a/common/predictive-text/testing/two-stage-embedded-webworker/worker/canaryWorker.ts b/common/predictive-text/testing/two-stage-embedded-webworker/worker/canaryWorker.ts deleted file mode 100644 index cf8674d330..0000000000 --- a/common/predictive-text/testing/two-stage-embedded-webworker/worker/canaryWorker.ts +++ /dev/null @@ -1,9 +0,0 @@ -var counter = 0; - -onmessage = function(e) { - counter++; - - console.log("Message received from main page: ", e.data); - - postMessage(counter); -} \ No newline at end of file diff --git a/common/predictive-text/testing/two-stage-embedded-webworker/worker/tsconfig.json b/common/predictive-text/testing/two-stage-embedded-webworker/worker/tsconfig.json deleted file mode 100644 index ca8006ba44..0000000000 --- a/common/predictive-text/testing/two-stage-embedded-webworker/worker/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "allowJs": false, - "module": "none", - "outFile": "../worker.js", - "inlineSources": true, - "sourceMap": true, - "lib": ["webworker", "es6"], - "target": "es5" - } -} diff --git a/common/tools/hextobin/tsconfig.json b/common/tools/hextobin/tsconfig.json index db0a65ae9d..55e3f66308 100644 --- a/common/tools/hextobin/tsconfig.json +++ b/common/tools/hextobin/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.esm-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "rootDir": ".", "outDir": "build/" diff --git a/common/tools/sourcemap-path-remapper/tsconfig.json b/common/tools/sourcemap-path-remapper/tsconfig.json index f9b531b311..72809897bd 100644 --- a/common/tools/sourcemap-path-remapper/tsconfig.json +++ b/common/tools/sourcemap-path-remapper/tsconfig.json @@ -1,12 +1,11 @@ { - "extends": "../../../tsconfig-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "allowJs": false, "allowSyntheticDefaultImports": true, "declaration": true, "module": "es6", - "moduleResolution": "node", "inlineSourceMap": true, "inlineSources": true, "sourceRoot": "/common/tools/sourcemap-path-remapper/src", diff --git a/common/web/es-bundling/tsconfig.json b/common/web/es-bundling/tsconfig.json index d2ab738acf..a5149b51c6 100644 --- a/common/web/es-bundling/tsconfig.json +++ b/common/web/es-bundling/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.esm-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "baseUrl": "./", "outDir": "build/", diff --git a/common/web/keyman-version/tsconfig.json b/common/web/keyman-version/tsconfig.json index 03478f6021..0712c03f75 100644 --- a/common/web/keyman-version/tsconfig.json +++ b/common/web/keyman-version/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.esm-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "./build", diff --git a/common/web/lm-message-types/tsconfig.json b/common/web/lm-message-types/tsconfig.json index 124def350d..f9d427f0bf 100644 --- a/common/web/lm-message-types/tsconfig.json +++ b/common/web/lm-message-types/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "declaration": true, "module": "none", diff --git a/common/web/sentry-manager/src/tsconfig.json b/common/web/sentry-manager/src/tsconfig.json index 490c315dc9..f42eaea73b 100644 --- a/common/web/sentry-manager/src/tsconfig.json +++ b/common/web/sentry-manager/src/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../../tsconfig-base.json", + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, @@ -7,7 +7,6 @@ "inlineSources": true, "lib": ["es6", "dom"], "module": "es6", - "moduleResolution": "Node16", "outDir": "../build/obj", "rootDir": "./", "sourceMap": true, diff --git a/common/web/types/test/tsconfig.json b/common/web/types/test/tsconfig.json index c522129c99..ee468c7fbd 100644 --- a/common/web/types/test/tsconfig.json +++ b/common/web/types/test/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../../tsconfig.esm-base.json", + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "rootDir": ".", diff --git a/common/web/types/tsconfig.json b/common/web/types/tsconfig.json index 5059030c0f..730244e67c 100644 --- a/common/web/types/tsconfig.json +++ b/common/web/types/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.esm-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "build/src/", diff --git a/core/include/ldml/tsconfig.build.json b/core/include/ldml/tsconfig.build.json index 17c809a857..fd0f003272 100644 --- a/core/include/ldml/tsconfig.build.json +++ b/core/include/ldml/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.esm-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "composite": true, "declaration": true, diff --git a/core/include/ldml/tsconfig.json b/core/include/ldml/tsconfig.json index b89c96a018..fa4135b021 100644 --- a/core/include/ldml/tsconfig.json +++ b/core/include/ldml/tsconfig.json @@ -1,10 +1,8 @@ { - "extends": "../../../tsconfig-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "composite": true, "declaration": true, - "module": "es2020", - "moduleResolution": "node", "rootDir": ".", "outDir": "build/", }, diff --git a/developer/src/common/web/test-helpers/tsconfig.json b/developer/src/common/web/test-helpers/tsconfig.json index 47646be3a6..d7089c703f 100644 --- a/developer/src/common/web/test-helpers/tsconfig.json +++ b/developer/src/common/web/test-helpers/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../../../tsconfig.esm-base.json", + "extends": "../../../../../tsconfig.base.json", "compilerOptions": { "rootDir": ".", diff --git a/developer/src/kmc-analyze/tsconfig.json b/developer/src/kmc-analyze/tsconfig.json index 3a9149e121..987abd3cc3 100644 --- a/developer/src/kmc-analyze/tsconfig.json +++ b/developer/src/kmc-analyze/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.esm-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "build/src/", diff --git a/developer/src/kmc-keyboard-info/test/tsconfig.json b/developer/src/kmc-keyboard-info/test/tsconfig.json index bf96b7b150..6d48ad864d 100644 --- a/developer/src/kmc-keyboard-info/test/tsconfig.json +++ b/developer/src/kmc-keyboard-info/test/tsconfig.json @@ -6,7 +6,6 @@ "rootDirs": ["./", "../src/"], "outDir": "../build/test", "esModuleInterop": true, - "moduleResolution": "node16", "allowSyntheticDefaultImports": true, "baseUrl": ".", "paths": { diff --git a/developer/src/kmc-kmn/tsconfig.json b/developer/src/kmc-kmn/tsconfig.json index 04683902ea..4210b750af 100644 --- a/developer/src/kmc-kmn/tsconfig.json +++ b/developer/src/kmc-kmn/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.esm-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "build/src/", diff --git a/developer/src/kmc-ldml/tsconfig.json b/developer/src/kmc-ldml/tsconfig.json index c9ec649b40..fdcf5fd82b 100644 --- a/developer/src/kmc-ldml/tsconfig.json +++ b/developer/src/kmc-ldml/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.esm-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "build/src/", diff --git a/developer/src/kmc-model-info/test/tsconfig.json b/developer/src/kmc-model-info/test/tsconfig.json index bf96b7b150..6d48ad864d 100644 --- a/developer/src/kmc-model-info/test/tsconfig.json +++ b/developer/src/kmc-model-info/test/tsconfig.json @@ -6,7 +6,6 @@ "rootDirs": ["./", "../src/"], "outDir": "../build/test", "esModuleInterop": true, - "moduleResolution": "node16", "allowSyntheticDefaultImports": true, "baseUrl": ".", "paths": { diff --git a/developer/src/kmc-model/test/tsconfig.json b/developer/src/kmc-model/test/tsconfig.json index 3902bed57f..0917ea186a 100644 --- a/developer/src/kmc-model/test/tsconfig.json +++ b/developer/src/kmc-model/test/tsconfig.json @@ -6,7 +6,6 @@ "rootDirs": ["./", "../src/"], "outDir": "../build/test", "esModuleInterop": true, - "moduleResolution": "node16", "allowSyntheticDefaultImports": true, "baseUrl": ".", "paths": { diff --git a/developer/src/kmc/tsconfig.kmc-base.json b/developer/src/kmc/tsconfig.kmc-base.json index f8cff50b3f..6956b6e05d 100644 --- a/developer/src/kmc/tsconfig.kmc-base.json +++ b/developer/src/kmc/tsconfig.kmc-base.json @@ -1,3 +1,3 @@ { - "extends": "../../../tsconfig.esm-base.json", + "extends": "../../../tsconfig.base.json", } diff --git a/developer/src/server/tsconfig.json b/developer/src/server/tsconfig.json index 701a97af6c..e5adde9578 100644 --- a/developer/src/server/tsconfig.json +++ b/developer/src/server/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.esm-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "target": "es2022", diff --git a/resources/build/version/tsconfig.json b/resources/build/version/tsconfig.json index 9f537c799d..2d99762ca9 100644 --- a/resources/build/version/tsconfig.json +++ b/resources/build/version/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.esm-base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "rootDir": ".", "outDir": "build/", diff --git a/tsconfig-base.json b/tsconfig.base.json similarity index 65% rename from tsconfig-base.json rename to tsconfig.base.json index 8e3eafb6cf..2c56fd7079 100644 --- a/tsconfig-base.json +++ b/tsconfig.base.json @@ -1,5 +1,18 @@ { "compilerOptions": { + "module": "ES2022", + "target": "es2022", + "moduleResolution": "node16", + "forceConsistentCasingInFileNames": true, + "sourceMap": true, + "alwaysStrict": true, + "noImplicitThis": true, + "noImplicitReturns": true, + "noImplicitAny": true, + "strictBindCallApply": true, + "strictFunctionTypes": true, + "noUnusedLocals": true, + "rootDir": ".", // TODO: move all compiler options here @@ -9,7 +22,9 @@ "declarationMap": true, "baseUrl": ".", + "paths": { + "@keymanapp/common-types": ["./common/web/types/src/main"], "@keymanapp/input-processor": ["./common/web/input-processor/src"], "@keymanapp/keyboard-processor": ["./common/web/keyboard-processor/src"], "@keymanapp/keyman": ["./web" ], diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json deleted file mode 100644 index 701d06ce3b..0000000000 --- a/tsconfig.cjs.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - // Lists only CommonJS or 'none' modules; as we move modules from cjs/none to - // esm, we should move them from here into tsconfig.esm.json. Eventually, when - // we have only ES modules, we'll delete this file. - "files": [], - "include": [], - "references": [ - { "path": "./common/predictive-text/testing/one-stage-embedded-webworker/tsconfig.json" }, - { "path": "./common/predictive-text/testing/two-stage-embedded-webworker/tsconfig.json" }, - { "path": "./common/predictive-text/testing/two-stage-embedded-webworker/worker/tsconfig.json" }, - ] -} \ No newline at end of file diff --git a/tsconfig.esm-base.json b/tsconfig.esm-base.json deleted file mode 100644 index d17d505e5c..0000000000 --- a/tsconfig.esm-base.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "extends": "./tsconfig-base.json", - - "compilerOptions": { - "module": "ES2022", - "target": "es2022", - "moduleResolution": "Node16", - "forceConsistentCasingInFileNames": true, - "sourceMap": true, - "alwaysStrict": true, - "noImplicitThis": true, - "noImplicitReturns": true, - "noImplicitAny": true, - "strictBindCallApply": true, - "strictFunctionTypes": true, - "noUnusedLocals": true, - - "paths": { - "@keymanapp/keyman-version": ["./common/web/keyman-version/keyman-version.mts"], - "@keymanapp/common-types": ["./common/web/types/src/main"], - // "@keymanapp/": ["core/include/ldml/ldml-keyboard-constants"], - }, - }, -} diff --git a/tsconfig.esm.json b/tsconfig.json similarity index 87% rename from tsconfig.esm.json rename to tsconfig.json index 0252447c63..497bcf7344 100644 --- a/tsconfig.esm.json +++ b/tsconfig.json @@ -1,19 +1,28 @@ { - // Lists only ES modules; as we move modules from cjs/none to esm, we should - // move them from tsconfig.cjs.json to here. Eventually, when we have only ES - // modules, we can rename this to tsconfig.json. - "files": [], - "include": [], "references": [ { "path": "./core/include/ldml/tsconfig.json" }, - //{ "path": "./developer/src/kmc/test/tsconfig.json" }, + { "path": "./common/models/templates/tsconfig.json" }, + { "path": "./common/models/types/tsconfig.json" }, + { "path": "./common/models/wordbreakers/tsconfig.json" }, + { "path": "./common/predictive-text/tsconfig.json" }, + { "path": "./common/tools/hextobin/" }, + { "path": "./common/web/input-processor/tsconfig.json" }, + { "path": "./common/web/keyboard-processor/tsconfig.json" }, + { "path": "./common/web/keyman-version" }, + { "path": "./common/web/lm-message-types/" }, + { "path": "./common/web/lm-worker/" }, + { "path": "./common/web/recorder/tsconfig.json" }, + { "path": "./common/web/sentry-manager/src/tsconfig.json" }, + { "path": "./common/web/types/" }, + { "path": "./common/web/utils/tsconfig.json" }, + { "path": "./developer/src/common/web/test-helpers/tsconfig.json" }, { "path": "./developer/src/kmc/tsconfig.json" }, - - // { "path": "./developer/src/kmc-analyze/test/tsconfig.json" }, + { "path": "./developer/src/kmc/test/tsconfig.json" }, { "path": "./developer/src/kmc-analyze/tsconfig.json" }, + // { "path": "./developer/src/kmc-analyze/test/tsconfig.json" }, { "path": "./developer/src/kmc-kmn/test/tsconfig.json" }, { "path": "./developer/src/kmc-kmn/tsconfig.json" }, { "path": "./developer/src/kmc-keyboard-info/test/tsconfig.json" }, @@ -28,27 +37,10 @@ { "path": "./developer/src/kmc-package/tsconfig.json" }, { "path": "./developer/src/server/tsconfig.json" }, - { "path": "./common/web/keyman-version" }, - { "path": "./common/web/types/" }, - - { "path": "./common/web/input-processor/tsconfig.json" }, - { "path": "./common/web/keyboard-processor/tsconfig.json" }, - { "path": "./common/web/recorder/tsconfig.json" }, - { "path": "./common/web/sentry-manager/src/tsconfig.json" }, - { "path": "./common/web/utils/tsconfig.json" }, - - { "path": "./common/models/templates/tsconfig.json" }, - { "path": "./common/models/types/tsconfig.json" }, - { "path": "./common/models/wordbreakers/tsconfig.json" }, - { "path": "./common/predictive-text/tsconfig.json" }, + { "path": "./resources/build/version/" }, { "path": "./web/src/tsconfig.all.json" }, // { "path": "./web/tools/recorder/tsconfig.json" }, // { "path": "./web/tools/sourcemap-root/tsconfig.json" }, - { "path": "./common/web/lm-message-types/" }, - { "path": "./common/web/lm-worker/" }, - { "path": "./common/tools/hextobin/" }, - - { "path": "./resources/build/version/" }, ] } \ No newline at end of file diff --git a/web/tsconfig.base.json b/web/tsconfig.base.json index a2b78b7b15..fa60ca26e6 100644 --- a/web/tsconfig.base.json +++ b/web/tsconfig.base.json @@ -1,5 +1,5 @@ { - "extends": "../tsconfig-base.json", + "extends": "../tsconfig.base.json", "compilerOptions": { // Primary settings - the version of ES6 we can target in TS, our downcompile target, @@ -7,7 +7,6 @@ "allowSyntheticDefaultImports": true, "lib": ["es6"], "module": "es6", - "moduleResolution": "Node16", "target": "es5", // Other settings - declaration files, sourcemapping, and other miscellaneous bits. From 75a0977cdbbfd55fcfd3cd6dff4b5f604dc20270 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 14:17:59 +0700 Subject: [PATCH 068/107] chore(developer): fix server tests --- developer/src/server/build.sh | 10 +++++++++- developer/src/server/package.json | 4 ++-- developer/src/server/test/tsconfig.json | 16 ++++++++++++++++ .../server/{src => test}/version-data.test.ts | 4 +--- package-lock.json | 9 +++++---- 5 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 developer/src/server/test/tsconfig.json rename developer/src/server/{src => test}/version-data.test.ts (97%) diff --git a/developer/src/server/build.sh b/developer/src/server/build.sh index 44cdbe1ca7..7e47d4f663 100755 --- a/developer/src/server/build.sh +++ b/developer/src/server/build.sh @@ -125,11 +125,19 @@ function installer_server() { cp -R "$PRODBUILDTEMP"/* "$KEYMAN_ROOT/developer/bin/server/" rm -rf "$PRODBUILDTEMP" } + +function test_server() { + # eslint . + tsc --build test + # c8 --reporter=lcov --reporter=text + mocha +} + builder_run_action clean:server clean_server builder_run_action configure:server configure_server builder_run_action build:server build_server builder_run_action build:addins build_addins -builder_run_action test:server mocha +builder_run_action test:server test_server # builder_run_action test:addins # no op builder_run_action installer:server installer_server diff --git a/developer/src/server/package.json b/developer/src/server/package.json index 6d23e11bfb..fbba345439 100644 --- a/developer/src/server/package.json +++ b/developer/src/server/package.json @@ -28,7 +28,7 @@ "@types/express": "^4.17.13", "@types/mocha": "^9.1.0", "@types/multer": "^1.4.7", - "@types/node": "^17.0.0", + "@types/node": "^20.4.1", "@types/ws": "^8.2.2", "chai": "^4.3.4", "copyfiles": "^2.4.1", @@ -39,6 +39,6 @@ }, "mocha": { "require": "ts-node/register", - "spec": "**/*.test.ts" + "spec": "build/**/*.test.js" } } diff --git a/developer/src/server/test/tsconfig.json b/developer/src/server/test/tsconfig.json new file mode 100644 index 0000000000..e25eb9fb3f --- /dev/null +++ b/developer/src/server/test/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../../tsconfig.esm-base.json", + + "compilerOptions": { + "rootDir": ".", + "rootDirs": ["./", "../src/"], + "outDir": "../build/test", + "baseUrl": ".", + }, + "include": [ + "**/*.test.ts" + ], + "references": [ + { "path": "../" }, + ] +} \ No newline at end of file diff --git a/developer/src/server/src/version-data.test.ts b/developer/src/server/test/version-data.test.ts similarity index 97% rename from developer/src/server/src/version-data.test.ts rename to developer/src/server/test/version-data.test.ts index 9f7ebd385f..74762b7d7f 100644 --- a/developer/src/server/src/version-data.test.ts +++ b/developer/src/server/test/version-data.test.ts @@ -1,8 +1,6 @@ import {assert} from 'chai'; import 'mocha'; - -import { extractVersionData } from './version-data.js'; - +import { extractVersionData } from '../src/version-data.js'; describe('extractVersionData', function() { it('should parse version strings', function() { diff --git a/package-lock.json b/package-lock.json index 405d2154cf..75cab78dd2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2654,7 +2654,7 @@ "@types/express": "^4.17.13", "@types/mocha": "^9.1.0", "@types/multer": "^1.4.7", - "@types/node": "^17.0.0", + "@types/node": "^20.4.1", "@types/ws": "^8.2.2", "chai": "^4.3.4", "copyfiles": "^2.4.1", @@ -2674,9 +2674,10 @@ "license": "MIT" }, "developer/src/server/node_modules/@types/node": { - "version": "17.0.45", - "dev": true, - "license": "MIT" + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", + "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==", + "dev": true }, "developer/src/server/node_modules/busboy": { "version": "1.6.0", From 39699f75d5db883673176d70b89664a600182713 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 14:24:17 +0700 Subject: [PATCH 069/107] chore(common): restore es5 target for keyman-version --- common/web/keyman-version/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/common/web/keyman-version/tsconfig.json b/common/web/keyman-version/tsconfig.json index 03478f6021..9f4f718745 100644 --- a/common/web/keyman-version/tsconfig.json +++ b/common/web/keyman-version/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./build", + "target": "es5", "rootDir": "." }, From 27dfef024d11f076c4cb3bce72fe0e227fcac57f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 14:41:31 +0700 Subject: [PATCH 070/107] chore(common): restore (unused) test target for keyman-version --- common/web/keyman-version/build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/web/keyman-version/build.sh b/common/web/keyman-version/build.sh index 28dd297211..d4a07e4c76 100755 --- a/common/web/keyman-version/build.sh +++ b/common/web/keyman-version/build.sh @@ -18,7 +18,8 @@ builder_describe "Build the include script for current Keyman version" \ clean \ build \ "pack build a local .tgz pack for testing" \ - "publish publish to npm" + "publish publish to npm" \ + test builder_describe_outputs \ configure "/node_modules" \ From 33b6b5abc26444d278d00405b1efb58dc0655ef0 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 15:16:34 +0700 Subject: [PATCH 071/107] chore: update tsconfig --- developer/src/server/test/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/src/server/test/tsconfig.json b/developer/src/server/test/tsconfig.json index e25eb9fb3f..fa377b0fde 100644 --- a/developer/src/server/test/tsconfig.json +++ b/developer/src/server/test/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../../tsconfig.esm-base.json", + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "rootDir": ".", From f832b9ff3d7c5852f0076e30953745950e223b2f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 15:25:01 +0700 Subject: [PATCH 072/107] chore(developer): remove temp non-esm module in kmc-model --- .../sourcemap-path-remapper/tsconfig.json | 1 - .../kmc-model/test/test-join-word-breaker.ts | 2 +- .../test/test-override-script-defaults.ts | 2 +- .../src/kmc-model/test/wordbreakers/README.md | 3 - .../src/kmc-model/test/wordbreakers/data.ts | 1776 ----------------- .../wordbreakers/default-wordbreaker-esm.ts | 383 ---- 6 files changed, 2 insertions(+), 2165 deletions(-) delete mode 100644 developer/src/kmc-model/test/wordbreakers/README.md delete mode 100644 developer/src/kmc-model/test/wordbreakers/data.ts delete mode 100644 developer/src/kmc-model/test/wordbreakers/default-wordbreaker-esm.ts diff --git a/common/tools/sourcemap-path-remapper/tsconfig.json b/common/tools/sourcemap-path-remapper/tsconfig.json index 72809897bd..6bf1a23b8d 100644 --- a/common/tools/sourcemap-path-remapper/tsconfig.json +++ b/common/tools/sourcemap-path-remapper/tsconfig.json @@ -5,7 +5,6 @@ "allowJs": false, "allowSyntheticDefaultImports": true, "declaration": true, - "module": "es6", "inlineSourceMap": true, "inlineSources": true, "sourceRoot": "/common/tools/sourcemap-path-remapper/src", diff --git a/developer/src/kmc-model/test/test-join-word-breaker.ts b/developer/src/kmc-model/test/test-join-word-breaker.ts index d06bc7a6ef..b08411cb56 100644 --- a/developer/src/kmc-model/test/test-join-word-breaker.ts +++ b/developer/src/kmc-model/test/test-join-word-breaker.ts @@ -1,5 +1,5 @@ import { assert } from "chai"; -import defaultWordBreaker from './wordbreakers/default-wordbreaker-esm.js'; +import defaultWordBreaker from '@keymanapp/models-wordbreakers'; import {decorateWithJoin} from '../src/join-word-breaker-decorator.js'; describe('The join word breaker decorator', function () { diff --git a/developer/src/kmc-model/test/test-override-script-defaults.ts b/developer/src/kmc-model/test/test-override-script-defaults.ts index 909f52c298..a0500320fd 100644 --- a/developer/src/kmc-model/test/test-override-script-defaults.ts +++ b/developer/src/kmc-model/test/test-override-script-defaults.ts @@ -1,5 +1,5 @@ import { assert } from "chai"; -import defaultWordBreaker from './wordbreakers/default-wordbreaker-esm.js'; +import defaultWordBreaker from '@keymanapp/models-wordbreakers'; import {decorateWithScriptOverrides} from '../src/script-overrides-decorator.js'; const THIN_SPACE = "\u2009"; diff --git a/developer/src/kmc-model/test/wordbreakers/README.md b/developer/src/kmc-model/test/wordbreakers/README.md deleted file mode 100644 index d204b51c6a..0000000000 --- a/developer/src/kmc-model/test/wordbreakers/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Wordbreakers ES Module format - -TODO: once we move common/models/wordbreakers to ESM, eliminate this. diff --git a/developer/src/kmc-model/test/wordbreakers/data.ts b/developer/src/kmc-model/test/wordbreakers/data.ts deleted file mode 100644 index 5622bf5c03..0000000000 --- a/developer/src/kmc-model/test/wordbreakers/data.ts +++ /dev/null @@ -1,1776 +0,0 @@ -// TEMP: esm version of /common/models/wordbreakers/default/data.ts -// Hand updated version of automatically generated file. -/** - * Valid values for a word break property. - */ -export enum WordBreakProperty { - Other, - LF, - Newline, - CR, - WSegSpace, - Double_Quote, - Single_Quote, - MidNum, - MidNumLet, - Numeric, - MidLetter, - ALetter, - ExtendNumLet, - Format, - Extend, - Hebrew_Letter, - ZWJ, - Katakana, - Regional_Indicator, - sot, - eot -}; - -/** - * Constants for indexing values in WORD_BREAK_PROPERTY. - */ -export enum I { - Start = 0, - Value = 1 -} - -export const WORD_BREAK_PROPERTY: [number, WordBreakProperty][] = [ - [/*start*/ 0x0, WordBreakProperty.Other], - [/*start*/ 0xA, WordBreakProperty.LF], - [/*start*/ 0xB, WordBreakProperty.Newline], - [/*start*/ 0xD, WordBreakProperty.CR], - [/*start*/ 0xE, WordBreakProperty.Other], - [/*start*/ 0x20, WordBreakProperty.WSegSpace], - [/*start*/ 0x21, WordBreakProperty.Other], - [/*start*/ 0x22, WordBreakProperty.Double_Quote], - [/*start*/ 0x23, WordBreakProperty.Other], - [/*start*/ 0x27, WordBreakProperty.Single_Quote], - [/*start*/ 0x28, WordBreakProperty.Other], - [/*start*/ 0x2C, WordBreakProperty.MidNum], - [/*start*/ 0x2D, WordBreakProperty.Other], - [/*start*/ 0x2E, WordBreakProperty.MidNumLet], - [/*start*/ 0x2F, WordBreakProperty.Other], - [/*start*/ 0x30, WordBreakProperty.Numeric], - [/*start*/ 0x3A, WordBreakProperty.MidLetter], - [/*start*/ 0x3B, WordBreakProperty.MidNum], - [/*start*/ 0x3C, WordBreakProperty.Other], - [/*start*/ 0x41, WordBreakProperty.ALetter], - [/*start*/ 0x5B, WordBreakProperty.Other], - [/*start*/ 0x5F, WordBreakProperty.ExtendNumLet], - [/*start*/ 0x60, WordBreakProperty.Other], - [/*start*/ 0x61, WordBreakProperty.ALetter], - [/*start*/ 0x7B, WordBreakProperty.Other], - [/*start*/ 0x85, WordBreakProperty.Newline], - [/*start*/ 0x86, WordBreakProperty.Other], - [/*start*/ 0xAA, WordBreakProperty.ALetter], - [/*start*/ 0xAB, WordBreakProperty.Other], - [/*start*/ 0xAD, WordBreakProperty.Format], - [/*start*/ 0xAE, WordBreakProperty.Other], - [/*start*/ 0xB5, WordBreakProperty.ALetter], - [/*start*/ 0xB6, WordBreakProperty.Other], - [/*start*/ 0xB7, WordBreakProperty.MidLetter], - [/*start*/ 0xB8, WordBreakProperty.Other], - [/*start*/ 0xBA, WordBreakProperty.ALetter], - [/*start*/ 0xBB, WordBreakProperty.Other], - [/*start*/ 0xC0, WordBreakProperty.ALetter], - [/*start*/ 0xD7, WordBreakProperty.Other], - [/*start*/ 0xD8, WordBreakProperty.ALetter], - [/*start*/ 0xF7, WordBreakProperty.Other], - [/*start*/ 0xF8, WordBreakProperty.ALetter], - [/*start*/ 0x2D8, WordBreakProperty.Other], - [/*start*/ 0x2DE, WordBreakProperty.ALetter], - [/*start*/ 0x300, WordBreakProperty.Extend], - [/*start*/ 0x370, WordBreakProperty.ALetter], - [/*start*/ 0x375, WordBreakProperty.Other], - [/*start*/ 0x376, WordBreakProperty.ALetter], - [/*start*/ 0x378, WordBreakProperty.Other], - [/*start*/ 0x37A, WordBreakProperty.ALetter], - [/*start*/ 0x37E, WordBreakProperty.MidNum], - [/*start*/ 0x37F, WordBreakProperty.ALetter], - [/*start*/ 0x380, WordBreakProperty.Other], - [/*start*/ 0x386, WordBreakProperty.ALetter], - [/*start*/ 0x387, WordBreakProperty.MidLetter], - [/*start*/ 0x388, WordBreakProperty.ALetter], - [/*start*/ 0x38B, WordBreakProperty.Other], - [/*start*/ 0x38C, WordBreakProperty.ALetter], - [/*start*/ 0x38D, WordBreakProperty.Other], - [/*start*/ 0x38E, WordBreakProperty.ALetter], - [/*start*/ 0x3A2, WordBreakProperty.Other], - [/*start*/ 0x3A3, WordBreakProperty.ALetter], - [/*start*/ 0x3F6, WordBreakProperty.Other], - [/*start*/ 0x3F7, WordBreakProperty.ALetter], - [/*start*/ 0x482, WordBreakProperty.Other], - [/*start*/ 0x483, WordBreakProperty.Extend], - [/*start*/ 0x48A, WordBreakProperty.ALetter], - [/*start*/ 0x530, WordBreakProperty.Other], - [/*start*/ 0x531, WordBreakProperty.ALetter], - [/*start*/ 0x557, WordBreakProperty.Other], - [/*start*/ 0x559, WordBreakProperty.ALetter], - [/*start*/ 0x55D, WordBreakProperty.Other], - [/*start*/ 0x55E, WordBreakProperty.ALetter], - [/*start*/ 0x55F, WordBreakProperty.MidLetter], - [/*start*/ 0x560, WordBreakProperty.ALetter], - [/*start*/ 0x589, WordBreakProperty.MidNum], - [/*start*/ 0x58A, WordBreakProperty.ALetter], - [/*start*/ 0x58B, WordBreakProperty.Other], - [/*start*/ 0x591, WordBreakProperty.Extend], - [/*start*/ 0x5BE, WordBreakProperty.Other], - [/*start*/ 0x5BF, WordBreakProperty.Extend], - [/*start*/ 0x5C0, WordBreakProperty.Other], - [/*start*/ 0x5C1, WordBreakProperty.Extend], - [/*start*/ 0x5C3, WordBreakProperty.Other], - [/*start*/ 0x5C4, WordBreakProperty.Extend], - [/*start*/ 0x5C6, WordBreakProperty.Other], - [/*start*/ 0x5C7, WordBreakProperty.Extend], - [/*start*/ 0x5C8, WordBreakProperty.Other], - [/*start*/ 0x5D0, WordBreakProperty.Hebrew_Letter], - [/*start*/ 0x5EB, WordBreakProperty.Other], - [/*start*/ 0x5EF, WordBreakProperty.Hebrew_Letter], - [/*start*/ 0x5F3, WordBreakProperty.ALetter], - [/*start*/ 0x5F4, WordBreakProperty.MidLetter], - [/*start*/ 0x5F5, WordBreakProperty.Other], - [/*start*/ 0x600, WordBreakProperty.Format], - [/*start*/ 0x606, WordBreakProperty.Other], - [/*start*/ 0x60C, WordBreakProperty.MidNum], - [/*start*/ 0x60E, WordBreakProperty.Other], - [/*start*/ 0x610, WordBreakProperty.Extend], - [/*start*/ 0x61B, WordBreakProperty.Other], - [/*start*/ 0x61C, WordBreakProperty.Format], - [/*start*/ 0x61D, WordBreakProperty.Other], - [/*start*/ 0x620, WordBreakProperty.ALetter], - [/*start*/ 0x64B, WordBreakProperty.Extend], - [/*start*/ 0x660, WordBreakProperty.Numeric], - [/*start*/ 0x66A, WordBreakProperty.Other], - [/*start*/ 0x66B, WordBreakProperty.Numeric], - [/*start*/ 0x66C, WordBreakProperty.MidNum], - [/*start*/ 0x66D, WordBreakProperty.Other], - [/*start*/ 0x66E, WordBreakProperty.ALetter], - [/*start*/ 0x670, WordBreakProperty.Extend], - [/*start*/ 0x671, WordBreakProperty.ALetter], - [/*start*/ 0x6D4, WordBreakProperty.Other], - [/*start*/ 0x6D5, WordBreakProperty.ALetter], - [/*start*/ 0x6D6, WordBreakProperty.Extend], - [/*start*/ 0x6DD, WordBreakProperty.Format], - [/*start*/ 0x6DE, WordBreakProperty.Other], - [/*start*/ 0x6DF, WordBreakProperty.Extend], - [/*start*/ 0x6E5, WordBreakProperty.ALetter], - [/*start*/ 0x6E7, WordBreakProperty.Extend], - [/*start*/ 0x6E9, WordBreakProperty.Other], - [/*start*/ 0x6EA, WordBreakProperty.Extend], - [/*start*/ 0x6EE, WordBreakProperty.ALetter], - [/*start*/ 0x6F0, WordBreakProperty.Numeric], - [/*start*/ 0x6FA, WordBreakProperty.ALetter], - [/*start*/ 0x6FD, WordBreakProperty.Other], - [/*start*/ 0x6FF, WordBreakProperty.ALetter], - [/*start*/ 0x700, WordBreakProperty.Other], - [/*start*/ 0x70F, WordBreakProperty.Format], - [/*start*/ 0x710, WordBreakProperty.ALetter], - [/*start*/ 0x711, WordBreakProperty.Extend], - [/*start*/ 0x712, WordBreakProperty.ALetter], - [/*start*/ 0x730, WordBreakProperty.Extend], - [/*start*/ 0x74B, WordBreakProperty.Other], - [/*start*/ 0x74D, WordBreakProperty.ALetter], - [/*start*/ 0x7A6, WordBreakProperty.Extend], - [/*start*/ 0x7B1, WordBreakProperty.ALetter], - [/*start*/ 0x7B2, WordBreakProperty.Other], - [/*start*/ 0x7C0, WordBreakProperty.Numeric], - [/*start*/ 0x7CA, WordBreakProperty.ALetter], - [/*start*/ 0x7EB, WordBreakProperty.Extend], - [/*start*/ 0x7F4, WordBreakProperty.ALetter], - [/*start*/ 0x7F6, WordBreakProperty.Other], - [/*start*/ 0x7F8, WordBreakProperty.MidNum], - [/*start*/ 0x7F9, WordBreakProperty.Other], - [/*start*/ 0x7FA, WordBreakProperty.ALetter], - [/*start*/ 0x7FB, WordBreakProperty.Other], - [/*start*/ 0x7FD, WordBreakProperty.Extend], - [/*start*/ 0x7FE, WordBreakProperty.Other], - [/*start*/ 0x800, WordBreakProperty.ALetter], - [/*start*/ 0x816, WordBreakProperty.Extend], - [/*start*/ 0x81A, WordBreakProperty.ALetter], - [/*start*/ 0x81B, WordBreakProperty.Extend], - [/*start*/ 0x824, WordBreakProperty.ALetter], - [/*start*/ 0x825, WordBreakProperty.Extend], - [/*start*/ 0x828, WordBreakProperty.ALetter], - [/*start*/ 0x829, WordBreakProperty.Extend], - [/*start*/ 0x82E, WordBreakProperty.Other], - [/*start*/ 0x840, WordBreakProperty.ALetter], - [/*start*/ 0x859, WordBreakProperty.Extend], - [/*start*/ 0x85C, WordBreakProperty.Other], - [/*start*/ 0x860, WordBreakProperty.ALetter], - [/*start*/ 0x86B, WordBreakProperty.Other], - [/*start*/ 0x8A0, WordBreakProperty.ALetter], - [/*start*/ 0x8B5, WordBreakProperty.Other], - [/*start*/ 0x8B6, WordBreakProperty.ALetter], - [/*start*/ 0x8C8, WordBreakProperty.Other], - [/*start*/ 0x8D3, WordBreakProperty.Extend], - [/*start*/ 0x8E2, WordBreakProperty.Format], - [/*start*/ 0x8E3, WordBreakProperty.Extend], - [/*start*/ 0x904, WordBreakProperty.ALetter], - [/*start*/ 0x93A, WordBreakProperty.Extend], - [/*start*/ 0x93D, WordBreakProperty.ALetter], - [/*start*/ 0x93E, WordBreakProperty.Extend], - [/*start*/ 0x950, WordBreakProperty.ALetter], - [/*start*/ 0x951, WordBreakProperty.Extend], - [/*start*/ 0x958, WordBreakProperty.ALetter], - [/*start*/ 0x962, WordBreakProperty.Extend], - [/*start*/ 0x964, WordBreakProperty.Other], - [/*start*/ 0x966, WordBreakProperty.Numeric], - [/*start*/ 0x970, WordBreakProperty.Other], - [/*start*/ 0x971, WordBreakProperty.ALetter], - [/*start*/ 0x981, WordBreakProperty.Extend], - [/*start*/ 0x984, WordBreakProperty.Other], - [/*start*/ 0x985, WordBreakProperty.ALetter], - [/*start*/ 0x98D, WordBreakProperty.Other], - [/*start*/ 0x98F, WordBreakProperty.ALetter], - [/*start*/ 0x991, WordBreakProperty.Other], - [/*start*/ 0x993, WordBreakProperty.ALetter], - [/*start*/ 0x9A9, WordBreakProperty.Other], - [/*start*/ 0x9AA, WordBreakProperty.ALetter], - [/*start*/ 0x9B1, WordBreakProperty.Other], - [/*start*/ 0x9B2, WordBreakProperty.ALetter], - [/*start*/ 0x9B3, WordBreakProperty.Other], - [/*start*/ 0x9B6, WordBreakProperty.ALetter], - [/*start*/ 0x9BA, WordBreakProperty.Other], - [/*start*/ 0x9BC, WordBreakProperty.Extend], - [/*start*/ 0x9BD, WordBreakProperty.ALetter], - [/*start*/ 0x9BE, WordBreakProperty.Extend], - [/*start*/ 0x9C5, WordBreakProperty.Other], - [/*start*/ 0x9C7, WordBreakProperty.Extend], - [/*start*/ 0x9C9, WordBreakProperty.Other], - [/*start*/ 0x9CB, WordBreakProperty.Extend], - [/*start*/ 0x9CE, WordBreakProperty.ALetter], - [/*start*/ 0x9CF, WordBreakProperty.Other], - [/*start*/ 0x9D7, WordBreakProperty.Extend], - [/*start*/ 0x9D8, WordBreakProperty.Other], - [/*start*/ 0x9DC, WordBreakProperty.ALetter], - [/*start*/ 0x9DE, WordBreakProperty.Other], - [/*start*/ 0x9DF, WordBreakProperty.ALetter], - [/*start*/ 0x9E2, WordBreakProperty.Extend], - [/*start*/ 0x9E4, WordBreakProperty.Other], - [/*start*/ 0x9E6, WordBreakProperty.Numeric], - [/*start*/ 0x9F0, WordBreakProperty.ALetter], - [/*start*/ 0x9F2, WordBreakProperty.Other], - [/*start*/ 0x9FC, WordBreakProperty.ALetter], - [/*start*/ 0x9FD, WordBreakProperty.Other], - [/*start*/ 0x9FE, WordBreakProperty.Extend], - [/*start*/ 0x9FF, WordBreakProperty.Other], - [/*start*/ 0xA01, WordBreakProperty.Extend], - [/*start*/ 0xA04, WordBreakProperty.Other], - [/*start*/ 0xA05, WordBreakProperty.ALetter], - [/*start*/ 0xA0B, WordBreakProperty.Other], - [/*start*/ 0xA0F, WordBreakProperty.ALetter], - [/*start*/ 0xA11, WordBreakProperty.Other], - [/*start*/ 0xA13, WordBreakProperty.ALetter], - [/*start*/ 0xA29, WordBreakProperty.Other], - [/*start*/ 0xA2A, WordBreakProperty.ALetter], - [/*start*/ 0xA31, WordBreakProperty.Other], - [/*start*/ 0xA32, WordBreakProperty.ALetter], - [/*start*/ 0xA34, WordBreakProperty.Other], - [/*start*/ 0xA35, WordBreakProperty.ALetter], - [/*start*/ 0xA37, WordBreakProperty.Other], - [/*start*/ 0xA38, WordBreakProperty.ALetter], - [/*start*/ 0xA3A, WordBreakProperty.Other], - [/*start*/ 0xA3C, WordBreakProperty.Extend], - [/*start*/ 0xA3D, WordBreakProperty.Other], - [/*start*/ 0xA3E, WordBreakProperty.Extend], - [/*start*/ 0xA43, WordBreakProperty.Other], - [/*start*/ 0xA47, WordBreakProperty.Extend], - [/*start*/ 0xA49, WordBreakProperty.Other], - [/*start*/ 0xA4B, WordBreakProperty.Extend], - [/*start*/ 0xA4E, WordBreakProperty.Other], - [/*start*/ 0xA51, WordBreakProperty.Extend], - [/*start*/ 0xA52, WordBreakProperty.Other], - [/*start*/ 0xA59, WordBreakProperty.ALetter], - [/*start*/ 0xA5D, WordBreakProperty.Other], - [/*start*/ 0xA5E, WordBreakProperty.ALetter], - [/*start*/ 0xA5F, WordBreakProperty.Other], - [/*start*/ 0xA66, WordBreakProperty.Numeric], - [/*start*/ 0xA70, WordBreakProperty.Extend], - [/*start*/ 0xA72, WordBreakProperty.ALetter], - [/*start*/ 0xA75, WordBreakProperty.Extend], - [/*start*/ 0xA76, WordBreakProperty.Other], - [/*start*/ 0xA81, WordBreakProperty.Extend], - [/*start*/ 0xA84, WordBreakProperty.Other], - [/*start*/ 0xA85, WordBreakProperty.ALetter], - [/*start*/ 0xA8E, WordBreakProperty.Other], - [/*start*/ 0xA8F, WordBreakProperty.ALetter], - [/*start*/ 0xA92, WordBreakProperty.Other], - [/*start*/ 0xA93, WordBreakProperty.ALetter], - [/*start*/ 0xAA9, WordBreakProperty.Other], - [/*start*/ 0xAAA, WordBreakProperty.ALetter], - [/*start*/ 0xAB1, WordBreakProperty.Other], - [/*start*/ 0xAB2, WordBreakProperty.ALetter], - [/*start*/ 0xAB4, WordBreakProperty.Other], - [/*start*/ 0xAB5, WordBreakProperty.ALetter], - [/*start*/ 0xABA, WordBreakProperty.Other], - [/*start*/ 0xABC, WordBreakProperty.Extend], - [/*start*/ 0xABD, WordBreakProperty.ALetter], - [/*start*/ 0xABE, WordBreakProperty.Extend], - [/*start*/ 0xAC6, WordBreakProperty.Other], - [/*start*/ 0xAC7, WordBreakProperty.Extend], - [/*start*/ 0xACA, WordBreakProperty.Other], - [/*start*/ 0xACB, WordBreakProperty.Extend], - [/*start*/ 0xACE, WordBreakProperty.Other], - [/*start*/ 0xAD0, WordBreakProperty.ALetter], - [/*start*/ 0xAD1, WordBreakProperty.Other], - [/*start*/ 0xAE0, WordBreakProperty.ALetter], - [/*start*/ 0xAE2, WordBreakProperty.Extend], - [/*start*/ 0xAE4, WordBreakProperty.Other], - [/*start*/ 0xAE6, WordBreakProperty.Numeric], - [/*start*/ 0xAF0, WordBreakProperty.Other], - [/*start*/ 0xAF9, WordBreakProperty.ALetter], - [/*start*/ 0xAFA, WordBreakProperty.Extend], - [/*start*/ 0xB00, WordBreakProperty.Other], - [/*start*/ 0xB01, WordBreakProperty.Extend], - [/*start*/ 0xB04, WordBreakProperty.Other], - [/*start*/ 0xB05, WordBreakProperty.ALetter], - [/*start*/ 0xB0D, WordBreakProperty.Other], - [/*start*/ 0xB0F, WordBreakProperty.ALetter], - [/*start*/ 0xB11, WordBreakProperty.Other], - [/*start*/ 0xB13, WordBreakProperty.ALetter], - [/*start*/ 0xB29, WordBreakProperty.Other], - [/*start*/ 0xB2A, WordBreakProperty.ALetter], - [/*start*/ 0xB31, WordBreakProperty.Other], - [/*start*/ 0xB32, WordBreakProperty.ALetter], - [/*start*/ 0xB34, WordBreakProperty.Other], - [/*start*/ 0xB35, WordBreakProperty.ALetter], - [/*start*/ 0xB3A, WordBreakProperty.Other], - [/*start*/ 0xB3C, WordBreakProperty.Extend], - [/*start*/ 0xB3D, WordBreakProperty.ALetter], - [/*start*/ 0xB3E, WordBreakProperty.Extend], - [/*start*/ 0xB45, WordBreakProperty.Other], - [/*start*/ 0xB47, WordBreakProperty.Extend], - [/*start*/ 0xB49, WordBreakProperty.Other], - [/*start*/ 0xB4B, WordBreakProperty.Extend], - [/*start*/ 0xB4E, WordBreakProperty.Other], - [/*start*/ 0xB55, WordBreakProperty.Extend], - [/*start*/ 0xB58, WordBreakProperty.Other], - [/*start*/ 0xB5C, WordBreakProperty.ALetter], - [/*start*/ 0xB5E, WordBreakProperty.Other], - [/*start*/ 0xB5F, WordBreakProperty.ALetter], - [/*start*/ 0xB62, WordBreakProperty.Extend], - [/*start*/ 0xB64, WordBreakProperty.Other], - [/*start*/ 0xB66, WordBreakProperty.Numeric], - [/*start*/ 0xB70, WordBreakProperty.Other], - [/*start*/ 0xB71, WordBreakProperty.ALetter], - [/*start*/ 0xB72, WordBreakProperty.Other], - [/*start*/ 0xB82, WordBreakProperty.Extend], - [/*start*/ 0xB83, WordBreakProperty.ALetter], - [/*start*/ 0xB84, WordBreakProperty.Other], - [/*start*/ 0xB85, WordBreakProperty.ALetter], - [/*start*/ 0xB8B, WordBreakProperty.Other], - [/*start*/ 0xB8E, WordBreakProperty.ALetter], - [/*start*/ 0xB91, WordBreakProperty.Other], - [/*start*/ 0xB92, WordBreakProperty.ALetter], - [/*start*/ 0xB96, WordBreakProperty.Other], - [/*start*/ 0xB99, WordBreakProperty.ALetter], - [/*start*/ 0xB9B, WordBreakProperty.Other], - [/*start*/ 0xB9C, WordBreakProperty.ALetter], - [/*start*/ 0xB9D, WordBreakProperty.Other], - [/*start*/ 0xB9E, WordBreakProperty.ALetter], - [/*start*/ 0xBA0, WordBreakProperty.Other], - [/*start*/ 0xBA3, WordBreakProperty.ALetter], - [/*start*/ 0xBA5, WordBreakProperty.Other], - [/*start*/ 0xBA8, WordBreakProperty.ALetter], - [/*start*/ 0xBAB, WordBreakProperty.Other], - [/*start*/ 0xBAE, WordBreakProperty.ALetter], - [/*start*/ 0xBBA, WordBreakProperty.Other], - [/*start*/ 0xBBE, WordBreakProperty.Extend], - [/*start*/ 0xBC3, WordBreakProperty.Other], - [/*start*/ 0xBC6, WordBreakProperty.Extend], - [/*start*/ 0xBC9, WordBreakProperty.Other], - [/*start*/ 0xBCA, WordBreakProperty.Extend], - [/*start*/ 0xBCE, WordBreakProperty.Other], - [/*start*/ 0xBD0, WordBreakProperty.ALetter], - [/*start*/ 0xBD1, WordBreakProperty.Other], - [/*start*/ 0xBD7, WordBreakProperty.Extend], - [/*start*/ 0xBD8, WordBreakProperty.Other], - [/*start*/ 0xBE6, WordBreakProperty.Numeric], - [/*start*/ 0xBF0, WordBreakProperty.Other], - [/*start*/ 0xC00, WordBreakProperty.Extend], - [/*start*/ 0xC05, WordBreakProperty.ALetter], - [/*start*/ 0xC0D, WordBreakProperty.Other], - [/*start*/ 0xC0E, WordBreakProperty.ALetter], - [/*start*/ 0xC11, WordBreakProperty.Other], - [/*start*/ 0xC12, WordBreakProperty.ALetter], - [/*start*/ 0xC29, WordBreakProperty.Other], - [/*start*/ 0xC2A, WordBreakProperty.ALetter], - [/*start*/ 0xC3A, WordBreakProperty.Other], - [/*start*/ 0xC3D, WordBreakProperty.ALetter], - [/*start*/ 0xC3E, WordBreakProperty.Extend], - [/*start*/ 0xC45, WordBreakProperty.Other], - [/*start*/ 0xC46, WordBreakProperty.Extend], - [/*start*/ 0xC49, WordBreakProperty.Other], - [/*start*/ 0xC4A, WordBreakProperty.Extend], - [/*start*/ 0xC4E, WordBreakProperty.Other], - [/*start*/ 0xC55, WordBreakProperty.Extend], - [/*start*/ 0xC57, WordBreakProperty.Other], - [/*start*/ 0xC58, WordBreakProperty.ALetter], - [/*start*/ 0xC5B, WordBreakProperty.Other], - [/*start*/ 0xC60, WordBreakProperty.ALetter], - [/*start*/ 0xC62, WordBreakProperty.Extend], - [/*start*/ 0xC64, WordBreakProperty.Other], - [/*start*/ 0xC66, WordBreakProperty.Numeric], - [/*start*/ 0xC70, WordBreakProperty.Other], - [/*start*/ 0xC80, WordBreakProperty.ALetter], - [/*start*/ 0xC81, WordBreakProperty.Extend], - [/*start*/ 0xC84, WordBreakProperty.Other], - [/*start*/ 0xC85, WordBreakProperty.ALetter], - [/*start*/ 0xC8D, WordBreakProperty.Other], - [/*start*/ 0xC8E, WordBreakProperty.ALetter], - [/*start*/ 0xC91, WordBreakProperty.Other], - [/*start*/ 0xC92, WordBreakProperty.ALetter], - [/*start*/ 0xCA9, WordBreakProperty.Other], - [/*start*/ 0xCAA, WordBreakProperty.ALetter], - [/*start*/ 0xCB4, WordBreakProperty.Other], - [/*start*/ 0xCB5, WordBreakProperty.ALetter], - [/*start*/ 0xCBA, WordBreakProperty.Other], - [/*start*/ 0xCBC, WordBreakProperty.Extend], - [/*start*/ 0xCBD, WordBreakProperty.ALetter], - [/*start*/ 0xCBE, WordBreakProperty.Extend], - [/*start*/ 0xCC5, WordBreakProperty.Other], - [/*start*/ 0xCC6, WordBreakProperty.Extend], - [/*start*/ 0xCC9, WordBreakProperty.Other], - [/*start*/ 0xCCA, WordBreakProperty.Extend], - [/*start*/ 0xCCE, WordBreakProperty.Other], - [/*start*/ 0xCD5, WordBreakProperty.Extend], - [/*start*/ 0xCD7, WordBreakProperty.Other], - [/*start*/ 0xCDE, WordBreakProperty.ALetter], - [/*start*/ 0xCDF, WordBreakProperty.Other], - [/*start*/ 0xCE0, WordBreakProperty.ALetter], - [/*start*/ 0xCE2, WordBreakProperty.Extend], - [/*start*/ 0xCE4, WordBreakProperty.Other], - [/*start*/ 0xCE6, WordBreakProperty.Numeric], - [/*start*/ 0xCF0, WordBreakProperty.Other], - [/*start*/ 0xCF1, WordBreakProperty.ALetter], - [/*start*/ 0xCF3, WordBreakProperty.Other], - [/*start*/ 0xD00, WordBreakProperty.Extend], - [/*start*/ 0xD04, WordBreakProperty.ALetter], - [/*start*/ 0xD0D, WordBreakProperty.Other], - [/*start*/ 0xD0E, WordBreakProperty.ALetter], - [/*start*/ 0xD11, WordBreakProperty.Other], - [/*start*/ 0xD12, WordBreakProperty.ALetter], - [/*start*/ 0xD3B, WordBreakProperty.Extend], - [/*start*/ 0xD3D, WordBreakProperty.ALetter], - [/*start*/ 0xD3E, WordBreakProperty.Extend], - [/*start*/ 0xD45, WordBreakProperty.Other], - [/*start*/ 0xD46, WordBreakProperty.Extend], - [/*start*/ 0xD49, WordBreakProperty.Other], - [/*start*/ 0xD4A, WordBreakProperty.Extend], - [/*start*/ 0xD4E, WordBreakProperty.ALetter], - [/*start*/ 0xD4F, WordBreakProperty.Other], - [/*start*/ 0xD54, WordBreakProperty.ALetter], - [/*start*/ 0xD57, WordBreakProperty.Extend], - [/*start*/ 0xD58, WordBreakProperty.Other], - [/*start*/ 0xD5F, WordBreakProperty.ALetter], - [/*start*/ 0xD62, WordBreakProperty.Extend], - [/*start*/ 0xD64, WordBreakProperty.Other], - [/*start*/ 0xD66, WordBreakProperty.Numeric], - [/*start*/ 0xD70, WordBreakProperty.Other], - [/*start*/ 0xD7A, WordBreakProperty.ALetter], - [/*start*/ 0xD80, WordBreakProperty.Other], - [/*start*/ 0xD81, WordBreakProperty.Extend], - [/*start*/ 0xD84, WordBreakProperty.Other], - [/*start*/ 0xD85, WordBreakProperty.ALetter], - [/*start*/ 0xD97, WordBreakProperty.Other], - [/*start*/ 0xD9A, WordBreakProperty.ALetter], - [/*start*/ 0xDB2, WordBreakProperty.Other], - [/*start*/ 0xDB3, WordBreakProperty.ALetter], - [/*start*/ 0xDBC, WordBreakProperty.Other], - [/*start*/ 0xDBD, WordBreakProperty.ALetter], - [/*start*/ 0xDBE, WordBreakProperty.Other], - [/*start*/ 0xDC0, WordBreakProperty.ALetter], - [/*start*/ 0xDC7, WordBreakProperty.Other], - [/*start*/ 0xDCA, WordBreakProperty.Extend], - [/*start*/ 0xDCB, WordBreakProperty.Other], - [/*start*/ 0xDCF, WordBreakProperty.Extend], - [/*start*/ 0xDD5, WordBreakProperty.Other], - [/*start*/ 0xDD6, WordBreakProperty.Extend], - [/*start*/ 0xDD7, WordBreakProperty.Other], - [/*start*/ 0xDD8, WordBreakProperty.Extend], - [/*start*/ 0xDE0, WordBreakProperty.Other], - [/*start*/ 0xDE6, WordBreakProperty.Numeric], - [/*start*/ 0xDF0, WordBreakProperty.Other], - [/*start*/ 0xDF2, WordBreakProperty.Extend], - [/*start*/ 0xDF4, WordBreakProperty.Other], - [/*start*/ 0xE31, WordBreakProperty.Extend], - [/*start*/ 0xE32, WordBreakProperty.Other], - [/*start*/ 0xE34, WordBreakProperty.Extend], - [/*start*/ 0xE3B, WordBreakProperty.Other], - [/*start*/ 0xE47, WordBreakProperty.Extend], - [/*start*/ 0xE4F, WordBreakProperty.Other], - [/*start*/ 0xE50, WordBreakProperty.Numeric], - [/*start*/ 0xE5A, WordBreakProperty.Other], - [/*start*/ 0xEB1, WordBreakProperty.Extend], - [/*start*/ 0xEB2, WordBreakProperty.Other], - [/*start*/ 0xEB4, WordBreakProperty.Extend], - [/*start*/ 0xEBD, WordBreakProperty.Other], - [/*start*/ 0xEC8, WordBreakProperty.Extend], - [/*start*/ 0xECE, WordBreakProperty.Other], - [/*start*/ 0xED0, WordBreakProperty.Numeric], - [/*start*/ 0xEDA, WordBreakProperty.Other], - [/*start*/ 0xF00, WordBreakProperty.ALetter], - [/*start*/ 0xF01, WordBreakProperty.Other], - [/*start*/ 0xF18, WordBreakProperty.Extend], - [/*start*/ 0xF1A, WordBreakProperty.Other], - [/*start*/ 0xF20, WordBreakProperty.Numeric], - [/*start*/ 0xF2A, WordBreakProperty.Other], - [/*start*/ 0xF35, WordBreakProperty.Extend], - [/*start*/ 0xF36, WordBreakProperty.Other], - [/*start*/ 0xF37, WordBreakProperty.Extend], - [/*start*/ 0xF38, WordBreakProperty.Other], - [/*start*/ 0xF39, WordBreakProperty.Extend], - [/*start*/ 0xF3A, WordBreakProperty.Other], - [/*start*/ 0xF3E, WordBreakProperty.Extend], - [/*start*/ 0xF40, WordBreakProperty.ALetter], - [/*start*/ 0xF48, WordBreakProperty.Other], - [/*start*/ 0xF49, WordBreakProperty.ALetter], - [/*start*/ 0xF6D, WordBreakProperty.Other], - [/*start*/ 0xF71, WordBreakProperty.Extend], - [/*start*/ 0xF85, WordBreakProperty.Other], - [/*start*/ 0xF86, WordBreakProperty.Extend], - [/*start*/ 0xF88, WordBreakProperty.ALetter], - [/*start*/ 0xF8D, WordBreakProperty.Extend], - [/*start*/ 0xF98, WordBreakProperty.Other], - [/*start*/ 0xF99, WordBreakProperty.Extend], - [/*start*/ 0xFBD, WordBreakProperty.Other], - [/*start*/ 0xFC6, WordBreakProperty.Extend], - [/*start*/ 0xFC7, WordBreakProperty.Other], - [/*start*/ 0x102B, WordBreakProperty.Extend], - [/*start*/ 0x103F, WordBreakProperty.Other], - [/*start*/ 0x1040, WordBreakProperty.Numeric], - [/*start*/ 0x104A, WordBreakProperty.Other], - [/*start*/ 0x1056, WordBreakProperty.Extend], - [/*start*/ 0x105A, WordBreakProperty.Other], - [/*start*/ 0x105E, WordBreakProperty.Extend], - [/*start*/ 0x1061, WordBreakProperty.Other], - [/*start*/ 0x1062, WordBreakProperty.Extend], - [/*start*/ 0x1065, WordBreakProperty.Other], - [/*start*/ 0x1067, WordBreakProperty.Extend], - [/*start*/ 0x106E, WordBreakProperty.Other], - [/*start*/ 0x1071, WordBreakProperty.Extend], - [/*start*/ 0x1075, WordBreakProperty.Other], - [/*start*/ 0x1082, WordBreakProperty.Extend], - [/*start*/ 0x108E, WordBreakProperty.Other], - [/*start*/ 0x108F, WordBreakProperty.Extend], - [/*start*/ 0x1090, WordBreakProperty.Numeric], - [/*start*/ 0x109A, WordBreakProperty.Extend], - [/*start*/ 0x109E, WordBreakProperty.Other], - [/*start*/ 0x10A0, WordBreakProperty.ALetter], - [/*start*/ 0x10C6, WordBreakProperty.Other], - [/*start*/ 0x10C7, WordBreakProperty.ALetter], - [/*start*/ 0x10C8, WordBreakProperty.Other], - [/*start*/ 0x10CD, WordBreakProperty.ALetter], - [/*start*/ 0x10CE, WordBreakProperty.Other], - [/*start*/ 0x10D0, WordBreakProperty.ALetter], - [/*start*/ 0x10FB, WordBreakProperty.Other], - [/*start*/ 0x10FC, WordBreakProperty.ALetter], - [/*start*/ 0x1249, WordBreakProperty.Other], - [/*start*/ 0x124A, WordBreakProperty.ALetter], - [/*start*/ 0x124E, WordBreakProperty.Other], - [/*start*/ 0x1250, WordBreakProperty.ALetter], - [/*start*/ 0x1257, WordBreakProperty.Other], - [/*start*/ 0x1258, WordBreakProperty.ALetter], - [/*start*/ 0x1259, WordBreakProperty.Other], - [/*start*/ 0x125A, WordBreakProperty.ALetter], - [/*start*/ 0x125E, WordBreakProperty.Other], - [/*start*/ 0x1260, WordBreakProperty.ALetter], - [/*start*/ 0x1289, WordBreakProperty.Other], - [/*start*/ 0x128A, WordBreakProperty.ALetter], - [/*start*/ 0x128E, WordBreakProperty.Other], - [/*start*/ 0x1290, WordBreakProperty.ALetter], - [/*start*/ 0x12B1, WordBreakProperty.Other], - [/*start*/ 0x12B2, WordBreakProperty.ALetter], - [/*start*/ 0x12B6, WordBreakProperty.Other], - [/*start*/ 0x12B8, WordBreakProperty.ALetter], - [/*start*/ 0x12BF, WordBreakProperty.Other], - [/*start*/ 0x12C0, WordBreakProperty.ALetter], - [/*start*/ 0x12C1, WordBreakProperty.Other], - [/*start*/ 0x12C2, WordBreakProperty.ALetter], - [/*start*/ 0x12C6, WordBreakProperty.Other], - [/*start*/ 0x12C8, WordBreakProperty.ALetter], - [/*start*/ 0x12D7, WordBreakProperty.Other], - [/*start*/ 0x12D8, WordBreakProperty.ALetter], - [/*start*/ 0x1311, WordBreakProperty.Other], - [/*start*/ 0x1312, WordBreakProperty.ALetter], - [/*start*/ 0x1316, WordBreakProperty.Other], - [/*start*/ 0x1318, WordBreakProperty.ALetter], - [/*start*/ 0x135B, WordBreakProperty.Other], - [/*start*/ 0x135D, WordBreakProperty.Extend], - [/*start*/ 0x1360, WordBreakProperty.Other], - [/*start*/ 0x1380, WordBreakProperty.ALetter], - [/*start*/ 0x1390, WordBreakProperty.Other], - [/*start*/ 0x13A0, WordBreakProperty.ALetter], - [/*start*/ 0x13F6, WordBreakProperty.Other], - [/*start*/ 0x13F8, WordBreakProperty.ALetter], - [/*start*/ 0x13FE, WordBreakProperty.Other], - [/*start*/ 0x1401, WordBreakProperty.ALetter], - [/*start*/ 0x166D, WordBreakProperty.Other], - [/*start*/ 0x166F, WordBreakProperty.ALetter], - [/*start*/ 0x1680, WordBreakProperty.WSegSpace], - [/*start*/ 0x1681, WordBreakProperty.ALetter], - [/*start*/ 0x169B, WordBreakProperty.Other], - [/*start*/ 0x16A0, WordBreakProperty.ALetter], - [/*start*/ 0x16EB, WordBreakProperty.Other], - [/*start*/ 0x16EE, WordBreakProperty.ALetter], - [/*start*/ 0x16F9, WordBreakProperty.Other], - [/*start*/ 0x1700, WordBreakProperty.ALetter], - [/*start*/ 0x170D, WordBreakProperty.Other], - [/*start*/ 0x170E, WordBreakProperty.ALetter], - [/*start*/ 0x1712, WordBreakProperty.Extend], - [/*start*/ 0x1715, WordBreakProperty.Other], - [/*start*/ 0x1720, WordBreakProperty.ALetter], - [/*start*/ 0x1732, WordBreakProperty.Extend], - [/*start*/ 0x1735, WordBreakProperty.Other], - [/*start*/ 0x1740, WordBreakProperty.ALetter], - [/*start*/ 0x1752, WordBreakProperty.Extend], - [/*start*/ 0x1754, WordBreakProperty.Other], - [/*start*/ 0x1760, WordBreakProperty.ALetter], - [/*start*/ 0x176D, WordBreakProperty.Other], - [/*start*/ 0x176E, WordBreakProperty.ALetter], - [/*start*/ 0x1771, WordBreakProperty.Other], - [/*start*/ 0x1772, WordBreakProperty.Extend], - [/*start*/ 0x1774, WordBreakProperty.Other], - [/*start*/ 0x17B4, WordBreakProperty.Extend], - [/*start*/ 0x17D4, WordBreakProperty.Other], - [/*start*/ 0x17DD, WordBreakProperty.Extend], - [/*start*/ 0x17DE, WordBreakProperty.Other], - [/*start*/ 0x17E0, WordBreakProperty.Numeric], - [/*start*/ 0x17EA, WordBreakProperty.Other], - [/*start*/ 0x180B, WordBreakProperty.Extend], - [/*start*/ 0x180E, WordBreakProperty.Format], - [/*start*/ 0x180F, WordBreakProperty.Other], - [/*start*/ 0x1810, WordBreakProperty.Numeric], - [/*start*/ 0x181A, WordBreakProperty.Other], - [/*start*/ 0x1820, WordBreakProperty.ALetter], - [/*start*/ 0x1879, WordBreakProperty.Other], - [/*start*/ 0x1880, WordBreakProperty.ALetter], - [/*start*/ 0x1885, WordBreakProperty.Extend], - [/*start*/ 0x1887, WordBreakProperty.ALetter], - [/*start*/ 0x18A9, WordBreakProperty.Extend], - [/*start*/ 0x18AA, WordBreakProperty.ALetter], - [/*start*/ 0x18AB, WordBreakProperty.Other], - [/*start*/ 0x18B0, WordBreakProperty.ALetter], - [/*start*/ 0x18F6, WordBreakProperty.Other], - [/*start*/ 0x1900, WordBreakProperty.ALetter], - [/*start*/ 0x191F, WordBreakProperty.Other], - [/*start*/ 0x1920, WordBreakProperty.Extend], - [/*start*/ 0x192C, WordBreakProperty.Other], - [/*start*/ 0x1930, WordBreakProperty.Extend], - [/*start*/ 0x193C, WordBreakProperty.Other], - [/*start*/ 0x1946, WordBreakProperty.Numeric], - [/*start*/ 0x1950, WordBreakProperty.Other], - [/*start*/ 0x19D0, WordBreakProperty.Numeric], - [/*start*/ 0x19DA, WordBreakProperty.Other], - [/*start*/ 0x1A00, WordBreakProperty.ALetter], - [/*start*/ 0x1A17, WordBreakProperty.Extend], - [/*start*/ 0x1A1C, WordBreakProperty.Other], - [/*start*/ 0x1A55, WordBreakProperty.Extend], - [/*start*/ 0x1A5F, WordBreakProperty.Other], - [/*start*/ 0x1A60, WordBreakProperty.Extend], - [/*start*/ 0x1A7D, WordBreakProperty.Other], - [/*start*/ 0x1A7F, WordBreakProperty.Extend], - [/*start*/ 0x1A80, WordBreakProperty.Numeric], - [/*start*/ 0x1A8A, WordBreakProperty.Other], - [/*start*/ 0x1A90, WordBreakProperty.Numeric], - [/*start*/ 0x1A9A, WordBreakProperty.Other], - [/*start*/ 0x1AB0, WordBreakProperty.Extend], - [/*start*/ 0x1AC1, WordBreakProperty.Other], - [/*start*/ 0x1B00, WordBreakProperty.Extend], - [/*start*/ 0x1B05, WordBreakProperty.ALetter], - [/*start*/ 0x1B34, WordBreakProperty.Extend], - [/*start*/ 0x1B45, WordBreakProperty.ALetter], - [/*start*/ 0x1B4C, WordBreakProperty.Other], - [/*start*/ 0x1B50, WordBreakProperty.Numeric], - [/*start*/ 0x1B5A, WordBreakProperty.Other], - [/*start*/ 0x1B6B, WordBreakProperty.Extend], - [/*start*/ 0x1B74, WordBreakProperty.Other], - [/*start*/ 0x1B80, WordBreakProperty.Extend], - [/*start*/ 0x1B83, WordBreakProperty.ALetter], - [/*start*/ 0x1BA1, WordBreakProperty.Extend], - [/*start*/ 0x1BAE, WordBreakProperty.ALetter], - [/*start*/ 0x1BB0, WordBreakProperty.Numeric], - [/*start*/ 0x1BBA, WordBreakProperty.ALetter], - [/*start*/ 0x1BE6, WordBreakProperty.Extend], - [/*start*/ 0x1BF4, WordBreakProperty.Other], - [/*start*/ 0x1C00, WordBreakProperty.ALetter], - [/*start*/ 0x1C24, WordBreakProperty.Extend], - [/*start*/ 0x1C38, WordBreakProperty.Other], - [/*start*/ 0x1C40, WordBreakProperty.Numeric], - [/*start*/ 0x1C4A, WordBreakProperty.Other], - [/*start*/ 0x1C4D, WordBreakProperty.ALetter], - [/*start*/ 0x1C50, WordBreakProperty.Numeric], - [/*start*/ 0x1C5A, WordBreakProperty.ALetter], - [/*start*/ 0x1C7E, WordBreakProperty.Other], - [/*start*/ 0x1C80, WordBreakProperty.ALetter], - [/*start*/ 0x1C89, WordBreakProperty.Other], - [/*start*/ 0x1C90, WordBreakProperty.ALetter], - [/*start*/ 0x1CBB, WordBreakProperty.Other], - [/*start*/ 0x1CBD, WordBreakProperty.ALetter], - [/*start*/ 0x1CC0, WordBreakProperty.Other], - [/*start*/ 0x1CD0, WordBreakProperty.Extend], - [/*start*/ 0x1CD3, WordBreakProperty.Other], - [/*start*/ 0x1CD4, WordBreakProperty.Extend], - [/*start*/ 0x1CE9, WordBreakProperty.ALetter], - [/*start*/ 0x1CED, WordBreakProperty.Extend], - [/*start*/ 0x1CEE, WordBreakProperty.ALetter], - [/*start*/ 0x1CF4, WordBreakProperty.Extend], - [/*start*/ 0x1CF5, WordBreakProperty.ALetter], - [/*start*/ 0x1CF7, WordBreakProperty.Extend], - [/*start*/ 0x1CFA, WordBreakProperty.ALetter], - [/*start*/ 0x1CFB, WordBreakProperty.Other], - [/*start*/ 0x1D00, WordBreakProperty.ALetter], - [/*start*/ 0x1DC0, WordBreakProperty.Extend], - [/*start*/ 0x1DFA, WordBreakProperty.Other], - [/*start*/ 0x1DFB, WordBreakProperty.Extend], - [/*start*/ 0x1E00, WordBreakProperty.ALetter], - [/*start*/ 0x1F16, WordBreakProperty.Other], - [/*start*/ 0x1F18, WordBreakProperty.ALetter], - [/*start*/ 0x1F1E, WordBreakProperty.Other], - [/*start*/ 0x1F20, WordBreakProperty.ALetter], - [/*start*/ 0x1F46, WordBreakProperty.Other], - [/*start*/ 0x1F48, WordBreakProperty.ALetter], - [/*start*/ 0x1F4E, WordBreakProperty.Other], - [/*start*/ 0x1F50, WordBreakProperty.ALetter], - [/*start*/ 0x1F58, WordBreakProperty.Other], - [/*start*/ 0x1F59, WordBreakProperty.ALetter], - [/*start*/ 0x1F5A, WordBreakProperty.Other], - [/*start*/ 0x1F5B, WordBreakProperty.ALetter], - [/*start*/ 0x1F5C, WordBreakProperty.Other], - [/*start*/ 0x1F5D, WordBreakProperty.ALetter], - [/*start*/ 0x1F5E, WordBreakProperty.Other], - [/*start*/ 0x1F5F, WordBreakProperty.ALetter], - [/*start*/ 0x1F7E, WordBreakProperty.Other], - [/*start*/ 0x1F80, WordBreakProperty.ALetter], - [/*start*/ 0x1FB5, WordBreakProperty.Other], - [/*start*/ 0x1FB6, WordBreakProperty.ALetter], - [/*start*/ 0x1FBD, WordBreakProperty.Other], - [/*start*/ 0x1FBE, WordBreakProperty.ALetter], - [/*start*/ 0x1FBF, WordBreakProperty.Other], - [/*start*/ 0x1FC2, WordBreakProperty.ALetter], - [/*start*/ 0x1FC5, WordBreakProperty.Other], - [/*start*/ 0x1FC6, WordBreakProperty.ALetter], - [/*start*/ 0x1FCD, WordBreakProperty.Other], - [/*start*/ 0x1FD0, WordBreakProperty.ALetter], - [/*start*/ 0x1FD4, WordBreakProperty.Other], - [/*start*/ 0x1FD6, WordBreakProperty.ALetter], - [/*start*/ 0x1FDC, WordBreakProperty.Other], - [/*start*/ 0x1FE0, WordBreakProperty.ALetter], - [/*start*/ 0x1FED, WordBreakProperty.Other], - [/*start*/ 0x1FF2, WordBreakProperty.ALetter], - [/*start*/ 0x1FF5, WordBreakProperty.Other], - [/*start*/ 0x1FF6, WordBreakProperty.ALetter], - [/*start*/ 0x1FFD, WordBreakProperty.Other], - [/*start*/ 0x2000, WordBreakProperty.WSegSpace], - [/*start*/ 0x2007, WordBreakProperty.Other], - [/*start*/ 0x2008, WordBreakProperty.WSegSpace], - [/*start*/ 0x200B, WordBreakProperty.Other], - [/*start*/ 0x200C, WordBreakProperty.Extend], - [/*start*/ 0x200D, WordBreakProperty.ZWJ], - [/*start*/ 0x200E, WordBreakProperty.Format], - [/*start*/ 0x2010, WordBreakProperty.Other], - [/*start*/ 0x2018, WordBreakProperty.MidNumLet], - [/*start*/ 0x201A, WordBreakProperty.Other], - [/*start*/ 0x2024, WordBreakProperty.MidNumLet], - [/*start*/ 0x2025, WordBreakProperty.Other], - [/*start*/ 0x2027, WordBreakProperty.MidLetter], - [/*start*/ 0x2028, WordBreakProperty.Newline], - [/*start*/ 0x202A, WordBreakProperty.Format], - [/*start*/ 0x202F, WordBreakProperty.ExtendNumLet], - [/*start*/ 0x2030, WordBreakProperty.Other], - [/*start*/ 0x203F, WordBreakProperty.ExtendNumLet], - [/*start*/ 0x2041, WordBreakProperty.Other], - [/*start*/ 0x2044, WordBreakProperty.MidNum], - [/*start*/ 0x2045, WordBreakProperty.Other], - [/*start*/ 0x2054, WordBreakProperty.ExtendNumLet], - [/*start*/ 0x2055, WordBreakProperty.Other], - [/*start*/ 0x205F, WordBreakProperty.WSegSpace], - [/*start*/ 0x2060, WordBreakProperty.Format], - [/*start*/ 0x2065, WordBreakProperty.Other], - [/*start*/ 0x2066, WordBreakProperty.Format], - [/*start*/ 0x2070, WordBreakProperty.Other], - [/*start*/ 0x2071, WordBreakProperty.ALetter], - [/*start*/ 0x2072, WordBreakProperty.Other], - [/*start*/ 0x207F, WordBreakProperty.ALetter], - [/*start*/ 0x2080, WordBreakProperty.Other], - [/*start*/ 0x2090, WordBreakProperty.ALetter], - [/*start*/ 0x209D, WordBreakProperty.Other], - [/*start*/ 0x20D0, WordBreakProperty.Extend], - [/*start*/ 0x20F1, WordBreakProperty.Other], - [/*start*/ 0x2102, WordBreakProperty.ALetter], - [/*start*/ 0x2103, WordBreakProperty.Other], - [/*start*/ 0x2107, WordBreakProperty.ALetter], - [/*start*/ 0x2108, WordBreakProperty.Other], - [/*start*/ 0x210A, WordBreakProperty.ALetter], - [/*start*/ 0x2114, WordBreakProperty.Other], - [/*start*/ 0x2115, WordBreakProperty.ALetter], - [/*start*/ 0x2116, WordBreakProperty.Other], - [/*start*/ 0x2119, WordBreakProperty.ALetter], - [/*start*/ 0x211E, WordBreakProperty.Other], - [/*start*/ 0x2124, WordBreakProperty.ALetter], - [/*start*/ 0x2125, WordBreakProperty.Other], - [/*start*/ 0x2126, WordBreakProperty.ALetter], - [/*start*/ 0x2127, WordBreakProperty.Other], - [/*start*/ 0x2128, WordBreakProperty.ALetter], - [/*start*/ 0x2129, WordBreakProperty.Other], - [/*start*/ 0x212A, WordBreakProperty.ALetter], - [/*start*/ 0x212E, WordBreakProperty.Other], - [/*start*/ 0x212F, WordBreakProperty.ALetter], - [/*start*/ 0x213A, WordBreakProperty.Other], - [/*start*/ 0x213C, WordBreakProperty.ALetter], - [/*start*/ 0x2140, WordBreakProperty.Other], - [/*start*/ 0x2145, WordBreakProperty.ALetter], - [/*start*/ 0x214A, WordBreakProperty.Other], - [/*start*/ 0x214E, WordBreakProperty.ALetter], - [/*start*/ 0x214F, WordBreakProperty.Other], - [/*start*/ 0x2160, WordBreakProperty.ALetter], - [/*start*/ 0x2189, WordBreakProperty.Other], - [/*start*/ 0x24B6, WordBreakProperty.ALetter], - [/*start*/ 0x24EA, WordBreakProperty.Other], - [/*start*/ 0x2C00, WordBreakProperty.ALetter], - [/*start*/ 0x2C2F, WordBreakProperty.Other], - [/*start*/ 0x2C30, WordBreakProperty.ALetter], - [/*start*/ 0x2C5F, WordBreakProperty.Other], - [/*start*/ 0x2C60, WordBreakProperty.ALetter], - [/*start*/ 0x2CE5, WordBreakProperty.Other], - [/*start*/ 0x2CEB, WordBreakProperty.ALetter], - [/*start*/ 0x2CEF, WordBreakProperty.Extend], - [/*start*/ 0x2CF2, WordBreakProperty.ALetter], - [/*start*/ 0x2CF4, WordBreakProperty.Other], - [/*start*/ 0x2D00, WordBreakProperty.ALetter], - [/*start*/ 0x2D26, WordBreakProperty.Other], - [/*start*/ 0x2D27, WordBreakProperty.ALetter], - [/*start*/ 0x2D28, WordBreakProperty.Other], - [/*start*/ 0x2D2D, WordBreakProperty.ALetter], - [/*start*/ 0x2D2E, WordBreakProperty.Other], - [/*start*/ 0x2D30, WordBreakProperty.ALetter], - [/*start*/ 0x2D68, WordBreakProperty.Other], - [/*start*/ 0x2D6F, WordBreakProperty.ALetter], - [/*start*/ 0x2D70, WordBreakProperty.Other], - [/*start*/ 0x2D7F, WordBreakProperty.Extend], - [/*start*/ 0x2D80, WordBreakProperty.ALetter], - [/*start*/ 0x2D97, WordBreakProperty.Other], - [/*start*/ 0x2DA0, WordBreakProperty.ALetter], - [/*start*/ 0x2DA7, WordBreakProperty.Other], - [/*start*/ 0x2DA8, WordBreakProperty.ALetter], - [/*start*/ 0x2DAF, WordBreakProperty.Other], - [/*start*/ 0x2DB0, WordBreakProperty.ALetter], - [/*start*/ 0x2DB7, WordBreakProperty.Other], - [/*start*/ 0x2DB8, WordBreakProperty.ALetter], - [/*start*/ 0x2DBF, WordBreakProperty.Other], - [/*start*/ 0x2DC0, WordBreakProperty.ALetter], - [/*start*/ 0x2DC7, WordBreakProperty.Other], - [/*start*/ 0x2DC8, WordBreakProperty.ALetter], - [/*start*/ 0x2DCF, WordBreakProperty.Other], - [/*start*/ 0x2DD0, WordBreakProperty.ALetter], - [/*start*/ 0x2DD7, WordBreakProperty.Other], - [/*start*/ 0x2DD8, WordBreakProperty.ALetter], - [/*start*/ 0x2DDF, WordBreakProperty.Other], - [/*start*/ 0x2DE0, WordBreakProperty.Extend], - [/*start*/ 0x2E00, WordBreakProperty.Other], - [/*start*/ 0x2E2F, WordBreakProperty.ALetter], - [/*start*/ 0x2E30, WordBreakProperty.Other], - [/*start*/ 0x3000, WordBreakProperty.WSegSpace], - [/*start*/ 0x3001, WordBreakProperty.Other], - [/*start*/ 0x3005, WordBreakProperty.ALetter], - [/*start*/ 0x3006, WordBreakProperty.Other], - [/*start*/ 0x302A, WordBreakProperty.Extend], - [/*start*/ 0x3030, WordBreakProperty.Other], - [/*start*/ 0x3031, WordBreakProperty.Katakana], - [/*start*/ 0x3036, WordBreakProperty.Other], - [/*start*/ 0x303B, WordBreakProperty.ALetter], - [/*start*/ 0x303D, WordBreakProperty.Other], - [/*start*/ 0x3099, WordBreakProperty.Extend], - [/*start*/ 0x309B, WordBreakProperty.Katakana], - [/*start*/ 0x309D, WordBreakProperty.Other], - [/*start*/ 0x30A0, WordBreakProperty.Katakana], - [/*start*/ 0x30FB, WordBreakProperty.Other], - [/*start*/ 0x30FC, WordBreakProperty.Katakana], - [/*start*/ 0x3100, WordBreakProperty.Other], - [/*start*/ 0x3105, WordBreakProperty.ALetter], - [/*start*/ 0x3130, WordBreakProperty.Other], - [/*start*/ 0x3131, WordBreakProperty.ALetter], - [/*start*/ 0x318F, WordBreakProperty.Other], - [/*start*/ 0x31A0, WordBreakProperty.ALetter], - [/*start*/ 0x31C0, WordBreakProperty.Other], - [/*start*/ 0x31F0, WordBreakProperty.Katakana], - [/*start*/ 0x3200, WordBreakProperty.Other], - [/*start*/ 0x32D0, WordBreakProperty.Katakana], - [/*start*/ 0x32FF, WordBreakProperty.Other], - [/*start*/ 0x3300, WordBreakProperty.Katakana], - [/*start*/ 0x3358, WordBreakProperty.Other], - [/*start*/ 0xA000, WordBreakProperty.ALetter], - [/*start*/ 0xA48D, WordBreakProperty.Other], - [/*start*/ 0xA4D0, WordBreakProperty.ALetter], - [/*start*/ 0xA4FE, WordBreakProperty.Other], - [/*start*/ 0xA500, WordBreakProperty.ALetter], - [/*start*/ 0xA60D, WordBreakProperty.Other], - [/*start*/ 0xA610, WordBreakProperty.ALetter], - [/*start*/ 0xA620, WordBreakProperty.Numeric], - [/*start*/ 0xA62A, WordBreakProperty.ALetter], - [/*start*/ 0xA62C, WordBreakProperty.Other], - [/*start*/ 0xA640, WordBreakProperty.ALetter], - [/*start*/ 0xA66F, WordBreakProperty.Extend], - [/*start*/ 0xA673, WordBreakProperty.Other], - [/*start*/ 0xA674, WordBreakProperty.Extend], - [/*start*/ 0xA67E, WordBreakProperty.Other], - [/*start*/ 0xA67F, WordBreakProperty.ALetter], - [/*start*/ 0xA69E, WordBreakProperty.Extend], - [/*start*/ 0xA6A0, WordBreakProperty.ALetter], - [/*start*/ 0xA6F0, WordBreakProperty.Extend], - [/*start*/ 0xA6F2, WordBreakProperty.Other], - [/*start*/ 0xA708, WordBreakProperty.ALetter], - [/*start*/ 0xA7C0, WordBreakProperty.Other], - [/*start*/ 0xA7C2, WordBreakProperty.ALetter], - [/*start*/ 0xA7CB, WordBreakProperty.Other], - [/*start*/ 0xA7F5, WordBreakProperty.ALetter], - [/*start*/ 0xA802, WordBreakProperty.Extend], - [/*start*/ 0xA803, WordBreakProperty.ALetter], - [/*start*/ 0xA806, WordBreakProperty.Extend], - [/*start*/ 0xA807, WordBreakProperty.ALetter], - [/*start*/ 0xA80B, WordBreakProperty.Extend], - [/*start*/ 0xA80C, WordBreakProperty.ALetter], - [/*start*/ 0xA823, WordBreakProperty.Extend], - [/*start*/ 0xA828, WordBreakProperty.Other], - [/*start*/ 0xA82C, WordBreakProperty.Extend], - [/*start*/ 0xA82D, WordBreakProperty.Other], - [/*start*/ 0xA840, WordBreakProperty.ALetter], - [/*start*/ 0xA874, WordBreakProperty.Other], - [/*start*/ 0xA880, WordBreakProperty.Extend], - [/*start*/ 0xA882, WordBreakProperty.ALetter], - [/*start*/ 0xA8B4, WordBreakProperty.Extend], - [/*start*/ 0xA8C6, WordBreakProperty.Other], - [/*start*/ 0xA8D0, WordBreakProperty.Numeric], - [/*start*/ 0xA8DA, WordBreakProperty.Other], - [/*start*/ 0xA8E0, WordBreakProperty.Extend], - [/*start*/ 0xA8F2, WordBreakProperty.ALetter], - [/*start*/ 0xA8F8, WordBreakProperty.Other], - [/*start*/ 0xA8FB, WordBreakProperty.ALetter], - [/*start*/ 0xA8FC, WordBreakProperty.Other], - [/*start*/ 0xA8FD, WordBreakProperty.ALetter], - [/*start*/ 0xA8FF, WordBreakProperty.Extend], - [/*start*/ 0xA900, WordBreakProperty.Numeric], - [/*start*/ 0xA90A, WordBreakProperty.ALetter], - [/*start*/ 0xA926, WordBreakProperty.Extend], - [/*start*/ 0xA92E, WordBreakProperty.Other], - [/*start*/ 0xA930, WordBreakProperty.ALetter], - [/*start*/ 0xA947, WordBreakProperty.Extend], - [/*start*/ 0xA954, WordBreakProperty.Other], - [/*start*/ 0xA960, WordBreakProperty.ALetter], - [/*start*/ 0xA97D, WordBreakProperty.Other], - [/*start*/ 0xA980, WordBreakProperty.Extend], - [/*start*/ 0xA984, WordBreakProperty.ALetter], - [/*start*/ 0xA9B3, WordBreakProperty.Extend], - [/*start*/ 0xA9C1, WordBreakProperty.Other], - [/*start*/ 0xA9CF, WordBreakProperty.ALetter], - [/*start*/ 0xA9D0, WordBreakProperty.Numeric], - [/*start*/ 0xA9DA, WordBreakProperty.Other], - [/*start*/ 0xA9E5, WordBreakProperty.Extend], - [/*start*/ 0xA9E6, WordBreakProperty.Other], - [/*start*/ 0xA9F0, WordBreakProperty.Numeric], - [/*start*/ 0xA9FA, WordBreakProperty.Other], - [/*start*/ 0xAA00, WordBreakProperty.ALetter], - [/*start*/ 0xAA29, WordBreakProperty.Extend], - [/*start*/ 0xAA37, WordBreakProperty.Other], - [/*start*/ 0xAA40, WordBreakProperty.ALetter], - [/*start*/ 0xAA43, WordBreakProperty.Extend], - [/*start*/ 0xAA44, WordBreakProperty.ALetter], - [/*start*/ 0xAA4C, WordBreakProperty.Extend], - [/*start*/ 0xAA4E, WordBreakProperty.Other], - [/*start*/ 0xAA50, WordBreakProperty.Numeric], - [/*start*/ 0xAA5A, WordBreakProperty.Other], - [/*start*/ 0xAA7B, WordBreakProperty.Extend], - [/*start*/ 0xAA7E, WordBreakProperty.Other], - [/*start*/ 0xAAB0, WordBreakProperty.Extend], - [/*start*/ 0xAAB1, WordBreakProperty.Other], - [/*start*/ 0xAAB2, WordBreakProperty.Extend], - [/*start*/ 0xAAB5, WordBreakProperty.Other], - [/*start*/ 0xAAB7, WordBreakProperty.Extend], - [/*start*/ 0xAAB9, WordBreakProperty.Other], - [/*start*/ 0xAABE, WordBreakProperty.Extend], - [/*start*/ 0xAAC0, WordBreakProperty.Other], - [/*start*/ 0xAAC1, WordBreakProperty.Extend], - [/*start*/ 0xAAC2, WordBreakProperty.Other], - [/*start*/ 0xAAE0, WordBreakProperty.ALetter], - [/*start*/ 0xAAEB, WordBreakProperty.Extend], - [/*start*/ 0xAAF0, WordBreakProperty.Other], - [/*start*/ 0xAAF2, WordBreakProperty.ALetter], - [/*start*/ 0xAAF5, WordBreakProperty.Extend], - [/*start*/ 0xAAF7, WordBreakProperty.Other], - [/*start*/ 0xAB01, WordBreakProperty.ALetter], - [/*start*/ 0xAB07, WordBreakProperty.Other], - [/*start*/ 0xAB09, WordBreakProperty.ALetter], - [/*start*/ 0xAB0F, WordBreakProperty.Other], - [/*start*/ 0xAB11, WordBreakProperty.ALetter], - [/*start*/ 0xAB17, WordBreakProperty.Other], - [/*start*/ 0xAB20, WordBreakProperty.ALetter], - [/*start*/ 0xAB27, WordBreakProperty.Other], - [/*start*/ 0xAB28, WordBreakProperty.ALetter], - [/*start*/ 0xAB2F, WordBreakProperty.Other], - [/*start*/ 0xAB30, WordBreakProperty.ALetter], - [/*start*/ 0xAB6A, WordBreakProperty.Other], - [/*start*/ 0xAB70, WordBreakProperty.ALetter], - [/*start*/ 0xABE3, WordBreakProperty.Extend], - [/*start*/ 0xABEB, WordBreakProperty.Other], - [/*start*/ 0xABEC, WordBreakProperty.Extend], - [/*start*/ 0xABEE, WordBreakProperty.Other], - [/*start*/ 0xABF0, WordBreakProperty.Numeric], - [/*start*/ 0xABFA, WordBreakProperty.Other], - [/*start*/ 0xAC00, WordBreakProperty.ALetter], - [/*start*/ 0xD7A4, WordBreakProperty.Other], - [/*start*/ 0xD7B0, WordBreakProperty.ALetter], - [/*start*/ 0xD7C7, WordBreakProperty.Other], - [/*start*/ 0xD7CB, WordBreakProperty.ALetter], - [/*start*/ 0xD7FC, WordBreakProperty.Other], - [/*start*/ 0xFB00, WordBreakProperty.ALetter], - [/*start*/ 0xFB07, WordBreakProperty.Other], - [/*start*/ 0xFB13, WordBreakProperty.ALetter], - [/*start*/ 0xFB18, WordBreakProperty.Other], - [/*start*/ 0xFB1D, WordBreakProperty.Hebrew_Letter], - [/*start*/ 0xFB1E, WordBreakProperty.Extend], - [/*start*/ 0xFB1F, WordBreakProperty.Hebrew_Letter], - [/*start*/ 0xFB29, WordBreakProperty.Other], - [/*start*/ 0xFB2A, WordBreakProperty.Hebrew_Letter], - [/*start*/ 0xFB37, WordBreakProperty.Other], - [/*start*/ 0xFB38, WordBreakProperty.Hebrew_Letter], - [/*start*/ 0xFB3D, WordBreakProperty.Other], - [/*start*/ 0xFB3E, WordBreakProperty.Hebrew_Letter], - [/*start*/ 0xFB3F, WordBreakProperty.Other], - [/*start*/ 0xFB40, WordBreakProperty.Hebrew_Letter], - [/*start*/ 0xFB42, WordBreakProperty.Other], - [/*start*/ 0xFB43, WordBreakProperty.Hebrew_Letter], - [/*start*/ 0xFB45, WordBreakProperty.Other], - [/*start*/ 0xFB46, WordBreakProperty.Hebrew_Letter], - [/*start*/ 0xFB50, WordBreakProperty.ALetter], - [/*start*/ 0xFBB2, WordBreakProperty.Other], - [/*start*/ 0xFBD3, WordBreakProperty.ALetter], - [/*start*/ 0xFD3E, WordBreakProperty.Other], - [/*start*/ 0xFD50, WordBreakProperty.ALetter], - [/*start*/ 0xFD90, WordBreakProperty.Other], - [/*start*/ 0xFD92, WordBreakProperty.ALetter], - [/*start*/ 0xFDC8, WordBreakProperty.Other], - [/*start*/ 0xFDF0, WordBreakProperty.ALetter], - [/*start*/ 0xFDFC, WordBreakProperty.Other], - [/*start*/ 0xFE00, WordBreakProperty.Extend], - [/*start*/ 0xFE10, WordBreakProperty.MidNum], - [/*start*/ 0xFE11, WordBreakProperty.Other], - [/*start*/ 0xFE13, WordBreakProperty.MidLetter], - [/*start*/ 0xFE14, WordBreakProperty.MidNum], - [/*start*/ 0xFE15, WordBreakProperty.Other], - [/*start*/ 0xFE20, WordBreakProperty.Extend], - [/*start*/ 0xFE30, WordBreakProperty.Other], - [/*start*/ 0xFE33, WordBreakProperty.ExtendNumLet], - [/*start*/ 0xFE35, WordBreakProperty.Other], - [/*start*/ 0xFE4D, WordBreakProperty.ExtendNumLet], - [/*start*/ 0xFE50, WordBreakProperty.MidNum], - [/*start*/ 0xFE51, WordBreakProperty.Other], - [/*start*/ 0xFE52, WordBreakProperty.MidNumLet], - [/*start*/ 0xFE53, WordBreakProperty.Other], - [/*start*/ 0xFE54, WordBreakProperty.MidNum], - [/*start*/ 0xFE55, WordBreakProperty.MidLetter], - [/*start*/ 0xFE56, WordBreakProperty.Other], - [/*start*/ 0xFE70, WordBreakProperty.ALetter], - [/*start*/ 0xFE75, WordBreakProperty.Other], - [/*start*/ 0xFE76, WordBreakProperty.ALetter], - [/*start*/ 0xFEFD, WordBreakProperty.Other], - [/*start*/ 0xFEFF, WordBreakProperty.Format], - [/*start*/ 0xFF00, WordBreakProperty.Other], - [/*start*/ 0xFF07, WordBreakProperty.MidNumLet], - [/*start*/ 0xFF08, WordBreakProperty.Other], - [/*start*/ 0xFF0C, WordBreakProperty.MidNum], - [/*start*/ 0xFF0D, WordBreakProperty.Other], - [/*start*/ 0xFF0E, WordBreakProperty.MidNumLet], - [/*start*/ 0xFF0F, WordBreakProperty.Other], - [/*start*/ 0xFF10, WordBreakProperty.Numeric], - [/*start*/ 0xFF1A, WordBreakProperty.MidLetter], - [/*start*/ 0xFF1B, WordBreakProperty.MidNum], - [/*start*/ 0xFF1C, WordBreakProperty.Other], - [/*start*/ 0xFF21, WordBreakProperty.ALetter], - [/*start*/ 0xFF3B, WordBreakProperty.Other], - [/*start*/ 0xFF3F, WordBreakProperty.ExtendNumLet], - [/*start*/ 0xFF40, WordBreakProperty.Other], - [/*start*/ 0xFF41, WordBreakProperty.ALetter], - [/*start*/ 0xFF5B, WordBreakProperty.Other], - [/*start*/ 0xFF66, WordBreakProperty.Katakana], - [/*start*/ 0xFF9E, WordBreakProperty.Extend], - [/*start*/ 0xFFA0, WordBreakProperty.ALetter], - [/*start*/ 0xFFBF, WordBreakProperty.Other], - [/*start*/ 0xFFC2, WordBreakProperty.ALetter], - [/*start*/ 0xFFC8, WordBreakProperty.Other], - [/*start*/ 0xFFCA, WordBreakProperty.ALetter], - [/*start*/ 0xFFD0, WordBreakProperty.Other], - [/*start*/ 0xFFD2, WordBreakProperty.ALetter], - [/*start*/ 0xFFD8, WordBreakProperty.Other], - [/*start*/ 0xFFDA, WordBreakProperty.ALetter], - [/*start*/ 0xFFDD, WordBreakProperty.Other], - [/*start*/ 0xFFF9, WordBreakProperty.Format], - [/*start*/ 0xFFFC, WordBreakProperty.Other], - [/*start*/ 0x10000, WordBreakProperty.ALetter], - [/*start*/ 0x1000C, WordBreakProperty.Other], - [/*start*/ 0x1000D, WordBreakProperty.ALetter], - [/*start*/ 0x10027, WordBreakProperty.Other], - [/*start*/ 0x10028, WordBreakProperty.ALetter], - [/*start*/ 0x1003B, WordBreakProperty.Other], - [/*start*/ 0x1003C, WordBreakProperty.ALetter], - [/*start*/ 0x1003E, WordBreakProperty.Other], - [/*start*/ 0x1003F, WordBreakProperty.ALetter], - [/*start*/ 0x1004E, WordBreakProperty.Other], - [/*start*/ 0x10050, WordBreakProperty.ALetter], - [/*start*/ 0x1005E, WordBreakProperty.Other], - [/*start*/ 0x10080, WordBreakProperty.ALetter], - [/*start*/ 0x100FB, WordBreakProperty.Other], - [/*start*/ 0x10140, WordBreakProperty.ALetter], - [/*start*/ 0x10175, WordBreakProperty.Other], - [/*start*/ 0x101FD, WordBreakProperty.Extend], - [/*start*/ 0x101FE, WordBreakProperty.Other], - [/*start*/ 0x10280, WordBreakProperty.ALetter], - [/*start*/ 0x1029D, WordBreakProperty.Other], - [/*start*/ 0x102A0, WordBreakProperty.ALetter], - [/*start*/ 0x102D1, WordBreakProperty.Other], - [/*start*/ 0x102E0, WordBreakProperty.Extend], - [/*start*/ 0x102E1, WordBreakProperty.Other], - [/*start*/ 0x10300, WordBreakProperty.ALetter], - [/*start*/ 0x10320, WordBreakProperty.Other], - [/*start*/ 0x1032D, WordBreakProperty.ALetter], - [/*start*/ 0x1034B, WordBreakProperty.Other], - [/*start*/ 0x10350, WordBreakProperty.ALetter], - [/*start*/ 0x10376, WordBreakProperty.Extend], - [/*start*/ 0x1037B, WordBreakProperty.Other], - [/*start*/ 0x10380, WordBreakProperty.ALetter], - [/*start*/ 0x1039E, WordBreakProperty.Other], - [/*start*/ 0x103A0, WordBreakProperty.ALetter], - [/*start*/ 0x103C4, WordBreakProperty.Other], - [/*start*/ 0x103C8, WordBreakProperty.ALetter], - [/*start*/ 0x103D0, WordBreakProperty.Other], - [/*start*/ 0x103D1, WordBreakProperty.ALetter], - [/*start*/ 0x103D6, WordBreakProperty.Other], - [/*start*/ 0x10400, WordBreakProperty.ALetter], - [/*start*/ 0x1049E, WordBreakProperty.Other], - [/*start*/ 0x104A0, WordBreakProperty.Numeric], - [/*start*/ 0x104AA, WordBreakProperty.Other], - [/*start*/ 0x104B0, WordBreakProperty.ALetter], - [/*start*/ 0x104D4, WordBreakProperty.Other], - [/*start*/ 0x104D8, WordBreakProperty.ALetter], - [/*start*/ 0x104FC, WordBreakProperty.Other], - [/*start*/ 0x10500, WordBreakProperty.ALetter], - [/*start*/ 0x10528, WordBreakProperty.Other], - [/*start*/ 0x10530, WordBreakProperty.ALetter], - [/*start*/ 0x10564, WordBreakProperty.Other], - [/*start*/ 0x10600, WordBreakProperty.ALetter], - [/*start*/ 0x10737, WordBreakProperty.Other], - [/*start*/ 0x10740, WordBreakProperty.ALetter], - [/*start*/ 0x10756, WordBreakProperty.Other], - [/*start*/ 0x10760, WordBreakProperty.ALetter], - [/*start*/ 0x10768, WordBreakProperty.Other], - [/*start*/ 0x10800, WordBreakProperty.ALetter], - [/*start*/ 0x10806, WordBreakProperty.Other], - [/*start*/ 0x10808, WordBreakProperty.ALetter], - [/*start*/ 0x10809, WordBreakProperty.Other], - [/*start*/ 0x1080A, WordBreakProperty.ALetter], - [/*start*/ 0x10836, WordBreakProperty.Other], - [/*start*/ 0x10837, WordBreakProperty.ALetter], - [/*start*/ 0x10839, WordBreakProperty.Other], - [/*start*/ 0x1083C, WordBreakProperty.ALetter], - [/*start*/ 0x1083D, WordBreakProperty.Other], - [/*start*/ 0x1083F, WordBreakProperty.ALetter], - [/*start*/ 0x10856, WordBreakProperty.Other], - [/*start*/ 0x10860, WordBreakProperty.ALetter], - [/*start*/ 0x10877, WordBreakProperty.Other], - [/*start*/ 0x10880, WordBreakProperty.ALetter], - [/*start*/ 0x1089F, WordBreakProperty.Other], - [/*start*/ 0x108E0, WordBreakProperty.ALetter], - [/*start*/ 0x108F3, WordBreakProperty.Other], - [/*start*/ 0x108F4, WordBreakProperty.ALetter], - [/*start*/ 0x108F6, WordBreakProperty.Other], - [/*start*/ 0x10900, WordBreakProperty.ALetter], - [/*start*/ 0x10916, WordBreakProperty.Other], - [/*start*/ 0x10920, WordBreakProperty.ALetter], - [/*start*/ 0x1093A, WordBreakProperty.Other], - [/*start*/ 0x10980, WordBreakProperty.ALetter], - [/*start*/ 0x109B8, WordBreakProperty.Other], - [/*start*/ 0x109BE, WordBreakProperty.ALetter], - [/*start*/ 0x109C0, WordBreakProperty.Other], - [/*start*/ 0x10A00, WordBreakProperty.ALetter], - [/*start*/ 0x10A01, WordBreakProperty.Extend], - [/*start*/ 0x10A04, WordBreakProperty.Other], - [/*start*/ 0x10A05, WordBreakProperty.Extend], - [/*start*/ 0x10A07, WordBreakProperty.Other], - [/*start*/ 0x10A0C, WordBreakProperty.Extend], - [/*start*/ 0x10A10, WordBreakProperty.ALetter], - [/*start*/ 0x10A14, WordBreakProperty.Other], - [/*start*/ 0x10A15, WordBreakProperty.ALetter], - [/*start*/ 0x10A18, WordBreakProperty.Other], - [/*start*/ 0x10A19, WordBreakProperty.ALetter], - [/*start*/ 0x10A36, WordBreakProperty.Other], - [/*start*/ 0x10A38, WordBreakProperty.Extend], - [/*start*/ 0x10A3B, WordBreakProperty.Other], - [/*start*/ 0x10A3F, WordBreakProperty.Extend], - [/*start*/ 0x10A40, WordBreakProperty.Other], - [/*start*/ 0x10A60, WordBreakProperty.ALetter], - [/*start*/ 0x10A7D, WordBreakProperty.Other], - [/*start*/ 0x10A80, WordBreakProperty.ALetter], - [/*start*/ 0x10A9D, WordBreakProperty.Other], - [/*start*/ 0x10AC0, WordBreakProperty.ALetter], - [/*start*/ 0x10AC8, WordBreakProperty.Other], - [/*start*/ 0x10AC9, WordBreakProperty.ALetter], - [/*start*/ 0x10AE5, WordBreakProperty.Extend], - [/*start*/ 0x10AE7, WordBreakProperty.Other], - [/*start*/ 0x10B00, WordBreakProperty.ALetter], - [/*start*/ 0x10B36, WordBreakProperty.Other], - [/*start*/ 0x10B40, WordBreakProperty.ALetter], - [/*start*/ 0x10B56, WordBreakProperty.Other], - [/*start*/ 0x10B60, WordBreakProperty.ALetter], - [/*start*/ 0x10B73, WordBreakProperty.Other], - [/*start*/ 0x10B80, WordBreakProperty.ALetter], - [/*start*/ 0x10B92, WordBreakProperty.Other], - [/*start*/ 0x10C00, WordBreakProperty.ALetter], - [/*start*/ 0x10C49, WordBreakProperty.Other], - [/*start*/ 0x10C80, WordBreakProperty.ALetter], - [/*start*/ 0x10CB3, WordBreakProperty.Other], - [/*start*/ 0x10CC0, WordBreakProperty.ALetter], - [/*start*/ 0x10CF3, WordBreakProperty.Other], - [/*start*/ 0x10D00, WordBreakProperty.ALetter], - [/*start*/ 0x10D24, WordBreakProperty.Extend], - [/*start*/ 0x10D28, WordBreakProperty.Other], - [/*start*/ 0x10D30, WordBreakProperty.Numeric], - [/*start*/ 0x10D3A, WordBreakProperty.Other], - [/*start*/ 0x10E80, WordBreakProperty.ALetter], - [/*start*/ 0x10EAA, WordBreakProperty.Other], - [/*start*/ 0x10EAB, WordBreakProperty.Extend], - [/*start*/ 0x10EAD, WordBreakProperty.Other], - [/*start*/ 0x10EB0, WordBreakProperty.ALetter], - [/*start*/ 0x10EB2, WordBreakProperty.Other], - [/*start*/ 0x10F00, WordBreakProperty.ALetter], - [/*start*/ 0x10F1D, WordBreakProperty.Other], - [/*start*/ 0x10F27, WordBreakProperty.ALetter], - [/*start*/ 0x10F28, WordBreakProperty.Other], - [/*start*/ 0x10F30, WordBreakProperty.ALetter], - [/*start*/ 0x10F46, WordBreakProperty.Extend], - [/*start*/ 0x10F51, WordBreakProperty.Other], - [/*start*/ 0x10FB0, WordBreakProperty.ALetter], - [/*start*/ 0x10FC5, WordBreakProperty.Other], - [/*start*/ 0x10FE0, WordBreakProperty.ALetter], - [/*start*/ 0x10FF7, WordBreakProperty.Other], - [/*start*/ 0x11000, WordBreakProperty.Extend], - [/*start*/ 0x11003, WordBreakProperty.ALetter], - [/*start*/ 0x11038, WordBreakProperty.Extend], - [/*start*/ 0x11047, WordBreakProperty.Other], - [/*start*/ 0x11066, WordBreakProperty.Numeric], - [/*start*/ 0x11070, WordBreakProperty.Other], - [/*start*/ 0x1107F, WordBreakProperty.Extend], - [/*start*/ 0x11083, WordBreakProperty.ALetter], - [/*start*/ 0x110B0, WordBreakProperty.Extend], - [/*start*/ 0x110BB, WordBreakProperty.Other], - [/*start*/ 0x110BD, WordBreakProperty.Format], - [/*start*/ 0x110BE, WordBreakProperty.Other], - [/*start*/ 0x110CD, WordBreakProperty.Format], - [/*start*/ 0x110CE, WordBreakProperty.Other], - [/*start*/ 0x110D0, WordBreakProperty.ALetter], - [/*start*/ 0x110E9, WordBreakProperty.Other], - [/*start*/ 0x110F0, WordBreakProperty.Numeric], - [/*start*/ 0x110FA, WordBreakProperty.Other], - [/*start*/ 0x11100, WordBreakProperty.Extend], - [/*start*/ 0x11103, WordBreakProperty.ALetter], - [/*start*/ 0x11127, WordBreakProperty.Extend], - [/*start*/ 0x11135, WordBreakProperty.Other], - [/*start*/ 0x11136, WordBreakProperty.Numeric], - [/*start*/ 0x11140, WordBreakProperty.Other], - [/*start*/ 0x11144, WordBreakProperty.ALetter], - [/*start*/ 0x11145, WordBreakProperty.Extend], - [/*start*/ 0x11147, WordBreakProperty.ALetter], - [/*start*/ 0x11148, WordBreakProperty.Other], - [/*start*/ 0x11150, WordBreakProperty.ALetter], - [/*start*/ 0x11173, WordBreakProperty.Extend], - [/*start*/ 0x11174, WordBreakProperty.Other], - [/*start*/ 0x11176, WordBreakProperty.ALetter], - [/*start*/ 0x11177, WordBreakProperty.Other], - [/*start*/ 0x11180, WordBreakProperty.Extend], - [/*start*/ 0x11183, WordBreakProperty.ALetter], - [/*start*/ 0x111B3, WordBreakProperty.Extend], - [/*start*/ 0x111C1, WordBreakProperty.ALetter], - [/*start*/ 0x111C5, WordBreakProperty.Other], - [/*start*/ 0x111C9, WordBreakProperty.Extend], - [/*start*/ 0x111CD, WordBreakProperty.Other], - [/*start*/ 0x111CE, WordBreakProperty.Extend], - [/*start*/ 0x111D0, WordBreakProperty.Numeric], - [/*start*/ 0x111DA, WordBreakProperty.ALetter], - [/*start*/ 0x111DB, WordBreakProperty.Other], - [/*start*/ 0x111DC, WordBreakProperty.ALetter], - [/*start*/ 0x111DD, WordBreakProperty.Other], - [/*start*/ 0x11200, WordBreakProperty.ALetter], - [/*start*/ 0x11212, WordBreakProperty.Other], - [/*start*/ 0x11213, WordBreakProperty.ALetter], - [/*start*/ 0x1122C, WordBreakProperty.Extend], - [/*start*/ 0x11238, WordBreakProperty.Other], - [/*start*/ 0x1123E, WordBreakProperty.Extend], - [/*start*/ 0x1123F, WordBreakProperty.Other], - [/*start*/ 0x11280, WordBreakProperty.ALetter], - [/*start*/ 0x11287, WordBreakProperty.Other], - [/*start*/ 0x11288, WordBreakProperty.ALetter], - [/*start*/ 0x11289, WordBreakProperty.Other], - [/*start*/ 0x1128A, WordBreakProperty.ALetter], - [/*start*/ 0x1128E, WordBreakProperty.Other], - [/*start*/ 0x1128F, WordBreakProperty.ALetter], - [/*start*/ 0x1129E, WordBreakProperty.Other], - [/*start*/ 0x1129F, WordBreakProperty.ALetter], - [/*start*/ 0x112A9, WordBreakProperty.Other], - [/*start*/ 0x112B0, WordBreakProperty.ALetter], - [/*start*/ 0x112DF, WordBreakProperty.Extend], - [/*start*/ 0x112EB, WordBreakProperty.Other], - [/*start*/ 0x112F0, WordBreakProperty.Numeric], - [/*start*/ 0x112FA, WordBreakProperty.Other], - [/*start*/ 0x11300, WordBreakProperty.Extend], - [/*start*/ 0x11304, WordBreakProperty.Other], - [/*start*/ 0x11305, WordBreakProperty.ALetter], - [/*start*/ 0x1130D, WordBreakProperty.Other], - [/*start*/ 0x1130F, WordBreakProperty.ALetter], - [/*start*/ 0x11311, WordBreakProperty.Other], - [/*start*/ 0x11313, WordBreakProperty.ALetter], - [/*start*/ 0x11329, WordBreakProperty.Other], - [/*start*/ 0x1132A, WordBreakProperty.ALetter], - [/*start*/ 0x11331, WordBreakProperty.Other], - [/*start*/ 0x11332, WordBreakProperty.ALetter], - [/*start*/ 0x11334, WordBreakProperty.Other], - [/*start*/ 0x11335, WordBreakProperty.ALetter], - [/*start*/ 0x1133A, WordBreakProperty.Other], - [/*start*/ 0x1133B, WordBreakProperty.Extend], - [/*start*/ 0x1133D, WordBreakProperty.ALetter], - [/*start*/ 0x1133E, WordBreakProperty.Extend], - [/*start*/ 0x11345, WordBreakProperty.Other], - [/*start*/ 0x11347, WordBreakProperty.Extend], - [/*start*/ 0x11349, WordBreakProperty.Other], - [/*start*/ 0x1134B, WordBreakProperty.Extend], - [/*start*/ 0x1134E, WordBreakProperty.Other], - [/*start*/ 0x11350, WordBreakProperty.ALetter], - [/*start*/ 0x11351, WordBreakProperty.Other], - [/*start*/ 0x11357, WordBreakProperty.Extend], - [/*start*/ 0x11358, WordBreakProperty.Other], - [/*start*/ 0x1135D, WordBreakProperty.ALetter], - [/*start*/ 0x11362, WordBreakProperty.Extend], - [/*start*/ 0x11364, WordBreakProperty.Other], - [/*start*/ 0x11366, WordBreakProperty.Extend], - [/*start*/ 0x1136D, WordBreakProperty.Other], - [/*start*/ 0x11370, WordBreakProperty.Extend], - [/*start*/ 0x11375, WordBreakProperty.Other], - [/*start*/ 0x11400, WordBreakProperty.ALetter], - [/*start*/ 0x11435, WordBreakProperty.Extend], - [/*start*/ 0x11447, WordBreakProperty.ALetter], - [/*start*/ 0x1144B, WordBreakProperty.Other], - [/*start*/ 0x11450, WordBreakProperty.Numeric], - [/*start*/ 0x1145A, WordBreakProperty.Other], - [/*start*/ 0x1145E, WordBreakProperty.Extend], - [/*start*/ 0x1145F, WordBreakProperty.ALetter], - [/*start*/ 0x11462, WordBreakProperty.Other], - [/*start*/ 0x11480, WordBreakProperty.ALetter], - [/*start*/ 0x114B0, WordBreakProperty.Extend], - [/*start*/ 0x114C4, WordBreakProperty.ALetter], - [/*start*/ 0x114C6, WordBreakProperty.Other], - [/*start*/ 0x114C7, WordBreakProperty.ALetter], - [/*start*/ 0x114C8, WordBreakProperty.Other], - [/*start*/ 0x114D0, WordBreakProperty.Numeric], - [/*start*/ 0x114DA, WordBreakProperty.Other], - [/*start*/ 0x11580, WordBreakProperty.ALetter], - [/*start*/ 0x115AF, WordBreakProperty.Extend], - [/*start*/ 0x115B6, WordBreakProperty.Other], - [/*start*/ 0x115B8, WordBreakProperty.Extend], - [/*start*/ 0x115C1, WordBreakProperty.Other], - [/*start*/ 0x115D8, WordBreakProperty.ALetter], - [/*start*/ 0x115DC, WordBreakProperty.Extend], - [/*start*/ 0x115DE, WordBreakProperty.Other], - [/*start*/ 0x11600, WordBreakProperty.ALetter], - [/*start*/ 0x11630, WordBreakProperty.Extend], - [/*start*/ 0x11641, WordBreakProperty.Other], - [/*start*/ 0x11644, WordBreakProperty.ALetter], - [/*start*/ 0x11645, WordBreakProperty.Other], - [/*start*/ 0x11650, WordBreakProperty.Numeric], - [/*start*/ 0x1165A, WordBreakProperty.Other], - [/*start*/ 0x11680, WordBreakProperty.ALetter], - [/*start*/ 0x116AB, WordBreakProperty.Extend], - [/*start*/ 0x116B8, WordBreakProperty.ALetter], - [/*start*/ 0x116B9, WordBreakProperty.Other], - [/*start*/ 0x116C0, WordBreakProperty.Numeric], - [/*start*/ 0x116CA, WordBreakProperty.Other], - [/*start*/ 0x1171D, WordBreakProperty.Extend], - [/*start*/ 0x1172C, WordBreakProperty.Other], - [/*start*/ 0x11730, WordBreakProperty.Numeric], - [/*start*/ 0x1173A, WordBreakProperty.Other], - [/*start*/ 0x11800, WordBreakProperty.ALetter], - [/*start*/ 0x1182C, WordBreakProperty.Extend], - [/*start*/ 0x1183B, WordBreakProperty.Other], - [/*start*/ 0x118A0, WordBreakProperty.ALetter], - [/*start*/ 0x118E0, WordBreakProperty.Numeric], - [/*start*/ 0x118EA, WordBreakProperty.Other], - [/*start*/ 0x118FF, WordBreakProperty.ALetter], - [/*start*/ 0x11907, WordBreakProperty.Other], - [/*start*/ 0x11909, WordBreakProperty.ALetter], - [/*start*/ 0x1190A, WordBreakProperty.Other], - [/*start*/ 0x1190C, WordBreakProperty.ALetter], - [/*start*/ 0x11914, WordBreakProperty.Other], - [/*start*/ 0x11915, WordBreakProperty.ALetter], - [/*start*/ 0x11917, WordBreakProperty.Other], - [/*start*/ 0x11918, WordBreakProperty.ALetter], - [/*start*/ 0x11930, WordBreakProperty.Extend], - [/*start*/ 0x11936, WordBreakProperty.Other], - [/*start*/ 0x11937, WordBreakProperty.Extend], - [/*start*/ 0x11939, WordBreakProperty.Other], - [/*start*/ 0x1193B, WordBreakProperty.Extend], - [/*start*/ 0x1193F, WordBreakProperty.ALetter], - [/*start*/ 0x11940, WordBreakProperty.Extend], - [/*start*/ 0x11941, WordBreakProperty.ALetter], - [/*start*/ 0x11942, WordBreakProperty.Extend], - [/*start*/ 0x11944, WordBreakProperty.Other], - [/*start*/ 0x11950, WordBreakProperty.Numeric], - [/*start*/ 0x1195A, WordBreakProperty.Other], - [/*start*/ 0x119A0, WordBreakProperty.ALetter], - [/*start*/ 0x119A8, WordBreakProperty.Other], - [/*start*/ 0x119AA, WordBreakProperty.ALetter], - [/*start*/ 0x119D1, WordBreakProperty.Extend], - [/*start*/ 0x119D8, WordBreakProperty.Other], - [/*start*/ 0x119DA, WordBreakProperty.Extend], - [/*start*/ 0x119E1, WordBreakProperty.ALetter], - [/*start*/ 0x119E2, WordBreakProperty.Other], - [/*start*/ 0x119E3, WordBreakProperty.ALetter], - [/*start*/ 0x119E4, WordBreakProperty.Extend], - [/*start*/ 0x119E5, WordBreakProperty.Other], - [/*start*/ 0x11A00, WordBreakProperty.ALetter], - [/*start*/ 0x11A01, WordBreakProperty.Extend], - [/*start*/ 0x11A0B, WordBreakProperty.ALetter], - [/*start*/ 0x11A33, WordBreakProperty.Extend], - [/*start*/ 0x11A3A, WordBreakProperty.ALetter], - [/*start*/ 0x11A3B, WordBreakProperty.Extend], - [/*start*/ 0x11A3F, WordBreakProperty.Other], - [/*start*/ 0x11A47, WordBreakProperty.Extend], - [/*start*/ 0x11A48, WordBreakProperty.Other], - [/*start*/ 0x11A50, WordBreakProperty.ALetter], - [/*start*/ 0x11A51, WordBreakProperty.Extend], - [/*start*/ 0x11A5C, WordBreakProperty.ALetter], - [/*start*/ 0x11A8A, WordBreakProperty.Extend], - [/*start*/ 0x11A9A, WordBreakProperty.Other], - [/*start*/ 0x11A9D, WordBreakProperty.ALetter], - [/*start*/ 0x11A9E, WordBreakProperty.Other], - [/*start*/ 0x11AC0, WordBreakProperty.ALetter], - [/*start*/ 0x11AF9, WordBreakProperty.Other], - [/*start*/ 0x11C00, WordBreakProperty.ALetter], - [/*start*/ 0x11C09, WordBreakProperty.Other], - [/*start*/ 0x11C0A, WordBreakProperty.ALetter], - [/*start*/ 0x11C2F, WordBreakProperty.Extend], - [/*start*/ 0x11C37, WordBreakProperty.Other], - [/*start*/ 0x11C38, WordBreakProperty.Extend], - [/*start*/ 0x11C40, WordBreakProperty.ALetter], - [/*start*/ 0x11C41, WordBreakProperty.Other], - [/*start*/ 0x11C50, WordBreakProperty.Numeric], - [/*start*/ 0x11C5A, WordBreakProperty.Other], - [/*start*/ 0x11C72, WordBreakProperty.ALetter], - [/*start*/ 0x11C90, WordBreakProperty.Other], - [/*start*/ 0x11C92, WordBreakProperty.Extend], - [/*start*/ 0x11CA8, WordBreakProperty.Other], - [/*start*/ 0x11CA9, WordBreakProperty.Extend], - [/*start*/ 0x11CB7, WordBreakProperty.Other], - [/*start*/ 0x11D00, WordBreakProperty.ALetter], - [/*start*/ 0x11D07, WordBreakProperty.Other], - [/*start*/ 0x11D08, WordBreakProperty.ALetter], - [/*start*/ 0x11D0A, WordBreakProperty.Other], - [/*start*/ 0x11D0B, WordBreakProperty.ALetter], - [/*start*/ 0x11D31, WordBreakProperty.Extend], - [/*start*/ 0x11D37, WordBreakProperty.Other], - [/*start*/ 0x11D3A, WordBreakProperty.Extend], - [/*start*/ 0x11D3B, WordBreakProperty.Other], - [/*start*/ 0x11D3C, WordBreakProperty.Extend], - [/*start*/ 0x11D3E, WordBreakProperty.Other], - [/*start*/ 0x11D3F, WordBreakProperty.Extend], - [/*start*/ 0x11D46, WordBreakProperty.ALetter], - [/*start*/ 0x11D47, WordBreakProperty.Extend], - [/*start*/ 0x11D48, WordBreakProperty.Other], - [/*start*/ 0x11D50, WordBreakProperty.Numeric], - [/*start*/ 0x11D5A, WordBreakProperty.Other], - [/*start*/ 0x11D60, WordBreakProperty.ALetter], - [/*start*/ 0x11D66, WordBreakProperty.Other], - [/*start*/ 0x11D67, WordBreakProperty.ALetter], - [/*start*/ 0x11D69, WordBreakProperty.Other], - [/*start*/ 0x11D6A, WordBreakProperty.ALetter], - [/*start*/ 0x11D8A, WordBreakProperty.Extend], - [/*start*/ 0x11D8F, WordBreakProperty.Other], - [/*start*/ 0x11D90, WordBreakProperty.Extend], - [/*start*/ 0x11D92, WordBreakProperty.Other], - [/*start*/ 0x11D93, WordBreakProperty.Extend], - [/*start*/ 0x11D98, WordBreakProperty.ALetter], - [/*start*/ 0x11D99, WordBreakProperty.Other], - [/*start*/ 0x11DA0, WordBreakProperty.Numeric], - [/*start*/ 0x11DAA, WordBreakProperty.Other], - [/*start*/ 0x11EE0, WordBreakProperty.ALetter], - [/*start*/ 0x11EF3, WordBreakProperty.Extend], - [/*start*/ 0x11EF7, WordBreakProperty.Other], - [/*start*/ 0x11FB0, WordBreakProperty.ALetter], - [/*start*/ 0x11FB1, WordBreakProperty.Other], - [/*start*/ 0x12000, WordBreakProperty.ALetter], - [/*start*/ 0x1239A, WordBreakProperty.Other], - [/*start*/ 0x12400, WordBreakProperty.ALetter], - [/*start*/ 0x1246F, WordBreakProperty.Other], - [/*start*/ 0x12480, WordBreakProperty.ALetter], - [/*start*/ 0x12544, WordBreakProperty.Other], - [/*start*/ 0x13000, WordBreakProperty.ALetter], - [/*start*/ 0x1342F, WordBreakProperty.Other], - [/*start*/ 0x13430, WordBreakProperty.Format], - [/*start*/ 0x13439, WordBreakProperty.Other], - [/*start*/ 0x14400, WordBreakProperty.ALetter], - [/*start*/ 0x14647, WordBreakProperty.Other], - [/*start*/ 0x16800, WordBreakProperty.ALetter], - [/*start*/ 0x16A39, WordBreakProperty.Other], - [/*start*/ 0x16A40, WordBreakProperty.ALetter], - [/*start*/ 0x16A5F, WordBreakProperty.Other], - [/*start*/ 0x16A60, WordBreakProperty.Numeric], - [/*start*/ 0x16A6A, WordBreakProperty.Other], - [/*start*/ 0x16AD0, WordBreakProperty.ALetter], - [/*start*/ 0x16AEE, WordBreakProperty.Other], - [/*start*/ 0x16AF0, WordBreakProperty.Extend], - [/*start*/ 0x16AF5, WordBreakProperty.Other], - [/*start*/ 0x16B00, WordBreakProperty.ALetter], - [/*start*/ 0x16B30, WordBreakProperty.Extend], - [/*start*/ 0x16B37, WordBreakProperty.Other], - [/*start*/ 0x16B40, WordBreakProperty.ALetter], - [/*start*/ 0x16B44, WordBreakProperty.Other], - [/*start*/ 0x16B50, WordBreakProperty.Numeric], - [/*start*/ 0x16B5A, WordBreakProperty.Other], - [/*start*/ 0x16B63, WordBreakProperty.ALetter], - [/*start*/ 0x16B78, WordBreakProperty.Other], - [/*start*/ 0x16B7D, WordBreakProperty.ALetter], - [/*start*/ 0x16B90, WordBreakProperty.Other], - [/*start*/ 0x16E40, WordBreakProperty.ALetter], - [/*start*/ 0x16E80, WordBreakProperty.Other], - [/*start*/ 0x16F00, WordBreakProperty.ALetter], - [/*start*/ 0x16F4B, WordBreakProperty.Other], - [/*start*/ 0x16F4F, WordBreakProperty.Extend], - [/*start*/ 0x16F50, WordBreakProperty.ALetter], - [/*start*/ 0x16F51, WordBreakProperty.Extend], - [/*start*/ 0x16F88, WordBreakProperty.Other], - [/*start*/ 0x16F8F, WordBreakProperty.Extend], - [/*start*/ 0x16F93, WordBreakProperty.ALetter], - [/*start*/ 0x16FA0, WordBreakProperty.Other], - [/*start*/ 0x16FE0, WordBreakProperty.ALetter], - [/*start*/ 0x16FE2, WordBreakProperty.Other], - [/*start*/ 0x16FE3, WordBreakProperty.ALetter], - [/*start*/ 0x16FE4, WordBreakProperty.Extend], - [/*start*/ 0x16FE5, WordBreakProperty.Other], - [/*start*/ 0x16FF0, WordBreakProperty.Extend], - [/*start*/ 0x16FF2, WordBreakProperty.Other], - [/*start*/ 0x1B000, WordBreakProperty.Katakana], - [/*start*/ 0x1B001, WordBreakProperty.Other], - [/*start*/ 0x1B164, WordBreakProperty.Katakana], - [/*start*/ 0x1B168, WordBreakProperty.Other], - [/*start*/ 0x1BC00, WordBreakProperty.ALetter], - [/*start*/ 0x1BC6B, WordBreakProperty.Other], - [/*start*/ 0x1BC70, WordBreakProperty.ALetter], - [/*start*/ 0x1BC7D, WordBreakProperty.Other], - [/*start*/ 0x1BC80, WordBreakProperty.ALetter], - [/*start*/ 0x1BC89, WordBreakProperty.Other], - [/*start*/ 0x1BC90, WordBreakProperty.ALetter], - [/*start*/ 0x1BC9A, WordBreakProperty.Other], - [/*start*/ 0x1BC9D, WordBreakProperty.Extend], - [/*start*/ 0x1BC9F, WordBreakProperty.Other], - [/*start*/ 0x1BCA0, WordBreakProperty.Format], - [/*start*/ 0x1BCA4, WordBreakProperty.Other], - [/*start*/ 0x1D165, WordBreakProperty.Extend], - [/*start*/ 0x1D16A, WordBreakProperty.Other], - [/*start*/ 0x1D16D, WordBreakProperty.Extend], - [/*start*/ 0x1D173, WordBreakProperty.Format], - [/*start*/ 0x1D17B, WordBreakProperty.Extend], - [/*start*/ 0x1D183, WordBreakProperty.Other], - [/*start*/ 0x1D185, WordBreakProperty.Extend], - [/*start*/ 0x1D18C, WordBreakProperty.Other], - [/*start*/ 0x1D1AA, WordBreakProperty.Extend], - [/*start*/ 0x1D1AE, WordBreakProperty.Other], - [/*start*/ 0x1D242, WordBreakProperty.Extend], - [/*start*/ 0x1D245, WordBreakProperty.Other], - [/*start*/ 0x1D400, WordBreakProperty.ALetter], - [/*start*/ 0x1D455, WordBreakProperty.Other], - [/*start*/ 0x1D456, WordBreakProperty.ALetter], - [/*start*/ 0x1D49D, WordBreakProperty.Other], - [/*start*/ 0x1D49E, WordBreakProperty.ALetter], - [/*start*/ 0x1D4A0, WordBreakProperty.Other], - [/*start*/ 0x1D4A2, WordBreakProperty.ALetter], - [/*start*/ 0x1D4A3, WordBreakProperty.Other], - [/*start*/ 0x1D4A5, WordBreakProperty.ALetter], - [/*start*/ 0x1D4A7, WordBreakProperty.Other], - [/*start*/ 0x1D4A9, WordBreakProperty.ALetter], - [/*start*/ 0x1D4AD, WordBreakProperty.Other], - [/*start*/ 0x1D4AE, WordBreakProperty.ALetter], - [/*start*/ 0x1D4BA, WordBreakProperty.Other], - [/*start*/ 0x1D4BB, WordBreakProperty.ALetter], - [/*start*/ 0x1D4BC, WordBreakProperty.Other], - [/*start*/ 0x1D4BD, WordBreakProperty.ALetter], - [/*start*/ 0x1D4C4, WordBreakProperty.Other], - [/*start*/ 0x1D4C5, WordBreakProperty.ALetter], - [/*start*/ 0x1D506, WordBreakProperty.Other], - [/*start*/ 0x1D507, WordBreakProperty.ALetter], - [/*start*/ 0x1D50B, WordBreakProperty.Other], - [/*start*/ 0x1D50D, WordBreakProperty.ALetter], - [/*start*/ 0x1D515, WordBreakProperty.Other], - [/*start*/ 0x1D516, WordBreakProperty.ALetter], - [/*start*/ 0x1D51D, WordBreakProperty.Other], - [/*start*/ 0x1D51E, WordBreakProperty.ALetter], - [/*start*/ 0x1D53A, WordBreakProperty.Other], - [/*start*/ 0x1D53B, WordBreakProperty.ALetter], - [/*start*/ 0x1D53F, WordBreakProperty.Other], - [/*start*/ 0x1D540, WordBreakProperty.ALetter], - [/*start*/ 0x1D545, WordBreakProperty.Other], - [/*start*/ 0x1D546, WordBreakProperty.ALetter], - [/*start*/ 0x1D547, WordBreakProperty.Other], - [/*start*/ 0x1D54A, WordBreakProperty.ALetter], - [/*start*/ 0x1D551, WordBreakProperty.Other], - [/*start*/ 0x1D552, WordBreakProperty.ALetter], - [/*start*/ 0x1D6A6, WordBreakProperty.Other], - [/*start*/ 0x1D6A8, WordBreakProperty.ALetter], - [/*start*/ 0x1D6C1, WordBreakProperty.Other], - [/*start*/ 0x1D6C2, WordBreakProperty.ALetter], - [/*start*/ 0x1D6DB, WordBreakProperty.Other], - [/*start*/ 0x1D6DC, WordBreakProperty.ALetter], - [/*start*/ 0x1D6FB, WordBreakProperty.Other], - [/*start*/ 0x1D6FC, WordBreakProperty.ALetter], - [/*start*/ 0x1D715, WordBreakProperty.Other], - [/*start*/ 0x1D716, WordBreakProperty.ALetter], - [/*start*/ 0x1D735, WordBreakProperty.Other], - [/*start*/ 0x1D736, WordBreakProperty.ALetter], - [/*start*/ 0x1D74F, WordBreakProperty.Other], - [/*start*/ 0x1D750, WordBreakProperty.ALetter], - [/*start*/ 0x1D76F, WordBreakProperty.Other], - [/*start*/ 0x1D770, WordBreakProperty.ALetter], - [/*start*/ 0x1D789, WordBreakProperty.Other], - [/*start*/ 0x1D78A, WordBreakProperty.ALetter], - [/*start*/ 0x1D7A9, WordBreakProperty.Other], - [/*start*/ 0x1D7AA, WordBreakProperty.ALetter], - [/*start*/ 0x1D7C3, WordBreakProperty.Other], - [/*start*/ 0x1D7C4, WordBreakProperty.ALetter], - [/*start*/ 0x1D7CC, WordBreakProperty.Other], - [/*start*/ 0x1D7CE, WordBreakProperty.Numeric], - [/*start*/ 0x1D800, WordBreakProperty.Other], - [/*start*/ 0x1DA00, WordBreakProperty.Extend], - [/*start*/ 0x1DA37, WordBreakProperty.Other], - [/*start*/ 0x1DA3B, WordBreakProperty.Extend], - [/*start*/ 0x1DA6D, WordBreakProperty.Other], - [/*start*/ 0x1DA75, WordBreakProperty.Extend], - [/*start*/ 0x1DA76, WordBreakProperty.Other], - [/*start*/ 0x1DA84, WordBreakProperty.Extend], - [/*start*/ 0x1DA85, WordBreakProperty.Other], - [/*start*/ 0x1DA9B, WordBreakProperty.Extend], - [/*start*/ 0x1DAA0, WordBreakProperty.Other], - [/*start*/ 0x1DAA1, WordBreakProperty.Extend], - [/*start*/ 0x1DAB0, WordBreakProperty.Other], - [/*start*/ 0x1E000, WordBreakProperty.Extend], - [/*start*/ 0x1E007, WordBreakProperty.Other], - [/*start*/ 0x1E008, WordBreakProperty.Extend], - [/*start*/ 0x1E019, WordBreakProperty.Other], - [/*start*/ 0x1E01B, WordBreakProperty.Extend], - [/*start*/ 0x1E022, WordBreakProperty.Other], - [/*start*/ 0x1E023, WordBreakProperty.Extend], - [/*start*/ 0x1E025, WordBreakProperty.Other], - [/*start*/ 0x1E026, WordBreakProperty.Extend], - [/*start*/ 0x1E02B, WordBreakProperty.Other], - [/*start*/ 0x1E100, WordBreakProperty.ALetter], - [/*start*/ 0x1E12D, WordBreakProperty.Other], - [/*start*/ 0x1E130, WordBreakProperty.Extend], - [/*start*/ 0x1E137, WordBreakProperty.ALetter], - [/*start*/ 0x1E13E, WordBreakProperty.Other], - [/*start*/ 0x1E140, WordBreakProperty.Numeric], - [/*start*/ 0x1E14A, WordBreakProperty.Other], - [/*start*/ 0x1E14E, WordBreakProperty.ALetter], - [/*start*/ 0x1E14F, WordBreakProperty.Other], - [/*start*/ 0x1E2C0, WordBreakProperty.ALetter], - [/*start*/ 0x1E2EC, WordBreakProperty.Extend], - [/*start*/ 0x1E2F0, WordBreakProperty.Numeric], - [/*start*/ 0x1E2FA, WordBreakProperty.Other], - [/*start*/ 0x1E800, WordBreakProperty.ALetter], - [/*start*/ 0x1E8C5, WordBreakProperty.Other], - [/*start*/ 0x1E8D0, WordBreakProperty.Extend], - [/*start*/ 0x1E8D7, WordBreakProperty.Other], - [/*start*/ 0x1E900, WordBreakProperty.ALetter], - [/*start*/ 0x1E944, WordBreakProperty.Extend], - [/*start*/ 0x1E94B, WordBreakProperty.ALetter], - [/*start*/ 0x1E94C, WordBreakProperty.Other], - [/*start*/ 0x1E950, WordBreakProperty.Numeric], - [/*start*/ 0x1E95A, WordBreakProperty.Other], - [/*start*/ 0x1EE00, WordBreakProperty.ALetter], - [/*start*/ 0x1EE04, WordBreakProperty.Other], - [/*start*/ 0x1EE05, WordBreakProperty.ALetter], - [/*start*/ 0x1EE20, WordBreakProperty.Other], - [/*start*/ 0x1EE21, WordBreakProperty.ALetter], - [/*start*/ 0x1EE23, WordBreakProperty.Other], - [/*start*/ 0x1EE24, WordBreakProperty.ALetter], - [/*start*/ 0x1EE25, WordBreakProperty.Other], - [/*start*/ 0x1EE27, WordBreakProperty.ALetter], - [/*start*/ 0x1EE28, WordBreakProperty.Other], - [/*start*/ 0x1EE29, WordBreakProperty.ALetter], - [/*start*/ 0x1EE33, WordBreakProperty.Other], - [/*start*/ 0x1EE34, WordBreakProperty.ALetter], - [/*start*/ 0x1EE38, WordBreakProperty.Other], - [/*start*/ 0x1EE39, WordBreakProperty.ALetter], - [/*start*/ 0x1EE3A, WordBreakProperty.Other], - [/*start*/ 0x1EE3B, WordBreakProperty.ALetter], - [/*start*/ 0x1EE3C, WordBreakProperty.Other], - [/*start*/ 0x1EE42, WordBreakProperty.ALetter], - [/*start*/ 0x1EE43, WordBreakProperty.Other], - [/*start*/ 0x1EE47, WordBreakProperty.ALetter], - [/*start*/ 0x1EE48, WordBreakProperty.Other], - [/*start*/ 0x1EE49, WordBreakProperty.ALetter], - [/*start*/ 0x1EE4A, WordBreakProperty.Other], - [/*start*/ 0x1EE4B, WordBreakProperty.ALetter], - [/*start*/ 0x1EE4C, WordBreakProperty.Other], - [/*start*/ 0x1EE4D, WordBreakProperty.ALetter], - [/*start*/ 0x1EE50, WordBreakProperty.Other], - [/*start*/ 0x1EE51, WordBreakProperty.ALetter], - [/*start*/ 0x1EE53, WordBreakProperty.Other], - [/*start*/ 0x1EE54, WordBreakProperty.ALetter], - [/*start*/ 0x1EE55, WordBreakProperty.Other], - [/*start*/ 0x1EE57, WordBreakProperty.ALetter], - [/*start*/ 0x1EE58, WordBreakProperty.Other], - [/*start*/ 0x1EE59, WordBreakProperty.ALetter], - [/*start*/ 0x1EE5A, WordBreakProperty.Other], - [/*start*/ 0x1EE5B, WordBreakProperty.ALetter], - [/*start*/ 0x1EE5C, WordBreakProperty.Other], - [/*start*/ 0x1EE5D, WordBreakProperty.ALetter], - [/*start*/ 0x1EE5E, WordBreakProperty.Other], - [/*start*/ 0x1EE5F, WordBreakProperty.ALetter], - [/*start*/ 0x1EE60, WordBreakProperty.Other], - [/*start*/ 0x1EE61, WordBreakProperty.ALetter], - [/*start*/ 0x1EE63, WordBreakProperty.Other], - [/*start*/ 0x1EE64, WordBreakProperty.ALetter], - [/*start*/ 0x1EE65, WordBreakProperty.Other], - [/*start*/ 0x1EE67, WordBreakProperty.ALetter], - [/*start*/ 0x1EE6B, WordBreakProperty.Other], - [/*start*/ 0x1EE6C, WordBreakProperty.ALetter], - [/*start*/ 0x1EE73, WordBreakProperty.Other], - [/*start*/ 0x1EE74, WordBreakProperty.ALetter], - [/*start*/ 0x1EE78, WordBreakProperty.Other], - [/*start*/ 0x1EE79, WordBreakProperty.ALetter], - [/*start*/ 0x1EE7D, WordBreakProperty.Other], - [/*start*/ 0x1EE7E, WordBreakProperty.ALetter], - [/*start*/ 0x1EE7F, WordBreakProperty.Other], - [/*start*/ 0x1EE80, WordBreakProperty.ALetter], - [/*start*/ 0x1EE8A, WordBreakProperty.Other], - [/*start*/ 0x1EE8B, WordBreakProperty.ALetter], - [/*start*/ 0x1EE9C, WordBreakProperty.Other], - [/*start*/ 0x1EEA1, WordBreakProperty.ALetter], - [/*start*/ 0x1EEA4, WordBreakProperty.Other], - [/*start*/ 0x1EEA5, WordBreakProperty.ALetter], - [/*start*/ 0x1EEAA, WordBreakProperty.Other], - [/*start*/ 0x1EEAB, WordBreakProperty.ALetter], - [/*start*/ 0x1EEBC, WordBreakProperty.Other], - [/*start*/ 0x1F130, WordBreakProperty.ALetter], - [/*start*/ 0x1F14A, WordBreakProperty.Other], - [/*start*/ 0x1F150, WordBreakProperty.ALetter], - [/*start*/ 0x1F16A, WordBreakProperty.Other], - [/*start*/ 0x1F170, WordBreakProperty.ALetter], - [/*start*/ 0x1F18A, WordBreakProperty.Other], - [/*start*/ 0x1F1E6, WordBreakProperty.Regional_Indicator], - [/*start*/ 0x1F200, WordBreakProperty.Other], - [/*start*/ 0x1F3FB, WordBreakProperty.Extend], - [/*start*/ 0x1F400, WordBreakProperty.Other], - [/*start*/ 0x1FBF0, WordBreakProperty.Numeric], - [/*start*/ 0x1FBFA, WordBreakProperty.Other], - [/*start*/ 0xE0001, WordBreakProperty.Format], - [/*start*/ 0xE0002, WordBreakProperty.Other], - [/*start*/ 0xE0020, WordBreakProperty.Extend], - [/*start*/ 0xE0080, WordBreakProperty.Other], - [/*start*/ 0xE0100, WordBreakProperty.Extend], - [/*start*/ 0xE01F0, WordBreakProperty.Other], -]; diff --git a/developer/src/kmc-model/test/wordbreakers/default-wordbreaker-esm.ts b/developer/src/kmc-model/test/wordbreakers/default-wordbreaker-esm.ts deleted file mode 100644 index 55c0e560da..0000000000 --- a/developer/src/kmc-model/test/wordbreakers/default-wordbreaker-esm.ts +++ /dev/null @@ -1,383 +0,0 @@ -// TEMP: esm version of /common/models/wordbreakers/default/index.ts - - import { I, WORD_BREAK_PROPERTY, WordBreakProperty } from './data.js'; - - - /** - * Word breaker based on Unicode Standard Annex #29, Section 4.1: - * Default Word Boundary Specification. - * - * @see http://unicode.org/reports/tr29/#Word_Boundaries - * @see https://github.com/eddieantonio/unicode-default-word-boundary/tree/v12.0.0 - */ - export default function default_(text: string): Span[] { - let boundaries = findBoundaries(text); - if (boundaries.length == 0) { - return []; - } - - // All non-empty strings have at least TWO boundaries: at the start and at the end of - // the string. - let spans = []; - for (let i = 0; i < boundaries.length - 1; i++) { - let start = boundaries[i]; - let end = boundaries[i + 1]; - let span = new LazySpan(text, start, end); - - if (isNonSpace(span.text)) { - spans.push(span); - // Preserve a sequence-final space if it exists. Needed to signal "end of word". - } else if (i == boundaries.length - 2) { // if "we just checked the final boundary"... - // We don't want to return the whitespace itself; the correct token is simply ''. - span = new LazySpan(text, end, end); - spans.push(span); - } - } - return spans; - } - - // Utilities // - // type WordBreakProperty = data.WordBreakProperty; - // const WordBreakProperty = data.WordBreakProperty; - // type I = data.I; - // const I = data.I; - // const WORD_BREAK_PROPERTY = data.WORD_BREAK_PROPERTY; - - /** - * A span that does not cut out the substring until it absolutely has to! - */ - class LazySpan implements Span { - private _source: string; - readonly start: number; - readonly end: number; - constructor(source: string, start: number, end: number) { - this._source = source; - this.start = start; - this.end = end; - } - - get text(): string { - return this._source.substring(this.start, this.end); - } - - get length(): number { - return this.end - this.start; - } - } - - /** - * Returns true when the chunk does not solely consist of whitespace. - * - * @param chunk a chunk of text. Starts and ends at word boundaries. - */ - function isNonSpace(chunk: string): boolean { - return !Array.from(chunk).map(property).every(wb => ( - wb === WordBreakProperty.CR || - wb === WordBreakProperty.LF || - wb === WordBreakProperty.Newline || - wb === WordBreakProperty.WSegSpace - )); - } - - /** - * Yields a series of string indices where a word break should - * occur. That is, there should be a break BEFORE each string - * index yielded by this generator. - * - * @param text Text to find word boundaries in. - */ - function findBoundaries(text: string): number[] { - // WB1 and WB2: no boundaries if given an empty string. - if (text.length === 0) { - // There are no boundaries in an empty string! - return []; - } - - // This algorithm works by maintaining a sliding window of four SCALAR VALUES. - // - // - Scalar values? JavaScript strings are NOT actually a string of - // Unicode code points; some characters are made up of TWO - // JavaScript indices. e.g., - // "💩".length === 2; - // "💩"[0] === '\uD83D'; - // "💩"[1] === '\uDCA9'; - // - // These characters that are represented by TWO indices are - // called "surrogate pairs". Since we don't want to be in the - // "middle" of a character, make sure we're always advancing - // by scalar values, and NOT indices. That means, we sometimes - // need to advance by TWO indices, not just one. - // - Four values? Some rules look at what's to the left of - // left, and some look at what's to the right of right. So - // keep track of this! - - let boundaries = []; - - let rightPos: number; - let lookaheadPos = 0; // lookahead, one scalar value to the right of right. - // Before the start of the string is also the start of the string. - let lookbehind: WordBreakProperty; - let left = WordBreakProperty.sot; - let right = WordBreakProperty.sot; - let lookahead = wordbreakPropertyAt(0); - // Count RIs to make sure we're not splitting emoji flags: - let nConsecutiveRegionalIndicators = 0; - - do { - // Shift all positions, one scalar value to the right. - rightPos = lookaheadPos; - lookaheadPos = positionAfter(lookaheadPos); - // Shift all properties, one scalar value to the right. - [lookbehind, left, right, lookahead] = - [left, right, lookahead, wordbreakPropertyAt(lookaheadPos)]; - - // Break at the start and end of text, unless the text is empty. - // WB1: Break at start of text... - if (left === WordBreakProperty.sot) { - boundaries.push(rightPos); - continue; - } - // WB2: Break at the end of text... - if (right === WordBreakProperty.eot) { - boundaries.push(rightPos); - break; // Reached the end of the string. We're done! - } - // WB3: Do not break within CRLF: - if (left === WordBreakProperty.CR && right === WordBreakProperty.LF) - continue; - // WB3b: Otherwise, break after... - if (left === WordBreakProperty.Newline || - left === WordBreakProperty.CR || - left === WordBreakProperty.LF) { - boundaries.push(rightPos); - continue; - } - // WB3a: ...and before newlines - if (right === WordBreakProperty.Newline || - right === WordBreakProperty.CR || - right === WordBreakProperty.LF) { - boundaries.push(rightPos); - continue; - } - - // TODO: WB3c is not implemented, due to its complex, error-prone - // implementation, requiring a ginormous regexp, and the fact that - // the only thing it does is prevent big emoji sequences from being - // split up, like 🧚🏼‍♂️ - // https://www.unicode.org/Public/emoji/12.0/emoji-zwj-sequences.txt - - // WB3d: Keep horizontal whitespace together - if (left === WordBreakProperty.WSegSpace && right == WordBreakProperty.WSegSpace) - continue; - - // WB4: Ignore format and extend characters - // This is to keep grapheme clusters together! - // See: Section 6.2: https://unicode.org/reports/tr29/#Grapheme_Cluster_and_Format_Rules - // N.B.: The rule about "except after sot, CR, LF, and - // Newline" already been by WB1, WB2, WB3a, and WB3b above. - while (right === WordBreakProperty.Format || - right === WordBreakProperty.Extend || - right === WordBreakProperty.ZWJ) { - // Continue advancing in the string, as if these - // characters do not exist. DO NOT update left and - // lookbehind however! - [rightPos, lookaheadPos] = [lookaheadPos, positionAfter(lookaheadPos)]; - [right, lookahead] = [lookahead, wordbreakPropertyAt(lookaheadPos)]; - } - // In ignoring the characters in the previous loop, we could - // have fallen off the end of the string, so end the loop - // prematurely if that happens! - if (right === WordBreakProperty.eot) { - boundaries.push(rightPos); - break; - } - // WB4 (continued): Lookahead must ALSO ignore these format, - // extend, ZWJ characters! - while (lookahead === WordBreakProperty.Format || - lookahead === WordBreakProperty.Extend || - lookahead === WordBreakProperty.ZWJ) { - // Continue advancing in the string, as if these - // characters do not exist. DO NOT update left and right, - // however! - lookaheadPos = positionAfter(lookaheadPos); - lookahead = wordbreakPropertyAt(lookaheadPos); - } - - // WB5: Do not break between most letters. - if (isAHLetter(left) && isAHLetter(right)) - continue; - // Do not break across certain punctuation - // WB6: (Don't break before apostrophes in contractions) - if (isAHLetter(left) && isAHLetter(lookahead) && - (right === WordBreakProperty.MidLetter || isMidNumLetQ(right))) - continue; - // WB7: (Don't break after apostrophes in contractions) - if (isAHLetter(lookbehind) && isAHLetter(right) && - (left === WordBreakProperty.MidLetter || isMidNumLetQ(left))) - continue; - // WB7a - if (left === WordBreakProperty.Hebrew_Letter && right === WordBreakProperty.Single_Quote) - continue; - // WB7b - if (left === WordBreakProperty.Hebrew_Letter && right === WordBreakProperty.Double_Quote && - lookahead === WordBreakProperty.Hebrew_Letter) - continue; - // WB7c - if (lookbehind === WordBreakProperty.Hebrew_Letter && left === WordBreakProperty.Double_Quote && - right === WordBreakProperty.Hebrew_Letter) - continue; - // Do not break within sequences of digits, or digits adjacent to letters. - // e.g., "3a" or "A3" - // WB8 - if (left === WordBreakProperty.Numeric && right === WordBreakProperty.Numeric) - continue; - // WB9 - if (isAHLetter(left) && right === WordBreakProperty.Numeric) - continue; - // WB10 - if (left === WordBreakProperty.Numeric && isAHLetter(right)) - continue; - // Do not break within sequences, such as 3.2, 3,456.789 - // WB11 - if (lookbehind === WordBreakProperty.Numeric && right === WordBreakProperty.Numeric && - (left === WordBreakProperty.MidNum || isMidNumLetQ(left))) - continue; - // WB12 - if (left === WordBreakProperty.Numeric && lookahead === WordBreakProperty.Numeric && - (right === WordBreakProperty.MidNum || isMidNumLetQ(right))) - continue; - // WB13: Do not break between Katakana - if (left === WordBreakProperty.Katakana && right === WordBreakProperty.Katakana) - continue; - // Do not break from extenders (e.g., U+202F NARROW NO-BREAK SPACE) - // WB13a - if ((isAHLetter(left) || - left === WordBreakProperty.Numeric || - left === WordBreakProperty.Katakana || - left === WordBreakProperty.ExtendNumLet) && - right === WordBreakProperty.ExtendNumLet) - continue; - // WB13b - if ((isAHLetter(right) || - right === WordBreakProperty.Numeric || - right === WordBreakProperty.Katakana) && left === WordBreakProperty.ExtendNumLet) - continue; - - // WB15 & WB16: - // Do not break within emoji flag sequences. That is, do not break between - // regional indicator (RI) symbols if there is an odd number of RI - // characters before the break point. - if (right === WordBreakProperty.Regional_Indicator) { - // Emoji flags are actually composed of TWO scalar values, each being a - // "regional indicator". These indicators correspond to Latin letters. Put - // two of them together, and they spell out an ISO 3166-1-alpha-2 country - // code. Since these always come in pairs, NEVER split the pairs! So, if - // we happen to be inside the middle of an odd numbered of - // Regional_Indicators, DON'T SPLIT IT! - nConsecutiveRegionalIndicators += 1; - if ((nConsecutiveRegionalIndicators % 2) == 1) { - continue; - } - } else { - nConsecutiveRegionalIndicators = 0; - } - // WB999: Otherwise, break EVERYWHERE (including around ideographs) - boundaries.push(rightPos); - } while (rightPos < text.length); - - return boundaries; - - ///// Internal utility functions ///// - - /** - * Returns the position of the start of the next scalar value. This jumps - * over surrogate pairs. - * - * If asked for the character AFTER the end of the string, this always - * returns the length of the string. - */ - function positionAfter(pos: number): number { - if (pos >= text.length) { - return text.length; - } else if (isStartOfSurrogatePair(text[pos])) { - return pos + 2; - } - return pos + 1; - } - - /** - * Return the value of the Word_Break property at the given string index. - * @param pos position in the text. - */ - function wordbreakPropertyAt(pos: number) { - if (pos < 0) { - return WordBreakProperty.sot; // Always "start of string" before the string starts! - } else if (pos >= text.length) { - return WordBreakProperty.eot; // Always "end of string" after the string ends! - } else if (isStartOfSurrogatePair(text[pos])) { - // Surrogate pairs the next TWO items from the string! - return property(text[pos] + text[pos + 1]); - } - return property(text[pos]); - } - - // Word_Break rule macros - // See: https://unicode.org/reports/tr29/#WB_Rule_Macros - function isAHLetter(prop: WordBreakProperty): boolean { - return prop === WordBreakProperty.ALetter || - prop === WordBreakProperty.Hebrew_Letter; - } - - function isMidNumLetQ(prop: WordBreakProperty): boolean { - return prop === WordBreakProperty.MidNumLet || - prop === WordBreakProperty.Single_Quote; - } - } - - function isStartOfSurrogatePair(character: string) { - let codeUnit = character.charCodeAt(0); - return codeUnit >= 0xD800 && codeUnit <= 0xDBFF; - } - - /** - * Return the Word_Break property value for a character. - * Note that - * @param character a scalar value - */ - function property(character: string): WordBreakProperty { - // This MUST be a scalar value. - // TODO: remove dependence on character.codepointAt()? - let codepoint = character.codePointAt(0) as number; - return searchForProperty(codepoint, 0, WORD_BREAK_PROPERTY.length - 1); - } - - /** - * Binary search for the word break property of a given CODE POINT. - * - * The auto-generated data.ts master array defines a **character range** - * lookup table. If a character's codepoint is equal to or greater than - * the I.Start value for an entry and exclusively less than the next entry, - * it falls in the first entry's range bucket and is classified accordingly - * by this method. - */ - function searchForProperty(codePoint: number, left: number, right: number): WordBreakProperty { - // All items that are not found in the array are assigned the 'Other' property. - if (right < left) { - return WordBreakProperty.Other; - } - - let midpoint = left + ~~((right - left) / 2); - let candidate = WORD_BREAK_PROPERTY[midpoint]; - - let nextRange = WORD_BREAK_PROPERTY[midpoint + 1]; - let startOfNextRange = nextRange ? nextRange[I.Start] : Infinity; - - if (codePoint < candidate[I.Start]) { - return searchForProperty(codePoint, left, midpoint - 1); - } else if (codePoint >= startOfNextRange) { - return searchForProperty(codePoint, midpoint + 1, right); - } - - // We found it! - return candidate[I.Value]; - } From 383678a00241228073074e290be2bc620b51dae0 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 4 Oct 2023 17:34:43 +0700 Subject: [PATCH 073/107] chore(developer): cleanup hextobin call --- developer/src/kmc-ldml/test/test-compiler-e2e.ts | 4 +--- .../src/kmc-ldml/test/test-visual-keyboard-compiler-e2e.ts | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/developer/src/kmc-ldml/test/test-compiler-e2e.ts b/developer/src/kmc-ldml/test/test-compiler-e2e.ts index 41acd7c81d..343f6cc7ac 100644 --- a/developer/src/kmc-ldml/test/test-compiler-e2e.ts +++ b/developer/src/kmc-ldml/test/test-compiler-e2e.ts @@ -1,12 +1,10 @@ import 'mocha'; import {assert} from 'chai'; -import x_hextobin from '@keymanapp/hextobin'; +import hextobin from '@keymanapp/hextobin'; import { KMXBuilder } from '@keymanapp/common-types'; import {checkMessages, compileKeyboard, compilerTestCallbacks, compilerTestOptions, makePathToFixture} from './helpers/index.js'; import { LdmlKeyboardCompiler } from '../src/compiler/compiler.js'; -const hextobin = (x_hextobin as any).default; - describe('compiler-tests', function() { this.slow(500); // 0.5 sec -- json schema validation takes a while diff --git a/developer/src/kmc-ldml/test/test-visual-keyboard-compiler-e2e.ts b/developer/src/kmc-ldml/test/test-visual-keyboard-compiler-e2e.ts index 87d4d914c9..133f4286c8 100644 --- a/developer/src/kmc-ldml/test/test-visual-keyboard-compiler-e2e.ts +++ b/developer/src/kmc-ldml/test/test-visual-keyboard-compiler-e2e.ts @@ -1,11 +1,9 @@ import 'mocha'; import {assert} from 'chai'; -import x_hextobin from '@keymanapp/hextobin'; +import hextobin from '@keymanapp/hextobin'; import { KvkFileWriter } from '@keymanapp/common-types'; import {checkMessages, compilerTestOptions, compileVisualKeyboard, makePathToFixture} from './helpers/index.js'; -const hextobin = (x_hextobin as any).default; - describe('visual-keyboard-compiler', function() { this.slow(500); // 0.5 sec -- json schema validation takes a while From 2dd480c8e5c877b85a090c10facbe0cd2f650f22 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Wed, 4 Oct 2023 14:03:47 -0400 Subject: [PATCH 074/107] auto: increment master version to 17.0.187 --- HISTORY.md | 9 +++++++++ VERSION.md | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index afc72e7a17..e22d0e994b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,14 @@ # Keyman Version History +## 17.0.186 alpha 2023-10-04 + +* feat(developer): show an INFO message when warnings have failed a build (#9652) +* chore(developer): reduce duplicate words warning to hint (#9653) +* feat(developer): issue hint if package includes keyboard source files (#9658) +* chore(developer): switch on code coverage reporting for kmc (#9662) +* fix(core): clean cached ICU in core (#9668) +* feat(developer): warn if .kps includes a .js which is not touch-capable (#9667) + ## 17.0.185 alpha 2023-10-03 * chore(web): Add non-printing characters to the OSK (#9547) diff --git a/VERSION.md b/VERSION.md index e7118d25e1..8eb52f8484 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.186 \ No newline at end of file +17.0.187 \ No newline at end of file From 2472a941cfc3558d830a77413696d98c32bf68d8 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Wed, 4 Oct 2023 18:34:20 -0500 Subject: [PATCH 075/107] =?UTF-8?q?feat(core):=20match=20any=20marker=20?= =?UTF-8?q?=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add a regex form that matches any marker For: #9119 --- common/web/types/src/kmx/kmx-plus.ts | 4 ++-- .../types/src/ldml-keyboard/pattern-parser.ts | 12 ++++++++--- .../test/ldml-keyboard/test-pattern-parser.ts | 12 +++++++++++ core/src/ldml/C9134_ldml_markers.md | 2 ++ .../unit/ldml/keyboards/k_210_marker-test.xml | 20 ++++++++++++------- .../unit/ldml/keyboards/k_210_marker.xml | 3 +++ developer/src/kmc-ldml/src/compiler/tran.ts | 4 ++-- 7 files changed, 43 insertions(+), 14 deletions(-) diff --git a/common/web/types/src/kmx/kmx-plus.ts b/common/web/types/src/kmx/kmx-plus.ts index 1b653f2f5a..ea36f7908a 100644 --- a/common/web/types/src/kmx/kmx-plus.ts +++ b/common/web/types/src/kmx/kmx-plus.ts @@ -293,8 +293,8 @@ export class Vars extends Section { return v[0]; } } - substituteMarkerString(s : string) : string { - return MarkerParser.toSentinelString(s, this.markers); + substituteMarkerString(s : string, forMatch? : boolean) : string { + return MarkerParser.toSentinelString(s, this.markers, forMatch); } }; diff --git a/common/web/types/src/ldml-keyboard/pattern-parser.ts b/common/web/types/src/ldml-keyboard/pattern-parser.ts index f6013248d2..b02440553e 100644 --- a/common/web/types/src/ldml-keyboard/pattern-parser.ts +++ b/common/web/types/src/ldml-keyboard/pattern-parser.ts @@ -64,6 +64,9 @@ export class MarkerParser { public static readonly MAX_MARKER_INDEX = constants.marker_max_index; /** Max count of markers */ public static readonly MAX_MARKER_COUNT = constants.marker_max_count; + /** Expression that matches any marker */ + public static readonly ANY_MARKER_MATCH = + this.SENTINEL + this.MARKER_CODE + `[\\u0001-\\u${this.MAX_MARKER_INDEX.toString(16)}]`; /** * Pattern for matching a marker reference, OR the special marker \m{.} @@ -91,10 +94,13 @@ export class MarkerParser { } /** @returns all marker strings as sentinel values */ - public static toSentinelString(s: string, markers?: OrderedStringList) : string { + public static toSentinelString(s: string, markers?: OrderedStringList, forMatch?: boolean) : string { if (!s) return s; return s.replaceAll(this.REFERENCE, (sub, arg) => { if (arg === MarkerParser.ANY_MARKER_ID) { + if (forMatch) { + return this.ANY_MARKER_MATCH; + } return MarkerParser.markerOutput(MarkerParser.ANY_MARKER_INDEX); } if (!markers) { @@ -103,10 +109,10 @@ export class MarkerParser { const order = markers.getItemOrder(arg); if (order === -1) { throw RangeError(`Internal Error: Could not find marker \\m{${arg}}`); - } else if(order >= MarkerParser.MAX_MARKER_INDEX) { + } else if(order > MarkerParser.MAX_MARKER_INDEX) { throw RangeError(`Internal Error: marker \\m{${arg}} has out of range index ${order}`); } else { - return MarkerParser.markerOutput(order+1); + return MarkerParser.markerOutput(order + 1); } }); } diff --git a/common/web/types/test/ldml-keyboard/test-pattern-parser.ts b/common/web/types/test/ldml-keyboard/test-pattern-parser.ts index e7f06a1c55..1ea96797a7 100644 --- a/common/web/types/test/ldml-keyboard/test-pattern-parser.ts +++ b/common/web/types/test/ldml-keyboard/test-pattern-parser.ts @@ -75,6 +75,7 @@ describe('Test of Pattern Parsers', () => { 'a': 0, 'b': 1, 'c': 2, + 'zz': MarkerParser.MAX_MARKER_INDEX - 1, // this is an ordering, so needs to be -1 'zzz': 0x2FFFFF, }; const o = m[item]; @@ -103,6 +104,17 @@ describe('Test of Pattern Parsers', () => { markers ) ); + // verify the matching behavior of these + assert.isTrue(new RegExp(MarkerParser.toSentinelString(`Q\\m{a}`, markers, true), 'u') + .test(MarkerParser.toSentinelString(`Q\\m{a}`, markers, false)), `Q\\m{a} did not match`); + assert.isFalse(new RegExp(MarkerParser.toSentinelString(`Q\\m{a}`, markers, true), 'u') + .test(MarkerParser.toSentinelString(`Q\\m{b}`, markers, false)), `Q\\m{a} should not match Q\\m{b}`); + assert.isTrue(new RegExp(MarkerParser.toSentinelString(`Q\\m{.}`, markers, true), 'u') + .test(MarkerParser.toSentinelString(`Q\\m{a}`, markers, false)), `Q\\m{.} did not match Q\\m{a}`); + assert.isTrue(new RegExp(MarkerParser.toSentinelString(`Q\\m{.}`, markers, true), 'u') + .test(MarkerParser.toSentinelString(`Q\\m{zz}`, markers, false)), `Q\\m{.} did not match Q\\m{zz} (max marker)`); + assert.isFalse(new RegExp(MarkerParser.toSentinelString(`Q\\m{.}`, markers, true), 'u') + .test(MarkerParser.toSentinelString(`\\m{a}`, markers, false)), `Q\\m{.} did not match \\m{a}`); }); it('should match some marker constants', () => { assert.equal(constants.uc_sentinel, KMXFile.UC_SENTINEL); diff --git a/core/src/ldml/C9134_ldml_markers.md b/core/src/ldml/C9134_ldml_markers.md index 065dd0ee2f..788cd82b50 100644 --- a/core/src/ldml/C9134_ldml_markers.md +++ b/core/src/ldml/C9134_ldml_markers.md @@ -47,6 +47,8 @@ Note that this is different from other 0-based indices in KMX+. If there are thr ## Compiler (kmc) - `U+FFFF` needs to be illegal as a literal or escaped sequence. So `\u{FFFF}` is not allowed, for example, nor as a literal in the UTF-8 .xml stream. +- Matching `\m{abc}` (some marker) will turn into a match for `U+FFFF U+0008 U+XXXX` for that match. +- Matching `\m{.}` (_any_ marker) will turn into the special sequence `U+FFFF U+0008 [U+0001-U+D7FE]` where the latter is a range ### `vars` diff --git a/core/tests/unit/ldml/keyboards/k_210_marker-test.xml b/core/tests/unit/ldml/keyboards/k_210_marker-test.xml index 3286ac1179..73083e180f 100644 --- a/core/tests/unit/ldml/keyboards/k_210_marker-test.xml +++ b/core/tests/unit/ldml/keyboards/k_210_marker-test.xml @@ -3,7 +3,7 @@ - + - - @@ -41,6 +35,18 @@ + --> + + + + + + diff --git a/core/tests/unit/ldml/keyboards/k_210_marker.xml b/core/tests/unit/ldml/keyboards/k_210_marker.xml index 1635ce0a2a..d411725f6d 100644 --- a/core/tests/unit/ldml/keyboards/k_210_marker.xml +++ b/core/tests/unit/ldml/keyboards/k_210_marker.xml @@ -33,6 +33,9 @@ + + + diff --git a/developer/src/kmc-ldml/src/compiler/tran.ts b/developer/src/kmc-ldml/src/compiler/tran.ts index 9f39e302ef..f874273f6f 100644 --- a/developer/src/kmc-ldml/src/compiler/tran.ts +++ b/developer/src/kmc-ldml/src/compiler/tran.ts @@ -142,8 +142,8 @@ export class TransformCompiler Date: Wed, 4 Oct 2023 18:45:45 -0500 Subject: [PATCH 076/107] =?UTF-8?q?feat(core):=20more=20marker=20?= =?UTF-8?q?=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - reenable some tests For: #9119 --- .../unit/ldml/keyboards/k_210_marker-test.xml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/core/tests/unit/ldml/keyboards/k_210_marker-test.xml b/core/tests/unit/ldml/keyboards/k_210_marker-test.xml index 73083e180f..24f104f4d7 100644 --- a/core/tests/unit/ldml/keyboards/k_210_marker-test.xml +++ b/core/tests/unit/ldml/keyboards/k_210_marker-test.xml @@ -3,7 +3,7 @@ - + - + + + + + + + + + + From 41145243a3ae17dfac9629751bf609b280d2a519 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Wed, 4 Oct 2023 18:54:16 -0500 Subject: [PATCH 077/107] =?UTF-8?q?feat(developer):=20test:=20more=20vars?= =?UTF-8?q?=20and=20markers=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add and re-enable some tests For: #9121 For: #9119 --- .../src/kmc-ldml/test/fixtures/sections/disp/maximal.xml | 6 +++++- .../src/kmc-ldml/test/fixtures/sections/keys/maximal.xml | 7 +++++-- developer/src/kmc-ldml/test/test-keys.ts | 8 ++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/developer/src/kmc-ldml/test/fixtures/sections/disp/maximal.xml b/developer/src/kmc-ldml/test/fixtures/sections/disp/maximal.xml index 1a698edddb..18bc33ffd3 100644 --- a/developer/src/kmc-ldml/test/fixtures/sections/disp/maximal.xml +++ b/developer/src/kmc-ldml/test/fixtures/sections/disp/maximal.xml @@ -9,7 +9,11 @@ - + + + + + diff --git a/developer/src/kmc-ldml/test/fixtures/sections/keys/maximal.xml b/developer/src/kmc-ldml/test/fixtures/sections/keys/maximal.xml index 6c9b983fbd..7aaa99aa74 100644 --- a/developer/src/kmc-ldml/test/fixtures/sections/keys/maximal.xml +++ b/developer/src/kmc-ldml/test/fixtures/sections/keys/maximal.xml @@ -15,10 +15,9 @@ - + - @@ -34,4 +33,8 @@ + + + + diff --git a/developer/src/kmc-ldml/test/test-keys.ts b/developer/src/kmc-ldml/test/test-keys.ts index fb36f9a96f..0941169b4f 100644 --- a/developer/src/kmc-ldml/test/test-keys.ts +++ b/developer/src/kmc-ldml/test/test-keys.ts @@ -57,7 +57,7 @@ describe('keys', function () { const [flick0_ne_sw] = flick0.flicks.filter(({ directions }) => directions && directions.isEqual('ne sw'.split(' '))); assert.ok(flick0_ne_sw); - assert.equal(flick0_ne_sw.to?.value, 'ê'); + assert.equal(flick0_ne_sw.to?.value, 'ê'); // via variable }, }, { @@ -129,11 +129,11 @@ describe('keys', function () { const MARKER_1 = MarkerParser.markerOutput(1); assert.equal(ww.to.value, MARKER_1); assert.equal(ww.longPressDefault.value, MARKER_1); - // TODO-LDML: assert.equal(ww.longPress[0].value.value, MARKER_1); - // TODO-LDML: assert.equal(ww.multiTap[0].value.value, MARKER_1); + assert.equal(ww.longPress[0].value.value, MARKER_1); + assert.equal(ww.multiTap[0].value.value, MARKER_1); const [flickw] = keys.flicks?.filter(({id}) => id.value === 'flickw'); assert.ok(flickw); - // TODO-LDML: assert.equal(flickw.flicks[0].to.value, MARKER_1); + assert.equal(flickw.flicks[0].to.value, MARKER_1); }, }, ]); From e04b41e89ebe7d261015cea58a01283720a23f55 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Wed, 4 Oct 2023 19:21:04 -0500 Subject: [PATCH 078/107] =?UTF-8?q?feat(developer):=20fix=20vars=20and=20m?= =?UTF-8?q?arkers=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - finish all of the developer LDML-TODOs around markers and variables For: #9121 For: #9119 --- common/web/types/src/kmx/kmx-plus.ts | 13 +++++++ developer/src/kmc-ldml/src/compiler/disp.ts | 9 ++--- developer/src/kmc-ldml/src/compiler/keys.ts | 34 ++++++++++--------- .../test/fixtures/sections/disp/maximal.xml | 2 +- .../test/fixtures/sections/keys/maximal.xml | 3 +- developer/src/kmc-ldml/test/test-keys.ts | 4 +++ 6 files changed, 43 insertions(+), 22 deletions(-) diff --git a/common/web/types/src/kmx/kmx-plus.ts b/common/web/types/src/kmx/kmx-plus.ts index ea36f7908a..6ffffc138f 100644 --- a/common/web/types/src/kmx/kmx-plus.ts +++ b/common/web/types/src/kmx/kmx-plus.ts @@ -234,6 +234,7 @@ export class Vars extends Section { }); } substituteStrings(str: string, sections: DependencySections): string { + if (!str) return str; return str.replaceAll(VariableParser.STRING_REFERENCE, (_entire, id) => { const val = this.findStringVariableValue(id); if (val === null) { @@ -513,6 +514,18 @@ export class List extends Section { } return this.allocList(strs, s.split(' ').map(unescapeString)); } + /** perform string variable, marker, and unescaping */ + allocListFromSubstitutedSpaces(s: string, sections: DependencySections): ListItem { + if(s === undefined || s === null) { + s = ''; + } + return this.allocList(sections.strs, s.split(' ').map(s => { + s = sections.vars.substituteStrings(s, sections); + s = sections.vars.substituteMarkerString(s); + s = unescapeString(s); + return s; + })); + } /** * Return a List object referring to the string list. * Note that a falsy list, or a list containing only an empty string diff --git a/developer/src/kmc-ldml/src/compiler/disp.ts b/developer/src/kmc-ldml/src/compiler/disp.ts index 77c9609876..a3d8ae36fc 100644 --- a/developer/src/kmc-ldml/src/compiler/disp.ts +++ b/developer/src/kmc-ldml/src/compiler/disp.ts @@ -59,13 +59,14 @@ export class DispCompiler extends SectionCompiler { // displayOptions result.baseCharacter = sections.strs.allocAndUnescapeString(this.keyboard3.displays?.displayOptions?.baseCharacter); - // TODO-LDML: substitute variables! - // displays result.disps = this.keyboard3.displays?.display.map(display => ({ - to: sections.strs.allocAndUnescapeString(sections.vars.substituteMarkerString(display.to)), + to: sections.strs.allocAndUnescapeString( + sections.vars.substituteMarkerString( + sections.vars.substituteStrings(display.to, sections))), id: sections.strs.allocString(display.id), // not escaped, not substituted - display: sections.strs.allocAndUnescapeString(display.display), + display: sections.strs.allocAndUnescapeString( + sections.vars.substituteStrings(display.display, sections)), })) || []; // TODO-LDML: need coverage for the [] result.disps.sort((a: DispItem, b: DispItem) => { diff --git a/developer/src/kmc-ldml/src/compiler/keys.ts b/developer/src/kmc-ldml/src/compiler/keys.ts index 8482de316c..aad5e76f37 100644 --- a/developer/src/kmc-ldml/src/compiler/keys.ts +++ b/developer/src/kmc-ldml/src/compiler/keys.ts @@ -130,7 +130,11 @@ export class KeysCompiler extends SectionCompiler { for (let lkflick of lkflicks.flick) { let flags = 0; - const to = sections.strs.allocAndUnescapeString(lkflick.to, true); + let cookedTo = lkflick.to; + // pull in string variables and markers + cookedTo = sections.vars.substituteStrings(cookedTo, sections); + cookedTo = sections.vars.substituteMarkerString(cookedTo); + const to = sections.strs.allocAndUnescapeString(cookedTo, true); if (!to.isOneChar) { flags |= constants.keys_flick_flags_extend; } @@ -141,7 +145,6 @@ export class KeysCompiler extends SectionCompiler { flicks.flicks.push({ directions, flags, - // TODO-LDML: markers,variables to, }); } @@ -168,24 +171,23 @@ export class KeysCompiler extends SectionCompiler { flags |= constants.keys_key_flags_notransform; } const id = sections.strs.allocString(key.id); - const longPress: ListItem = sections.list.allocListFromEscapedSpaces( - sections.strs, - // TODO-LDML: markers,variables - key.longPress + const longPress: ListItem = sections.list.allocListFromSubstitutedSpaces( + key.longPress, + sections, ); - const longPressDefault = sections.strs.allocAndUnescapeString( - // TODO-LDML: variables - sections.vars.substituteMarkerString(key.longPressDefault), - ); - const multiTap: ListItem = sections.list.allocListFromEscapedSpaces( - sections.strs, - // TODO-LDML: markers,variables - key.multiTap + let cookedLongPressDefault = key.longPressDefault; + cookedLongPressDefault = sections.vars.substituteStrings(cookedLongPressDefault, sections); + cookedLongPressDefault = sections.vars.substituteMarkerString(cookedLongPressDefault) + const longPressDefault = sections.strs.allocAndUnescapeString(cookedLongPressDefault); + + const multiTap: ListItem = sections.list.allocListFromSubstitutedSpaces( + key.multiTap, + sections, ); const keySwitch = sections.strs.allocString(key.switch); // 'switch' is a reserved word const toRaw = key.to; - // TODO-LDML: variables - let toCooked = sections.vars.substituteMarkerString(toRaw); + let toCooked = sections.vars.substituteStrings(toRaw, sections); + toCooked = sections.vars.substituteMarkerString(toCooked); const to = sections.strs.allocAndUnescapeString(toCooked, true); if (!to.isOneChar) { flags |= constants.keys_key_flags_extend; diff --git a/developer/src/kmc-ldml/test/fixtures/sections/disp/maximal.xml b/developer/src/kmc-ldml/test/fixtures/sections/disp/maximal.xml index 18bc33ffd3..862c931004 100644 --- a/developer/src/kmc-ldml/test/fixtures/sections/disp/maximal.xml +++ b/developer/src/kmc-ldml/test/fixtures/sections/disp/maximal.xml @@ -9,7 +9,7 @@ - + diff --git a/developer/src/kmc-ldml/test/fixtures/sections/keys/maximal.xml b/developer/src/kmc-ldml/test/fixtures/sections/keys/maximal.xml index 7aaa99aa74..40f0be95ba 100644 --- a/developer/src/kmc-ldml/test/fixtures/sections/keys/maximal.xml +++ b/developer/src/kmc-ldml/test/fixtures/sections/keys/maximal.xml @@ -12,7 +12,7 @@ - + @@ -36,5 +36,6 @@ + diff --git a/developer/src/kmc-ldml/test/test-keys.ts b/developer/src/kmc-ldml/test/test-keys.ts index 0941169b4f..5a085a0d0f 100644 --- a/developer/src/kmc-ldml/test/test-keys.ts +++ b/developer/src/kmc-ldml/test/test-keys.ts @@ -38,6 +38,10 @@ describe('keys', function () { assert.equal(compilerTestCallbacks.messages.length, 0); assert.equal(keys.keys.length, 4); + const [w] = keys.keys.filter(({ id }) => id.value === 'w'); + assert.ok(w); + assert.equal(w.to.value, 'w', 'substituted key value'); + const [q] = keys.keys.filter(({ id }) => id.value === 'q'); assert.ok(q); assert.isFalse(!!(q.flags & constants.keys_key_flags_gap)); From a314ba46a6a87d7e6c687a3181d3da04baa22420 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 5 Oct 2023 14:42:33 +0700 Subject: [PATCH 079/107] fix(developer): server node addin paths --- developer/src/server/build-addins.inc.sh | 23 +++++++++++++++-------- developer/src/server/build.sh | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/developer/src/server/build-addins.inc.sh b/developer/src/server/build-addins.inc.sh index 3643ebffcd..d48d44d1e7 100644 --- a/developer/src/server/build-addins.inc.sh +++ b/developer/src/server/build-addins.inc.sh @@ -29,8 +29,13 @@ do_build_addins() { echo "TRAYICON_TARGET=$TRAYICON_TARGET" echo "HIDECONSOLE_TARGET=$HIDECONSOLE_TARGET" - HIDECONSOLE_TARGET="$KEYMAN_ROOT/developer/src/server/src/win32/console/$HIDECONSOLE_TARGET" - TRAYICON_TARGET="$KEYMAN_ROOT/developer/src/server/src/win32/trayicon/$TRAYICON_TARGET" + local HIDECONSOLE_SRC_TARGET="$KEYMAN_ROOT/developer/src/server/src/win32/console/$HIDECONSOLE_TARGET" + local HIDECONSOLE_BIN_TARGET="$KEYMAN_ROOT/developer/src/server/build/src/win32/console/$HIDECONSOLE_TARGET" + local TRAYICON_SRC_TARGET="$KEYMAN_ROOT/developer/src/server/src/win32/trayicon/$TRAYICON_TARGET" + local TRAYICON_BIN_TARGET="$KEYMAN_ROOT/developer/src/server/build/src/win32/trayicon/$TRAYICON_TARGET" + + mkdir -p "$(dirname "$HIDECONSOLE_BIN_TARGET")" + mkdir -p "$(dirname "$TRAYICON_BIN_TARGET")" # # Build node-windows-trayicon @@ -39,7 +44,8 @@ do_build_addins() { pushd "$KEYMAN_ROOT/node_modules/node-windows-trayicon" rm -rf build npx node-gyp clean configure build --arch=$ARCH --silent - cp build/Release/addon.node "$TRAYICON_TARGET" + cp build/Release/addon.node "$TRAYICON_SRC_TARGET" + cp build/Release/addon.node "$TRAYICON_BIN_TARGET" popd # @@ -49,7 +55,8 @@ do_build_addins() { pushd "$KEYMAN_ROOT/node_modules/hetrodo-node-hide-console-window-napi" rm -rf build npx node-gyp clean configure build --arch=$ARCH --silent - cp build/Release/node-hide-console-window.node "$HIDECONSOLE_TARGET" + cp build/Release/node-hide-console-window.node "$HIDECONSOLE_SRC_TARGET" + cp build/Release/node-hide-console-window.node "$HIDECONSOLE_BIN_TARGET" popd # @@ -57,10 +64,10 @@ do_build_addins() { # if (( NODEX64 )); then - [[ $(isFileX64 "$TRAYICON_TARGET") == 1 ]] || builder_die "$TRAYICON_TARGET should be 64-bit" - [[ $(isFileX64 "$HIDECONSOLE_TARGET") == 1 ]] || builder_die "$HIDECONSOLE_TARGET should be 64-bit" + [[ $(isFileX64 "$TRAYICON_BIN_TARGET") == 1 ]] || builder_die "$TRAYICON_TARGET should be 64-bit" + [[ $(isFileX64 "$HIDECONSOLE_BIN_TARGET") == 1 ]] || builder_die "$HIDECONSOLE_TARGET should be 64-bit" else - [[ $(isFileX64 "$TRAYICON_TARGET") == 0 ]] || builder_die "$TRAYICON_TARGET should not be 64-bit" - [[ $(isFileX64 "$HIDECONSOLE_TARGET") == 0 ]] || builder_die "$HIDECONSOLE_TARGET should not be 64-bit" + [[ $(isFileX64 "$TRAYICON_BIN_TARGET") == 0 ]] || builder_die "$TRAYICON_TARGET should not be 64-bit" + [[ $(isFileX64 "$HIDECONSOLE_BIN_TARGET") == 0 ]] || builder_die "$HIDECONSOLE_TARGET should not be 64-bit" fi } diff --git a/developer/src/server/build.sh b/developer/src/server/build.sh index 7e47d4f663..51523c52a3 100755 --- a/developer/src/server/build.sh +++ b/developer/src/server/build.sh @@ -32,7 +32,7 @@ builder_describe_outputs \ configure:server /node_modules \ configure:addins /node_modules \ build:server /developer/src/server/build/src/index.js \ - build:addins /developer/src/server/build/src/win32/console/index.js + build:addins /developer/src/server/build/src/win32/trayicon/addon.node builder_parse "$@" From 3f21f65c43124b779c98ed10bac1eb37593509d5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 5 Oct 2023 14:46:14 +0700 Subject: [PATCH 080/107] chore(common): fixup sourcemap-path-remapper build settings --- common/tools/sourcemap-path-remapper/src/convert-source-map.d.ts | 1 + common/tools/sourcemap-path-remapper/tsconfig.json | 1 + 2 files changed, 2 insertions(+) create mode 100644 common/tools/sourcemap-path-remapper/src/convert-source-map.d.ts diff --git a/common/tools/sourcemap-path-remapper/src/convert-source-map.d.ts b/common/tools/sourcemap-path-remapper/src/convert-source-map.d.ts new file mode 100644 index 0000000000..15a4da3c64 --- /dev/null +++ b/common/tools/sourcemap-path-remapper/src/convert-source-map.d.ts @@ -0,0 +1 @@ +declare module 'convert-source-map'; \ No newline at end of file diff --git a/common/tools/sourcemap-path-remapper/tsconfig.json b/common/tools/sourcemap-path-remapper/tsconfig.json index 6bf1a23b8d..e207097f61 100644 --- a/common/tools/sourcemap-path-remapper/tsconfig.json +++ b/common/tools/sourcemap-path-remapper/tsconfig.json @@ -5,6 +5,7 @@ "allowJs": false, "allowSyntheticDefaultImports": true, "declaration": true, + "sourceMap": false, "inlineSourceMap": true, "inlineSources": true, "sourceRoot": "/common/tools/sourcemap-path-remapper/src", From 6cfcf08f3fad0cfdf389fea5da7e8dfdc989427e Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 5 Oct 2023 15:32:43 +0700 Subject: [PATCH 081/107] chore(web): reduce strictness on ts --- web/tsconfig.base.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/web/tsconfig.base.json b/web/tsconfig.base.json index fa60ca26e6..ccb568c867 100644 --- a/web/tsconfig.base.json +++ b/web/tsconfig.base.json @@ -1,14 +1,24 @@ { "extends": "../tsconfig.base.json", + // TODO: eliminate settings duplicated in ../tsconfig.base.json "compilerOptions": { // Primary settings - the version of ES6 we can target in TS, our downcompile target, // and our module-related settings. "allowSyntheticDefaultImports": true, + "lib": ["es6"], "module": "es6", "target": "es5", + // TODO: These override ../tsconfig.base.json settings, and so should be removed if possible, + // but existing code in web/ breaks some of these settinsg + "noImplicitThis": false, + "noImplicitReturns": false, + "noImplicitAny": false, + "strictFunctionTypes": false, + "noUnusedLocals": false, + // Other settings - declaration files, sourcemapping, and other miscellaneous bits. "allowJs": false, "declaration": true, From 7e7c81e7ee28c7a0fa7ef80f735877730f3a7607 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 5 Oct 2023 15:48:53 +0700 Subject: [PATCH 082/107] chore(common): reduce strictness on ts for sentry-manager --- common/web/sentry-manager/src/tsconfig.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/common/web/sentry-manager/src/tsconfig.json b/common/web/sentry-manager/src/tsconfig.json index f42eaea73b..1b438c93c4 100644 --- a/common/web/sentry-manager/src/tsconfig.json +++ b/common/web/sentry-manager/src/tsconfig.json @@ -1,6 +1,16 @@ { "extends": "../../../../tsconfig.base.json", "compilerOptions": { + + // TODO: These override /tsconfig.base.json settings, and so should be removed if possible, + // but existing code in web/ breaks some of these settinsg + "noImplicitThis": false, + "noImplicitReturns": false, + "noImplicitAny": false, + "strictFunctionTypes": false, + "noUnusedLocals": false, + + "allowJs": true, "allowSyntheticDefaultImports": true, "baseUrl": "./", From 4c0cab2796dad1d02be58a7ca36fc9db6fee7976 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 5 Oct 2023 17:40:30 -0500 Subject: [PATCH 083/107] =?UTF-8?q?feat(common,developer):=20DRY=20out=20s?= =?UTF-8?q?trings=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - refactor string preprocessing pipeline into an options bag --- common/web/types/src/kmx/element-string.ts | 6 +- common/web/types/src/kmx/kmx-plus.ts | 99 +++++++++++---------- common/web/types/src/kmx/string-list.ts | 7 +- developer/src/kmc-ldml/src/compiler/disp.ts | 16 ++-- developer/src/kmc-ldml/src/compiler/keys.ts | 60 ++++++++----- developer/src/kmc-ldml/src/compiler/tran.ts | 23 ++--- developer/src/kmc-ldml/src/compiler/vars.ts | 2 +- 7 files changed, 121 insertions(+), 92 deletions(-) diff --git a/common/web/types/src/kmx/element-string.ts b/common/web/types/src/kmx/element-string.ts index ed64a498ff..816627c3d3 100644 --- a/common/web/types/src/kmx/element-string.ts +++ b/common/web/types/src/kmx/element-string.ts @@ -80,16 +80,16 @@ export class ElementString extends Array { throw Error(`Could not parse uset ${item.segment}`); } elem.uset = sections.uset.allocUset(uset, sections); - elem.value = sections.strs.allocString('', true); // no string + elem.value = sections.strs.allocString('', {singleOk: true}); // no string } else if (item.type === ElementType.codepoint || item.type === ElementType.escaped || item.type === ElementType.string) { // some kind of a string let str = item.segment; if (item.type === ElementType.escaped && !MATCH_HEX_ESCAPE.test(str)) { str = unescapeOneQuadString(str); // TODO-LDML: any other escape forms here? - elem.value = sections.strs.allocString(str, true); + elem.value = sections.strs.allocString(str, { singleOk: true }); } else { - elem.value = sections.strs.allocAndUnescapeString(str, true); + elem.value = sections.strs.allocString(str, { unescape: true, singleOk: true }); } // Now did we end up with one char or no? if (elem.value.isOneChar) { diff --git a/common/web/types/src/kmx/kmx-plus.ts b/common/web/types/src/kmx/kmx-plus.ts index 6ffffc138f..d28bcbfd3f 100644 --- a/common/web/types/src/kmx/kmx-plus.ts +++ b/common/web/types/src/kmx/kmx-plus.ts @@ -143,45 +143,67 @@ export class CharStrsItem extends StrsItem { } }; +/** class for string manipulation options. These are in order of the pipeline. */ +export interface StrsOptions { + /** apply string variables (requires sections) */ + stringVariables?: boolean; + /** apply markers (requires sections) */ + markers?: boolean; + /** unescape with unescapeString */ + unescape?: boolean; + /** string can be stored as a single CharStrsItem, not in strs table. */ + singleOk?: boolean; +}; + export class Strs extends Section { strings: StrsItem[] = [ new StrsItem('') ]; // C7043: The null string is always requierd /** * Allocate a StrsItem given the string, unescaping if necessary. * @param s escaped string - * @param singleOk if true, allocate a CharStrsItem (not in strs table) if single-char capable. - * @returns + * @param opts options for allocation + * @param sections other sections, if needed + * @returns StrsItem */ - allocAndUnescapeString(s?: string, singleOk?: boolean): StrsItem { - return this.allocString(unescapeString(s), singleOk); - } - /** - * Allocate a StrsItem given the string. - * @param s string - * @param singleOk if true, allocate a CharStrsItem (not in strs table) if single-char capable. - * @returns - */ - allocString(s?: string, singleOk?: boolean): StrsItem { - if(s === undefined || s === null) { - // undefined or null are always equivalent to empty string, see C7043 - s = ''; - } + allocString(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem { + // Run the string processing pipeline + s = Strs.processString(s, opts, sections); - if(typeof s !== 'string') { - throw new Error('alloc_string: s must be a string, undefined, or null.'); - } - - // if it's a single char, don't push it into the list - if (singleOk && isOneChar(s)) { + // if it's a single char, don't push it into the strs table + if (opts?.singleOk && isOneChar(s)) { return new CharStrsItem(s); } + // default: look to see if the string is already present let result = this.strings.find(item => item.value === s); if(result === undefined) { + // only add if not already present result = new StrsItem(s); this.strings.push(result); } return result; } + + /** process everything according to opts */ + static processString(s: string, opts: StrsOptions, sections: DependencySections) { + s = s ?? ''; + // type check everything else + if (typeof s !== 'string') { + throw new Error('alloc_string: s must be a string, undefined, or null.'); + } + // substitute variables + if (opts?.stringVariables) { + s = sections.vars.substituteStrings(s, sections); + } + // substitute markers + if (opts?.markers) { + s = sections.vars.substituteMarkerString(s); + } + // unescape \u{…} + if (opts?.unescape) { + s = unescapeString(s); + } + return s; + } }; /** @@ -310,7 +332,7 @@ export class VarsItem extends Section { constructor(id: string, value: string, sections: DependencySections) { super(); this.id = sections.strs.allocString(id); - this.value = sections.strs.allocAndUnescapeString(value); + this.value = sections.strs.allocString(value, {unescape: true}); } valid() : boolean { @@ -500,31 +522,14 @@ export class List extends Section { * Allocate a list from a space-separated list of items. * Note that passing undefined or null or `''` will * end up being the same as the empty list `[]` - * @param strs Strs section for allocation * @param s space-separated list of items + * @param opts string options + * @param sections sections * @returns a List object */ - allocListFromSpaces(strs: Strs, s?: string): ListItem { + allocListFromSpaces(s: string, opts: StrsOptions, sections: DependencySections): ListItem { s = s ?? ''; - return this.allocList(strs, s.split(' ')); - } - allocListFromEscapedSpaces(strs: Strs, s?: string): ListItem { - if(s === undefined || s === null) { - s = ''; - } - return this.allocList(strs, s.split(' ').map(unescapeString)); - } - /** perform string variable, marker, and unescaping */ - allocListFromSubstitutedSpaces(s: string, sections: DependencySections): ListItem { - if(s === undefined || s === null) { - s = ''; - } - return this.allocList(sections.strs, s.split(' ').map(s => { - s = sections.vars.substituteStrings(s, sections); - s = sections.vars.substituteMarkerString(s); - s = unescapeString(s); - return s; - })); + return this.allocList(s.split(' '), opts, sections); } /** * Return a List object referring to the string list. @@ -534,7 +539,7 @@ export class List extends Section { * @param s string list to allocate * @returns */ - allocList(strs: Strs, s?: string[]): ListItem { + allocList(s: string[], opts: StrsOptions, sections: DependencySections): ListItem { // Special case the 'null' list for [] or [''] if (!s || (s.length === 1 && s[0] === '')) { return this.lists[0]; @@ -542,14 +547,14 @@ export class List extends Section { let result = this.lists.find(item => item.isEqual(s)); if(result === undefined) { // allocate a new ListItem - result = new ListItem(strs, s); + result = new ListItem(s, opts, sections); this.lists.push(result); } return result; } constructor(strs: Strs) { super(); - this.lists.push(new ListItem(strs, [])); // C7043: null element string + this.lists.push(new ListItem([], {}, { strs })); // C7043: null element string } lists: ListItem[] = []; }; diff --git a/common/web/types/src/kmx/string-list.ts b/common/web/types/src/kmx/string-list.ts index f9f4b46e91..cbeb4e425d 100644 --- a/common/web/types/src/kmx/string-list.ts +++ b/common/web/types/src/kmx/string-list.ts @@ -1,5 +1,5 @@ import { OrderedStringList } from 'src/ldml-keyboard/pattern-parser.js'; -import { Strs, StrsItem } from './kmx-plus.js'; +import { DependencySections, StrsItem, StrsOptions } from './kmx-plus.js'; /** * A single entry in a ListItem. @@ -31,14 +31,13 @@ export class ListItem extends Array implements OrderedStringList { * @param source array of strings * @returns */ - constructor(strs: Strs, source: Array) { + constructor(source: Array, opts: StrsOptions, sections: DependencySections) { super(); if(!source) { return; } - for (const str of source) { - let index = new ListIndex(strs.allocString(str)); + let index = new ListIndex(sections.strs.allocString(str, opts, sections)); this.push(index); } } diff --git a/developer/src/kmc-ldml/src/compiler/disp.ts b/developer/src/kmc-ldml/src/compiler/disp.ts index a3d8ae36fc..ade215b1fa 100644 --- a/developer/src/kmc-ldml/src/compiler/disp.ts +++ b/developer/src/kmc-ldml/src/compiler/disp.ts @@ -57,16 +57,20 @@ export class DispCompiler extends SectionCompiler { let result = new Disp(); // displayOptions - result.baseCharacter = sections.strs.allocAndUnescapeString(this.keyboard3.displays?.displayOptions?.baseCharacter); + result.baseCharacter = sections.strs.allocString(this.keyboard3.displays?.displayOptions?.baseCharacter, {unescape: true}); // displays result.disps = this.keyboard3.displays?.display.map(display => ({ - to: sections.strs.allocAndUnescapeString( - sections.vars.substituteMarkerString( - sections.vars.substituteStrings(display.to, sections))), + to: sections.strs.allocString(display.to, { + stringVariables: true, + markers: true, + unescape: true, + }, sections), id: sections.strs.allocString(display.id), // not escaped, not substituted - display: sections.strs.allocAndUnescapeString( - sections.vars.substituteStrings(display.display, sections)), + display: sections.strs.allocString(display.display, { + stringVariables: true, + unescape: true, + }, sections), })) || []; // TODO-LDML: need coverage for the [] result.disps.sort((a: DispItem, b: DispItem) => { diff --git a/developer/src/kmc-ldml/src/compiler/keys.ts b/developer/src/kmc-ldml/src/compiler/keys.ts index aad5e76f37..a09ebbf2b2 100644 --- a/developer/src/kmc-ldml/src/compiler/keys.ts +++ b/developer/src/kmc-ldml/src/compiler/keys.ts @@ -130,18 +130,18 @@ export class KeysCompiler extends SectionCompiler { for (let lkflick of lkflicks.flick) { let flags = 0; - let cookedTo = lkflick.to; - // pull in string variables and markers - cookedTo = sections.vars.substituteStrings(cookedTo, sections); - cookedTo = sections.vars.substituteMarkerString(cookedTo); - const to = sections.strs.allocAndUnescapeString(cookedTo, true); + const to = sections.strs.allocString(lkflick.to, { + stringVariables: true, markers: true, unescape: true, singleOk: true + }, sections); if (!to.isOneChar) { flags |= constants.keys_flick_flags_extend; } let directions: ListItem = sections.list.allocListFromSpaces( - sections.strs, - lkflick.directions - ); + lkflick.directions, + { + stringVariables: true, markers: true, unescape: true + }, + sections); flicks.flicks.push({ directions, flags, @@ -171,24 +171,44 @@ export class KeysCompiler extends SectionCompiler { flags |= constants.keys_key_flags_notransform; } const id = sections.strs.allocString(key.id); - const longPress: ListItem = sections.list.allocListFromSubstitutedSpaces( - key.longPress, - sections, - ); - let cookedLongPressDefault = key.longPressDefault; - cookedLongPressDefault = sections.vars.substituteStrings(cookedLongPressDefault, sections); - cookedLongPressDefault = sections.vars.substituteMarkerString(cookedLongPressDefault) - const longPressDefault = sections.strs.allocAndUnescapeString(cookedLongPressDefault); + const longPress: ListItem = sections.list.allocListFromSpaces( + key.longPress, { + stringVariables: true, + markers: true, + unescape: true, + }, + sections); - const multiTap: ListItem = sections.list.allocListFromSubstitutedSpaces( + const longPressDefault = sections.strs.allocString(key.longPressDefault, + { + stringVariables: true, + markers: true, + unescape: true, + }, + sections); + + const multiTap: ListItem = sections.list.allocListFromSpaces( key.multiTap, - sections, - ); + { + stringVariables: true, + markers: true, + unescape: true, + }, + sections); const keySwitch = sections.strs.allocString(key.switch); // 'switch' is a reserved word + const toRaw = key.to; + let toCooked = sections.vars.substituteStrings(toRaw, sections); toCooked = sections.vars.substituteMarkerString(toCooked); - const to = sections.strs.allocAndUnescapeString(toCooked, true); + const to = sections.strs.allocString(key.to, + { + stringVariables: true, + markers: true, + unescape: true, + singleOk: true + }, + sections); if (!to.isOneChar) { flags |= constants.keys_key_flags_extend; } diff --git a/developer/src/kmc-ldml/src/compiler/tran.ts b/developer/src/kmc-ldml/src/compiler/tran.ts index f874273f6f..89a9d61f1c 100644 --- a/developer/src/kmc-ldml/src/compiler/tran.ts +++ b/developer/src/kmc-ldml/src/compiler/tran.ts @@ -121,12 +121,11 @@ export class TransformCompiler m !== MarkerParser.ANY_MARKER_ID).sort(); - result.markers = sections.list.allocList(sections.strs, allMarkers); + result.markers = sections.list.allocList(allMarkers, {}, sections); return result.valid() ? result : null; } From eeb755f76a2b65ff95d9c1a2eabeff154558f040 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 6 Oct 2023 09:14:35 +0700 Subject: [PATCH 084/107] fix(windows): re-enable signature check Fixes #9692. Signature checking was skipped because we missed a ".virtual" to force nmake to build the test and test_i3633 targets. This opened up a small cascade of related formatting issues on Makefiles, and the fact that the test_i3633 (has there ever been a more poorly named project?) Makefile did not even work. Refactored significantly, added same tests to Developer Makefile, and also now verifying the .msi and installer executable. We can improve this further but I'd like to get this in to avoid further critical issues with code signing given the current broken signing configuration. --- .../windows/delphi/ext/sentry/test/Makefile | 3 +- common/windows/delphi/tools/Makefile | 6 +++- .../delphi/tools/verify_signatures/Makefile | 13 ++++++++ .../tools/verify_signatures}/sigcheck.bin | Bin .../verify_signatures/verify_signatures.dpr | 4 +-- .../verify_signatures/verify_signatures.dproj | 6 ++-- .../verify_signatures/verify_signatures.res | Bin developer/src/Makefile | 2 ++ developer/src/inst/download.in.mak | 3 ++ .../src/tools/verify_signatures/Makefile | 19 +++++++++++ windows/src/Defines.mak | 9 +++++ windows/src/Makefile | 2 +- windows/src/desktop/inst/download.in | 4 +++ windows/src/desktop/insthelp/Makefile | 4 +-- windows/src/desktop/kmconfig/Makefile | 2 +- windows/src/desktop/kmshell/Makefile | 2 +- windows/src/support/charident/Makefile | 2 +- windows/src/support/km_yim/Makefile | 5 +-- windows/src/test/Makefile | 14 ++++---- windows/src/test/test_i3633/Makefile | 31 ------------------ windows/src/test/verify_signatures/Makefile | 21 ++++++++++++ 21 files changed, 100 insertions(+), 52 deletions(-) create mode 100644 common/windows/delphi/tools/verify_signatures/Makefile rename {windows/src/test/test_i3633 => common/windows/delphi/tools/verify_signatures}/sigcheck.bin (100%) rename windows/src/test/test_i3633/verify.dpr => common/windows/delphi/tools/verify_signatures/verify_signatures.dpr (94%) rename windows/src/test/test_i3633/verify.dproj => common/windows/delphi/tools/verify_signatures/verify_signatures.dproj (99%) rename windows/src/test/test_i3633/verify.res => common/windows/delphi/tools/verify_signatures/verify_signatures.res (100%) create mode 100644 developer/src/tools/verify_signatures/Makefile delete mode 100644 windows/src/test/test_i3633/Makefile create mode 100644 windows/src/test/verify_signatures/Makefile diff --git a/common/windows/delphi/ext/sentry/test/Makefile b/common/windows/delphi/ext/sentry/test/Makefile index 63fc664b01..b2e92bb896 100644 --- a/common/windows/delphi/ext/sentry/test/Makefile +++ b/common/windows/delphi/ext/sentry/test/Makefile @@ -4,7 +4,8 @@ !include ..\..\..\Defines.mak -build: dirs # version.res manifest.res +build: dirs +# version.res manifest.res $(DELPHI_MSBUILD) SentryClientTest.dproj "/p:Platform=Win32" $(DELPHI_MSBUILD) SentryClientVclTest.dproj "/p:Platform=Win32" diff --git a/common/windows/delphi/tools/Makefile b/common/windows/delphi/tools/Makefile index a9c1151473..2ea11ab237 100644 --- a/common/windows/delphi/tools/Makefile +++ b/common/windows/delphi/tools/Makefile @@ -7,7 +7,7 @@ NOTARGET_SIGNCODE=yes !ifdef NODELPHI TARGETS=.virtual !else -TARGETS=build_standards_data buildunidata devtools sentrytool test-klog +TARGETS=build_standards_data buildunidata devtools sentrytool test-klog verify_signatures !endif CLEANS=clean-tools @@ -28,6 +28,10 @@ buildunidata: .virtual cd $(COMMON_ROOT)\tools\buildunidata $(MAKE) $(TARGET) +verify_signatures: .virtual + cd $(COMMON_ROOT)\tools\verify_signatures + $(MAKE) $(TARGET) + devtools: .virtual !ifdef NODELPHI echo Skipping devtools diff --git a/common/windows/delphi/tools/verify_signatures/Makefile b/common/windows/delphi/tools/verify_signatures/Makefile new file mode 100644 index 0000000000..0f67747665 --- /dev/null +++ b/common/windows/delphi/tools/verify_signatures/Makefile @@ -0,0 +1,13 @@ +# +# test for signatures and version information being correct in ?install directory or ?bin directory +# + +!include ..\..\Defines.mak + +build: + $(DELPHI_MSBUILD) verify_signatures.dproj + copy sigcheck.bin $(WIN32_TARGET_PATH)\sigcheck.exe + +clean: def-clean + +!include ..\..\Target.mak diff --git a/windows/src/test/test_i3633/sigcheck.bin b/common/windows/delphi/tools/verify_signatures/sigcheck.bin similarity index 100% rename from windows/src/test/test_i3633/sigcheck.bin rename to common/windows/delphi/tools/verify_signatures/sigcheck.bin diff --git a/windows/src/test/test_i3633/verify.dpr b/common/windows/delphi/tools/verify_signatures/verify_signatures.dpr similarity index 94% rename from windows/src/test/test_i3633/verify.dpr rename to common/windows/delphi/tools/verify_signatures/verify_signatures.dpr index b3707d8461..fe77f887d7 100644 --- a/windows/src/test/test_i3633/verify.dpr +++ b/common/windows/delphi/tools/verify_signatures/verify_signatures.dpr @@ -1,4 +1,4 @@ -program verify; +program verify_signatures; {$APPTYPE CONSOLE} @@ -90,7 +90,7 @@ begin if (ParamStr(1) = '-?') or (ParamCount < 1) then begin - writeln('verify [-d] VERSION.md: Verify the output of sigcheck to ensure all executables are signed and have proper version.'); + writeln('verify_signatures [-d] VERSION.md: Verify the output of sigcheck to ensure all executables are signed and have proper version.'); writeln(' -d: Check the timestamp on the signature is less than 2 days old.'); writeln(' VERSION.md: path to the version to verify against'); Halt(2); diff --git a/windows/src/test/test_i3633/verify.dproj b/common/windows/delphi/tools/verify_signatures/verify_signatures.dproj similarity index 99% rename from windows/src/test/test_i3633/verify.dproj rename to common/windows/delphi/tools/verify_signatures/verify_signatures.dproj index e23aeb3a4d..323353c79b 100644 --- a/windows/src/test/test_i3633/verify.dproj +++ b/common/windows/delphi/tools/verify_signatures/verify_signatures.dproj @@ -3,7 +3,7 @@ {A6DCA558-8DD0-4FFF-8DAE-F305AB8D2AF4} 18.8 None - verify.dpr + verify_signatures.dpr True Debug Win32 @@ -45,7 +45,7 @@ true - verify + verify_signatures $(BDS)\bin\delphi_PROJECTICNS.icns $(BDS)\bin\delphi_PROJECTICON.ico bindcompfmx;fmx;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;DBXInterBaseDriver;xmlrtl;DbxCommonDriver;DBXMySQLDriver;dbxcds;soaprtl;bindengine;CustomIPTransport;dsnap;fmxase;inet;fmxobj;inetdbxpress;fmxdae;dbexpress;$(DCC_UsePackage) @@ -161,7 +161,7 @@ - verify.dpr + verify_signatures.dpr Microsoft Office 2000 Sample Automation Server Wrapper Components diff --git a/windows/src/test/test_i3633/verify.res b/common/windows/delphi/tools/verify_signatures/verify_signatures.res similarity index 100% rename from windows/src/test/test_i3633/verify.res rename to common/windows/delphi/tools/verify_signatures/verify_signatures.res diff --git a/developer/src/Makefile b/developer/src/Makefile index 0c6c81ece6..6a1cf398e5 100644 --- a/developer/src/Makefile +++ b/developer/src/Makefile @@ -153,6 +153,8 @@ do-build-release: $(MAKE) build-release-dependencies $(MAKE) "SIGNCODE_BUILD=SIGNCODE_BUILD" build test $(MAKE) signcode + cd $(DEVELOPER_ROOT)\src\tools\verify_signatures + $(MAKE) test cd $(DEVELOPER_ROOT)\src\inst $(MAKE) diff --git a/developer/src/inst/download.in.mak b/developer/src/inst/download.in.mak index eeadd67ac0..871f4b012c 100644 --- a/developer/src/inst/download.in.mak +++ b/developer/src/inst/download.in.mak @@ -26,6 +26,9 @@ copykmdev: makeinstaller make-kmcomp-install-zip -mkdir $(DEVELOPER_ROOT)\release\$Version copy /Y $(DEVELOPER_ROOT)\src\inst\keymandeveloper.msi $(DEVELOPER_ROOT)\release\$Version\keymandeveloper.msi copy /Y $(DEVELOPER_ROOT)\src\inst\keymandeveloper-$Version.exe $(DEVELOPER_ROOT)\release\$Version\keymandeveloper-$Version.exe + $(SIGCHECK) $(DEVELOPER_ROOT)\release\$Version\* > sig1 + $(VERIFY_SIGNATURES) < sig1 + -del sig1 test-releaseexists: if exist $(DEVELOPER_ROOT)\release\$Version\keymandeveloper*.msi echo. & echo Release $Version already exists. Delete it or update VERSION.md and try again & exit 1 diff --git a/developer/src/tools/verify_signatures/Makefile b/developer/src/tools/verify_signatures/Makefile new file mode 100644 index 0000000000..003f6aa5d5 --- /dev/null +++ b/developer/src/tools/verify_signatures/Makefile @@ -0,0 +1,19 @@ +# +# test for signatures and version information being correct in bin folder +# + +!include ..\..\Defines.mak + +test: prereq + $(SIGCHECK) $(DEVELOPER_PROGRAM)\* > sig1 + $(VERIFY_SIGNATURES) < sig1 + +# prereq may not be needed? +prereq: + cd $(VERIFY_SIGNATURES_PATH) + $(MAKE) + +clean: def-clean + -del sig1 + +!include ..\..\Target.mak diff --git a/windows/src/Defines.mak b/windows/src/Defines.mak index bf8f77b998..9506dfa6df 100644 --- a/windows/src/Defines.mak +++ b/windows/src/Defines.mak @@ -322,3 +322,12 @@ SYMSTORE="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\symstore.exe" add /compress /f CLEAN=-del /S /Q + +# +# Signature checks +# + +VERIFY_SIGNATURES_PATH=$(KEYMAN_ROOT)\common\windows\delphi\tools\verify_signatures +# Note: hyphen prefix is important to ignore return value from sigcheck +SIGCHECK=-$(VERIFY_SIGNATURES_PATH)\$(WIN32_TARGET_PATH)\sigcheck -q -s -e -v -accepteula +VERIFY_SIGNATURES=$(VERIFY_SIGNATURES_PATH)\$(WIN32_TARGET_PATH)\verify_signatures -d $(KEYMAN_ROOT)\VERSION.md diff --git a/windows/src/Makefile b/windows/src/Makefile index 7dda885263..e9048fcf71 100644 --- a/windows/src/Makefile +++ b/windows/src/Makefile @@ -81,7 +81,7 @@ support: global $(MAKE) $(TARGET) cd $(ROOT)\src -test: +test: .virtual cd $(ROOT)\src\test $(MAKE) $(TARGET) cd $(ROOT)\src diff --git a/windows/src/desktop/inst/download.in b/windows/src/desktop/inst/download.in index 0bf062eeba..17b832210c 100644 --- a/windows/src/desktop/inst/download.in +++ b/windows/src/desktop/inst/download.in @@ -17,6 +17,10 @@ copyredist-desktop: copy /Y keymandesktop.exe $(ROOT)\release\$Version\keyman-$Version.exe copy /Y $(ROOT)\bin\desktop\setup.exe $(ROOT)\release\$Version\setup.exe + $(SIGCHECK) $(ROOT)\release\$Version\* > sig1 + $(VERIFY_SIGNATURES) < sig1 + -del sig1 + # Copy the unsigned setup.exe for use in bundling scenarios; zip it up for clarity $(WZZIP) $(ROOT)\release\$Version\setup-redist.zip $(ROOT)\bin\desktop\setup-redist.exe diff --git a/windows/src/desktop/insthelp/Makefile b/windows/src/desktop/insthelp/Makefile index b3d4dcdf07..b1ca957636 100644 --- a/windows/src/desktop/insthelp/Makefile +++ b/windows/src/desktop/insthelp/Makefile @@ -11,9 +11,9 @@ build: version.res dirs $(COPY) $(WIN32_TARGET_PATH)\insthelp.exe $(ROOT)\bin\desktop\insthelp.exe test-manifest: - # test that (a) linked manifest exists and correct, and (b) has uiAccess=true +# test that (a) linked manifest exists and correct, and (b) has uiAccess=true @rem $(MT) -nologo -inputresource:$(PROGRAM)\desktop\insthelp.exe -validate_manifest - # TODO: Investigate why no manifest included? +# TODO: Investigate why no manifest included? clean: def-clean diff --git a/windows/src/desktop/kmconfig/Makefile b/windows/src/desktop/kmconfig/Makefile index d7f308f9d6..9802875833 100644 --- a/windows/src/desktop/kmconfig/Makefile +++ b/windows/src/desktop/kmconfig/Makefile @@ -21,7 +21,7 @@ wrap-symbols: $(SYMSTORE) $(DEBUGPATH)\desktop\kmconfig.dbg /t keyman-windows test-manifest: - # test that linked manifest exists and correct +# test that linked manifest exists and correct $(MT) -nologo -inputresource:$(PROGRAM)\desktop\kmconfig.exe -validate_manifest install: diff --git a/windows/src/desktop/kmshell/Makefile b/windows/src/desktop/kmshell/Makefile index caaa7da54e..773942d0a1 100644 --- a/windows/src/desktop/kmshell/Makefile +++ b/windows/src/desktop/kmshell/Makefile @@ -39,7 +39,7 @@ wrap-symbols: $(SYMSTORE) $(DEBUGPATH)\desktop\kmshell.dbg /t keyman-windows test-manifest: - # test that (a) linked manifest exists and correct, and (b) has uiAccess=true +# test that (a) linked manifest exists and correct, and (b) has uiAccess=true $(MT) -nologo -inputresource:$(PROGRAM)\desktop\kmshell.exe -validate_manifest install: .virtual diff --git a/windows/src/support/charident/Makefile b/windows/src/support/charident/Makefile index dd6721c5c0..cff6741677 100644 --- a/windows/src/support/charident/Makefile +++ b/windows/src/support/charident/Makefile @@ -15,6 +15,6 @@ signcode: wrap-symbols: $(SYMSTORE) $(PROGRAM)\support\charident.exe /t keyman-windows - #TODO: $(SYMSTORE) $(DEBUGPATH)\support\charident.dbg /t keyman-windows +#TODO: $(SYMSTORE) $(DEBUGPATH)\support\charident.dbg /t keyman-windows !include ..\..\Target.mak diff --git a/windows/src/support/km_yim/Makefile b/windows/src/support/km_yim/Makefile index f0f93e6fe2..1aef5f80f0 100644 --- a/windows/src/support/km_yim/Makefile +++ b/windows/src/support/km_yim/Makefile @@ -4,12 +4,13 @@ !include ..\..\Defines.mak -build: # version.res +build: +# version.res $(DCC32) km_yim.dpr rem $(TDSPACK) $(PROGRAM)\desktop\km_yim.exe km_yim.tds rem $(TDS2DBG) $(PROGRAM)\desktop\km_yim.exe $(WZZIP) inst_km_yim.zip km_yim.exe - # $(WZSE) inst_km_yim -setup -t inst_km_yim.dialog.txt -st "Tavultesoft Keyman Desktop Yahoo Messenger Addin" -c km_yim.exe +# $(WZSE) inst_km_yim -setup -t inst_km_yim.dialog.txt -st "Tavultesoft Keyman Desktop Yahoo Messenger Addin" -c km_yim.exe clean: def-clean if exist inst_km_yim.zip del inst_km_yim.zip diff --git a/windows/src/test/Makefile b/windows/src/test/Makefile index 5df2892dfa..5e8dec85b5 100644 --- a/windows/src/test/Makefile +++ b/windows/src/test/Makefile @@ -4,12 +4,14 @@ # ---------------------------------------------------------------------- +# TODO: both test-manifest-exec and verify_signatures are really part of buildtools + !ifdef NODELPHI TARGETS=.virtual !else -TARGETS=test_i3633 +TARGETS=verify_signatures !endif -CLEAN=test_i3633 +CLEAN=verify_signatures test: test-manifest-exec $(MAKE) "TARGET=test" $(TARGETS) @@ -22,10 +24,10 @@ test-manifest-exec: $(MAKE) test-manifest cd test -# test_i3633: validate certificates and binary metadata on executables -# TODO: Move this to buildtools -test_i3633: - cd $(ROOT)\src\test\test_i3633 +# validate certificates and binary metadata on executables +# TODO: move to buildtools? +verify_signatures: .virtual + cd $(ROOT)\src\buildtools\verify_signatures $(MAKE) $(TARGET) # ---------------------------------------------------------------------- diff --git a/windows/src/test/test_i3633/Makefile b/windows/src/test/test_i3633/Makefile deleted file mode 100644 index 575d77e7e8..0000000000 --- a/windows/src/test/test_i3633/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# -# test for signatures and version information being correct in ?install directory or ?bin directory -# - -!include ..\..\Defines.mak - -SIGCHECK=-$(WIN32_TARGET_PATH)\sigcheck -q -s -e -v -accepteula -VERIFY=$(WIN32_TARGET_PATH)\verify -d $(KEYMAN_ROOT)\VERSION.md - -test: test-bin - -test-bin: prereq - $(SIGCHECK) $(ROOT)\bin\desktop\* > sig1 - $(SIGCHECK) $(ROOT)\bin\developer\* >> sig1 - $(SIGCHECK) $(ROOT)\bin\engine\* >> sig1 - $(SIGCHECK) $(ROOT)\bin\inst\* >> sig1 - $(VERIFY) < sig1 - -test-install: prereq - - -prereq: - $(DELPHI_MSBUILD) verify.dproj "/p:Platform=Win32" - copy sigcheck.bin $(WIN32_TARGET_PATH)\sigcheck.exe - - -clean: def-clean - -del sig1 - -del sig2 - -!include ..\..\Target.mak diff --git a/windows/src/test/verify_signatures/Makefile b/windows/src/test/verify_signatures/Makefile new file mode 100644 index 0000000000..dfd1495992 --- /dev/null +++ b/windows/src/test/verify_signatures/Makefile @@ -0,0 +1,21 @@ +# +# test for signatures and version information being correct in bin folder +# + +!include ..\..\Defines.mak + +test: prereq + $(SIGCHECK) $(ROOT)\bin\desktop\* > sig1 + $(SIGCHECK) $(ROOT)\bin\engine\* >> sig1 + $(SIGCHECK) $(ROOT)\bin\inst\* >> sig1 + $(VERIFY_SIGNATURES) < sig1 + +# prereq may not be needed? +prereq: + cd $(VERIFY_SIGNATURES) + $(MAKE) + +clean: def-clean + -del sig1 + +!include ..\..\Target.mak From 9461a3b5832faafbcc1fa6348e89fd05f845d8eb Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 6 Oct 2023 09:45:22 +0700 Subject: [PATCH 085/107] chore(windows): fix path in Makefile --- windows/src/test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/src/test/Makefile b/windows/src/test/Makefile index 5e8dec85b5..2087f3d8a0 100644 --- a/windows/src/test/Makefile +++ b/windows/src/test/Makefile @@ -27,7 +27,7 @@ test-manifest-exec: # validate certificates and binary metadata on executables # TODO: move to buildtools? verify_signatures: .virtual - cd $(ROOT)\src\buildtools\verify_signatures + cd $(ROOT)\src\test\verify_signatures $(MAKE) $(TARGET) # ---------------------------------------------------------------------- From 702b3a0582da7cad144b8126064aaa788642eff2 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 6 Oct 2023 10:11:08 +0700 Subject: [PATCH 086/107] chore(windows): fix typo --- windows/src/test/verify_signatures/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/src/test/verify_signatures/Makefile b/windows/src/test/verify_signatures/Makefile index dfd1495992..607e5d22cf 100644 --- a/windows/src/test/verify_signatures/Makefile +++ b/windows/src/test/verify_signatures/Makefile @@ -12,7 +12,7 @@ test: prereq # prereq may not be needed? prereq: - cd $(VERIFY_SIGNATURES) + cd $(VERIFY_SIGNATURES_PATH) $(MAKE) clean: def-clean From 3dc9ac245f5d713376bd9e893b2baf08cdec9508 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 6 Oct 2023 10:22:02 +0700 Subject: [PATCH 087/107] chore(ios): renew certificate --- ios/exportAppStore.plist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/exportAppStore.plist b/ios/exportAppStore.plist index 6393f3c4cb..48ef58f532 100644 --- a/ios/exportAppStore.plist +++ b/ios/exportAppStore.plist @@ -7,9 +7,9 @@ teamID 3YE4W86L3G signingCertificate - 05473BF50CCD4B78B304656FB4D93FDC7EE7ACD0 + BB842A0081298BBA6D034C85451750B08FC9EE8A installerSigningCertificate - 05473BF50CCD4B78B304656FB4D93FDC7EE7ACD0 + BB842A0081298BBA6D034C85451750B08FC9EE8A provisioningProfiles Tavultesoft.Keyman From 7c2d3624cdfd790740a84b5f4cd790bc93ee38b1 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 6 Oct 2023 10:37:25 +0700 Subject: [PATCH 088/107] chore(developer): sign addons in server --- developer/src/server/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/developer/src/server/Makefile b/developer/src/server/Makefile index 0a580ea3d6..a66eb449c1 100644 --- a/developer/src/server/Makefile +++ b/developer/src/server/Makefile @@ -14,7 +14,10 @@ clean: .virtual -del tsconfig.tsbuildinfo signcode: - @rem nothing to do + $(SIGNCODE) /d "Keyman" build\src\win32\console\node-hide-console-window.node + $(SIGNCODE) /d "Keyman" build\src\win32\console\node-hide-console-window.x64.node + $(SIGNCODE) /d "Keyman" build\src\win32\trayicon\addon.node + $(SIGNCODE) /d "Keyman" build\src\win32\trayicon\addon.x64.node wrap-symbols: @rem nothing to do From c970b1e2460b26970e22f3ab367b8e39e0328411 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 6 Oct 2023 11:38:55 +0700 Subject: [PATCH 089/107] chore(developer): fix paths for addon signing --- developer/src/server/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/developer/src/server/Makefile b/developer/src/server/Makefile index a66eb449c1..214732e41d 100644 --- a/developer/src/server/Makefile +++ b/developer/src/server/Makefile @@ -14,10 +14,10 @@ clean: .virtual -del tsconfig.tsbuildinfo signcode: - $(SIGNCODE) /d "Keyman" build\src\win32\console\node-hide-console-window.node - $(SIGNCODE) /d "Keyman" build\src\win32\console\node-hide-console-window.x64.node - $(SIGNCODE) /d "Keyman" build\src\win32\trayicon\addon.node - $(SIGNCODE) /d "Keyman" build\src\win32\trayicon\addon.x64.node + $(SIGNCODE) /d "Keyman Developer" $(DEVELOPER_PROGRAM)\server\dist\win32\console\node-hide-console-window.node + $(SIGNCODE) /d "Keyman Developer" $(DEVELOPER_PROGRAM)\server\dist\win32\console\node-hide-console-window.x64.node + $(SIGNCODE) /d "Keyman Developer" $(DEVELOPER_PROGRAM)\server\dist\win32\trayicon\addon.node + $(SIGNCODE) /d "Keyman Developer" $(DEVELOPER_PROGRAM)\server\dist\win32\trayicon\addon.x64.node wrap-symbols: @rem nothing to do From 2e4dd105229436b75e52bca0ef4613f92b676a4c Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 6 Oct 2023 16:48:57 +0200 Subject: [PATCH 090/107] fix(linux): Explicitly initialize GTK Usually this is done automatically. However, if e.g. no `DISPLAY` variable is set it'll fail. When we explicitly initialize GTK it still fails, but shows a more helpful warning instead of throwing a runtime error. Fixes #9705. --- linux/keyman-config/km-config | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/linux/keyman-config/km-config b/linux/keyman-config/km-config index dfdbb7d451..604e7d17cf 100755 --- a/linux/keyman-config/km-config +++ b/linux/keyman-config/km-config @@ -2,6 +2,12 @@ import argparse import logging +import sys +import gi + +gi.require_version('Gtk', '3.0') + +from gi.repository import Gtk from keyman_config import __versionwithtag__, __pkgversion__, add_standard_arguments, initialize_logging, initialize_sentry from keyman_config.handle_install import download_and_install_package @@ -30,6 +36,8 @@ if __name__ == '__main__': args = parser.parse_args() + Gtk.init(sys.argv[1:]) + initialize_logging(args) initialize_sentry() From 25c20ee812a619391574a9633c8e21e243a65b9d Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 6 Oct 2023 11:58:59 -0500 Subject: [PATCH 091/107] =?UTF-8?q?feat(common):=20fix=20marker=20parsing?= =?UTF-8?q?=20=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - cleaned up regex For: #9119 --- .../web/types/src/ldml-keyboard/pattern-parser.ts | 10 ++++++++-- .../test/ldml-keyboard/test-pattern-parser.ts | 14 +++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/common/web/types/src/ldml-keyboard/pattern-parser.ts b/common/web/types/src/ldml-keyboard/pattern-parser.ts index b02440553e..b0d6fb0796 100644 --- a/common/web/types/src/ldml-keyboard/pattern-parser.ts +++ b/common/web/types/src/ldml-keyboard/pattern-parser.ts @@ -64,9 +64,15 @@ export class MarkerParser { public static readonly MAX_MARKER_INDEX = constants.marker_max_index; /** Max count of markers */ public static readonly MAX_MARKER_COUNT = constants.marker_max_count; + + private static anyMarkerMatch() : string { + const start = (`0000` + (this.MIN_MARKER_INDEX).toString(16)).slice(-4); + const end = (`0000` + (this.MAX_MARKER_INDEX).toString(16)).slice(-4); + return `${this.SENTINEL}${this.MARKER_CODE}[\\u${start}-\\u${end}]`; + } + /** Expression that matches any marker */ - public static readonly ANY_MARKER_MATCH = - this.SENTINEL + this.MARKER_CODE + `[\\u0001-\\u${this.MAX_MARKER_INDEX.toString(16)}]`; + public static readonly ANY_MARKER_MATCH = MarkerParser.anyMarkerMatch(); /** * Pattern for matching a marker reference, OR the special marker \m{.} diff --git a/common/web/types/test/ldml-keyboard/test-pattern-parser.ts b/common/web/types/test/ldml-keyboard/test-pattern-parser.ts index 1ea96797a7..0274f2a5c2 100644 --- a/common/web/types/test/ldml-keyboard/test-pattern-parser.ts +++ b/common/web/types/test/ldml-keyboard/test-pattern-parser.ts @@ -105,16 +105,20 @@ describe('Test of Pattern Parsers', () => { ) ); // verify the matching behavior of these - assert.isTrue(new RegExp(MarkerParser.toSentinelString(`Q\\m{a}`, markers, true), 'u') + assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^Q\\m{a}$`, markers, true), 'u') .test(MarkerParser.toSentinelString(`Q\\m{a}`, markers, false)), `Q\\m{a} did not match`); - assert.isFalse(new RegExp(MarkerParser.toSentinelString(`Q\\m{a}`, markers, true), 'u') + assert.isFalse(new RegExp(MarkerParser.toSentinelString(`^Q\\m{a}$`, markers, true), 'u') .test(MarkerParser.toSentinelString(`Q\\m{b}`, markers, false)), `Q\\m{a} should not match Q\\m{b}`); - assert.isTrue(new RegExp(MarkerParser.toSentinelString(`Q\\m{.}`, markers, true), 'u') + assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^Q\\m{.}$`, markers, true), 'u') .test(MarkerParser.toSentinelString(`Q\\m{a}`, markers, false)), `Q\\m{.} did not match Q\\m{a}`); - assert.isTrue(new RegExp(MarkerParser.toSentinelString(`Q\\m{.}`, markers, true), 'u') + assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^Q\\m{.}$`, markers, true), 'u') .test(MarkerParser.toSentinelString(`Q\\m{zz}`, markers, false)), `Q\\m{.} did not match Q\\m{zz} (max marker)`); - assert.isFalse(new RegExp(MarkerParser.toSentinelString(`Q\\m{.}`, markers, true), 'u') + assert.isFalse(new RegExp(MarkerParser.toSentinelString(`^Q\\m{.}$`, markers, true), 'u') .test(MarkerParser.toSentinelString(`\\m{a}`, markers, false)), `Q\\m{.} did not match \\m{a}`); + assert.isTrue(new RegExp(MarkerParser.toSentinelString(`^\\m{.}$`, markers, true), 'u') + .test(MarkerParser.toSentinelString(`\\m{a}`, markers, false)), `\\m{.} did not match \\m{a}`); + assert.isFalse(new RegExp(MarkerParser.toSentinelString(`^\\m{.}$`, markers, true), 'u') + .test(MarkerParser.toSentinelString(`\\m{a}\\m{b}`, markers, false)), `\\m{.} did not match \\m{a}\\m{b}`); }); it('should match some marker constants', () => { assert.equal(constants.uc_sentinel, KMXFile.UC_SENTINEL); From 982fdd0318a8fd4a10dda826bec652ced6841393 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Sat, 7 Oct 2023 05:49:25 +0700 Subject: [PATCH 092/107] fix(developer): skip resource check for node addons --- .../delphi/tools/verify_signatures/verify_signatures.dpr | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/common/windows/delphi/tools/verify_signatures/verify_signatures.dpr b/common/windows/delphi/tools/verify_signatures/verify_signatures.dpr index fe77f887d7..49478ac3ed 100644 --- a/common/windows/delphi/tools/verify_signatures/verify_signatures.dpr +++ b/common/windows/delphi/tools/verify_signatures/verify_signatures.dpr @@ -36,6 +36,7 @@ begin Delete(s,1,1); end; + // TODO: sign these files and move the check down to the EndsWith node test if str[0].ToLower.Contains('sentry.') or str[0].ToLower.Contains('crashpad_handler') or str[0].ToLower.Contains('keymanmc') then // We don't verify sentry.dll or sentry.x64.dll or crashpad_handler.exe because they're not our files // We don't verify keymanmc.dll because it has no version resources, as it is mc-generated @@ -62,6 +63,14 @@ begin end; end; + if str[0].ToLower.EndsWith('node') then + begin + // It's one of the node addons -- in developer server at time of writing + // we don't have a version resource but we have signed it, so treat it + // as valid + Exit(''); + end; + if str[3] <> 'SIL International' then begin Exit('File has wrong company name'); From b7c7a1c7b36b57080bc6c779546126f4c284a8a1 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 6 Oct 2023 18:11:37 -0500 Subject: [PATCH 093/107] =?UTF-8?q?feat(developer):=20fix=20vars=20and=20m?= =?UTF-8?q?arkers=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - workaround for debugger/test issue For: #9121 For: #9119 --- common/web/types/src/kmx/string-list.ts | 12 ++++++++++-- developer/src/kmc-ldml/test/test-vars.ts | 5 +++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/common/web/types/src/kmx/string-list.ts b/common/web/types/src/kmx/string-list.ts index cbeb4e425d..88ab5bbcf7 100644 --- a/common/web/types/src/kmx/string-list.ts +++ b/common/web/types/src/kmx/string-list.ts @@ -73,10 +73,18 @@ export class ListItem extends Array implements OrderedStringList { } /** for debugging, print as single string */ toString(): string { - return this.toStringArray().join(' '); + let ss = ''; + for (let i = 0 ;i < this.length; i++) { + if (ss) { + ss = ss + ' '; + } + ss = ss + (this[i].toString()); + } + return ss; + // return this.toStringArray().join(' '); } /** for debugging, map to string array */ toStringArray(): string[] { - return this.map(v => v.value.value); + return this.map(v => v.toString()); } }; diff --git a/developer/src/kmc-ldml/test/test-vars.ts b/developer/src/kmc-ldml/test/test-vars.ts index 5bdd5e65f0..4b053c30d2 100644 --- a/developer/src/kmc-ldml/test/test-vars.ts +++ b/developer/src/kmc-ldml/test/test-vars.ts @@ -203,8 +203,9 @@ describe('vars', function () { callback(sect) { const vars = sect; assert.ok(vars.markers); - assert.sameDeepOrderedMembers(vars.markers.toStringArray(), - ['m','x']); + // assert.sameDeepOrderedMembers(vars.markers.toStringArray(), + // ['m','x']); + assert.equal(vars.markers.toString(), 'm x'); }, }, { From 450e29cf2aee9a659af091f2cf841b240e801ef2 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Sat, 7 Oct 2023 08:48:18 -0500 Subject: [PATCH 094/107] =?UTF-8?q?feat(developer):=20fix=20vars=20and=20m?= =?UTF-8?q?arkers=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - odd, but seems to work this way For: #9121 For: #9119 --- common/web/types/src/kmx/string-list.ts | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/common/web/types/src/kmx/string-list.ts b/common/web/types/src/kmx/string-list.ts index 88ab5bbcf7..2e313dae0c 100644 --- a/common/web/types/src/kmx/string-list.ts +++ b/common/web/types/src/kmx/string-list.ts @@ -27,8 +27,10 @@ export class ListItem extends Array implements OrderedStringList { /** * Construct a new list from an array of strings. * Use List. This is meant to be called by the List.allocString*() functions. - * @param strs the Strs section is needed to construct this object. * @param source array of strings + * @param opts string handling options + * @param sections the Strs section is needed to construct this object, and other sections may + * be needed depending on the options * @returns */ constructor(source: Array, opts: StrsOptions, sections: DependencySections) { @@ -71,20 +73,13 @@ export class ListItem extends Array implements OrderedStringList { return 0; } } - /** for debugging, print as single string */ + /** for debugging and tests, print as single string */ toString(): string { - let ss = ''; - for (let i = 0 ;i < this.length; i++) { - if (ss) { - ss = ss + ' '; - } - ss = ss + (this[i].toString()); - } - return ss; - // return this.toStringArray().join(' '); + return this.toStringArray().join(' '); } - /** for debugging, map to string array */ + /** for debugging and tests, map to string array */ toStringArray(): string[] { - return this.map(v => v.toString()); + // TODO-LDML: this crashes: return this.map(v => v.toString()); + return Array.from(this.values()).map(v => v.toString()); } }; From 12bb554b5a6680d28f0af2bfba2fb29aae9f699f Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Sat, 7 Oct 2023 09:11:27 -0500 Subject: [PATCH 095/107] =?UTF-8?q?feat(developer):=20fix=20vars=20and=20m?= =?UTF-8?q?arkers=20=F0=9F=99=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Figured it out. Problem was a custom Array constructor. - also updated ElementString class, which would have the same issue. For: #9121 For: #9119 --- common/web/types/src/kmx/element-string.ts | 11 ++++++----- common/web/types/src/kmx/kmx-plus.ts | 8 ++++---- common/web/types/src/kmx/string-list.ts | 11 ++++++----- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/common/web/types/src/kmx/element-string.ts b/common/web/types/src/kmx/element-string.ts index 816627c3d3..ebf4d398e5 100644 --- a/common/web/types/src/kmx/element-string.ts +++ b/common/web/types/src/kmx/element-string.ts @@ -31,11 +31,11 @@ export class ElementString extends Array { * @param source if a string array, does not get reinterpreted as UnicodeSet. This is used with vars, etc. Or pass `["str"]` for an explicit 1-element elem. * If it is a string, will be interpreted per reorder element rules. */ - constructor(sections: DependencySections, source: string | string[], order?: string, tertiary?: string, tertiary_base?: string, prebase?: string) { - super(); - //TODO-LDML: full UnicodeSet and parsing + static fromStrings(sections: DependencySections, source: string | string[], order?: string, tertiary?: string, tertiary_base?: string, prebase?: string) : ElementString { + // the returned array + const array = new ElementString(); if(!source) { - return; + return array; } let items : ElementSegment[]; @@ -104,8 +104,9 @@ export class ElementString extends Array { (ElemElementFlags.type & typeFlag) | (tertiary_bases?.[i] == '1' /* TODO-LDML: or 'true'? */ ? ElemElementFlags.tertiary_base : 0) | (prebases?.[i] == '1' /* TODO-LDML: or 'true'? */ ? ElemElementFlags.prebase : 0); - this.push(elem); + array.push(elem); }; + return array; } isEqual(a: ElementString): boolean { if (a.length != this.length) { diff --git a/common/web/types/src/kmx/kmx-plus.ts b/common/web/types/src/kmx/kmx-plus.ts index d28bcbfd3f..1060e50fba 100644 --- a/common/web/types/src/kmx/kmx-plus.ts +++ b/common/web/types/src/kmx/kmx-plus.ts @@ -35,14 +35,14 @@ export class Elem extends Section { strings: ElementString[] = []; constructor(sections: DependencySections) { super(); - this.strings.push(new ElementString(sections, '')); // C7043: null element string + this.strings.push(ElementString.fromStrings(sections, '')); // C7043: null element string } /** * @param source if a string array, does not get reinterpreted as UnicodeSet. This is used with vars, etc. Or pass `["str"]` for an explicit 1-element elem. * If it is a string, will be interpreted per reorder element ruls. */ allocElementString(sections: DependencySections, source: string | string[], order?: string, tertiary?: string, tertiary_base?: string, prebase?: string): ElementString { - let s = new ElementString(sections, source, order, tertiary, tertiary_base, prebase); + let s = ElementString.fromStrings(sections, source, order, tertiary, tertiary_base, prebase); let result = this.strings.find(item => item.isEqual(s)); if(result === undefined) { result = s; @@ -547,14 +547,14 @@ export class List extends Section { let result = this.lists.find(item => item.isEqual(s)); if(result === undefined) { // allocate a new ListItem - result = new ListItem(s, opts, sections); + result = ListItem.fromStrings(s, opts, sections); this.lists.push(result); } return result; } constructor(strs: Strs) { super(); - this.lists.push(new ListItem([], {}, { strs })); // C7043: null element string + this.lists.push(ListItem.fromStrings([], {}, { strs })); // C7043: null element string } lists: ListItem[] = []; }; diff --git a/common/web/types/src/kmx/string-list.ts b/common/web/types/src/kmx/string-list.ts index 2e313dae0c..411c940acf 100644 --- a/common/web/types/src/kmx/string-list.ts +++ b/common/web/types/src/kmx/string-list.ts @@ -33,15 +33,16 @@ export class ListItem extends Array implements OrderedStringList { * be needed depending on the options * @returns */ - constructor(source: Array, opts: StrsOptions, sections: DependencySections) { - super(); - if(!source) { - return; + static fromStrings(source: Array, opts: StrsOptions, sections: DependencySections) : ListItem { + const a = new ListItem(); + if (!source) { + return a; } for (const str of source) { let index = new ListIndex(sections.strs.allocString(str, opts, sections)); - this.push(index); + a.push(index); } + return a; } getItemOrder(item: string): number { return this.findIndex(({value}) => value.value === item); From 4ef18f5e29ad21fef15e975992089cb98092de62 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 9 Oct 2023 14:21:01 +0700 Subject: [PATCH 096/107] chore(core): rename keyboardprocessor.h to keyman_core_api.h Fixes #9721. Also tweaks some documentation references to keyboardprocessor, but does not touch those relating to debian/control. --- core/doc/hotdoc.json | 2 +- core/doc/introspection.schema | 2 +- core/doc/markdown_files/index.md | 2 +- core/doc/meson.build | 2 +- .../{keyboardprocessor.h => keyman_core_api.h} | 10 +++++----- ...rdprocessor_bits.h => keyman_core_api_bits.h} | 0 ...ocessor_consts.h => keyman_core_api_consts.h} | 0 ...processor_debug.h => keyman_core_api_debug.h} | 4 ++-- ...version.h.in => keyman_core_api_version.h.in} | 0 ...processor_vkeys.h => keyman_core_api_vkeys.h} | 2 +- core/include/keyman/meson.build | 16 ++++++++-------- core/src/context.hpp | 2 +- core/src/debug.hpp | 4 ++-- core/src/debuglog.h | 2 +- core/src/keyboard.hpp | 2 +- core/src/km_kbp_context_api.cpp | 2 +- core/src/km_kbp_debug_api.cpp | 2 +- core/src/km_kbp_keyboard_api.cpp | 2 +- core/src/km_kbp_options_api.cpp | 2 +- core/src/km_kbp_processevent_api.cpp | 2 +- core/src/km_kbp_state_api.cpp | 4 ++-- core/src/kmx/kmx_base.h | 4 ++-- core/src/kmx/kmx_capslock.cpp | 2 +- core/src/kmx/kmx_environment.cpp | 2 +- core/src/kmx/kmx_options.h | 2 +- core/src/kmx/kmx_processevent.cpp | 2 +- core/src/kmx/kmx_processevent.h | 2 +- core/src/kmx/kmx_processor.cpp | 2 +- core/src/kmx/kmx_processor.hpp | 2 +- core/src/ldml/ldml_processor.hpp | 2 +- core/src/ldml/ldml_vkeys.hpp | 2 +- core/src/mock/mock_processor.hpp | 2 +- core/src/option.hpp | 2 +- core/src/path.hpp | 2 +- core/src/processor.hpp | 4 ++-- core/src/state.cpp | 2 +- core/src/state.hpp | 2 +- core/src/version.rc | 2 +- core/tests/unit/kmnkbd/action_items.hpp | 2 +- core/tests/unit/kmnkbd/context_api.cpp | 2 +- core/tests/unit/kmnkbd/debug_api.cpp | 6 +++--- core/tests/unit/kmnkbd/debug_items.hpp | 4 ++-- core/tests/unit/kmnkbd/keyboard_api.cpp | 2 +- core/tests/unit/kmnkbd/options_api.cpp | 2 +- core/tests/unit/kmnkbd/state_api.cpp | 6 +++--- core/tests/unit/ldml/ldml_test_utils.hpp | 2 +- .../src/tike/main/Keyman.System.KeymanCore.pas | 6 +++--- .../tike/main/Keyman.System.KeymanCoreDebug.pas | 6 +++--- docs/settings/linux/settings.json | 2 +- linux/debian/tests/test-build | 4 ++-- linux/ibus-keyman/src/engine.c | 4 ++-- linux/ibus-keyman/src/keycodes.h | 2 +- linux/ibus-keyman/src/keymanutil.c | 2 +- linux/ibus-keyman/src/keymanutil.h | 2 +- linux/ibus-keyman/tests/testfixture.cpp | 2 +- windows/src/engine/keyman32/keymanengine.h | 8 ++++---- 56 files changed, 83 insertions(+), 83 deletions(-) rename core/include/keyman/{keyboardprocessor.h => keyman_core_api.h} (99%) rename core/include/keyman/{keyboardprocessor_bits.h => keyman_core_api_bits.h} (100%) rename core/include/keyman/{keyboardprocessor_consts.h => keyman_core_api_consts.h} (100%) rename core/include/keyman/{keyboardprocessor_debug.h => keyman_core_api_debug.h} (98%) rename core/include/keyman/{keyboardprocessor_version.h.in => keyman_core_api_version.h.in} (100%) rename core/include/keyman/{keyboardprocessor_vkeys.h => keyman_core_api_vkeys.h} (99%) diff --git a/core/doc/hotdoc.json b/core/doc/hotdoc.json index 4ece50d0f5..946c62beac 100644 --- a/core/doc/hotdoc.json +++ b/core/doc/hotdoc.json @@ -4,7 +4,7 @@ "sitemap": "@doc_dir@/sitemap.txt", "index": "@doc_dir@/markdown_files/index.md", "c_sources": [ - "@include_dir@/keyman/keyboardprocessor.h" + "@include_dir@/keyman/keyman_core_api.h" ], "c_include_directories": [ "@include_dir@", diff --git a/core/doc/introspection.schema b/core/doc/introspection.schema index ff10c7c969..3b7684e0e9 100644 --- a/core/doc/introspection.schema +++ b/core/doc/introspection.schema @@ -47,7 +47,7 @@ } }, "properties": { - "$schema": { "const": "keyman/keyboardprocessor/doc/introspection.schema" }, + "$schema": { "const": "keyman/core/doc/introspection.schema" }, "keyboard": { "$ref": "#/definitions/keyboard" }, "options": { "type": "object", diff --git a/core/doc/markdown_files/index.md b/core/doc/markdown_files/index.md index 98870c356d..bc196a0a0c 100644 --- a/core/doc/markdown_files/index.md +++ b/core/doc/markdown_files/index.md @@ -46,7 +46,7 @@ A virtual key board event and modifier map recevied from the Platform layer to b processed with the state object for this Client application. - __Virtual Key:__ A code based on the US English layout, with values matching the Windows -virtual key codes. See `keyboardprocessor_vkeys.h` for definitions. +virtual key codes. See `keyman_core_api_vkeys.h` for definitions. - __Modifier Key:__ The set of Control, Shift, Alt, Caps Lock keys. On some platforms these may have other names (e.g. Alt is called Option on macOS); other platform-specific diff --git a/core/doc/meson.build b/core/doc/meson.build index 01fcb5c98a..6039e2e2dd 100644 --- a/core/doc/meson.build +++ b/core/doc/meson.build @@ -18,7 +18,7 @@ if hotdoc.found() output: 'hotdoc.json', configuration: cfg) deps = files( - '../include/keyman/keyboardprocessor.h', + '../include/keyman/keyman_core_api.h', '../src/jsonpp.hpp', '../src/utfcodec.hpp' ) diff --git a/core/include/keyman/keyboardprocessor.h b/core/include/keyman/keyman_core_api.h similarity index 99% rename from core/include/keyman/keyboardprocessor.h rename to core/include/keyman/keyman_core_api.h index 429a8ae6cb..b32be63073 100644 --- a/core/include/keyman/keyboardprocessor.h +++ b/core/include/keyman/keyman_core_api.h @@ -57,7 +57,7 @@ A virtual key event and modifier map received from the Platform layer to be processed with the state object for this Client application. - __Virtual Key:__ A code based on the US English layout, with values matching the Windows -virtual key codes. See `keyboardprocessor_vkeys.h` for definitions. +virtual key codes. See `keyman_core_api_vkeys.h` for definitions. - __Modifier Key:__ The set of Control, Shift, Alt, Caps Lock keys. On some platforms these may have other names (e.g. Alt is called Option on macOS); other platform-specific @@ -100,9 +100,9 @@ nothing in that event. */ #include #include -#include -#include -#include +#include +#include +#include #if defined(__cplusplus) extern "C" @@ -989,7 +989,7 @@ used in IMX callbacks called during `km_kbp_process_event`. In the event the `state` or `action_items` pointer are null. ##### Parameters: - __state__: A pointer to the opaque `km_kbp_state` object to be queried. -- __action_items__: The action items to be added to the keyboardprocessor +- __action_items__: The action items to be added to the core queue. Must be terminated with a `KM_KBP_IT_END` entry. ```c diff --git a/core/include/keyman/keyboardprocessor_bits.h b/core/include/keyman/keyman_core_api_bits.h similarity index 100% rename from core/include/keyman/keyboardprocessor_bits.h rename to core/include/keyman/keyman_core_api_bits.h diff --git a/core/include/keyman/keyboardprocessor_consts.h b/core/include/keyman/keyman_core_api_consts.h similarity index 100% rename from core/include/keyman/keyboardprocessor_consts.h rename to core/include/keyman/keyman_core_api_consts.h diff --git a/core/include/keyman/keyboardprocessor_debug.h b/core/include/keyman/keyman_core_api_debug.h similarity index 98% rename from core/include/keyman/keyboardprocessor_debug.h rename to core/include/keyman/keyman_core_api_debug.h index 380b8ee301..f038e2cd81 100644 --- a/core/include/keyman/keyboardprocessor_debug.h +++ b/core/include/keyman/keyman_core_api_debug.h @@ -15,8 +15,8 @@ #include #include -#include -#include +#include +#include #if defined(__cplusplus) extern "C" diff --git a/core/include/keyman/keyboardprocessor_version.h.in b/core/include/keyman/keyman_core_api_version.h.in similarity index 100% rename from core/include/keyman/keyboardprocessor_version.h.in rename to core/include/keyman/keyman_core_api_version.h.in diff --git a/core/include/keyman/keyboardprocessor_vkeys.h b/core/include/keyman/keyman_core_api_vkeys.h similarity index 99% rename from core/include/keyman/keyboardprocessor_vkeys.h rename to core/include/keyman/keyman_core_api_vkeys.h index e8d8122bda..a1e580df28 100644 --- a/core/include/keyman/keyboardprocessor_vkeys.h +++ b/core/include/keyman/keyman_core_api_vkeys.h @@ -7,7 +7,7 @@ Create Date: 17 Oct 2018 Authors: Tim Eves (TSE) History: 17 Oct 2018 - TSE - Moved & refactored km_kbp_modifier_state - from keyboardprocessor.h. + from keyman_core_api.h. - Added VKey and mask definitions. 6 Oct 2018 - TSE - Move into keyman folder. diff --git a/core/include/keyman/meson.build b/core/include/keyman/meson.build index 7da255502d..6be28e4979 100644 --- a/core/include/keyman/meson.build +++ b/core/include/keyman/meson.build @@ -19,16 +19,16 @@ cfg.set('patchver', project_ver[2]) configure_file( configuration: cfg, - input: 'keyboardprocessor_version.h.in', - output: 'keyboardprocessor_version.h', + input: 'keyman_core_api_version.h.in', + output: 'keyman_core_api_version.h', ) -install_headers('keyboardprocessor.h', - 'keyboardprocessor_bits.h', - 'keyboardprocessor_consts.h', - 'keyboardprocessor_debug.h', - 'keyboardprocessor_vkeys.h', - join_paths(meson.current_build_dir(), 'keyboardprocessor_version.h'), +install_headers('keyman_core_api.h', + 'keyman_core_api_bits.h', + 'keyman_core_api_consts.h.h', + 'keyman_core_api_debug.h.h', + 'keyman_core_api_vkeys.h', + join_paths(meson.current_build_dir(), 'keyman_core_api_version.h'), '../../../common/include/km_types.h', '../../../common/include/kmx_file.h', subdir: 'keyman') diff --git a/core/src/context.hpp b/core/src/context.hpp index b344e0657c..03d4aeb2d7 100644 --- a/core/src/context.hpp +++ b/core/src/context.hpp @@ -9,7 +9,7 @@ #pragma once #include #include -#include +#include // Forward declarations class json; diff --git a/core/src/debug.hpp b/core/src/debug.hpp index 8069cfbc53..a910c03a28 100644 --- a/core/src/debug.hpp +++ b/core/src/debug.hpp @@ -9,8 +9,8 @@ #include #include -#include -#include +#include +#include namespace km { namespace kbp diff --git a/core/src/debuglog.h b/core/src/debuglog.h index 16fba46428..1ecbaca612 100644 --- a/core/src/debuglog.h +++ b/core/src/debuglog.h @@ -1,6 +1,6 @@ /* Debugging */ -#include +#include namespace km { namespace kbp { diff --git a/core/src/keyboard.hpp b/core/src/keyboard.hpp index 57f8128c78..6c8b93263c 100644 --- a/core/src/keyboard.hpp +++ b/core/src/keyboard.hpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include "option.hpp" #include "path.hpp" diff --git a/core/src/km_kbp_context_api.cpp b/core/src/km_kbp_context_api.cpp index a9111f66c4..a0845618b4 100644 --- a/core/src/km_kbp_context_api.cpp +++ b/core/src/km_kbp_context_api.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include "context.hpp" #include "jsonpp.hpp" diff --git a/core/src/km_kbp_debug_api.cpp b/core/src/km_kbp_debug_api.cpp index 0871df17ae..ff7ad03044 100644 --- a/core/src/km_kbp_debug_api.cpp +++ b/core/src/km_kbp_debug_api.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include "processor.hpp" #include "state.hpp" diff --git a/core/src/km_kbp_keyboard_api.cpp b/core/src/km_kbp_keyboard_api.cpp index 13f3cafc45..b12ae3a9cb 100644 --- a/core/src/km_kbp_keyboard_api.cpp +++ b/core/src/km_kbp_keyboard_api.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include "keyboard.hpp" #include "processor.hpp" #include "kmx/kmx_processor.hpp" diff --git a/core/src/km_kbp_options_api.cpp b/core/src/km_kbp_options_api.cpp index 7dc4879098..0f522d6ffe 100644 --- a/core/src/km_kbp_options_api.cpp +++ b/core/src/km_kbp_options_api.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include "processor.hpp" #include "jsonpp.hpp" diff --git a/core/src/km_kbp_processevent_api.cpp b/core/src/km_kbp_processevent_api.cpp index 69eba06a41..8e818ea42d 100644 --- a/core/src/km_kbp_processevent_api.cpp +++ b/core/src/km_kbp_processevent_api.cpp @@ -8,7 +8,7 @@ History: 17 Oct 2018 - TSE - Initial implementation. */ -#include +#include #include "processor.hpp" #include "state.hpp" diff --git a/core/src/km_kbp_state_api.cpp b/core/src/km_kbp_state_api.cpp index b966688950..168288423d 100644 --- a/core/src/km_kbp_state_api.cpp +++ b/core/src/km_kbp_state_api.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include "jsonpp.hpp" #include "processor.hpp" @@ -212,7 +212,7 @@ km_kbp_status km_kbp_state_to_json(km_kbp_state const *state, { // Pretty print the document. jo << json::object - << "$schema" << "keyman/keyboardprocessor/doc/introspection.schema" + << "$schema" << "keyman/core/doc/introspection.schema" << "keyboard" << state->processor().keyboard() // << "options" << state->options() TODO: Fix << "context" << state->context() diff --git a/core/src/kmx/kmx_base.h b/core/src/kmx/kmx_base.h index 7fc335cfc4..77cf53c209 100644 --- a/core/src/kmx/kmx_base.h +++ b/core/src/kmx/kmx_base.h @@ -1,7 +1,7 @@ #pragma once -#include -#include +#include +#include #if defined(_WIN32) || defined(_WIN64) #define snprintf _snprintf diff --git a/core/src/kmx/kmx_capslock.cpp b/core/src/kmx/kmx_capslock.cpp index e125ccd4cf..ca32477883 100644 --- a/core/src/kmx/kmx_capslock.cpp +++ b/core/src/kmx/kmx_capslock.cpp @@ -2,7 +2,7 @@ Copyright: Copyright (C) 2003-2018 SIL International. Authors: mcdurdin */ -#include +#include #include using namespace km::kbp; diff --git a/core/src/kmx/kmx_environment.cpp b/core/src/kmx/kmx_environment.cpp index 4d3d3c5490..b77971a403 100644 --- a/core/src/kmx/kmx_environment.cpp +++ b/core/src/kmx/kmx_environment.cpp @@ -3,7 +3,7 @@ Authors: mcdurdin */ #include -#include +#include #include #include diff --git a/core/src/kmx/kmx_options.h b/core/src/kmx/kmx_options.h index 76af7dc405..500dc7474e 100644 --- a/core/src/kmx/kmx_options.h +++ b/core/src/kmx/kmx_options.h @@ -4,7 +4,7 @@ #include #include -#include +#include #include "option.hpp" #include "kmx_base.h" diff --git a/core/src/kmx/kmx_processevent.cpp b/core/src/kmx/kmx_processevent.cpp index c6fec0e468..94015ef2c8 100644 --- a/core/src/kmx/kmx_processevent.cpp +++ b/core/src/kmx/kmx_processevent.cpp @@ -4,7 +4,7 @@ */ #include "kmx_processevent.h" #include "state.hpp" -#include +#include using namespace km::kbp; using namespace kmx; diff --git a/core/src/kmx/kmx_processevent.h b/core/src/kmx/kmx_processevent.h index 5dfdfc7190..13b6f0d6bb 100644 --- a/core/src/kmx/kmx_processevent.h +++ b/core/src/kmx/kmx_processevent.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include "debuglog.h" #include "kmx_base.h" #include "kmx_file.h" diff --git a/core/src/kmx/kmx_processor.cpp b/core/src/kmx/kmx_processor.cpp index 30b3ce7691..3bf136f1a2 100644 --- a/core/src/kmx/kmx_processor.cpp +++ b/core/src/kmx/kmx_processor.cpp @@ -1,4 +1,4 @@ -#include +#include #include "state.hpp" #include "kmx/kmx_processor.hpp" #include diff --git a/core/src/kmx/kmx_processor.hpp b/core/src/kmx/kmx_processor.hpp index c58743aff8..e279eb8f62 100644 --- a/core/src/kmx/kmx_processor.hpp +++ b/core/src/kmx/kmx_processor.hpp @@ -9,7 +9,7 @@ #pragma once #include -#include +#include #include "kmx/kmx_processevent.h" #include "keyboard.hpp" #include "processor.hpp" diff --git a/core/src/ldml/ldml_processor.hpp b/core/src/ldml/ldml_processor.hpp index 09c743d4d1..d2016e5c9f 100644 --- a/core/src/ldml/ldml_processor.hpp +++ b/core/src/ldml/ldml_processor.hpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include "processor.hpp" #include "option.hpp" #include "ldml_vkeys.hpp" diff --git a/core/src/ldml/ldml_vkeys.hpp b/core/src/ldml/ldml_vkeys.hpp index bfab902b0f..0b632f670c 100644 --- a/core/src/ldml/ldml_vkeys.hpp +++ b/core/src/ldml/ldml_vkeys.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include namespace km { namespace kbp { diff --git a/core/src/mock/mock_processor.hpp b/core/src/mock/mock_processor.hpp index e5a72cba4a..5e8857fb46 100644 --- a/core/src/mock/mock_processor.hpp +++ b/core/src/mock/mock_processor.hpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include "processor.hpp" #include "option.hpp" diff --git a/core/src/option.hpp b/core/src/option.hpp index 70627bfb8f..979cc80b96 100644 --- a/core/src/option.hpp +++ b/core/src/option.hpp @@ -12,7 +12,7 @@ #include -#include +#include // Forward declarations class json; diff --git a/core/src/path.hpp b/core/src/path.hpp index 9bb8145d74..ec08c064f4 100644 --- a/core/src/path.hpp +++ b/core/src/path.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include "jsonpp.hpp" #include "utfcodec.hpp" diff --git a/core/src/processor.hpp b/core/src/processor.hpp index 39edb120d2..7fc6a54318 100644 --- a/core/src/processor.hpp +++ b/core/src/processor.hpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include "keyboard.hpp" @@ -96,7 +96,7 @@ namespace kbp ) = 0; /** - * Returns the keyboardprocessor context as an array of + * Returns the core context as an array of * km_kbp_context_items. Caller is responsible for freeing * the memory * @return km_kbp_context_item* diff --git a/core/src/state.cpp b/core/src/state.cpp index d0e07573dd..e873af8287 100644 --- a/core/src/state.cpp +++ b/core/src/state.cpp @@ -7,7 +7,7 @@ #include "state.hpp" #include "processor.hpp" -#include +#include using namespace km::kbp; diff --git a/core/src/state.hpp b/core/src/state.hpp index c11f503cbe..0b5b2ad6ca 100644 --- a/core/src/state.hpp +++ b/core/src/state.hpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include "context.hpp" #include "option.hpp" diff --git a/core/src/version.rc b/core/src/version.rc index cd852f0154..fddda79e28 100644 --- a/core/src/version.rc +++ b/core/src/version.rc @@ -1,5 +1,5 @@ #include -#include "include/keyman/keyboardprocessor_version.h" +#include "include/keyman/keyman_core_api_version.h" // Encoding: UTF8 (compile with rc /c65001) // Use rc /n to append null to all strings diff --git a/core/tests/unit/kmnkbd/action_items.hpp b/core/tests/unit/kmnkbd/action_items.hpp index d7eabf20d3..da485589ef 100644 --- a/core/tests/unit/kmnkbd/action_items.hpp +++ b/core/tests/unit/kmnkbd/action_items.hpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/core/tests/unit/kmnkbd/context_api.cpp b/core/tests/unit/kmnkbd/context_api.cpp index 728a21924c..c8a6fc51ed 100644 --- a/core/tests/unit/kmnkbd/context_api.cpp +++ b/core/tests/unit/kmnkbd/context_api.cpp @@ -10,7 +10,7 @@ mutation functions. */ #include -#include +#include #include "context.hpp" #include "utfcodec.hpp" diff --git a/core/tests/unit/kmnkbd/debug_api.cpp b/core/tests/unit/kmnkbd/debug_api.cpp index b4cfae6ab3..57f6366697 100644 --- a/core/tests/unit/kmnkbd/debug_api.cpp +++ b/core/tests/unit/kmnkbd/debug_api.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include "path.hpp" #include "state.hpp" #include "kmx/kmx_base.h" @@ -462,14 +462,14 @@ int error_args() { int print_sizeof() { std::cout << std::endl; - std::cout << "keyboardprocessor.h:" << std::endl; + std::cout << "keyman_core_api.h:" << std::endl; std::cout << "sizeof(km_kbp_context_item): " << sizeof(km_kbp_context_item) << std::endl; std::cout << "sizeof(km_kbp_action_item): " << sizeof(km_kbp_action_item) << std::endl; std::cout << "sizeof(km_kbp_option_item): " << sizeof(km_kbp_option_item) << std::endl; std::cout << "sizeof(km_kbp_keyboard_attrs): " << sizeof(km_kbp_keyboard_attrs) << std::endl; std::cout << "sizeof(km_kbp_attr): " << sizeof(km_kbp_attr) << std::endl; std::cout << std::endl; - std::cout << "keyboardprocessor_debug.h:" << std::endl; + std::cout << "keyman_core_api_debug.h.h:" << std::endl; std::cout << "sizeof(km_kbp_state_debug_item): " << sizeof(km_kbp_state_debug_item) << std::endl; std::cout << "sizeof(km_kbp_state_debug_key_info): " << sizeof(km_kbp_state_debug_key_info) << std::endl; std::cout << "sizeof(km_kbp_state_debug_kmx_info): " << sizeof(km_kbp_state_debug_kmx_info) << std::endl; diff --git a/core/tests/unit/kmnkbd/debug_items.hpp b/core/tests/unit/kmnkbd/debug_items.hpp index 95703005c4..3ac2ff1f68 100644 --- a/core/tests/unit/kmnkbd/debug_items.hpp +++ b/core/tests/unit/kmnkbd/debug_items.hpp @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include #include "kmx/kmx_base.h" #include "kmx/kmx_xstring.h" diff --git a/core/tests/unit/kmnkbd/keyboard_api.cpp b/core/tests/unit/kmnkbd/keyboard_api.cpp index cefba0d47c..48e36197ce 100644 --- a/core/tests/unit/kmnkbd/keyboard_api.cpp +++ b/core/tests/unit/kmnkbd/keyboard_api.cpp @@ -6,7 +6,7 @@ */ #include -#include +#include #include "path.hpp" //#include "keyboard.hpp" diff --git a/core/tests/unit/kmnkbd/options_api.cpp b/core/tests/unit/kmnkbd/options_api.cpp index 5fa64cffc6..9612195847 100644 --- a/core/tests/unit/kmnkbd/options_api.cpp +++ b/core/tests/unit/kmnkbd/options_api.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include "option.hpp" #include "state.hpp" diff --git a/core/tests/unit/kmnkbd/state_api.cpp b/core/tests/unit/kmnkbd/state_api.cpp index 3ae446541c..866ebe49a4 100644 --- a/core/tests/unit/kmnkbd/state_api.cpp +++ b/core/tests/unit/kmnkbd/state_api.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include "path.hpp" #include "state.hpp" @@ -49,7 +49,7 @@ namespace constexpr char const *doc1_expected = u8"\ {\n\ - \"$schema\" : \"keyman/keyboardprocessor/doc/introspection.schema\",\n\ + \"$schema\" : \"keyman/core/doc/introspection.schema\",\n\ \"keyboard\" : {\n\ \"id\" : \"dummy\",\n\ \"folder\" : \"\",\n\ @@ -75,7 +75,7 @@ constexpr char const *doc1_expected = u8"\ constexpr char const *doc2_expected = u8"\ {\n\ - \"$schema\" : \"keyman/keyboardprocessor/doc/introspection.schema\",\n\ + \"$schema\" : \"keyman/core/doc/introspection.schema\",\n\ \"keyboard\" : {\n\ \"id\" : \"dummy\",\n\ \"folder\" : \"\",\n\ diff --git a/core/tests/unit/ldml/ldml_test_utils.hpp b/core/tests/unit/ldml/ldml_test_utils.hpp index 8b19edf8d3..146afef389 100644 --- a/core/tests/unit/ldml/ldml_test_utils.hpp +++ b/core/tests/unit/ldml/ldml_test_utils.hpp @@ -13,7 +13,7 @@ #include // for char to vk mapping tables #include // for surrogate pair macros #include -#include +#include namespace km { namespace tests { diff --git a/developer/src/tike/main/Keyman.System.KeymanCore.pas b/developer/src/tike/main/Keyman.System.KeymanCore.pas index 29a2341b18..159b3e6693 100644 --- a/developer/src/tike/main/Keyman.System.KeymanCore.pas +++ b/developer/src/tike/main/Keyman.System.KeymanCore.pas @@ -1,7 +1,7 @@ { * Keyman is copyright (C) SIL International. MIT License. * - * Interface for Keyman Core, matches keyboardprocessor.h + * Interface for Keyman Core, matches keyman_core_api.h } unit Keyman.System.KeymanCore; @@ -321,7 +321,7 @@ const KM_KBP_EVENT_FLAG_TOUCH = 1; // set if the event is touch, otherwise hardware -// keyboardprocessor_vkeys.h +// keyman_core_api_vkeys.h const // enum km_kbp_modifier_state - matches Keyman32 shift states @@ -620,7 +620,7 @@ const KM_KBP_VKEY__FE = $FE; KM_KBP_VKEY__FF = $FF; -// keyboardprocessor_consts.h +// keyman_core_api_consts.h.h const // Defined environment options for KMX processor KM_KBP_KMX_ENV_PLATFORM = 'platform'; diff --git a/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas b/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas index a1f63e3b38..bca7395088 100644 --- a/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas +++ b/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas @@ -1,7 +1,7 @@ { * Keyman is copyright (C) SIL International. MIT License. * - * Debug interface for Keyman Core, matches keyboardprocessor_debug.h + * Debug interface for Keyman Core, matches keyman_core_api_debug.h.h } unit Keyman.System.KeymanCoreDebug; @@ -181,7 +181,7 @@ initialization // Assertions generated by debug_api.cpp for win32 x86. // Usage: debug-api.exe --print-sizeof - //keyboardprocessor.h: + //keyman_core_api.h: Assert(sizeof(km_kbp_context_item) = 8); Assert(sizeof(km_kbp_context_item) = 8); Assert(sizeof(km_kbp_action_item) = 12); @@ -189,7 +189,7 @@ initialization Assert(sizeof(km_kbp_keyboard_attrs) = 16); Assert(sizeof(km_kbp_attr) = 16); - //keyboardprocessor_debug.h: + //keyman_core_api_debug.h.h: Assert(sizeof(km_kbp_state_debug_item) = 432); Assert(sizeof(km_kbp_state_debug_key_info) = 6); Assert(sizeof(km_kbp_state_debug_kmx_info) = 416); diff --git a/docs/settings/linux/settings.json b/docs/settings/linux/settings.json index 891507dd2e..f17739ece2 100644 --- a/docs/settings/linux/settings.json +++ b/docs/settings/linux/settings.json @@ -16,7 +16,7 @@ "python.pythonPath": "/usr/bin/python3", "files.associations": { "*.tcc": "cpp", - "keyboardprocessor.h": "c", + "keyman_core_api.h": "c", "engine.h": "c", "keyman-service.h": "c", "keymanutil.h": "c", diff --git a/linux/debian/tests/test-build b/linux/debian/tests/test-build index db0a343849..9fd3b6f077 100644 --- a/linux/debian/tests/test-build +++ b/linux/debian/tests/test-build @@ -11,7 +11,7 @@ cd "$WORKDIR" # Test all include files are available cat < keymantest.c -#include +#include km_kbp_context* c; EOF @@ -21,7 +21,7 @@ echo "build 1: OK" # Test pkg-config file - include without path cat < keymantest.c -#include +#include km_kbp_context* c; EOF diff --git a/linux/ibus-keyman/src/engine.c b/linux/ibus-keyman/src/engine.c index 49b9161f9a..2fb17c4ff7 100644 --- a/linux/ibus-keyman/src/engine.c +++ b/linux/ibus-keyman/src/engine.c @@ -28,8 +28,8 @@ #include #include -#include -#include +#include +#include #include "config.h" #include "keymanutil.h" diff --git a/linux/ibus-keyman/src/keycodes.h b/linux/ibus-keyman/src/keycodes.h index 2735da48cb..b563f11ad2 100644 --- a/linux/ibus-keyman/src/keycodes.h +++ b/linux/ibus-keyman/src/keycodes.h @@ -1,7 +1,7 @@ #ifndef __KEYCODES_H__ #define __KEYCODES_H__ -#include +#include // from android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMScanCodeMap.java // uses kernel keycodes which are (X11 keycode - 8) diff --git a/linux/ibus-keyman/src/keymanutil.c b/linux/ibus-keyman/src/keymanutil.c index 7ae92e2a2d..bcb92ee4d9 100644 --- a/linux/ibus-keyman/src/keymanutil.c +++ b/linux/ibus-keyman/src/keymanutil.c @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include "bcp47util.h" #include "kmpdetails.h" diff --git a/linux/ibus-keyman/src/keymanutil.h b/linux/ibus-keyman/src/keymanutil.h index 4b358c02ea..e76fc6253c 100644 --- a/linux/ibus-keyman/src/keymanutil.h +++ b/linux/ibus-keyman/src/keymanutil.h @@ -55,7 +55,7 @@ #include #include -#include +#include // Number of default Keyboard processor environment options for: "platform", "baseLayout", and "baseLayoutAlt" #define KEYMAN_ENVIRONMENT_OPTIONS 3 diff --git a/linux/ibus-keyman/tests/testfixture.cpp b/linux/ibus-keyman/tests/testfixture.cpp index 84aab933c8..6092407b1b 100644 --- a/linux/ibus-keyman/tests/testfixture.cpp +++ b/linux/ibus-keyman/tests/testfixture.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/windows/src/engine/keyman32/keymanengine.h b/windows/src/engine/keyman32/keymanengine.h index f40aeaf372..1bb8762ed7 100644 --- a/windows/src/engine/keyman32/keymanengine.h +++ b/windows/src/engine/keyman32/keymanengine.h @@ -18,11 +18,11 @@ #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1 #endif -// For keyboardprocessor_bits.h +// For keyman_core_api_bits.h #ifndef KMN_KBP_STATIC #define KMN_KBP_STATIC #endif -// For keyboardprocessor_bits.h +// For keyman_core_api_bits.h #ifndef _WIN32 #define _WIN32 1 #endif @@ -39,8 +39,8 @@ #include #include #include "../../../../common/windows/cpp/include/legacy_kmx_file.h" -#include -#include +#include +#include /***************************************************************************/ From 906a0a2ed7a8bead56fa0e682a6b0b32fdcd5a53 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 9 Oct 2023 14:41:01 +0700 Subject: [PATCH 097/107] chore: fix typo --- core/include/keyman/meson.build | 2 +- core/src/kmx/kmx_capslock.cpp | 2 +- core/src/kmx/kmx_environment.cpp | 2 +- core/src/kmx/kmx_processevent.cpp | 2 +- core/src/state.cpp | 2 +- developer/src/tike/main/Keyman.System.KeymanCore.pas | 2 +- linux/ibus-keyman/src/engine.c | 2 +- windows/src/engine/keyman32/keymanengine.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/include/keyman/meson.build b/core/include/keyman/meson.build index 6be28e4979..b807ac69a2 100644 --- a/core/include/keyman/meson.build +++ b/core/include/keyman/meson.build @@ -25,7 +25,7 @@ configure_file( install_headers('keyman_core_api.h', 'keyman_core_api_bits.h', - 'keyman_core_api_consts.h.h', + 'keyman_core_api_consts.h', 'keyman_core_api_debug.h.h', 'keyman_core_api_vkeys.h', join_paths(meson.current_build_dir(), 'keyman_core_api_version.h'), diff --git a/core/src/kmx/kmx_capslock.cpp b/core/src/kmx/kmx_capslock.cpp index ca32477883..f14745bf32 100644 --- a/core/src/kmx/kmx_capslock.cpp +++ b/core/src/kmx/kmx_capslock.cpp @@ -2,7 +2,7 @@ Copyright: Copyright (C) 2003-2018 SIL International. Authors: mcdurdin */ -#include +#include #include using namespace km::kbp; diff --git a/core/src/kmx/kmx_environment.cpp b/core/src/kmx/kmx_environment.cpp index b77971a403..eb5691c29d 100644 --- a/core/src/kmx/kmx_environment.cpp +++ b/core/src/kmx/kmx_environment.cpp @@ -3,7 +3,7 @@ Authors: mcdurdin */ #include -#include +#include #include #include diff --git a/core/src/kmx/kmx_processevent.cpp b/core/src/kmx/kmx_processevent.cpp index 94015ef2c8..2a4439f23f 100644 --- a/core/src/kmx/kmx_processevent.cpp +++ b/core/src/kmx/kmx_processevent.cpp @@ -4,7 +4,7 @@ */ #include "kmx_processevent.h" #include "state.hpp" -#include +#include using namespace km::kbp; using namespace kmx; diff --git a/core/src/state.cpp b/core/src/state.cpp index e873af8287..b8b0a44f8e 100644 --- a/core/src/state.cpp +++ b/core/src/state.cpp @@ -7,7 +7,7 @@ #include "state.hpp" #include "processor.hpp" -#include +#include using namespace km::kbp; diff --git a/developer/src/tike/main/Keyman.System.KeymanCore.pas b/developer/src/tike/main/Keyman.System.KeymanCore.pas index 159b3e6693..fb0410acc1 100644 --- a/developer/src/tike/main/Keyman.System.KeymanCore.pas +++ b/developer/src/tike/main/Keyman.System.KeymanCore.pas @@ -620,7 +620,7 @@ const KM_KBP_VKEY__FE = $FE; KM_KBP_VKEY__FF = $FF; -// keyman_core_api_consts.h.h +// keyman_core_api_consts.h const // Defined environment options for KMX processor KM_KBP_KMX_ENV_PLATFORM = 'platform'; diff --git a/linux/ibus-keyman/src/engine.c b/linux/ibus-keyman/src/engine.c index 2fb17c4ff7..889f78ee29 100644 --- a/linux/ibus-keyman/src/engine.c +++ b/linux/ibus-keyman/src/engine.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include "config.h" #include "keymanutil.h" diff --git a/windows/src/engine/keyman32/keymanengine.h b/windows/src/engine/keyman32/keymanengine.h index 1bb8762ed7..d6e0370a71 100644 --- a/windows/src/engine/keyman32/keymanengine.h +++ b/windows/src/engine/keyman32/keymanengine.h @@ -40,7 +40,7 @@ #include #include "../../../../common/windows/cpp/include/legacy_kmx_file.h" #include -#include +#include /***************************************************************************/ From 4e5cbc3b9680be3c697881ec19351f613f5fd9b1 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 9 Oct 2023 14:51:51 +0700 Subject: [PATCH 098/107] chore: fix typo --- core/include/keyman/meson.build | 2 +- core/src/debug.hpp | 2 +- core/tests/unit/kmnkbd/debug_api.cpp | 2 +- core/tests/unit/kmnkbd/debug_items.hpp | 2 +- developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/include/keyman/meson.build b/core/include/keyman/meson.build index b807ac69a2..8ef7d1a9f2 100644 --- a/core/include/keyman/meson.build +++ b/core/include/keyman/meson.build @@ -26,7 +26,7 @@ configure_file( install_headers('keyman_core_api.h', 'keyman_core_api_bits.h', 'keyman_core_api_consts.h', - 'keyman_core_api_debug.h.h', + 'keyman_core_api_debug.h', 'keyman_core_api_vkeys.h', join_paths(meson.current_build_dir(), 'keyman_core_api_version.h'), '../../../common/include/km_types.h', diff --git a/core/src/debug.hpp b/core/src/debug.hpp index a910c03a28..cee5e37c52 100644 --- a/core/src/debug.hpp +++ b/core/src/debug.hpp @@ -10,7 +10,7 @@ #include #include -#include +#include namespace km { namespace kbp diff --git a/core/tests/unit/kmnkbd/debug_api.cpp b/core/tests/unit/kmnkbd/debug_api.cpp index 57f6366697..ae59fd35ac 100644 --- a/core/tests/unit/kmnkbd/debug_api.cpp +++ b/core/tests/unit/kmnkbd/debug_api.cpp @@ -469,7 +469,7 @@ int print_sizeof() { std::cout << "sizeof(km_kbp_keyboard_attrs): " << sizeof(km_kbp_keyboard_attrs) << std::endl; std::cout << "sizeof(km_kbp_attr): " << sizeof(km_kbp_attr) << std::endl; std::cout << std::endl; - std::cout << "keyman_core_api_debug.h.h:" << std::endl; + std::cout << "keyman_core_api_debug.h:" << std::endl; std::cout << "sizeof(km_kbp_state_debug_item): " << sizeof(km_kbp_state_debug_item) << std::endl; std::cout << "sizeof(km_kbp_state_debug_key_info): " << sizeof(km_kbp_state_debug_key_info) << std::endl; std::cout << "sizeof(km_kbp_state_debug_kmx_info): " << sizeof(km_kbp_state_debug_kmx_info) << std::endl; diff --git a/core/tests/unit/kmnkbd/debug_items.hpp b/core/tests/unit/kmnkbd/debug_items.hpp index 3ac2ff1f68..880ceaaf73 100644 --- a/core/tests/unit/kmnkbd/debug_items.hpp +++ b/core/tests/unit/kmnkbd/debug_items.hpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include "kmx/kmx_base.h" #include "kmx/kmx_xstring.h" diff --git a/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas b/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas index bca7395088..9b190c8282 100644 --- a/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas +++ b/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas @@ -1,7 +1,7 @@ { * Keyman is copyright (C) SIL International. MIT License. * - * Debug interface for Keyman Core, matches keyman_core_api_debug.h.h + * Debug interface for Keyman Core, matches keyman_core_api_debug.h } unit Keyman.System.KeymanCoreDebug; @@ -189,7 +189,7 @@ initialization Assert(sizeof(km_kbp_keyboard_attrs) = 16); Assert(sizeof(km_kbp_attr) = 16); - //keyman_core_api_debug.h.h: + //keyman_core_api_debug.h: Assert(sizeof(km_kbp_state_debug_item) = 432); Assert(sizeof(km_kbp_state_debug_key_info) = 6); Assert(sizeof(km_kbp_state_debug_kmx_info) = 416); From 22362d435f68275f4ae85105f6efcf83a2fedbb3 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 9 Oct 2023 14:32:48 +0700 Subject: [PATCH 099/107] chore: rename pkm_kbp_ to pkm_core_ --- developer/src/tike/child/UfrmDebug.pas | 2 +- .../debug/Keyman.System.Debug.DebugCore.pas | 24 ++-- .../debug/Keyman.System.Debug.DebugEvent.pas | 26 ++-- .../tike/main/Keyman.System.KeymanCore.pas | 116 +++++++++--------- .../main/Keyman.System.KeymanCoreDebug.pas | 18 +-- .../Keyman.System.VisualKeyboardImportKMX.pas | 2 +- 6 files changed, 94 insertions(+), 94 deletions(-) diff --git a/developer/src/tike/child/UfrmDebug.pas b/developer/src/tike/child/UfrmDebug.pas index 615cfebc80..3a07d98bf4 100644 --- a/developer/src/tike/child/UfrmDebug.pas +++ b/developer/src/tike/child/UfrmDebug.pas @@ -371,7 +371,7 @@ end; function TfrmDebug.SetKeyEventContext: Boolean; var - context: pkm_kbp_context; + context: pkm_core_context; context_items: TArray; n, i: Integer; ch: Char; diff --git a/developer/src/tike/debug/Keyman.System.Debug.DebugCore.pas b/developer/src/tike/debug/Keyman.System.Debug.DebugCore.pas index 6b0a5b5fd5..c1107900a1 100644 --- a/developer/src/tike/debug/Keyman.System.Debug.DebugCore.pas +++ b/developer/src/tike/debug/Keyman.System.Debug.DebugCore.pas @@ -18,8 +18,8 @@ type TDebugCore = class private - FKeyboard: pkm_kbp_keyboard; - FState: pkm_kbp_state; + FKeyboard: pkm_core_keyboard; + FState: pkm_core_state; class var KeymanCoreLoaded: Boolean; class procedure InitKeymanCore; static; function GetKMXPlatform: string; @@ -30,8 +30,8 @@ type function GetOption(const name: string): string; procedure SetOption(const name, value: string); property KMXPlatform: string read GetKMXPlatform write SetKMXPlatform; - property Keyboard: pkm_kbp_keyboard read FKeyboard; - property State: pkm_kbp_state read FState; + property Keyboard: pkm_core_keyboard read FKeyboard; + property State: pkm_core_state read FState; end; implementation @@ -98,13 +98,13 @@ end; function TDebugCore.GetKMXPlatform: string; var - p: pkm_kbp_cp; + p: pkm_core_cp; status: km_kbp_status; begin status := km_kbp_state_option_lookup( FState, KM_KBP_OPT_ENVIRONMENT, - pkm_kbp_cp(PWideChar(KM_KBP_KMX_ENV_PLATFORM)), + pkm_core_cp(PWideChar(KM_KBP_KMX_ENV_PLATFORM)), p ); if status <> KM_KBP_STATUS_OK then @@ -117,8 +117,8 @@ var options: array[0..1] of km_kbp_option_item; status: km_kbp_status; begin - options[0].key := pkm_kbp_cp(PWideChar(KM_KBP_KMX_ENV_PLATFORM)); - options[0].value := pkm_kbp_cp(PWideChar(Value)); + options[0].key := pkm_core_cp(PWideChar(KM_KBP_KMX_ENV_PLATFORM)); + options[0].value := pkm_core_cp(PWideChar(Value)); options[0].scope := KM_KBP_OPT_ENVIRONMENT; options[1] := KM_KBP_OPTIONS_END; status := km_kbp_state_options_update(FState, @options[0]); @@ -128,13 +128,13 @@ end; function TDebugCore.GetOption(const name: string): string; var - p: pkm_kbp_cp; + p: pkm_core_cp; status: km_kbp_status; begin status := km_kbp_state_option_lookup( FState, KM_KBP_OPT_KEYBOARD, - pkm_kbp_cp(PWideChar(name)), + pkm_core_cp(PWideChar(name)), p ); if status <> KM_KBP_STATUS_OK then @@ -147,8 +147,8 @@ var options: array[0..1] of km_kbp_option_item; status: km_kbp_status; begin - options[0].key := pkm_kbp_cp(PWideChar(Name)); - options[0].value := pkm_kbp_cp(PWideChar(Value)); + options[0].key := pkm_core_cp(PWideChar(Name)); + options[0].value := pkm_core_cp(PWideChar(Value)); options[0].scope := KM_KBP_OPT_KEYBOARD; options[1] := KM_KBP_OPTIONS_END; status := km_kbp_state_options_update(FState, @options[0]); diff --git a/developer/src/tike/debug/Keyman.System.Debug.DebugEvent.pas b/developer/src/tike/debug/Keyman.System.Debug.DebugEvent.pas index 6a7e0b3f0e..5f8f6a2bf0 100644 --- a/developer/src/tike/debug/Keyman.System.Debug.DebugEvent.pas +++ b/developer/src/tike/debug/Keyman.System.Debug.DebugEvent.pas @@ -47,7 +47,7 @@ type Context: WideString; StoreOffsets: array[0..20] of Word; //TKeymanStoreEx; nStores: Integer; - procedure FillStoreList(event: pkm_kbp_state_debug_item; KeyboardMemory: PChar); + procedure FillStoreList(event: pkm_core_state_debug_item; KeyboardMemory: PChar); end; TDebugEventType = (etAction, etRuleMatch); @@ -73,23 +73,23 @@ type expected_value: uintptr_t); procedure Action_EmitKeystroke(const key: Word); procedure Action_Marker(marker: uintptr_t); - function AddActionItem(key: Word; action: pkm_kbp_action_item): Boolean; + function AddActionItem(key: Word; action: pkm_core_action_item): Boolean; procedure AddDebugItem( - debug: pkm_kbp_state_debug_item; + debug: pkm_core_state_debug_item; debugkeyboard: TDebugKeyboard; vk: uint16_t; modifier_state: uint16_t ); public function AddStateItems( - state: pkm_kbp_state; + state: pkm_core_state; vk: uint16_t; modifier_state: uint16_t; debugkeyboard: TDebugKeyboard ): Boolean; overload; function AddStateItems( - state: pkm_kbp_state; + state: pkm_core_state; vk: uint16_t; modifier_state: uint16_t ): Boolean; overload; @@ -133,7 +133,7 @@ begin end; end; -function TDebugEventList.AddActionItem(key: Word; action: pkm_kbp_action_item): Boolean; +function TDebugEventList.AddActionItem(key: Word; action: pkm_core_action_item): Boolean; begin Result := True; case action._type of @@ -220,7 +220,7 @@ begin end; procedure TDebugEventList.AddDebugItem( - debug: pkm_kbp_state_debug_item; + debug: pkm_core_state_debug_item; debugkeyboard: TDebugKeyboard; vk: uint16_t; modifier_state: uint16_t); @@ -312,12 +312,12 @@ begin end; function TDebugEventList.AddStateItems( - state: pkm_kbp_state; + state: pkm_core_state; vk: uint16_t; modifier_state: uint16_t ): Boolean; var - action: pkm_kbp_action_item; + action: pkm_core_action_item; begin Result := True; action := km_kbp_state_action_items(state, nil); @@ -329,14 +329,14 @@ begin end; function TDebugEventList.AddStateItems( - state: pkm_kbp_state; + state: pkm_core_state; vk: uint16_t; modifier_state: uint16_t; debugkeyboard: TDebugKeyboard ): Boolean; var - action: pkm_kbp_action_item; - debug: pkm_kbp_state_debug_item; + action: pkm_core_action_item; + debug: pkm_core_state_debug_item; action_index: Integer; begin Result := True; @@ -374,7 +374,7 @@ end; { TDebugEventRuleData } -procedure TDebugEventRuleData.FillStoreList(event: pkm_kbp_state_debug_item; KeyboardMemory: PChar); +procedure TDebugEventRuleData.FillStoreList(event: pkm_core_state_debug_item; KeyboardMemory: PChar); function StoreOffset(kfh: PKeyboardFileHeader; i: Word): PChar; begin Result := KeyboardMemory; diff --git a/developer/src/tike/main/Keyman.System.KeymanCore.pas b/developer/src/tike/main/Keyman.System.KeymanCore.pas index fb0410acc1..2cf5505c31 100644 --- a/developer/src/tike/main/Keyman.System.KeymanCore.pas +++ b/developer/src/tike/main/Keyman.System.KeymanCore.pas @@ -21,22 +21,22 @@ type km_kbp_usv = uint32_t; // UTF-32 km_kbp_cp = WideChar; - pkm_kbp_cp = ^km_kbp_cp; + pkm_core_cp = ^km_kbp_cp; km_kbp_context = record end; - pkm_kbp_context = ^km_kbp_context; + pkm_core_context = ^km_kbp_context; km_kbp_keyboard = record end; - pkm_kbp_keyboard = ^km_kbp_keyboard; + pkm_core_keyboard = ^km_kbp_keyboard; km_kbp_state = record end; - pkm_kbp_state = ^km_kbp_state; + pkm_core_state = ^km_kbp_state; km_kbp_options = record end; - pkm_kbp_options = ^km_kbp_options; + pkm_core_options = ^km_kbp_options; km_kbp_path_name = PWideChar; // on Windows - pkm_kbp_path_name = ^km_kbp_path_name; + pkm_core_path_name = ^km_kbp_path_name; type km_kbp_status = ( @@ -69,7 +69,7 @@ type 2: (marker: uint32_t); end; - pkm_kbp_context_item = ^km_kbp_context_item; + pkm_core_context_item = ^km_kbp_context_item; const KM_KBP_CONTEXT_ITEM_END: km_kbp_context_item = ( @@ -82,23 +82,23 @@ const kmnkbp0 = 'kmnkbp0-0.dll'; function km_kbp_context_items_from_utf16( - const text: pkm_kbp_cp; - var out_ptr: pkm_kbp_context_item + const text: pkm_core_cp; + var out_ptr: pkm_core_context_item ): km_kbp_status; cdecl; external kmnkbp0 delayed; function km_kbp_context_items_from_utf8( const text: PAnsiChar; - var out_ptr: pkm_kbp_context_item + var out_ptr: pkm_core_context_item ): km_kbp_status; cdecl; external kmnkbp0 delayed; function km_kbp_context_items_to_utf16( - const item: pkm_kbp_context_item; - buf: pkm_kbp_cp; + const item: pkm_core_context_item; + buf: pkm_core_cp; var buf_size: integer ): km_kbp_status; cdecl; external kmnkbp0 delayed; function km_kbp_context_items_to_utf8( - const item: pkm_kbp_context_item; + const item: pkm_core_context_item; buf: pansichar; var buf_size: integer ): km_kbp_status; cdecl; external kmnkbp0 delayed; @@ -108,28 +108,28 @@ procedure km_kbp_context_items_dispose( ); cdecl; external kmnkbp0 delayed; function km_kbp_context_set( - context: pkm_kbp_context; - context_items: pkm_kbp_context_item + context: pkm_core_context; + context_items: pkm_core_context_item ): km_kbp_status; cdecl; external kmnkbp0 delayed; function km_kbp_context_get( - context: pkm_kbp_context; - var context_items: pkm_kbp_context_item + context: pkm_core_context; + var context_items: pkm_core_context_item ): km_kbp_status; cdecl; external kmnkbp0 delayed; procedure km_kbp_context_clear( - context: pkm_kbp_context + context: pkm_core_context ); cdecl; external kmnkbp0 delayed; function km_kbp_context_append( - context: pkm_kbp_context; - context_items: pkm_kbp_context_item + context: pkm_core_context; + context_items: pkm_core_context_item ): km_kbp_status; cdecl; external kmnkbp0 delayed; function km_kbp_context_shrink( - context: pkm_kbp_context; + context: pkm_core_context; num: Integer; - prefix: pkm_kbp_context_item + prefix: pkm_core_context_item ): km_kbp_status; cdecl; external kmnkbp0 delayed; @@ -143,12 +143,12 @@ type ); km_kbp_option_item = record - key: pkm_kbp_cp; - value: pkm_kbp_cp; + key: pkm_core_cp; + value: pkm_core_cp; scope: km_kbp_option_scope; end; - pkm_kbp_option_item = ^km_kbp_option_item; + pkm_core_option_item = ^km_kbp_option_item; const KM_KBP_OPTIONS_END: km_kbp_option_item = (key: nil; value: nil; scope: KM_KBP_OPT_UNKNOWN); @@ -193,91 +193,91 @@ type {$ENDIF} case Integer of 0: (marker: uintptr_t); - 1: (option: pkm_kbp_option_item); + 1: (option: pkm_core_option_item); 2: (character: km_kbp_usv); 3: (backspace: km_kbp_backspace_item); 4: (capsLock: uint8_t); // CAPSLOCK type, 1 to turn on, 0 to turn off end; - pkm_kbp_action_item = ^km_kbp_action_item; + pkm_core_action_item = ^km_kbp_action_item; // These types are used only for debugging convenience type km_kbp_action_item_array = array[0..100] of km_kbp_action_item; - pkm_kbp_action_item_array = ^km_kbp_action_item_array; + pkm_core_action_item_array = ^km_kbp_action_item_array; function km_kbp_options_list_size( - opts: pkm_kbp_option_item + opts: pkm_core_option_item ): Integer; cdecl; external kmnkbp0 delayed; function km_kbp_state_option_lookup( - state: pkm_kbp_state; + state: pkm_core_state; scope: km_kbp_option_scope; - key: pkm_kbp_cp; - var value: pkm_kbp_cp + key: pkm_core_cp; + var value: pkm_core_cp ): km_kbp_status; cdecl; external kmnkbp0 delayed; function km_kbp_state_options_update( - state: pkm_kbp_state; - new_opts: pkm_kbp_option_item + state: pkm_core_state; + new_opts: pkm_core_option_item ): km_kbp_status; cdecl; external kmnkbp0 delayed; function km_kbp_state_options_to_json( - state: pkm_kbp_state; + state: pkm_core_state; buf: PAnsiChar; var space: Integer ): km_kbp_status; cdecl; external kmnkbp0 delayed; type km_kbp_keyboard_attrs = record - version_string: pkm_kbp_cp; - id: pkm_kbp_cp; + version_string: pkm_core_cp; + id: pkm_core_cp; folder_path: km_kbp_path_name; - default_optons: pkm_kbp_option_item + default_optons: pkm_core_option_item end; - pkm_kbp_keyboard_attrs = ^km_kbp_keyboard_attrs; + pkm_core_keyboard_attrs = ^km_kbp_keyboard_attrs; function km_kbp_keyboard_load( kb_path: km_kbp_path_name; - var keyboard: pkm_kbp_keyboard + var keyboard: pkm_core_keyboard ): km_kbp_status; cdecl; external kmnkbp0 delayed; procedure km_kbp_keyboard_dispose( - keyboard: pkm_kbp_keyboard + keyboard: pkm_core_keyboard ); cdecl; external kmnkbp0 delayed; function km_kbp_keyboard_get_attrs( - keyboard: pkm_kbp_keyboard; - var out: pkm_kbp_keyboard_attrs + keyboard: pkm_core_keyboard; + var out: pkm_core_keyboard_attrs ): km_kbp_status; cdecl; external kmnkbp0 delayed; function km_kbp_state_create( - keyboard: pkm_kbp_keyboard; - env: pkm_kbp_option_item; - var out: pkm_kbp_state + keyboard: pkm_core_keyboard; + env: pkm_core_option_item; + var out: pkm_core_state ): km_kbp_status; cdecl; external kmnkbp0 delayed; function km_kbp_state_clone( - state: pkm_kbp_state; - var out: pkm_kbp_state + state: pkm_core_state; + var out: pkm_core_state ): km_kbp_status; cdecl; external kmnkbp0 delayed; procedure km_kbp_state_dispose( - state: pkm_kbp_state + state: pkm_core_state ); cdecl; external kmnkbp0 delayed; function km_kbp_state_context( - state: pkm_kbp_state -): pkm_kbp_context; cdecl; external kmnkbp0 delayed; + state: pkm_core_state +): pkm_core_context; cdecl; external kmnkbp0 delayed; function km_kbp_state_action_items( - state: pkm_kbp_state; + state: pkm_core_state; num_items: pinteger -): pkm_kbp_action_item; cdecl; external kmnkbp0 delayed; +): pkm_core_action_item; cdecl; external kmnkbp0 delayed; function km_kbp_state_to_json( - state: pkm_kbp_state; + state: pkm_core_state; buf: PAnsiChar; space: pinteger ): km_kbp_status; cdecl; external kmnkbp0 delayed; @@ -293,7 +293,7 @@ type vendor: pansichar // Implementor of the processor. end; - pkm_kbp_attr = ^km_kbp_attr; + pkm_core_attr = ^km_kbp_attr; km_kbp_tech_value = ( KM_KBP_TECH_UNSPECIFIED = 0, @@ -304,12 +304,12 @@ type ); function km_kbp_get_engine_attrs( - state: pkm_kbp_state -): pkm_kbp_attr; cdecl; external kmnkbp0 delayed; + state: pkm_core_state +): pkm_core_attr; cdecl; external kmnkbp0 delayed; function km_kbp_process_event( - state: pkm_kbp_state; + state: pkm_core_state; vk: km_kbp_virtual_key; modifier_state: uint16_t; is_key_down: uint8_t; diff --git a/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas b/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas index 9b190c8282..4ff3a7bcad 100644 --- a/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas +++ b/developer/src/tike/main/Keyman.System.KeymanCoreDebug.pas @@ -50,14 +50,14 @@ km_kbp_state_debug_key_info = record character: char16_t; end; -pkm_kbp_state_debug_key_info = ^km_kbp_state_debug_key_info; +pkm_core_state_debug_key_info = ^km_kbp_state_debug_key_info; km_kbp_state_debug_kmx_option_info = record store: Pointer; // LPSTORE value: array[0..DEBUG_MAX_CONTEXT-1] of km_kbp_cp; // value to be saved into the store end; -pkm_kbp_state_debug_kmx_option_info = ^km_kbp_state_debug_kmx_option_info; +pkm_core_state_debug_kmx_option_info = ^km_kbp_state_debug_kmx_option_info; /// /// KMX processor data for each event. kmx_base.h defines the types that are @@ -83,7 +83,7 @@ km_kbp_state_debug_kmx_info = record option: km_kbp_state_debug_kmx_option_info; end; -pkm_kbp_state_debug_kmx_info = ^km_kbp_state_debug_kmx_info; +pkm_core_state_debug_kmx_info = ^km_kbp_state_debug_kmx_info; /// /// A single debug event. @@ -98,7 +98,7 @@ km_kbp_state_debug_item = record kmx_info: km_kbp_state_debug_kmx_info; end; -pkm_kbp_state_debug_item = ^km_kbp_state_debug_item; +pkm_core_state_debug_item = ^km_kbp_state_debug_item; /// /// A single debug event. @@ -109,7 +109,7 @@ km_kbp_debug_type = type uint32_t; // These types are used only for debugging convenience type km_kbp_state_debug_item_array = array[0..100] of km_kbp_state_debug_item; - pkm_kbp_state_debug_item_array = ^km_kbp_state_debug_item_array; + pkm_core_state_debug_item_array = ^km_kbp_state_debug_item_array; const KM_KBP_DEBUG_BEGIN = 0; @@ -145,7 +145,7 @@ const KM_KBP_DEBUG_FLAG_OUTPUTKEYSTROKE = $0001; /// @returns KM_KBP_STATUS_OK on success /// function km_kbp_state_debug_set( - state: pkm_kbp_state; + state: pkm_core_state; value: integer ): km_kbp_status; cdecl; external kmnkbp0 delayed; @@ -157,7 +157,7 @@ function km_kbp_state_debug_set( /// @returns 1 if debugging is enabled, 0 otherwise /// function km_kbp_state_debug_get( - state: pkm_kbp_state + state: pkm_core_state ): uint8_t; cdecl; external kmnkbp0 delayed; /// @@ -171,9 +171,9 @@ function km_kbp_state_debug_get( /// with last entry guaranteed to be KM_KBP_DEBUG_END. /// function km_kbp_state_debug_items( - state: pkm_kbp_state; + state: pkm_core_state; num_items: PCardinal -): pkm_kbp_state_debug_item; cdecl; external kmnkbp0 delayed; +): pkm_core_state_debug_item; cdecl; external kmnkbp0 delayed; implementation diff --git a/developer/src/tike/main/Keyman.System.VisualKeyboardImportKMX.pas b/developer/src/tike/main/Keyman.System.VisualKeyboardImportKMX.pas index e36216e155..8fc1f8aecd 100644 --- a/developer/src/tike/main/Keyman.System.VisualKeyboardImportKMX.pas +++ b/developer/src/tike/main/Keyman.System.VisualKeyboardImportKMX.pas @@ -106,7 +106,7 @@ procedure TVisualKeyboardImportKMX.ImportKey(vk: TVKKey); var data: string; i: Integer; - context: pkm_kbp_context; + context: pkm_core_context; begin context := km_kbp_state_context(FCore.State); km_kbp_context_clear(context); From ba5f18defd16cbcf3527252248614343fc85bc89 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 9 Oct 2023 14:35:58 +0700 Subject: [PATCH 100/107] chore: rename km_kbp_ to km_core_ --- HISTORY.md | 6 +- common/include/km_types.h | 12 +- core/doc/markdown_files/index.md | 2 +- core/include/keyman/keyman_core_api.h | 424 +++++++++--------- core/include/keyman/keyman_core_api_bits.h | 4 +- core/include/keyman/keyman_core_api_debug.h | 32 +- .../keyman/keyman_core_api_version.h.in | 6 +- core/include/keyman/keyman_core_api_vkeys.h | 6 +- core/src/context.hpp | 16 +- core/src/debug.hpp | 14 +- core/src/keyboard.cpp | 2 +- core/src/keyboard.hpp | 6 +- core/src/km_kbp_context_api.cpp | 62 +-- core/src/km_kbp_debug_api.cpp | 16 +- core/src/km_kbp_keyboard_api.cpp | 34 +- core/src/km_kbp_options_api.cpp | 22 +- core/src/km_kbp_processevent_api.cpp | 22 +- core/src/km_kbp_state_api.cpp | 48 +- core/src/kmx/kmx_debugger.cpp | 8 +- core/src/kmx/kmx_debugger.h | 6 +- core/src/kmx/kmx_environment.cpp | 2 +- core/src/kmx/kmx_environment.h | 4 +- core/src/kmx/kmx_file.cpp | 4 +- core/src/kmx/kmx_plus.cpp | 4 +- core/src/kmx/kmx_plus.h | 6 +- core/src/kmx/kmx_processevent.cpp | 10 +- core/src/kmx/kmx_processevent.h | 10 +- core/src/kmx/kmx_processor.cpp | 64 +-- core/src/kmx/kmx_processor.hpp | 38 +- core/src/kmx/kmx_xstring.cpp | 28 +- core/src/kmx/kmx_xstring.h | 40 +- core/src/ldml/ldml_processor.cpp | 46 +- core/src/ldml/ldml_processor.hpp | 38 +- core/src/ldml/ldml_transforms.cpp | 6 +- core/src/ldml/ldml_transforms.hpp | 8 +- core/src/ldml/ldml_vkeys.cpp | 4 +- core/src/ldml/ldml_vkeys.hpp | 6 +- core/src/meson.build | 24 +- core/src/mock/mock_processor.cpp | 40 +- core/src/mock/mock_processor.hpp | 30 +- core/src/option.cpp | 6 +- core/src/option.hpp | 14 +- core/src/path.hpp | 4 +- core/src/processor.hpp | 46 +- core/src/state.cpp | 14 +- core/src/state.hpp | 46 +- .../tests/kmx_test_source/kmx_test_source.cpp | 20 +- .../tests/kmx_test_source/kmx_test_source.hpp | 6 +- core/tests/unit/kmnkbd/action_items.hpp | 14 +- core/tests/unit/kmnkbd/context_api.cpp | 108 ++--- core/tests/unit/kmnkbd/debug_api.cpp | 300 ++++++------- core/tests/unit/kmnkbd/debug_items.hpp | 12 +- core/tests/unit/kmnkbd/keyboard_api.cpp | 22 +- core/tests/unit/kmnkbd/options_api.cpp | 40 +- core/tests/unit/kmnkbd/state_api.cpp | 76 ++-- core/tests/unit/kmx/kmx.cpp | 70 +-- core/tests/unit/kmx/kmx_external_event.cpp | 22 +- core/tests/unit/kmx/kmx_imx.cpp | 114 ++--- core/tests/unit/kmx/kmx_key_list.cpp | 32 +- core/tests/unit/kmx/kmx_key_list.kmn | 2 +- core/tests/unit/kmx/meson.build | 2 +- core/tests/unit/ldml/ldml.cpp | 72 +-- core/tests/unit/ldml/ldml_test_source.cpp | 28 +- core/tests/unit/ldml/ldml_test_source.hpp | 6 +- core/tests/unit/ldml/ldml_test_utils.cpp | 2 +- core/tests/unit/ldml/ldml_test_utils.hpp | 2 +- developer/src/kmcmplib/src/Compiler.cpp | 2 +- developer/src/tike/child/UfrmDebug.pas | 14 +- .../debug/Keyman.System.Debug.DebugCore.pas | 32 +- .../debug/Keyman.System.Debug.DebugEvent.pas | 12 +- .../tike/main/Keyman.System.KeymanCore.pas | 182 ++++---- .../main/Keyman.System.KeymanCoreDebug.pas | 66 +-- .../Keyman.System.VisualKeyboardImportKMX.pas | 6 +- linux/debian/libkmnkbp0-0.symbols | 78 ++-- linux/debian/tests/test-build | 4 +- linux/ibus-keyman/src/engine.c | 108 ++--- linux/ibus-keyman/src/keycodes.h | 2 +- linux/ibus-keyman/src/keymanutil.c | 6 +- linux/ibus-keyman/src/keymanutil.h | 2 +- .../src/engine/keyman32/CoreEnvironment.cpp | 10 +- windows/src/engine/keyman32/K32_load.cpp | 18 +- windows/src/engine/keyman32/appint/appint.cpp | 36 +- windows/src/engine/keyman32/appint/appint.h | 10 +- windows/src/engine/keyman32/calldll.cpp | 54 +-- windows/src/engine/keyman32/calldll.h | 2 +- .../src/engine/keyman32/keyboardoptions.cpp | 28 +- windows/src/engine/keyman32/keyboardoptions.h | 2 +- windows/src/engine/keyman32/keyman32.cpp | 8 +- windows/src/engine/keyman32/keymanengine.h | 18 +- .../src/engine/keyman32/kmhook_getmessage.cpp | 2 +- windows/src/engine/keyman32/kmprocess.cpp | 12 +- .../src/engine/keyman32/kmprocessactions.cpp | 28 +- .../src/engine/keyman32/preservedkeymap.cpp | 22 +- .../src/engine/keyman32/selectkeyboard.cpp | 4 +- .../keyboardoptionstests.cpp | 24 +- .../kmprocessactionstests.cpp | 48 +- 96 files changed, 1540 insertions(+), 1540 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e22d0e994b..37f73a8ec5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -926,7 +926,7 @@ * chore: git tag with release@semver (#8035) * fix(linux): Properly set context after changing IP (#8026) * chore(linux): use faster zero-length string check (#8037) -* chore(linux): log failures to `km_kbp_context_clear(context)` (#8036) +* chore(linux): log failures to `km_core_context_clear(context)` (#8036) * chore(linux): Update recommended extension (#8038) ## 17.0.30 alpha 2023-01-17 @@ -1600,14 +1600,14 @@ ## 16.0.60 alpha 2022-09-10 * fix(web): enhanced timer for prediction algorithm (#7037) -* chore(core): fixup km_kbp_event docs (#7253) +* chore(core): fixup km_core_event docs (#7253) * fix(windows) Update unit tests for tsf bkspace (#7254) * fix(android): Standardize language ID in language picker menu (#7239) ## 16.0.59 alpha 2022-09-09 * chore: use keyman.com instead of keyman-staging.com (#7233) -* feat(core): add `km_kbp_event` API endpoint (#7223) +* feat(core): add `km_core_event` API endpoint (#7223) * fix(windows): Delete both code units when deleting surrogate pairs in TSF-aware apps (#7243) ## 16.0.58 alpha 2022-09-08 diff --git a/common/include/km_types.h b/common/include/km_types.h index d81f267238..aa7fb2e518 100644 --- a/common/include/km_types.h +++ b/common/include/km_types.h @@ -28,14 +28,14 @@ typedef uint8_t KMX_BYTE; typedef uint16_t KMX_WORD; #if defined(__cplusplus) -typedef char16_t km_kbp_cp; -typedef char32_t km_kbp_usv; +typedef char16_t km_core_cp; +typedef char32_t km_core_usv; #else -typedef uint16_t km_kbp_cp; // code point -typedef uint32_t km_kbp_usv; // Unicode Scalar Value +typedef uint16_t km_core_cp; // code point +typedef uint32_t km_core_usv; // Unicode Scalar Value #endif -typedef km_kbp_cp KMX_WCHAR; // wc, 16-bit UNICODE character +typedef km_core_cp KMX_WCHAR; // wc, 16-bit UNICODE character typedef KMX_WCHAR* PKMX_WCHAR; typedef char KMX_CHAR; @@ -60,7 +60,7 @@ typedef KMX_DWORD* PKMX_DWORD; #ifdef USE_CHAR16_T #define lpuch(x) u ## x -typedef km_kbp_cp KMX_UCHAR; +typedef km_core_cp KMX_UCHAR; #else #define lpuch(x) L ## x typedef wchar_t KMX_UCHAR; diff --git a/core/doc/markdown_files/index.md b/core/doc/markdown_files/index.md index bc196a0a0c..d389857c5f 100644 --- a/core/doc/markdown_files/index.md +++ b/core/doc/markdown_files/index.md @@ -58,4 +58,4 @@ Caps Lock. ### Namespace -All calls, types and enums are prefixed with the namespace identifier `km_kbp_` +All calls, types and enums are prefixed with the namespace identifier `km_core_` diff --git a/core/include/keyman/keyman_core_api.h b/core/include/keyman/keyman_core_api.h index b32be63073..bbb194d431 100644 --- a/core/include/keyman/keyman_core_api.h +++ b/core/include/keyman/keyman_core_api.h @@ -67,12 +67,12 @@ Caps Lock. ## API ### Namespace -All calls, types and enums are prefixed with the namespace identifier `km_kbp_` +All calls, types and enums are prefixed with the namespace identifier `km_core_` ### API idioms Almost all calls marshalling variable length aggregate data in or out of an API object take the form: -> km_kbp_status *fn_name*(object_ref, buffer_ptr, size_ptr) +> km_core_status *fn_name*(object_ref, buffer_ptr, size_ptr) where the buffer is nullable and all other arguments are required (will result in an `KM_KBP_STATUS_INVALID_ARGUMENT` status being returned if nulled). When @@ -81,7 +81,7 @@ buffer in the variable pointed to by `size_ptr`. Calls which result in the allocation of resources, regardless of resulting ownership, are of the form: -> km_kbp_status *fn_name*(object_ref, out_ptr) +> km_core_status *fn_name*(object_ref, out_ptr) where `out_ptr` is a valid pointer to a caller allocated variable to hold the resulting ouput. This is often a reference to a created object. All arguments @@ -110,24 +110,24 @@ extern "C" #endif // Basic types // -typedef uint16_t km_kbp_virtual_key; // A virtual key code. -typedef uint32_t km_kbp_status; // Status return code. +typedef uint16_t km_core_virtual_key; // A virtual key code. +typedef uint32_t km_core_status; // Status return code. // Opaque object types. // -typedef struct km_kbp_context km_kbp_context; -typedef struct km_kbp_keyboard km_kbp_keyboard; -typedef struct km_kbp_state km_kbp_state; -typedef struct km_kbp_options km_kbp_options; +typedef struct km_core_context km_core_context; +typedef struct km_core_keyboard km_core_keyboard; +typedef struct km_core_state km_core_state; +typedef struct km_core_options km_core_options; // Forward declarations // -typedef struct km_kbp_option_item km_kbp_option_item; +typedef struct km_core_option_item km_core_option_item; // Callback function used to to access Input Method eXtension library functions // from Keyman Core // -typedef uint8_t (*km_kbp_keyboard_imx_platform)(km_kbp_state*, uint32_t, void*); +typedef uint8_t (*km_core_keyboard_imx_platform)(km_core_state*, uint32_t, void*); /*``` ### Error Handling @@ -137,7 +137,7 @@ value is an error). Any functions that can fail will always return a status value and all results are returned via outparams passed to the function. ```c */ -enum km_kbp_status_codes { +enum km_core_status_codes { KM_KBP_STATUS_OK = 0, KM_KBP_STATUS_NO_MEM = 1, KM_KBP_STATUS_IO_ERROR = 2, @@ -176,7 +176,7 @@ Contexts are always owned by their state. They may be set to a list of context_items or interrogated for their current list of context items. ```c */ -enum km_kbp_context_type { +enum km_core_context_type { KM_KBP_CT_END, KM_KBP_CT_CHAR, KM_KBP_CT_MARKER @@ -186,17 +186,17 @@ typedef struct { uint8_t type; uint8_t _reserved[3]; union { - km_kbp_usv character; + km_core_usv character; uint32_t marker; }; -} km_kbp_context_item; +} km_core_context_item; #define KM_KBP_CONTEXT_ITEM_END {KM_KBP_CT_END, {0,}, {0,}} /* ``` -### `km_kbp_context_items_from_utf16` +### `km_core_context_items_from_utf16` ##### Description: -Convert a UTF16 encoded Unicode string into an array of `km_kbp_context_item` +Convert a UTF16 encoded Unicode string into an array of `km_core_context_item` structures. Allocates memory as needed. ##### Return status: - `KM_KBP_STATUS_OK`: On success. @@ -208,23 +208,23 @@ structures. Allocates memory as needed. ##### Parameters: - __text__: a pointer to a null terminated array of utf16 encoded data. - __out_ptr__: a pointer to the result variable: - A pointer to the start of the `km_kbp_context_item` array containing the + A pointer to the start of the `km_core_context_item` array containing the representation of the input string. Terminated with a type of `KM_KBP_CT_END`. Must be disposed of with - `km_kbp_context_items_dispose`. + `km_core_context_items_dispose`. ```c */ KMN_API -km_kbp_status -km_kbp_context_items_from_utf16(km_kbp_cp const *text, - km_kbp_context_item **out_ptr); +km_core_status +km_core_context_items_from_utf16(km_core_cp const *text, + km_core_context_item **out_ptr); /* ``` -### `km_kbp_context_items_from_utf8` +### `km_core_context_items_from_utf8` ##### Description: -Convert an UTF8 encoded Unicode string into an array of `km_kbp_context_item` +Convert an UTF8 encoded Unicode string into an array of `km_core_context_item` structures. Allocates memory as needed. ##### Status: - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. @@ -235,20 +235,20 @@ decoded. ##### Parameters: - __text__: a pointer to a null terminated array of utf8 encoded data. - __out_ptr__: a pointer to the result variable: - A pointer to the start of the `km_kbp_context_item` array containing the + A pointer to the start of the `km_core_context_item` array containing the representation of the input string. Terminated with a type of `KM_KBP_CT_END`. ```c */ KMN_API -km_kbp_status -km_kbp_context_items_from_utf8(char const *text, - km_kbp_context_item **out_ptr); +km_core_status +km_core_context_items_from_utf8(char const *text, + km_core_context_item **out_ptr); /* ``` -### `km_kbp_context_items_to_utf16` +### `km_core_context_items_to_utf16` ##### Description: Convert a context item array into a UTF-16 encoded string placing it into the supplied buffer of specified size, and return the number of code units @@ -262,7 +262,7 @@ context during the conversion. `buf_size` will contain the space required. The contents of the buffer are undefined. ##### Parameters: -- __context_items__: A pointer to the start of an array `km_kbp_context_item`. +- __context_items__: A pointer to the start of an array `km_core_context_item`. Must be terminated with a type of `KM_KBP_CT_END`. - __buf__: A pointer to the buffer to place the UTF-16 string into. May be null to request size calculation. @@ -273,14 +273,14 @@ context during the conversion. ```c */ KMN_API -km_kbp_status -km_kbp_context_items_to_utf16(km_kbp_context_item const *item, - km_kbp_cp *buf, +km_core_status +km_core_context_items_to_utf16(km_core_context_item const *item, + km_core_cp *buf, size_t *buf_size); /* ``` -### `km_kbp_context_items_to_utf8` +### `km_core_context_items_to_utf8` ##### Description: Convert a context item array into a UTF-8 encoded string placing it into the supplied buffer of specified size, and return the number of code units @@ -294,7 +294,7 @@ context during the conversion. `buf_size` will contain the space required. The contents of the buffer are undefined. ##### Parameters: -- __context_items__: A pointer to the start of an array `km_kbp_context_item`. +- __context_items__: A pointer to the start of an array `km_core_context_item`. Must be terminated with a type of `KM_KBP_CT_END`. - __buf__: A pointer to the buffer to place the UTF-8 string into. May be null to request size calculation. @@ -305,33 +305,33 @@ context during the conversion. ```c */ KMN_API -km_kbp_status -km_kbp_context_items_to_utf8(km_kbp_context_item const *item, +km_core_status +km_core_context_items_to_utf8(km_core_context_item const *item, char *buf, size_t *buf_size); /* ``` -### `km_kbp_context_items_dispose` +### `km_core_context_items_dispose` ##### Description: -Free the allocated memory belonging to a `km_kbp_context_item` array previously -returned by `km_kbp_context_items_from_utf16` or `km_kbp_context_get` +Free the allocated memory belonging to a `km_core_context_item` array previously +returned by `km_core_context_items_from_utf16` or `km_core_context_get` ##### Parameters: -- __context_items__: A pointer to the start of the `km_kbp_context_item` array +- __context_items__: A pointer to the start of the `km_core_context_item` array to be disposed of. ```c */ KMN_API void -km_kbp_context_items_dispose(km_kbp_context_item *context_items); +km_core_context_items_dispose(km_core_context_item *context_items); /* ``` -### `km_kbp_context_set` +### `km_core_context_set` ##### Description: Replace the contents of the current context with a new sequence of -`km_kbp_context_item` entries. +`km_core_context_item` entries. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. @@ -339,45 +339,45 @@ Replace the contents of the current context with a new sequence of grow the context buffer internally. ##### Parameters: - __context__: A pointer to an opaque context object -- __context_items__: A pointer to the start of the `km_kbp_context_item` +- __context_items__: A pointer to the start of the `km_core_context_item` array containing the new context. It must be terminated with an item of type `KM_KBP_CT_END`. ```c */ KMN_API -km_kbp_status -km_kbp_context_set(km_kbp_context *context, - km_kbp_context_item const *context_items); +km_core_status +km_core_context_set(km_core_context *context, + km_core_context_item const *context_items); /* ``` -### `km_kbp_context_get` +### `km_core_context_get` ##### Description: Copies all items in the context into a new array and returns the new array. -This must be disposed of by caller using `km_kbp_context_items_dispose`. +This must be disposed of by caller using `km_core_context_items_dispose`. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event not enough memory can be allocated for the output buffer. ##### Parameters: -- __context_items__: A pointer to the start of an array `km_kbp_context_item`. +- __context_items__: A pointer to the start of an array `km_core_context_item`. - __out__: a pointer to the result variable: - A pointer to the start of the `km_kbp_context_item` array containing a + A pointer to the start of the `km_core_context_item` array containing a copy of the context. Terminated with a type of `KM_KBP_CT_END`. Must be - disposed of with `km_kbp_context_items_dispose`. + disposed of with `km_core_context_items_dispose`. ```c */ KMN_API -km_kbp_status -km_kbp_context_get(km_kbp_context const *context_items, - km_kbp_context_item **out); +km_core_status +km_core_context_get(km_core_context const *context_items, + km_core_context_item **out); /* ``` -### `km_kbp_context_clear` +### `km_core_context_clear` ##### Description: Removes all context_items from the internal array. If `context` is null, has no effect. @@ -388,11 +388,11 @@ null, has no effect. */ KMN_API void -km_kbp_context_clear(km_kbp_context *); +km_core_context_clear(km_core_context *); /* ``` -### `km_kbp_context_length` +### `km_core_context_length` ##### Description: Return the number of items in the context. ##### Return: @@ -405,11 +405,11 @@ pointer. */ KMN_API size_t -km_kbp_context_length(km_kbp_context *); +km_core_context_length(km_core_context *); /* ``` -### `km_kbp_context_append` +### `km_core_context_append` ##### Description: Add more items to the end (insertion point) of the context. If these exceed the maximum context length the same number of items will be dropped from the @@ -422,18 +422,18 @@ beginning of the context. ##### Parameters: - __context__: A pointer to an opaque context object. - __context_items__: A pointer to the start of the `KM_KBP_CT_END` terminated - array of `km_kbp_context_item` to append. + array of `km_core_context_item` to append. ```c */ KMN_API -km_kbp_status -km_kbp_context_append(km_kbp_context *context, - km_kbp_context_item const *context_items); +km_core_status +km_core_context_append(km_core_context *context, + km_core_context_item const *context_items); /* ``` -### `km_kbp_context_shrink` +### `km_core_context_shrink` ##### Description: Remove a specified number of items from the end of the context, optionally add up to the same number of the supplied items to the front of the context. @@ -446,34 +446,34 @@ add up to the same number of the supplied items to the front of the context. - __context__: A pointer to an opaque context object. - __num__: The number of items to remove from the end of context. - __context_items__: Pointer to the start of the `KM_KBP_CT_END` terminated - array of `km_kbp_context_item` to add to the front. Up to `num` items will + array of `km_core_context_item` to add to the front. Up to `num` items will be prepended. This may be null if not required. ```c */ KMN_API -km_kbp_status -km_kbp_context_shrink(km_kbp_context *context, +km_core_status +km_core_context_shrink(km_core_context *context, size_t num, - km_kbp_context_item const *prefix); + km_core_context_item const *prefix); /* ``` -### `km_kbp_context_item_list_size` +### `km_core_context_item_list_size` ##### Description: -Return the length of a terminated `km_kbp_context_item` array. +Return the length of a terminated `km_core_context_item` array. ##### Return: The number of items in the list, not including terminating item, or 0 if `context_items` is null. ##### Parameters: - __context_items__: A pointer to a `KM_KBP_CT_END` terminated array of - `km_kbp_context_item` values. + `km_core_context_item` values. ```c */ KMN_API size_t -km_kbp_context_item_list_size(km_kbp_context_item const *context_items); +km_core_context_item_list_size(km_core_context_item const *context_items); /* ``` @@ -486,11 +486,11 @@ other actions. */ typedef struct { - uint8_t expected_type; // km_kbp_backspace_type + uint8_t expected_type; // km_core_backspace_type uintptr_t expected_value; // used mainly in unit tests -} km_kbp_backspace_item; +} km_core_backspace_item; -enum km_kbp_backspace_type { +enum km_core_backspace_type { KM_KBP_BT_UNKNOWN = 0, // Used at beginning of context; user-initiated backspace KM_KBP_BT_CHAR = 1, // Deleting a character prior to insertion point KM_KBP_BT_MARKER = 2, // Deleting a marker prior to insertion point @@ -502,14 +502,14 @@ typedef struct { uint8_t _reserved[sizeof(void*)-sizeof(uint8_t)]; union { uintptr_t marker; // MARKER type - km_kbp_option_item const * option; // OPT types - km_kbp_usv character; // CHAR type + km_core_option_item const * option; // OPT types + km_core_usv character; // CHAR type uint8_t capsLock; // CAPSLOCK type, 1 to turn on, 0 to turn off - km_kbp_backspace_item backspace; // BACKSPACE type + km_core_backspace_item backspace; // BACKSPACE type }; -} km_kbp_action_item; +} km_core_action_item; -enum km_kbp_action_type { +enum km_core_action_type { KM_KBP_IT_END = 0, // Marks end of action items list. KM_KBP_IT_CHAR = 1, // A Unicode character has been generated. KM_KBP_IT_MARKER = 2, // Correlates to kmn's "deadkey" markers. @@ -533,9 +533,9 @@ enum km_kbp_action_type { A state’s default options are set from the keyboard at creation time and the environment. The Platform layer is then is expected to apply any persisted options it is maintaining. Options are passed into and out of API functions as -simple C arrays of `km_kbp_option_item` terminated with a `KM_KBP_OPTIONS_END` +simple C arrays of `km_core_option_item` terminated with a `KM_KBP_OPTIONS_END` sentinel value. A state's options are exposed and manipulatable via the -`km_kbp_options` API. All option values are of type C string. +`km_core_options` API. All option values are of type C string. During processing when the Platform layer finds a PERSIST action type it should store the updated option in the appropriate place, based on its scope. @@ -545,16 +545,16 @@ value. ```c */ -enum km_kbp_option_scope { +enum km_core_option_scope { KM_KBP_OPT_UNKNOWN = 0, KM_KBP_OPT_KEYBOARD = 1, KM_KBP_OPT_ENVIRONMENT = 2, KM_KBP_OPT_MAX_SCOPES }; -struct km_kbp_option_item { - km_kbp_cp const * key; - km_kbp_cp const * value; +struct km_core_option_item { + km_core_cp const * key; + km_core_cp const * value; uint8_t scope; // Scope which an option belongs to. }; @@ -563,26 +563,26 @@ struct km_kbp_option_item { /* ``` -### `km_kbp_options_list_size` +### `km_core_options_list_size` ##### Description: -Return the length of a terminated `km_kbp_option_item` array (options +Return the length of a terminated `km_core_option_item` array (options list). ##### Return: The number of items in the list, not including terminating item, or 0 if `opts` is null. ##### Parameters: - __opts__: A pointer to a `KM_KBP_OPTIONS_END` terminated array of - `km_kbp_option_item` values. + `km_core_option_item` values. ```c */ KMN_API size_t -km_kbp_options_list_size(km_kbp_option_item const *opts); +km_core_options_list_size(km_core_option_item const *opts); /* ``` -### `km_kbp_state_option_lookup` +### `km_core_state_option_lookup` ##### Description: Lookup an option based on its key, in an options list. ##### Return status: @@ -593,7 +593,7 @@ Lookup an option based on its key, in an options list. ##### Parameters: - __state__: An opaque pointer to a state object. - __scope__: Which key-value store to interrogate. -- __key__: A UTF-16 string that matches the key in the target `km_kbp_option_item`. +- __key__: A UTF-16 string that matches the key in the target `km_core_option_item`. - __value__: A pointer to the result variable: A pointer to a UTF-16 string value owned by the state or keyboard object at the time of the call. This pointer is only valid *until* the next call to any @@ -601,17 +601,17 @@ Lookup an option based on its key, in an options list. ```c */ KMN_API -km_kbp_status -km_kbp_state_option_lookup(km_kbp_state const *state, +km_core_status +km_core_state_option_lookup(km_core_state const *state, uint8_t scope, - km_kbp_cp const *key, - km_kbp_cp const **value); + km_core_cp const *key, + km_core_cp const **value); /* ``` -### `km_kbp_state_options_update` +### `km_core_state_options_update` ##### Description: -Adds or updates one or more options from a list of `km_kbp_option_item`s. +Adds or updates one or more options from a list of `km_core_option_item`s. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. @@ -619,21 +619,21 @@ Adds or updates one or more options from a list of `km_kbp_option_item`s. - `KM_KBP_STATUS_KEY_ERROR`: The key cannot be found. ##### Parameters: - __state__: An opaque pointer to a state object. -- __new_opts__: An array of `km_kbp_option_item` objects to update or add. Must be +- __new_opts__: An array of `km_core_option_item` objects to update or add. Must be terminated with `KM_KBP_OPTIONS_END`. ```c */ KMN_API -km_kbp_status -km_kbp_state_options_update(km_kbp_state *state, - km_kbp_option_item const *new_opts); +km_core_status +km_core_state_options_update(km_core_state *state, + km_core_option_item const *new_opts); /* ``` -### `km_kbp_state_options_to_json` +### `km_core_state_options_to_json` ##### Description: -Export the contents of a `km_kbp_options` array to a JSON formatted document and +Export the contents of a `km_core_options` array to a JSON formatted document and place it in the supplied buffer, reporting how much space was used. If null is passed as the buffer the number of bytes required is returned in `space`. If there is insufficent space to hold the document the contents of the buffer is @@ -653,8 +653,8 @@ null. On return it will hold how many bytes were used. ```c */ KMN_API -km_kbp_status -km_kbp_state_options_to_json(km_kbp_state const *state, +km_core_status +km_core_state_options_to_json(km_core_state const *state, char *buf, size_t *space); @@ -669,31 +669,31 @@ of state objects. ```c */ typedef struct { - km_kbp_cp const * version_string; // Processor specific version string. - km_kbp_cp const * id; // Keyman keyboard ID string. - km_kbp_path_name folder_path; // Path to the unpacked folder containing + km_core_cp const * version_string; // Processor specific version string. + km_core_cp const * id; // Keyman keyboard ID string. + km_core_path_name folder_path; // Path to the unpacked folder containing // the keyboard and associated resources. - km_kbp_option_item const * default_options; -} km_kbp_keyboard_attrs; + km_core_option_item const * default_options; +} km_core_keyboard_attrs; typedef struct { - km_kbp_virtual_key key; + km_core_virtual_key key; uint32_t modifier_flag; -} km_kbp_keyboard_key; +} km_core_keyboard_key; #define KM_KBP_KEYBOARD_KEY_LIST_END { 0, 0 } typedef struct { - km_kbp_cp const * library_name; - km_kbp_cp const * function_name; + km_core_cp const * library_name; + km_core_cp const * function_name; uint32_t imx_id; // unique identifier used to call this function -} km_kbp_keyboard_imx; +} km_core_keyboard_imx; #define KM_KBP_KEYBOARD_IMX_END { 0, 0, 0 } /* ``` -### `km_kbp_keyboard_load` +### `km_core_keyboard_load` ##### Description: Parse and load keyboard from the supplied path and a pointer to the loaded keyboard into the out paramter. @@ -711,21 +711,21 @@ into the out paramter. contains a valid path to the keyboard file. - __keyboard__: A pointer to result variable: A pointer to the opaque keyboard object returned by the Processor. This - memory must be freed with a call to `km_kbp_keyboard_dispose`. + memory must be freed with a call to `km_core_keyboard_dispose`. ```c */ KMN_API -km_kbp_status -km_kbp_keyboard_load(km_kbp_path_name kb_path, - km_kbp_keyboard **keyboard); +km_core_status +km_core_keyboard_load(km_core_path_name kb_path, + km_core_keyboard **keyboard); /* ``` -### `km_kbp_keyboard_dispose` +### `km_core_keyboard_dispose` ##### Description: Free the allocated memory belonging to an opaque keyboard object previously -returned by `km_kbp_keyboard_load`. +returned by `km_core_keyboard_load`. ##### Parameters: - __keyboard__: A pointer to the opaque keyboard object to be disposed of. @@ -734,11 +734,11 @@ returned by `km_kbp_keyboard_load`. */ KMN_API void -km_kbp_keyboard_dispose(km_kbp_keyboard *keyboard); +km_core_keyboard_dispose(km_core_keyboard *keyboard); /* ``` -### `km_kbp_keyboard_get_attrs` +### `km_core_keyboard_get_attrs` ##### Description: Returns the const internal attributes of the keyboard. This structure is valid for the lifetime of the opaque keyboard object. Do not modify the returned data. @@ -748,18 +748,18 @@ for the lifetime of the opaque keyboard object. Do not modify the returned data. ##### Parameters: - __keyboard__: A pointer to the opaque keyboard object to be queried. - __out__: A pointer to the result: - A pointer to a `km_kbp_keyboard_attrs` structure. + A pointer to a `km_core_keyboard_attrs` structure. ```c */ KMN_API -km_kbp_status -km_kbp_keyboard_get_attrs(km_kbp_keyboard const *keyboard, - km_kbp_keyboard_attrs const **out); +km_core_status +km_core_keyboard_get_attrs(km_core_keyboard const *keyboard, + km_core_keyboard_attrs const **out); /* ``` -### `km_kbp_keyboard_get_key_list` +### `km_core_keyboard_get_key_list` ##### Description: Returns the unordered full set of modifier+virtual keys that are handled by the keyboard. The matching dispose call needs to be called to free the memory. @@ -768,23 +768,23 @@ keyboard. The matching dispose call needs to be called to free the memory. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. ##### Parameters: - __keyboard__: A pointer to the opaque keyboard object to be queried. -- __out__: A pointer to an array of `km_kbp_keyboard_key` structures, +- __out__: A pointer to an array of `km_core_keyboard_key` structures, terminated by `KM_KBP_KEYBOARD_KEY_LIST_END`. ```c */ KMN_API -km_kbp_status -km_kbp_keyboard_get_key_list(km_kbp_keyboard const *keyboard, - km_kbp_keyboard_key **out); +km_core_status +km_core_keyboard_get_key_list(km_core_keyboard const *keyboard, + km_core_keyboard_key **out); /** ``` -### `km_kbp_keyboard_key_list_dispose` +### `km_core_keyboard_key_list_dispose` ##### Description: Free the allocated memory belonging to a keyboard key list previously -returned by `km_kbp_keyboard_get_key_list`. +returned by `km_core_keyboard_get_key_list`. ##### Parameters: - __key_list__: A pointer to the keyboard key list to be disposed of. @@ -792,46 +792,46 @@ returned by `km_kbp_keyboard_get_key_list`. ```c */ KMN_API -void km_kbp_keyboard_key_list_dispose(km_kbp_keyboard_key *key_list); +void km_core_keyboard_key_list_dispose(km_core_keyboard_key *key_list); /** - * km_kbp_keyboard_get_imx_list: + * km_core_keyboard_get_imx_list: * * Returns: the list of IMX libraries and function names that are referenced by * the keyboard.The matching dispose call needs to be called to free the memory. */ KMN_API -km_kbp_status km_kbp_keyboard_get_imx_list(km_kbp_keyboard const *keyboard, km_kbp_keyboard_imx **imx_list); +km_core_status km_core_keyboard_get_imx_list(km_core_keyboard const *keyboard, km_core_keyboard_imx **imx_list); /** - * km_kbp_keyboard_imx_list_dispose: + * km_core_keyboard_imx_list_dispose: * * Disposes of the IMX list * * Returns: -- */ KMN_API -void km_kbp_keyboard_imx_list_dispose(km_kbp_keyboard_imx *imx_list); +void km_core_keyboard_imx_list_dispose(km_core_keyboard_imx *imx_list); /** - * km_kbp_state_imx_register_callback: + * km_core_state_imx_register_callback: * * Register the IMX callback endpoint for the client. * * Returns: -- */ KMN_API -void km_kbp_state_imx_register_callback(km_kbp_state *state, km_kbp_keyboard_imx_platform imx_callback, void *callback_object); +void km_core_state_imx_register_callback(km_core_state *state, km_core_keyboard_imx_platform imx_callback, void *callback_object); /** - * km_kbp_state_imx_deregister_callback: + * km_core_state_imx_deregister_callback: * * De-register IMX callback endpoint for the client. * * Returns: -- */ KMN_API -void km_kbp_state_imx_deregister_callback(km_kbp_state *state); +void km_core_state_imx_deregister_callback(km_core_state *state); /* ``` @@ -844,7 +844,7 @@ and dynamic options ("option stores" in kmn format). /* ``` -### `km_kbp_state_create` +### `km_core_state_create` ##### Description: Create a keyboard processor state object, maintaining state for the keyboard in the environment passed. @@ -858,24 +858,24 @@ the environment passed. - __keyboard__: A pointer to the opaque keyboard object this object will hold state for. - __env__: -The array of `km_kbp_option_item` key/value pairs used to initialise the +The array of `km_core_option_item` key/value pairs used to initialise the environment, terminated by `KM_KBP_OPTIONS_END`. - __out__: A pointer to result variable: A pointer to the opaque state object returned by the Processor, initalised to maintain state for `keyboard`. -This must be disposed of by a call to `km_kbp_state_dispose`. +This must be disposed of by a call to `km_core_state_dispose`. ```c */ KMN_API -km_kbp_status -km_kbp_state_create(km_kbp_keyboard *keyboard, - km_kbp_option_item const *env, - km_kbp_state **out); +km_core_status +km_core_state_create(km_core_keyboard *keyboard, + km_core_option_item const *env, + km_core_state **out); /* ``` -### `km_kbp_state_clone` +### `km_core_state_clone` ##### Description: Clone an existing opaque state object. ##### Return status: @@ -890,22 +890,22 @@ A pointer to the opaque statea object to be cloned. - __out__: A pointer to result variable: A pointer to the opaque state object returned by the Processor, cloned from the existing object `state`. This -must be disposed of by a call to `km_kbp_state_dispose`. +must be disposed of by a call to `km_core_state_dispose`. ```c */ KMN_API -km_kbp_status -km_kbp_state_clone(km_kbp_state const *state, - km_kbp_state **out); +km_core_status +km_core_state_clone(km_core_state const *state, + km_core_state **out); /* ``` -### `km_kbp_state_dispose` +### `km_core_state_dispose` ##### Description: -Free the allocated resources belonging to a `km_kbp_state` object previously -returned by `km_kbp_state_create` or `km_kbp_state_clone`. After this all -pointers previously returned by any km_kbp_state family of calls will become +Free the allocated resources belonging to a `km_core_state` object previously +returned by `km_core_state_create` or `km_core_state_clone`. After this all +pointers previously returned by any km_core_state family of calls will become invalid. ##### Parameters: - __state__: A pointer to the opaque state object to be disposed. @@ -914,11 +914,11 @@ invalid. */ KMN_API void -km_kbp_state_dispose(km_kbp_state *state); +km_core_state_dispose(km_core_state *state); /* ``` -### `km_kbp_state_context` +### `km_core_state_context` ##### Description: Get access to the state object's context. ##### Return: @@ -930,8 +930,8 @@ of the state object. If null is passed in, then null is returned. ```c */ KMN_API -km_kbp_context * -km_kbp_state_context(km_kbp_state *state); +km_core_context * +km_core_state_context(km_core_state *state); /* @@ -942,29 +942,29 @@ Get access to the state object's keyboard processor's intermediate context. This is used during an IMX callback, part way through processing a keystroke. ##### Return: A pointer to an context item array. Must be disposed of by a call -to `km_kbp_context_items_dispose`. +to `km_core_context_items_dispose`. ##### Parameters: - __state__: A pointer to the opaque state object to be queried. ```c */ KMN_API -km_kbp_status -kbp_state_get_intermediate_context(km_kbp_state *state, km_kbp_context_item ** context_items); +km_core_status +kbp_state_get_intermediate_context(km_core_state *state, km_core_context_item ** context_items); /* ``` -### `km_kbp_state_action_items` +### `km_core_state_action_items` ##### Description: Get the list of action items generated by the last call to -`km_kbp_process_event`. +`km_core_process_event`. ##### Return: -A pointer to a `km_kbp_action_item` list, of `*num_items` in length. This data +A pointer to a `km_core_action_item` list, of `*num_items` in length. This data becomes invalid when the state object is destroyed, or after a call to -`km_kbp_process_event`. Do not modify the contents of this data. The returned +`km_core_process_event`. Do not modify the contents of this data. The returned array is terminated with a `KM_KBP_IT_END` entry. ##### Parameters: -- __state__: A pointer to the opaque `km_kbp_state` object to be queried. +- __state__: A pointer to the opaque `km_core_state` object to be queried. - __num_items__: A pointer to a result variable: The number of items in the action item list including the `KM_KBP_IT_END` terminator. May be null if not that @@ -973,37 +973,37 @@ information is required. ```c */ KMN_API -km_kbp_action_item const * -km_kbp_state_action_items(km_kbp_state const *state, +km_core_action_item const * +km_core_state_action_items(km_core_state const *state, size_t *num_items); /* ``` -### `km_kbp_state_queue_action_items` +### `km_core_state_queue_action_items` ##### Description: Queue actions for the current keyboard processor state; normally -used in IMX callbacks called during `km_kbp_process_event`. +used in IMX callbacks called during `km_core_process_event`. ##### Return: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: In the event the `state` or `action_items` pointer are null. ##### Parameters: -- __state__: A pointer to the opaque `km_kbp_state` object to be queried. +- __state__: A pointer to the opaque `km_core_state` object to be queried. - __action_items__: The action items to be added to the core queue. Must be terminated with a `KM_KBP_IT_END` entry. ```c */ KMN_API -km_kbp_status -km_kbp_state_queue_action_items(km_kbp_state *state, - km_kbp_action_item const *action_items); +km_core_status +km_core_state_queue_action_items(km_core_state *state, + km_core_action_item const *action_items); /* ``` ### `km_kpb_state_to_json` ##### Description: -Export the internal state of a `km_kbp_state` object to a JSON format document +Export the internal state of a `km_core_state` object to a JSON format document and place it in the supplied buffer, reporting how much space was used. If null is passed as the buffer the number of bytes required is returned. If there is insufficent space to hold the document, the contents of the buffer is undefined. @@ -1027,8 +1027,8 @@ null. On return it will hold how many bytes were used. ```c */ KMN_API -km_kbp_status -km_kbp_state_to_json(km_kbp_state const *state, +km_core_status +km_core_state_to_json(km_core_state const *state, char *buf, size_t *space); @@ -1045,9 +1045,9 @@ typedef struct { uint16_t technology; // A bit field specifiying which Keyboard // technologies the engine supports. char const *vendor; // Implementor of the processor. -} km_kbp_attr; +} km_core_attr; -enum km_kbp_tech_value { +enum km_core_tech_value { KM_KBP_TECH_UNSPECIFIED = 0, KM_KBP_TECH_MOCK = 1 << 0, KM_KBP_TECH_KMX = 1 << 1, @@ -1055,34 +1055,34 @@ enum km_kbp_tech_value { }; /** - * km_kbp_event_flags: + * km_core_event_flags: * - * Bit flags to be used with the event_flags parameter of km_kbp_process_event + * Bit flags to be used with the event_flags parameter of km_core_process_event */ -enum km_kbp_event_flags { +enum km_core_event_flags { KM_KBP_EVENT_FLAG_DEFAULT = 0, // default value: hardware KM_KBP_EVENT_FLAG_TOUCH = 1, // set if the event is touch, otherwise hardware }; /* ``` -### `km_kbp_get_engine_attrs` +### `km_core_get_engine_attrs` ##### Description: Get access processors attributes describing version and technology implemented. ##### Return: -A pointer to a `km_kbp_attr` structure. Do not modify the contents of this +A pointer to a `km_core_attr` structure. Do not modify the contents of this structure. ##### Parameters: -- __state__: An opaque pointer to an `km_kbp_state`. +- __state__: An opaque pointer to an `km_core_state`. ```c */ KMN_API -km_kbp_attr const * -km_kbp_get_engine_attrs(km_kbp_state const *state); +km_core_attr const * +km_core_get_engine_attrs(km_core_state const *state); /* ``` -### `km_kbp_process_event` +### `km_core_process_event` ##### Description: Run the keyboard on an opaque state object with the provided virtual key and modifer key state. Updates the state object as appropriate and fills out its action list. @@ -1102,26 +1102,26 @@ state is passed. - __vk__: A virtual key to be processed. - __modifier_state__: The combinations of modifier keys set at the time key `vk` was pressed, bitmask -from the `km_kbp_modifier_state` enum. -- __event_flags__: Event level flags, see km_kbp_event_flags +from the `km_core_modifier_state` enum. +- __event_flags__: Event level flags, see km_core_event_flags ```c */ KMN_API -km_kbp_status -km_kbp_process_event(km_kbp_state *state, - km_kbp_virtual_key vk, +km_core_status +km_core_process_event(km_core_state *state, + km_core_virtual_key vk, uint16_t modifier_state, uint8_t is_key_down, uint16_t event_flags); /* ``` -### `km_kbp_process_queued_actions` +### `km_core_process_queued_actions` ##### Description: Process the keyboard processors queued actions for the opaque state object. Updates the state object as appropriate and fills out its action list. -The client can add actions externally via the `km_kbp_state_queue_action_items` and +The client can add actions externally via the `km_core_state_queue_action_items` and then request the processing of the actions with this method. The state action list will be cleared at the start of this call; options and context in @@ -1139,12 +1139,12 @@ In the event the `state` pointer is null ```c */ KMN_API -km_kbp_status -km_kbp_process_queued_actions(km_kbp_state *state); +km_core_status +km_core_process_queued_actions(km_core_state *state); /* ``` -### `km_kbp_event` +### `km_core_event` ##### Description: Tell the keyboard processor that an external event has occurred, such as a keyboard being activated through the language switching UI. @@ -1163,20 +1163,20 @@ the state may also be modified. ##### Parameters: - __state__: A pointer to the opaque state object. -- __event__: The event to be processed, from km_kbp_event_code enumeration +- __event__: The event to be processed, from km_core_event_code enumeration - __data__: Additional event-specific data. Currently unused, must be nullptr. ```c */ KMN_API -km_kbp_status -km_kbp_event( - km_kbp_state *state, +km_core_status +km_core_event( + km_core_state *state, uint32_t event, void* data ); -enum km_kbp_event_code { +enum km_core_event_code { // A keyboard has been activated by the user. The processor may use this // event, for example, to switch caps lock state or provide other UX. KM_KBP_EVENT_KEYBOARD_ACTIVATED = 1, diff --git a/core/include/keyman/keyman_core_api_bits.h b/core/include/keyman/keyman_core_api_bits.h index 03892a62af..be2886d058 100644 --- a/core/include/keyman/keyman_core_api_bits.h +++ b/core/include/keyman/keyman_core_api_bits.h @@ -27,7 +27,7 @@ #endif #if defined _WIN32 || defined __CYGWIN__ - typedef wchar_t const * km_kbp_path_name; + typedef wchar_t const * km_core_path_name; #define _KM_KBP_PATH_SEPARATOR (L'\\') #define _KM_KBP_EXT_SEPARATOR (L'.') #if defined __GNUC__ // These three will be redefined for Windows @@ -43,7 +43,7 @@ #define _kmn_import_flag dllimport #define _kmn_static_flag #else - typedef char const * km_kbp_path_name; + typedef char const * km_core_path_name; #define _KM_KBP_PATH_SEPARATOR ('/') #define _KM_KBP_EXT_SEPARATOR ('.') #endif diff --git a/core/include/keyman/keyman_core_api_debug.h b/core/include/keyman/keyman_core_api_debug.h index f038e2cd81..527da030df 100644 --- a/core/include/keyman/keyman_core_api_debug.h +++ b/core/include/keyman/keyman_core_api_debug.h @@ -24,7 +24,7 @@ extern "C" #endif /** - * The maximum size of context in km_kbp_cp units for a single debug + * The maximum size of context in km_core_cp units for a single debug * event. This is taken from MAXCONTEXT in keyman32 (Windows) and is purely * a convenience value. We can increase it if there is a demonstrated need. */ @@ -56,7 +56,7 @@ typedef struct { uint16_t vk; uint16_t modifier_state; char16_t character; -} km_kbp_state_debug_key_info; +} km_core_state_debug_key_info; /** * Option event data. @@ -65,8 +65,8 @@ typedef struct { */ typedef struct { void *store; // LPSTORE - km_kbp_cp value[DEBUG_MAX_CONTEXT]; // value to be saved into the store -} km_kbp_state_debug_kmx_option_info; + km_core_cp value[DEBUG_MAX_CONTEXT]; // value to be saved into the store +} km_core_state_debug_kmx_option_info; /** * KMX processor data for each event. kmx_base.h defines the types that are @@ -80,7 +80,7 @@ typedef struct { */ typedef struct { - km_kbp_cp context[DEBUG_MAX_CONTEXT]; // The context matched by the rule (? may not need this?) // TODO: rename to context_matched + km_core_cp context[DEBUG_MAX_CONTEXT]; // The context matched by the rule (? may not need this?) // TODO: rename to context_matched void *group; // LPGROUP void *rule; // LPKEY uint16_t store_offsets[DEBUG_STORE_OFFSETS_SIZE]; // pairs--store, char position, terminated by 0xFFFF // TODO use a better structure here @@ -89,8 +89,8 @@ typedef struct { /// the debugger; the debugger uses this to determine when to /// execute the actions when single-stepping. uint16_t first_action; - km_kbp_state_debug_kmx_option_info option; -} km_kbp_state_debug_kmx_info; + km_core_state_debug_kmx_option_info option; +} km_core_state_debug_kmx_info; /** * A single debug event. @@ -98,14 +98,14 @@ typedef struct { typedef struct { uint32_t type; // 32 bits is better optimized than 8 bits uint32_t flags; - km_kbp_state_debug_key_info key_info; - km_kbp_state_debug_kmx_info kmx_info; -} km_kbp_state_debug_item; + km_core_state_debug_key_info key_info; + km_core_state_debug_kmx_info kmx_info; +} km_core_state_debug_item; /** * A single debug event. */ -enum km_kbp_debug_type { +enum km_core_debug_type { KM_KBP_DEBUG_BEGIN = 0, //KM_KBP_DEBUG_BEGIN_ANSI = 1, // not supported; instead rewrite ansi keyboards to Unicode with mcompile KM_KBP_DEBUG_GROUP_ENTER = 2, @@ -140,8 +140,8 @@ enum km_kbp_debug_type { * @returns KM_KBP_STATUS_OK on success */ KMN_API -km_kbp_status -km_kbp_state_debug_set(km_kbp_state *state, int value); +km_core_status +km_core_state_debug_set(km_core_state *state, int value); /** * Get current debug tracing status @@ -152,7 +152,7 @@ km_kbp_state_debug_set(km_kbp_state *state, int value); */ KMN_API uint8_t -km_kbp_state_debug_get(km_kbp_state const *state); +km_core_state_debug_get(km_core_state const *state); /** * Read current debug trace log @@ -165,8 +165,8 @@ km_kbp_state_debug_get(km_kbp_state const *state); * with last entry guaranteed to be KM_KBP_DEBUG_END. */ KMN_API -km_kbp_state_debug_item const * -km_kbp_state_debug_items(km_kbp_state const *state, size_t *num_items); +km_core_state_debug_item const * +km_core_state_debug_items(km_core_state const *state, size_t *num_items); #if defined(__cplusplus) } // extern "C" diff --git a/core/include/keyman/keyman_core_api_version.h.in b/core/include/keyman/keyman_core_api_version.h.in index d434ae4e48..0f8c293430 100644 --- a/core/include/keyman/keyman_core_api_version.h.in +++ b/core/include/keyman/keyman_core_api_version.h.in @@ -1,12 +1,12 @@ -#define km_kbp_version_stringify(x) km_kbp_version_to_string(x) -#define km_kbp_version_to_string(x) #x +#define km_core_version_stringify(x) km_core_version_to_string(x) +#define km_core_version_to_string(x) #x // Product versioning #define KM_KBP_VERSION_MAJOR @majorver@ #define KM_KBP_VERSION_MINOR @minorver@ #define KM_KBP_VERSION_PATCH @patchver@ -#define KM_KBP_VERSION_STRING km_kbp_version_stringify(@majorver@ ## . ## @minorver@ ## . ## @patchver@ ## .0) +#define KM_KBP_VERSION_STRING km_core_version_stringify(@majorver@ ## . ## @minorver@ ## . ## @patchver@ ## .0) // API versioning diff --git a/core/include/keyman/keyman_core_api_vkeys.h b/core/include/keyman/keyman_core_api_vkeys.h index a1e580df28..0e7ba5206e 100644 --- a/core/include/keyman/keyman_core_api_vkeys.h +++ b/core/include/keyman/keyman_core_api_vkeys.h @@ -6,7 +6,7 @@ maintain readability of the primary API header. Create Date: 17 Oct 2018 Authors: Tim Eves (TSE) - History: 17 Oct 2018 - TSE - Moved & refactored km_kbp_modifier_state + History: 17 Oct 2018 - TSE - Moved & refactored km_core_modifier_state from keyman_core_api.h. - Added VKey and mask definitions. 6 Oct 2018 - TSE - Move into keyman folder. @@ -15,7 +15,7 @@ #pragma once -enum km_kbp_modifier_state { +enum km_core_modifier_state { KM_KBP_MODIFIER_LCTRL = 1 << 0, KM_KBP_MODIFIER_RCTRL = 1 << 1, KM_KBP_MODIFIER_LALT = 1 << 2, @@ -40,7 +40,7 @@ enum km_kbp_modifier_state { */ }; -enum km_kbp_modifier_mask { +enum km_core_modifier_mask { KM_KBP_MODIFIER_MASK_ALL = 0x7f, KM_KBP_MODIFIER_MASK_ALT_GR_SIM = KM_KBP_MODIFIER_LCTRL|KM_KBP_MODIFIER_LALT, KM_KBP_MODIFIER_MASK_CHIRAL = 0x1f, diff --git a/core/src/context.hpp b/core/src/context.hpp index 03d4aeb2d7..9fcd46614b 100644 --- a/core/src/context.hpp +++ b/core/src/context.hpp @@ -3,7 +3,7 @@ Description: Internal context class and adaptor class for the API. Create Date: 2 Oct 2018 Authors: Tim Eves (TSE) - History: 2 Oct 2018 - TSE - Refactored out of km_kbp_context_api.cpp + History: 2 Oct 2018 - TSE - Refactored out of km_core_context_api.cpp */ #pragma once @@ -20,32 +20,32 @@ namespace kbp // This will likely be replaced with a class implementing a more space // efficient data structure such as a ring buffer or bounded queue. -class context: public std::list +class context: public std::list { public: - void push_character(km_kbp_usv); + void push_character(km_core_usv); void push_marker(uint32_t); }; inline -void context::push_character(km_kbp_usv usv) { - emplace_back(km_kbp_context_item { KM_KBP_CT_CHAR, {0,}, {usv} }); +void context::push_character(km_core_usv usv) { + emplace_back(km_core_context_item { KM_KBP_CT_CHAR, {0,}, {usv} }); } inline void context::push_marker(uint32_t marker) { - emplace_back(km_kbp_context_item { KM_KBP_CT_MARKER, {0,}, {marker} }); + emplace_back(km_core_context_item { KM_KBP_CT_MARKER, {0,}, {marker} }); } } // namespace kbp } // namespace km json & operator << (json &, km::kbp::context const &); -json & operator << (json &, km_kbp_context_item const &); +json & operator << (json &, km_core_context_item const &); -struct km_kbp_context : public km::kbp::context +struct km_core_context : public km::kbp::context { }; diff --git a/core/src/debug.hpp b/core/src/debug.hpp index cee5e37c52..c34eaf38e0 100644 --- a/core/src/debug.hpp +++ b/core/src/debug.hpp @@ -16,13 +16,13 @@ namespace km { namespace kbp { -class debug_items : public std::vector +class debug_items : public std::vector { private: bool _is_enabled; public: template debug_items(Args&&... args); - void push_begin(km_kbp_state_debug_key_info *key_info, uint32_t flags); + void push_begin(km_core_state_debug_key_info *key_info, uint32_t flags); void push_end(uint16_t first_action, uint32_t flags); void assert_push_entry(); bool is_enabled() const noexcept; @@ -31,10 +31,10 @@ public: template debug_items::debug_items(Args&&... args) -: std::vector(std::forward(args)...) +: std::vector(std::forward(args)...) { // Ensure the debug_items list is terminated in case the client calls - // km_kbp_state_debug_items before they call process_event. + // km_core_state_debug_items before they call process_event. _is_enabled = false; push_end(0, 0); } @@ -45,15 +45,15 @@ void debug_items::assert_push_entry() { } inline -void debug_items::push_begin(km_kbp_state_debug_key_info *key_info, uint32_t flags) { +void debug_items::push_begin(km_core_state_debug_key_info *key_info, uint32_t flags) { assert_push_entry(); - emplace_back(km_kbp_state_debug_item{ KM_KBP_DEBUG_BEGIN, flags, {*key_info, }, { }}); + emplace_back(km_core_state_debug_item{ KM_KBP_DEBUG_BEGIN, flags, {*key_info, }, { }}); } inline void debug_items::push_end(uint16_t first_action, uint32_t flags) { assert_push_entry(); - emplace_back(km_kbp_state_debug_item{ KM_KBP_DEBUG_END, flags, { }, { u"", nullptr, nullptr, { }, first_action, {} } }); + emplace_back(km_core_state_debug_item{ KM_KBP_DEBUG_END, flags, { }, { u"", nullptr, nullptr, { }, first_action, {} } }); } inline diff --git a/core/src/keyboard.cpp b/core/src/keyboard.cpp index 977da597d3..47693b9b66 100644 --- a/core/src/keyboard.cpp +++ b/core/src/keyboard.cpp @@ -3,7 +3,7 @@ Description: Internal keyboard class and adaptor class for the API. Create Date: 2 Oct 2018 Authors: Tim Eves (TSE) - History: 7 Oct 2018 - TSE - Refactored out of km_kbp_keyboard_api.cpp + History: 7 Oct 2018 - TSE - Refactored out of km_core_keyboard_api.cpp */ #include "keyboard.hpp" #include "jsonpp.hpp" diff --git a/core/src/keyboard.hpp b/core/src/keyboard.hpp index 6c8b93263c..97329b7e76 100644 --- a/core/src/keyboard.hpp +++ b/core/src/keyboard.hpp @@ -3,7 +3,7 @@ Description: Internal keyboard class and adaptor class for the API. Create Date: 2 Oct 2018 Authors: Tim Eves (TSE) - History: 2 Oct 2018 - TSE - Refactored out of km_kbp_keyboard_api.cpp + History: 2 Oct 2018 - TSE - Refactored out of km_core_keyboard_api.cpp */ #pragma once @@ -22,7 +22,7 @@ class json; namespace km { namespace kbp { - class keyboard_attributes : public km_kbp_keyboard_attrs + class keyboard_attributes : public km_core_keyboard_attrs { std::u16string _keyboard_id; std::u16string _version_string; @@ -36,7 +36,7 @@ namespace kbp using path_type = decltype(_folder_path); keyboard_attributes() - : km_kbp_keyboard_attrs {nullptr, nullptr, nullptr, nullptr} {} + : km_core_keyboard_attrs {nullptr, nullptr, nullptr, nullptr} {} keyboard_attributes(keyboard_attributes const &) = delete; keyboard_attributes(keyboard_attributes &&); diff --git a/core/src/km_kbp_context_api.cpp b/core/src/km_kbp_context_api.cpp index a0845618b4..3347ecdcdb 100644 --- a/core/src/km_kbp_context_api.cpp +++ b/core/src/km_kbp_context_api.cpp @@ -20,9 +20,9 @@ namespace { template - km_kbp_status + km_core_status _context_items_from(typename U::codeunit_t const *text, - km_kbp_context_item **out_ptr) + km_core_context_item **out_ptr) { assert(text); assert(out_ptr); if (!text || !out_ptr) return KM_KBP_STATUS_INVALID_ARGUMENT; @@ -30,17 +30,17 @@ namespace { *out_ptr = nullptr; try { - std::vector res; + std::vector res; for (auto i = typename U::const_iterator(text); *i; ++i) { if(i.error()) return KM_KBP_STATUS_INVALID_UTF; - res.emplace_back(km_kbp_context_item {KM_KBP_CT_CHAR, {0,}, {*i}}); + res.emplace_back(km_core_context_item {KM_KBP_CT_CHAR, {0,}, {*i}}); } // Terminate the context_items array. - res.emplace_back(km_kbp_context_item KM_KBP_CONTEXT_ITEM_END); + res.emplace_back(km_core_context_item KM_KBP_CONTEXT_ITEM_END); - *out_ptr = new km_kbp_context_item[res.size()]; + *out_ptr = new km_core_context_item[res.size()]; std::move(res.begin(), res.end(), *out_ptr); } catch (std::bad_alloc &) @@ -52,7 +52,7 @@ namespace { } template - km_kbp_status _context_items_to(km_kbp_context_item const *ci, + km_core_status _context_items_to(km_core_context_item const *ci, typename U::codeunit_t *buf, size_t * sz_ptr) { @@ -107,23 +107,23 @@ namespace { } } -km_kbp_status -km_kbp_context_items_from_utf16(km_kbp_cp const *text, - km_kbp_context_item **out_ptr) +km_core_status +km_core_context_items_from_utf16(km_core_cp const *text, + km_core_context_item **out_ptr) { return _context_items_from(reinterpret_cast(text), out_ptr); } -km_kbp_status -km_kbp_context_items_from_utf8(char const *text, - km_kbp_context_item **out_ptr) +km_core_status +km_core_context_items_from_utf8(char const *text, + km_core_context_item **out_ptr) { return _context_items_from(reinterpret_cast(text), out_ptr); } -km_kbp_status km_kbp_context_items_to_utf8(km_kbp_context_item const *ci, +km_core_status km_core_context_items_to_utf8(km_core_context_item const *ci, char *buf, size_t * sz_ptr) { return _context_items_to(ci, @@ -132,8 +132,8 @@ km_kbp_status km_kbp_context_items_to_utf8(km_kbp_context_item const *ci, } -km_kbp_status km_kbp_context_items_to_utf16(km_kbp_context_item const *ci, - km_kbp_cp *buf, size_t * sz_ptr) +km_core_status km_core_context_items_to_utf16(km_core_context_item const *ci, + km_core_cp *buf, size_t * sz_ptr) { return _context_items_to(ci, reinterpret_cast(buf), @@ -141,28 +141,28 @@ km_kbp_status km_kbp_context_items_to_utf16(km_kbp_context_item const *ci, } -void km_kbp_context_items_dispose(km_kbp_context_item *ci) +void km_core_context_items_dispose(km_core_context_item *ci) { delete [] ci; } -km_kbp_status km_kbp_context_set(km_kbp_context *ctxt, km_kbp_context_item const *ci) +km_core_status km_core_context_set(km_core_context *ctxt, km_core_context_item const *ci) { - km_kbp_context_clear(ctxt); - return km_kbp_context_append(ctxt, ci); + km_core_context_clear(ctxt); + return km_core_context_append(ctxt, ci); } -km_kbp_status km_kbp_context_get(km_kbp_context const *ctxt, - km_kbp_context_item **out_ptr) +km_core_status km_core_context_get(km_core_context const *ctxt, + km_core_context_item **out_ptr) { assert(ctxt); assert(out_ptr); if (!ctxt || !out_ptr) return KM_KBP_STATUS_INVALID_ARGUMENT; try { - *out_ptr = new km_kbp_context_item[ctxt->size() + 1]; + *out_ptr = new km_core_context_item[ctxt->size() + 1]; } catch (std::bad_alloc &) { @@ -175,7 +175,7 @@ km_kbp_status km_kbp_context_get(km_kbp_context const *ctxt, } -void km_kbp_context_clear(km_kbp_context *ctxt) +void km_core_context_clear(km_core_context *ctxt) { assert(ctxt); if (ctxt) @@ -185,15 +185,15 @@ void km_kbp_context_clear(km_kbp_context *ctxt) } -size_t km_kbp_context_length(km_kbp_context *ctxt) +size_t km_core_context_length(km_core_context *ctxt) { assert(ctxt); return ctxt ? ctxt->size() : 0; } -km_kbp_status km_kbp_context_append(km_kbp_context *ctxt, - km_kbp_context_item const *ci) +km_core_status km_core_context_append(km_core_context *ctxt, + km_core_context_item const *ci) { assert(ctxt); assert(ci); if (!ctxt || !ci) return KM_KBP_STATUS_INVALID_ARGUMENT; @@ -212,8 +212,8 @@ km_kbp_status km_kbp_context_append(km_kbp_context *ctxt, } -km_kbp_status km_kbp_context_shrink(km_kbp_context *ctxt, size_t num, - km_kbp_context_item const * ci) +km_core_status km_core_context_shrink(km_core_context *ctxt, size_t num, + km_core_context_item const * ci) { assert(ctxt); if (!ctxt) return KM_KBP_STATUS_INVALID_ARGUMENT; @@ -239,7 +239,7 @@ km_kbp_status km_kbp_context_shrink(km_kbp_context *ctxt, size_t num, } size_t -km_kbp_context_item_list_size(km_kbp_context_item const *context_items) +km_core_context_item_list_size(km_core_context_item const *context_items) { assert(context_items); if (!context_items) return 0; @@ -258,7 +258,7 @@ json & operator << (json & j, km::kbp::context const & ctxt) { return j << json::close; } -json & operator << (json & j, km_kbp_context_item const & i) +json & operator << (json & j, km_core_context_item const & i) { utf8::codeunit_t cps[7] = {0,}; // 6 bytes for maximal UTF-8 char (e.g. U+10FFFF) + nul terminator int8_t l = 4; diff --git a/core/src/km_kbp_debug_api.cpp b/core/src/km_kbp_debug_api.cpp index ff7ad03044..34d894d402 100644 --- a/core/src/km_kbp_debug_api.cpp +++ b/core/src/km_kbp_debug_api.cpp @@ -15,9 +15,9 @@ using namespace km::kbp; -km_kbp_status -km_kbp_state_debug_set( - km_kbp_state *state, +km_core_status +km_core_state_debug_set( + km_core_state *state, int value ) { assert(state); @@ -29,8 +29,8 @@ km_kbp_state_debug_set( } uint8_t -km_kbp_state_debug_get( - km_kbp_state const *state +km_core_state_debug_get( + km_core_state const *state ) { assert(state); if(!state) { @@ -39,9 +39,9 @@ km_kbp_state_debug_get( return state->debug_items().is_enabled() ? 1 : 0; } -km_kbp_state_debug_item const * -km_kbp_state_debug_items( - km_kbp_state const *state, +km_core_state_debug_item const * +km_core_state_debug_items( + km_core_state const *state, size_t *num_items ) { assert(state && state->debug_items().size() > 0); diff --git a/core/src/km_kbp_keyboard_api.cpp b/core/src/km_kbp_keyboard_api.cpp index b12ae3a9cb..71cfc01f0d 100644 --- a/core/src/km_kbp_keyboard_api.cpp +++ b/core/src/km_kbp_keyboard_api.cpp @@ -43,8 +43,8 @@ namespace } -km_kbp_status -km_kbp_keyboard_load(km_kbp_path_name kb_path, km_kbp_keyboard **keyboard) +km_core_status +km_core_keyboard_load(km_core_path_name kb_path, km_core_keyboard **keyboard) { assert(keyboard); if (!keyboard) @@ -53,12 +53,12 @@ km_kbp_keyboard_load(km_kbp_path_name kb_path, km_kbp_keyboard **keyboard) try { abstract_processor *kp = processor_factory(kb_path); - km_kbp_status status = kp->validate(); + km_core_status status = kp->validate(); if (status != KM_KBP_STATUS_OK) { delete kp; return status; } - *keyboard = static_cast(kp); + *keyboard = static_cast(kp); } catch (std::bad_alloc &) { @@ -68,14 +68,14 @@ km_kbp_keyboard_load(km_kbp_path_name kb_path, km_kbp_keyboard **keyboard) } void -km_kbp_keyboard_dispose(km_kbp_keyboard *keyboard) +km_core_keyboard_dispose(km_core_keyboard *keyboard) { delete keyboard; } -km_kbp_status -km_kbp_keyboard_get_attrs(km_kbp_keyboard const *keyboard, - km_kbp_keyboard_attrs const **out) +km_core_status +km_core_keyboard_get_attrs(km_core_keyboard const *keyboard, + km_core_keyboard_attrs const **out) { assert(keyboard); assert(out); if (!keyboard || !out) @@ -85,9 +85,9 @@ km_kbp_keyboard_get_attrs(km_kbp_keyboard const *keyboard, return KM_KBP_STATUS_OK; } -km_kbp_status -km_kbp_keyboard_get_key_list(km_kbp_keyboard const *keyboard, - km_kbp_keyboard_key **out) +km_core_status +km_core_keyboard_get_key_list(km_core_keyboard const *keyboard, + km_core_keyboard_key **out) { assert(keyboard); assert(out); if (!keyboard || !out) @@ -97,14 +97,14 @@ km_kbp_keyboard_get_key_list(km_kbp_keyboard const *keyboard, return KM_KBP_STATUS_OK; } -void km_kbp_keyboard_key_list_dispose(km_kbp_keyboard_key *key_list) +void km_core_keyboard_key_list_dispose(km_core_keyboard_key *key_list) { delete[] key_list; } -km_kbp_status km_kbp_keyboard_get_imx_list( - km_kbp_keyboard const *keyboard, - km_kbp_keyboard_imx** imx_list +km_core_status km_core_keyboard_get_imx_list( + km_core_keyboard const *keyboard, + km_core_keyboard_imx** imx_list ) { assert(keyboard); assert(imx_list); if (!keyboard || !imx_list) { @@ -115,13 +115,13 @@ km_kbp_status km_kbp_keyboard_get_imx_list( return KM_KBP_STATUS_OK; } -void km_kbp_keyboard_imx_list_dispose(km_kbp_keyboard_imx *imx_list) +void km_core_keyboard_imx_list_dispose(km_core_keyboard_imx *imx_list) { if(!imx_list) { return; } - km_kbp_keyboard_imx *imx_rule_it = imx_list; + km_core_keyboard_imx *imx_rule_it = imx_list; for (; imx_rule_it->library_name; ++imx_rule_it) { delete [] imx_rule_it->library_name; // from u16dup delete [] imx_rule_it->function_name; // from u16dup diff --git a/core/src/km_kbp_options_api.cpp b/core/src/km_kbp_options_api.cpp index 0f522d6ffe..27b7ac9784 100644 --- a/core/src/km_kbp_options_api.cpp +++ b/core/src/km_kbp_options_api.cpp @@ -19,7 +19,7 @@ size_t -km_kbp_options_list_size(km_kbp_option_item const *opts) +km_core_options_list_size(km_core_option_item const *opts) { assert(opts); if (!opts) return 0; @@ -33,10 +33,10 @@ km_kbp_options_list_size(km_kbp_option_item const *opts) } -km_kbp_status -km_kbp_state_option_lookup(km_kbp_state const *state, - uint8_t scope, km_kbp_cp const *key, - km_kbp_cp const **value_out) +km_core_status +km_core_state_option_lookup(km_core_state const *state, + uint8_t scope, km_core_cp const *key, + km_core_cp const **value_out) { assert(state); assert(key); assert(value_out); if (!state || !key || !value_out) return KM_KBP_STATUS_INVALID_ARGUMENT; @@ -46,15 +46,15 @@ km_kbp_state_option_lookup(km_kbp_state const *state, auto & processor = state->processor(); - *value_out = processor.lookup_option(km_kbp_option_scope(scope), key); + *value_out = processor.lookup_option(km_core_option_scope(scope), key); if (!*value_out) return KM_KBP_STATUS_KEY_ERROR; return KM_KBP_STATUS_OK; } -km_kbp_status -km_kbp_state_options_update(km_kbp_state *state, km_kbp_option_item const *opt) +km_core_status +km_core_state_options_update(km_core_state *state, km_core_option_item const *opt) { assert(state); assert(opt); if (!state|| !opt) return KM_KBP_STATUS_INVALID_ARGUMENT; @@ -69,7 +69,7 @@ km_kbp_state_options_update(km_kbp_state *state, km_kbp_option_item const *opt) return KM_KBP_STATUS_INVALID_ARGUMENT; if (processor.update_option( - km_kbp_option_scope(opt->scope), + km_core_option_scope(opt->scope), opt->key, opt->value).empty()) return KM_KBP_STATUS_KEY_ERROR; @@ -85,8 +85,8 @@ km_kbp_state_options_update(km_kbp_state *state, km_kbp_option_item const *opt) // This function doesn't need to use the json pretty printer for such a simple // list of key:value pairs but it's a good introduction to it. -km_kbp_status -km_kbp_state_options_to_json(km_kbp_state const *state, char *buf, size_t *space) +km_core_status +km_core_state_options_to_json(km_core_state const *state, char *buf, size_t *space) { assert(state); assert(space); if (!state || !space) diff --git a/core/src/km_kbp_processevent_api.cpp b/core/src/km_kbp_processevent_api.cpp index 8e818ea42d..9a0ccb14e3 100644 --- a/core/src/km_kbp_processevent_api.cpp +++ b/core/src/km_kbp_processevent_api.cpp @@ -12,9 +12,9 @@ #include "processor.hpp" #include "state.hpp" -km_kbp_status -km_kbp_event( - km_kbp_state *state, +km_core_status +km_core_event( + km_core_state *state, uint32_t event, void* data ) { @@ -39,9 +39,9 @@ km_kbp_event( return state->processor().external_event(state, event, data); } -km_kbp_status -km_kbp_process_event(km_kbp_state *state, - km_kbp_virtual_key vk, +km_core_status +km_core_process_event(km_core_state *state, + km_core_virtual_key vk, uint16_t modifier_state, uint8_t is_key_down, uint16_t event_flags) { @@ -52,9 +52,9 @@ km_kbp_process_event(km_kbp_state *state, return state->processor().process_event(state, vk, modifier_state, is_key_down, event_flags); } -km_kbp_status -km_kbp_process_queued_actions( - km_kbp_state *state +km_core_status +km_core_process_queued_actions( + km_core_state *state ) { assert(state != nullptr); if(state == nullptr) { @@ -63,8 +63,8 @@ km_kbp_process_queued_actions( return state->processor().process_queued_actions(state); } -km_kbp_attr const * -km_kbp_get_engine_attrs(km_kbp_state const *state) +km_core_attr const * +km_core_get_engine_attrs(km_core_state const *state) { assert(state != nullptr); if(state == nullptr) { diff --git a/core/src/km_kbp_state_api.cpp b/core/src/km_kbp_state_api.cpp index 168288423d..7fe6e1caa4 100644 --- a/core/src/km_kbp_state_api.cpp +++ b/core/src/km_kbp_state_api.cpp @@ -23,9 +23,9 @@ using namespace km::kbp; // Forward declarations class context; -km_kbp_status km_kbp_state_create(km_kbp_keyboard * keyboard, - km_kbp_option_item const *env, - km_kbp_state ** out) +km_core_status km_core_state_create(km_core_keyboard * keyboard, + km_core_option_item const *env, + km_core_state ** out) { assert(keyboard); assert(env); assert(out); if (!keyboard || !env || !out) @@ -33,7 +33,7 @@ km_kbp_status km_kbp_state_create(km_kbp_keyboard * keyboard, try { - *out = new km_kbp_state(static_cast(*keyboard), env); + *out = new km_core_state(static_cast(*keyboard), env); } catch (std::bad_alloc &) { @@ -43,35 +43,35 @@ km_kbp_status km_kbp_state_create(km_kbp_keyboard * keyboard, } -km_kbp_status km_kbp_state_clone(km_kbp_state const *state, - km_kbp_state ** out) +km_core_status km_core_state_clone(km_core_state const *state, + km_core_state ** out) { assert(state); assert(out); if (!state || !out) return KM_KBP_STATUS_INVALID_ARGUMENT; - *out = new km_kbp_state(*state); + *out = new km_core_state(*state); return KM_KBP_STATUS_OK; } -void km_kbp_state_dispose(km_kbp_state *state) +void km_core_state_dispose(km_core_state *state) { delete state; } -km_kbp_context *km_kbp_state_context(km_kbp_state *state) +km_core_context *km_core_state_context(km_core_state *state) { assert(state); if (!state) return nullptr; - return static_cast(&state->context()); + return static_cast(&state->context()); } -km_kbp_status kbp_state_get_intermediate_context( - km_kbp_state *state, - km_kbp_context_item ** context_items +km_core_status kbp_state_get_intermediate_context( + km_core_state *state, + km_core_context_item ** context_items ) { assert(state); assert(context_items); @@ -84,7 +84,7 @@ km_kbp_status kbp_state_get_intermediate_context( return KM_KBP_STATUS_OK; } -km_kbp_action_item const * km_kbp_state_action_items(km_kbp_state const *state, +km_core_action_item const * km_core_state_action_items(km_core_state const *state, size_t *num_items) { assert(state && state->actions().size() > 0); @@ -99,9 +99,9 @@ km_kbp_action_item const * km_kbp_state_action_items(km_kbp_state const *state, return state->actions().data(); } -km_kbp_status km_kbp_state_queue_action_items( - km_kbp_state *state, - km_kbp_action_item const *action_items +km_core_status km_core_state_queue_action_items( + km_core_state *state, + km_core_action_item const *action_items ) { assert(state); assert(action_items); @@ -146,7 +146,7 @@ namespace { } -json & operator << (json & j, km_kbp_action_item const &act) +json & operator << (json & j, km_core_action_item const &act) { j << json::flat << json::object; if (act.type >= KM_KBP_IT_MAX_TYPE_ID) @@ -165,7 +165,7 @@ json & operator << (json & j, km_kbp_action_item const &act) break; case KM_KBP_IT_CHAR: case KM_KBP_IT_MARKER: - j << km_kbp_context_item {act.type, {0,}, {act.character}}; // TODO: is act.type correct here? it may map okay but this is bad practice to mix constants across types. Similarly using act.character instead of act.type + j << km_core_context_item {act.type, {0,}, {act.character}}; // TODO: is act.type correct here? it may map okay but this is bad practice to mix constants across types. Similarly using act.character instead of act.type break; case KM_KBP_IT_PERSIST_OPT: j << json::object @@ -197,7 +197,7 @@ json & operator << (json & j, actions const & acts) } -km_kbp_status km_kbp_state_to_json(km_kbp_state const *state, +km_core_status km_core_state_to_json(km_core_state const *state, char *buf, size_t *space) { @@ -239,9 +239,9 @@ km_kbp_status km_kbp_state_to_json(km_kbp_state const *state, } -void km_kbp_state_imx_register_callback( - km_kbp_state *state, - km_kbp_keyboard_imx_platform imx_callback, +void km_core_state_imx_register_callback( + km_core_state *state, + km_core_keyboard_imx_platform imx_callback, void *callback_object ) { assert(state); @@ -251,7 +251,7 @@ void km_kbp_state_imx_register_callback( state->imx_register_callback(imx_callback, callback_object); } -void km_kbp_state_imx_deregister_callback(km_kbp_state *state) +void km_core_state_imx_deregister_callback(km_core_state *state) { assert(state); if (!state) { diff --git a/core/src/kmx/kmx_debugger.cpp b/core/src/kmx/kmx_debugger.cpp index c217086acd..a5126f13ab 100644 --- a/core/src/kmx/kmx_debugger.cpp +++ b/core/src/kmx/kmx_debugger.cpp @@ -21,7 +21,7 @@ void KMX_DebugItems::push_item( PKMX_WORD index_stack ) { _items->assert_push_entry(); - km_kbp_state_debug_item item = {type, flags, {}, {}}; + km_core_state_debug_item item = {type, flags, {}, {}}; item.kmx_info.rule = key; if(item.kmx_info.rule && index_stack) { this->fill_store_offsets(&item.kmx_info, index_stack); @@ -43,7 +43,7 @@ void KMX_DebugItems::push_set_option( KMX_WCHAR const * value ) { _items->assert_push_entry(); - km_kbp_state_debug_item item = {KM_KBP_DEBUG_SET_OPTION, 0, {}, {}}; + km_core_state_debug_item item = {KM_KBP_DEBUG_SET_OPTION, 0, {}, {}}; item.kmx_info.first_action = first_action; item.kmx_info.rule = nullptr; item.kmx_info.group = nullptr; @@ -57,11 +57,11 @@ void KMX_DebugItems::push_set_option( _items->emplace_back(item); } -void KMX_DebugItems::fill_store_offsets(km_kbp_state_debug_kmx_info *info, PKMX_WORD index_stack) { +void KMX_DebugItems::fill_store_offsets(km_core_state_debug_kmx_info *info, PKMX_WORD index_stack) { int i, n; - km_kbp_cp *p; + km_core_cp *p; // TODO turn this into a struct rather than interwoven values for(i = n = 0, p = static_cast(info->rule)->dpContext; p && *p; p = incxstr(p), i++) { diff --git a/core/src/kmx/kmx_debugger.h b/core/src/kmx/kmx_debugger.h index 20006e291c..915e4837a5 100644 --- a/core/src/kmx/kmx_debugger.h +++ b/core/src/kmx/kmx_debugger.h @@ -31,12 +31,12 @@ private: PKMX_WORD index_stack = nullptr ); void fill_store_offsets( - km_kbp_state_debug_kmx_info *info, + km_core_state_debug_kmx_info *info, PKMX_WORD index_stack ); public: KMX_DebugItems(debug_items *items); - void push_begin(km_kbp_state_debug_key_info *key_info, uint32_t flags); + void push_begin(km_core_state_debug_key_info *key_info, uint32_t flags); void push_end(uint16_t first_action, uint32_t flags); void push_group_enter(uint16_t first_action, LPGROUP group); void push_group_exit(uint16_t first_action, uint32_t flags, LPGROUP group); @@ -73,7 +73,7 @@ KMX_DebugItems::KMX_DebugItems(debug_items *items) { inline void KMX_DebugItems::push_begin( - km_kbp_state_debug_key_info *key_info, + km_core_state_debug_key_info *key_info, uint32_t flags ) { // As the vector always starts with a single KM_KBP_DEBUG_END entry, diff --git a/core/src/kmx/kmx_environment.cpp b/core/src/kmx/kmx_environment.cpp index eb5691c29d..b3069b0958 100644 --- a/core/src/kmx/kmx_environment.cpp +++ b/core/src/kmx/kmx_environment.cpp @@ -11,7 +11,7 @@ using namespace km::kbp; using namespace kmx; namespace { - km_kbp_cp const + km_core_cp const *DEFAULT_PLATFORM = u"windows hardware desktop native", *DEFAULT_BASELAYOUT = u"kbdus.dll", *DEFAULT_BASELAYOUTALT = u"en-US", diff --git a/core/src/kmx/kmx_environment.h b/core/src/kmx/kmx_environment.h index 4d934e0d10..d15b3c587b 100644 --- a/core/src/kmx/kmx_environment.h +++ b/core/src/kmx/kmx_environment.h @@ -15,8 +15,8 @@ private: std::u16string _platform; void InitOption( std::vector