From 3e518204823165f28f5a5383c98e42d9bd503777 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 15 Oct 2025 12:09:34 +0200 Subject: [PATCH 01/83] chore(linux): Update debian changelog (cherry picked from commit 392d85a1ad895dbb48e71f4ebf605d1612fa2b21) --- linux/debian/changelog | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/linux/debian/changelog b/linux/debian/changelog index ddb470e780..dd0f96f05a 100644 --- a/linux/debian/changelog +++ b/linux/debian/changelog @@ -1,9 +1,10 @@ -keyman (18.0.242-2) UNRELEASED; urgency=medium +keyman (18.0.243-1) unstable; urgency=medium * replace dbus-x11 dependency with default-dbus-session-bus | dbus-session-bus (closes: 1117068) + * New upstream release. - -- Eberhard Beilharz Mon, 06 Oct 2025 16:45:18 +0200 + -- Eberhard Beilharz Wed, 15 Oct 2025 12:09:24 +0200 keyman (18.0.242-1) unstable; urgency=medium From d0ea16b975d439a282e1699f475999e21617b186 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Tue, 21 Oct 2025 13:49:37 +0700 Subject: [PATCH 02/83] chore(web): Move chirality.js to common/test/resources/keyboards/ --- .../chirality => common/test/resources/keyboards}/chirality.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {web/src/test/manual/web/chirality => common/test/resources/keyboards}/chirality.js (100%) diff --git a/web/src/test/manual/web/chirality/chirality.js b/common/test/resources/keyboards/chirality.js similarity index 100% rename from web/src/test/manual/web/chirality/chirality.js rename to common/test/resources/keyboards/chirality.js From fb14a67db611c417966bbc134dbda8b2930e97f2 Mon Sep 17 00:00:00 2001 From: Markus Greiner Date: Tue, 7 Oct 2025 14:40:51 +0200 Subject: [PATCH 03/83] Docker changes permissions to match the file owner uid and gid There is an issue that the Docker containers cannot modify the files on KEYMAN_ROOT, since the user running build and tests on Docker does not have the same gid and uid as the host user starting the container. The issue is solved by temporarily changing the uid and gid to match the container user's uid and gid. Test-bot: skip Build-bot: skip --- resources/docker-images/android/Dockerfile | 13 +++++++++++++ resources/docker-images/base/Dockerfile | 1 + resources/docker-images/core/Dockerfile | 14 ++++++++++++++ resources/docker-images/developer/Dockerfile | 13 +++++++++++++ resources/docker-images/linux/Dockerfile | 13 +++++++++++++ resources/docker-images/web/Dockerfile | 13 +++++++++++++ 6 files changed, 67 insertions(+) diff --git a/resources/docker-images/android/Dockerfile b/resources/docker-images/android/Dockerfile index be99a2f247..923fb91eb3 100644 --- a/resources/docker-images/android/Dockerfile +++ b/resources/docker-images/android/Dockerfile @@ -36,11 +36,24 @@ EOF # Finish bashwrapper script and adjust permissions RUN <> /usr/bin/bashwrapper +uid=\$(stat -c "%u" /home/build/build) +gid=\$(stat -c "%g" /home/build/build) + +if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" + sudo chown -R build:build /home/build/build +fi + if [[ "\$@" =~ test ]] && [ -f /usr/bin/run-tests.sh ]; then /usr/bin/run-tests.sh "\${@:-bash}" else "\${@:-bash}" fi + +if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" + sudo chown -R \${uid}:\${gid} /home/build/build +fi EOF # now, switch to build user diff --git a/resources/docker-images/base/Dockerfile b/resources/docker-images/base/Dockerfile index 835806d63c..0cba2b73dc 100644 --- a/resources/docker-images/base/Dockerfile +++ b/resources/docker-images/base/Dockerfile @@ -53,6 +53,7 @@ EOF # Install NVM RUN NVM_RELEASE=$(curl -s https://api.github.com/repos/nvm-sh/nvm/releases/latest | grep tag_name | cut -d : -f 2 | cut -d '"' -f 2) && \ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_RELEASE}/install.sh | bash +RUN chmod -R +x,+r $HOME/ RUN <> /usr/bin/bashwrapper PATH=/home/build/.keyman/node:\$PATH export NVM_DIR="$HOME/.nvm" diff --git a/resources/docker-images/core/Dockerfile b/resources/docker-images/core/Dockerfile index 0519540865..c6a2454156 100644 --- a/resources/docker-images/core/Dockerfile +++ b/resources/docker-images/core/Dockerfile @@ -34,11 +34,25 @@ RUN echo "export EMSCRIPTEN_BASE=/home/build/emsdk/upstream/emscripten" >> /usr/ # Finish bashwrapper script and adjust permissions RUN <> /usr/bin/bashwrapper +uid=\$(stat -c "%u" /home/build/build) +gid=\$(stat -c "%g" /home/build/build) + +if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" + sudo chown -R build:build /home/build/build +fi + if [[ "\$@" =~ test ]] && [ -f /usr/bin/run-tests.sh ]; then /usr/bin/run-tests.sh "\${@:-bash}" else "\${@:-bash}" fi + +if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" + sudo chown -R \${uid}:\${gid} /home/build/build +fi + EOF # now, switch to build user diff --git a/resources/docker-images/developer/Dockerfile b/resources/docker-images/developer/Dockerfile index bfd25428e4..cb49ac04d7 100644 --- a/resources/docker-images/developer/Dockerfile +++ b/resources/docker-images/developer/Dockerfile @@ -34,11 +34,24 @@ RUN echo "export EMSCRIPTEN_BASE=/home/build/emsdk/upstream/emscripten" >> /usr/ # Finish bashwrapper script and adjust permissions RUN <> /usr/bin/bashwrapper +uid=\$(stat -c "%u" /home/build/build) +gid=\$(stat -c "%g" /home/build/build) + +if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" + sudo chown -R build:build /home/build/build +fi + if [[ "\$@" =~ test ]] && [ -f /usr/bin/run-tests.sh ]; then /usr/bin/run-tests.sh "\${@:-bash}" else "\${@:-bash}" fi + +if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" + sudo chown -R \${uid}:\${gid} /home/build/build +fi EOF # now, switch to build user diff --git a/resources/docker-images/linux/Dockerfile b/resources/docker-images/linux/Dockerfile index 9bf02375d2..269941af70 100644 --- a/resources/docker-images/linux/Dockerfile +++ b/resources/docker-images/linux/Dockerfile @@ -42,11 +42,24 @@ COPY run-tests.sh /usr/bin/run-tests.sh # Finish bashwrapper script and adjust permissions RUN <> /usr/bin/bashwrapper +uid=\$(stat -c "%u" /home/build/build) +gid=\$(stat -c "%g" /home/build/build) + +if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" + sudo chown -R build:build /home/build/build +fi + if [[ "\$@" =~ test ]] && [ -f /usr/bin/run-tests.sh ]; then /usr/bin/run-tests.sh "\${@:-bash}" else "\${@:-bash}" fi + +if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" + sudo chown -R \${uid}:\${gid} /home/build/build +fi EOF # now, switch to build user diff --git a/resources/docker-images/web/Dockerfile b/resources/docker-images/web/Dockerfile index a59f9869b1..fddc8a18b4 100644 --- a/resources/docker-images/web/Dockerfile +++ b/resources/docker-images/web/Dockerfile @@ -58,11 +58,24 @@ RUN curl https://packages.mozilla.org/apt/repo-signing-key.gpg > /etc/apt/keyrin # Finish bashwrapper script and adjust permissions RUN <> /usr/bin/bashwrapper +uid=\$(stat -c "%u" /home/build/build) +gid=\$(stat -c "%g" /home/build/build) + +if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" + sudo chown -R build:build /home/build/build +fi + if [[ "\$@" =~ test ]] && [ -f /usr/bin/run-tests.sh ]; then /usr/bin/run-tests.sh "\${@:-bash}" else "\${@:-bash}" fi + +if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" + sudo chown -R \${uid}:\${gid} /home/build/build +fi EOF # now, switch to build user From 54f5fc1ea3ffb9415c3d952b25197e396f66f504 Mon Sep 17 00:00:00 2001 From: Markus Greiner Date: Tue, 7 Oct 2025 14:58:47 +0200 Subject: [PATCH 04/83] Privileged mode is not required. --- resources/docker-images/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/docker-images/run.sh b/resources/docker-images/run.sh index 1c51600386..534e84eebf 100755 --- a/resources/docker-images/run.sh +++ b/resources/docker-images/run.sh @@ -51,7 +51,7 @@ run_android() { } run_core() { - docker_wrapper run "${DOCKER_RUN_ARGS[@]}" --privileged -i --rm -v "${KEYMAN_ROOT}":/home/build/build \ + docker_wrapper run "${DOCKER_RUN_ARGS[@]}" -i --rm -v "${KEYMAN_ROOT}":/home/build/build \ -v "${KEYMAN_ROOT}/core/build/docker-core/${build_dir}":/home/build/build/core/build \ "${registry_slash}keymanapp/keyman-core-ci:${image_version}" \ "${builder_extra_params[@]}" From 4bff2c81d5b20f18cddcb415463bbd4bbc0cf0ff Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 22 Oct 2025 06:53:29 +0700 Subject: [PATCH 05/83] chore(web): Update web test page reference to chirality.js --- web/src/test/manual/web/chirality/utilities.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/test/manual/web/chirality/utilities.js b/web/src/test/manual/web/chirality/utilities.js index 158a05c08e..d9226497f4 100644 --- a/web/src/test/manual/web/chirality/utilities.js +++ b/web/src/test/manual/web/chirality/utilities.js @@ -7,7 +7,7 @@ function loadKeyboards() languages:{ id:'en',name:'English',region:'North America' }, - filename:'chirality.js' + filename:'../../../../../../common/test/resources/keyboards/chirality.js' }); // A testing keyboard using 10.0 format and the KLS layout specifier From 5fa0dccbcb1a8f993509425961ea58c0989d752c Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 22 Oct 2025 06:54:01 +0700 Subject: [PATCH 06/83] chore(android): Update keyboard harness reference to chirality.js --- .../app/src/main/assets/keyboardharness.kmp | Bin 217993 -> 217932 bytes .../app/src/main/assets/keyboardharness.kpj | 50 ++---------------- .../app/src/main/assets/keyboardharness.kps | 2 +- 3 files changed, 4 insertions(+), 48 deletions(-) diff --git a/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kmp b/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kmp index f0380aabe531900823d6b362015da82ca8c0978a..9785ed733811c1938d1125c34725a47b5bd2897a 100644 GIT binary patch delta 3421 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 F{R8I3H2nYo delta 3467 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 E0B!I}X#fBK diff --git a/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kpj b/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kpj index c7fa5c530c..80a3e1568a 100644 --- a/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kpj +++ b/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kpj @@ -1,56 +1,12 @@ + 2.0 $PROJECTPATH + $PROJECTPATH\ True - True True + True lexicalmodel - - - id_165fd1598b940efe4a973aeb6eb61aba - keyboardharness.kps - keyboardharness.kps - 1.0 - .kps -
- keyboardharness - ©2020 SIL International - 1.0 -
-
- - id_f9b1213d4e83cb32ce1ead1ee852d618 - chirality.js - ..\..\..\..\..\..\..\web\testing\chirality\chirality.js - - .js - id_165fd1598b940efe4a973aeb6eb61aba - - - id_e01841691fa129428aea555142873f69 - platformtest.js - ..\..\..\..\..\..\..\web\testing\platform\platformtest.js - - .js - id_165fd1598b940efe4a973aeb6eb61aba - - - id_03df89bb84a1aa6cab40dfebf3a04c5b - code2001.ttf - code2001.ttf - - .ttf - id_165fd1598b940efe4a973aeb6eb61aba - - - id_2d07bd2b8c94e9600ac1a920c8cb9e0a - longpress.js - longpress.js - - .js - id_165fd1598b940efe4a973aeb6eb61aba - -
diff --git a/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kps b/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kps index 157aefd71c..9d03ec759b 100644 --- a/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kps +++ b/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kps @@ -20,7 +20,7 @@ - ..\..\..\..\..\..\..\web\src\test\manual\web\chirality\chirality.js + ../../../../../../../common/test/resources/keyboards/chirality.js File chirality.js 0 .js From c9b44d33c72ced82d53ae3713f34150edfdf9f12 Mon Sep 17 00:00:00 2001 From: Markus Greiner Date: Wed, 22 Oct 2025 15:39:17 +0200 Subject: [PATCH 07/83] Changing permissions only in the case if building and testing on GitHub --- resources/docker-images/android/Dockerfile | 18 +++++++---- resources/docker-images/build.sh | 2 +- resources/docker-images/core/Dockerfile | 32 +++++++++++--------- resources/docker-images/developer/Dockerfile | 21 +++++++------ resources/docker-images/docker-build.inc.sh | 4 ++- resources/docker-images/linux/Dockerfile | 20 +++++++----- 6 files changed, 57 insertions(+), 40 deletions(-) diff --git a/resources/docker-images/android/Dockerfile b/resources/docker-images/android/Dockerfile index 923fb91eb3..8fb47c8a38 100644 --- a/resources/docker-images/android/Dockerfile +++ b/resources/docker-images/android/Dockerfile @@ -39,9 +39,13 @@ RUN <> /usr/bin/bashwrapper uid=\$(stat -c "%u" /home/build/build) gid=\$(stat -c "%g" /home/build/build) -if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then - echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" - sudo chown -R build:build /home/build/build +if [[ -v CHANGE_PERMISSIONS ]]; then + uid=\$(stat -c "%u" /home/build/build) + gid=\$(stat -c "%g" /home/build/build) + if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" + sudo chown -R build:build /home/build/build + fi fi if [[ "\$@" =~ test ]] && [ -f /usr/bin/run-tests.sh ]; then @@ -50,9 +54,11 @@ else "\${@:-bash}" fi -if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then - echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" - sudo chown -R \${uid}:\${gid} /home/build/build +if [[ -v CHANGE_PERMISSIONS ]]; then + if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" + sudo chown -R \${uid}:\${gid} /home/build/build + fi fi EOF diff --git a/resources/docker-images/build.sh b/resources/docker-images/build.sh index 33f638ed6a..c07e732efb 100755 --- a/resources/docker-images/build.sh +++ b/resources/docker-images/build.sh @@ -105,7 +105,7 @@ if builder_has_action build; then fi builder_run_action test:core test_action core -# builder_run_action test:linux test_action linux +builder_run_action test:linux test_action linux builder_run_action test:web test_action web # Android uses artifacts from web, so it has to come after web builder_run_action test:android test_action android diff --git a/resources/docker-images/core/Dockerfile b/resources/docker-images/core/Dockerfile index c6a2454156..db22a66b4f 100644 --- a/resources/docker-images/core/Dockerfile +++ b/resources/docker-images/core/Dockerfile @@ -34,25 +34,27 @@ RUN echo "export EMSCRIPTEN_BASE=/home/build/emsdk/upstream/emscripten" >> /usr/ # Finish bashwrapper script and adjust permissions RUN <> /usr/bin/bashwrapper -uid=\$(stat -c "%u" /home/build/build) -gid=\$(stat -c "%g" /home/build/build) - -if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then - echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" - sudo chown -R build:build /home/build/build +if [[ -v CHANGE_PERMISSIONS ]]; then + uid=\$(stat -c "%u" /home/build/build) + gid=\$(stat -c "%g" /home/build/build) + if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" + sudo chown -R build:build /home/build/build + fi fi -if [[ "\$@" =~ test ]] && [ -f /usr/bin/run-tests.sh ]; then - /usr/bin/run-tests.sh "\${@:-bash}" -else - "\${@:-bash}" -fi + if [[ "\$@" =~ test ]] && [ -f /usr/bin/run-tests.sh ]; then + /usr/bin/run-tests.sh "\${@:-bash}" + else + "\${@:-bash}" + fi -if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then - echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" - sudo chown -R \${uid}:\${gid} /home/build/build +if [[ -v CHANGE_PERMISSIONS ]]; then + if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" + sudo chown -R \${uid}:\${gid} /home/build/build + fi fi - EOF # now, switch to build user diff --git a/resources/docker-images/developer/Dockerfile b/resources/docker-images/developer/Dockerfile index cb49ac04d7..b2f57df056 100644 --- a/resources/docker-images/developer/Dockerfile +++ b/resources/docker-images/developer/Dockerfile @@ -34,12 +34,13 @@ RUN echo "export EMSCRIPTEN_BASE=/home/build/emsdk/upstream/emscripten" >> /usr/ # Finish bashwrapper script and adjust permissions RUN <> /usr/bin/bashwrapper -uid=\$(stat -c "%u" /home/build/build) -gid=\$(stat -c "%g" /home/build/build) - -if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then - echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" - sudo chown -R build:build /home/build/build +if [[ -v CHANGE_PERMISSIONS ]]; then + uid=\$(stat -c "%u" /home/build/build) + gid=\$(stat -c "%g" /home/build/build) + if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" + sudo chown -R build:build /home/build/build + fi fi if [[ "\$@" =~ test ]] && [ -f /usr/bin/run-tests.sh ]; then @@ -48,9 +49,11 @@ else "\${@:-bash}" fi -if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then - echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" - sudo chown -R \${uid}:\${gid} /home/build/build +if [[ -v CHANGE_PERMISSIONS ]]; then + if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" + sudo chown -R \${uid}:\${gid} /home/build/build + fi fi EOF diff --git a/resources/docker-images/docker-build.inc.sh b/resources/docker-images/docker-build.inc.sh index 109d886c5e..e6427a75cb 100644 --- a/resources/docker-images/docker-build.inc.sh +++ b/resources/docker-images/docker-build.inc.sh @@ -87,7 +87,9 @@ setup_docker() { if [[ "${MSYSTEM:-}" == "MINGW64" ]]; then DOCKER_RUN_ARGS+=(--env DOCKER_RUN_AS_ROOT=1) fi - if ! builder_is_running_on_gha ; then + if builder_is_running_on_gha ; then + DOCKER_RUN_ARGS+=(--env CHANGE_PERMISSIONS=1) + else DOCKER_RUN_ARGS+=(-t) fi diff --git a/resources/docker-images/linux/Dockerfile b/resources/docker-images/linux/Dockerfile index 269941af70..a63aace65d 100644 --- a/resources/docker-images/linux/Dockerfile +++ b/resources/docker-images/linux/Dockerfile @@ -42,12 +42,14 @@ COPY run-tests.sh /usr/bin/run-tests.sh # Finish bashwrapper script and adjust permissions RUN <> /usr/bin/bashwrapper -uid=\$(stat -c "%u" /home/build/build) -gid=\$(stat -c "%g" /home/build/build) +if [[ -v CHANGE_PERMISSIONS ]]; then + uid=\$(stat -c "%u" /home/build/build) + gid=\$(stat -c "%g" /home/build/build) -if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then - echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" - sudo chown -R build:build /home/build/build + if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" + sudo chown -R build:build /home/build/build + fi fi if [[ "\$@" =~ test ]] && [ -f /usr/bin/run-tests.sh ]; then @@ -56,9 +58,11 @@ else "\${@:-bash}" fi -if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then - echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" - sudo chown -R \${uid}:\${gid} /home/build/build +if [[ -v CHANGE_PERMISSIONS ]]; then + if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" + sudo chown -R \${uid}:\${gid} /home/build/build + fi fi EOF From d9b4ec9baf448b28cf97f7a9636a3f38d093a1fe Mon Sep 17 00:00:00 2001 From: Markus Greiner Date: Wed, 22 Oct 2025 18:02:17 +0200 Subject: [PATCH 08/83] Weakening condition for gid and uid (after review Test-bot: skip Build-bot: skip --- resources/docker-images/android/Dockerfile | 4 ++-- resources/docker-images/core/Dockerfile | 4 ++-- resources/docker-images/developer/Dockerfile | 4 ++-- resources/docker-images/linux/Dockerfile | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/docker-images/android/Dockerfile b/resources/docker-images/android/Dockerfile index 8fb47c8a38..f943f880d3 100644 --- a/resources/docker-images/android/Dockerfile +++ b/resources/docker-images/android/Dockerfile @@ -42,7 +42,7 @@ gid=\$(stat -c "%g" /home/build/build) if [[ -v CHANGE_PERMISSIONS ]]; then uid=\$(stat -c "%u" /home/build/build) gid=\$(stat -c "%g" /home/build/build) - if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + if [[ "\${uid}" != "\$(id -u)" && "\${gid}" != "\$(id -g)" ]]; then echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" sudo chown -R build:build /home/build/build fi @@ -55,7 +55,7 @@ else fi if [[ -v CHANGE_PERMISSIONS ]]; then - if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + if [[ "\${uid}" != "\$(id -u)" && "\${gid}" != "\$(id -g)" ]]; then echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" sudo chown -R \${uid}:\${gid} /home/build/build fi diff --git a/resources/docker-images/core/Dockerfile b/resources/docker-images/core/Dockerfile index db22a66b4f..0589b8c2ee 100644 --- a/resources/docker-images/core/Dockerfile +++ b/resources/docker-images/core/Dockerfile @@ -37,7 +37,7 @@ RUN <> /usr/bin/bashwrapper if [[ -v CHANGE_PERMISSIONS ]]; then uid=\$(stat -c "%u" /home/build/build) gid=\$(stat -c "%g" /home/build/build) - if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + if [[ "\${uid}" != "\$(id -u)" && "\${gid}" != "\$(id -g)" ]]; then echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" sudo chown -R build:build /home/build/build fi @@ -50,7 +50,7 @@ fi fi if [[ -v CHANGE_PERMISSIONS ]]; then - if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + if [[ "\${uid}" != "\$(id -u)" && "\${gid}" != "\$(id -g)" ]]; then echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" sudo chown -R \${uid}:\${gid} /home/build/build fi diff --git a/resources/docker-images/developer/Dockerfile b/resources/docker-images/developer/Dockerfile index b2f57df056..19c69c5e98 100644 --- a/resources/docker-images/developer/Dockerfile +++ b/resources/docker-images/developer/Dockerfile @@ -37,7 +37,7 @@ RUN <> /usr/bin/bashwrapper if [[ -v CHANGE_PERMISSIONS ]]; then uid=\$(stat -c "%u" /home/build/build) gid=\$(stat -c "%g" /home/build/build) - if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + if [[ "\${uid}" != "\$(id -u)" && "\${gid}" != "\$(id -g)" ]]; then echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" sudo chown -R build:build /home/build/build fi @@ -50,7 +50,7 @@ else fi if [[ -v CHANGE_PERMISSIONS ]]; then - if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + if [[ "\${uid}" != "\$(id -u)" && "\${gid}" != "\$(id -g)" ]]; then echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" sudo chown -R \${uid}:\${gid} /home/build/build fi diff --git a/resources/docker-images/linux/Dockerfile b/resources/docker-images/linux/Dockerfile index a63aace65d..084b0f16c7 100644 --- a/resources/docker-images/linux/Dockerfile +++ b/resources/docker-images/linux/Dockerfile @@ -46,7 +46,7 @@ if [[ -v CHANGE_PERMISSIONS ]]; then uid=\$(stat -c "%u" /home/build/build) gid=\$(stat -c "%g" /home/build/build) - if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + if [[ "\${uid}" != "\$(id -u)" && "\${gid}" != "\$(id -g)" ]]; then echo "Adjusting build directory ownership to uid/gid \$(id -un):\$(id -gn)" sudo chown -R build:build /home/build/build fi @@ -59,7 +59,7 @@ else fi if [[ -v CHANGE_PERMISSIONS ]]; then - if [[ "\${uid}" != "\$(id -u)" || "\${gid}" != "\$(id -g)" ]]; then + if [[ "\${uid}" != "\$(id -u)" && "\${gid}" != "\$(id -g)" ]]; then echo "Reverting build directory ownership to uid/gid \${uid}:\${gid}" sudo chown -R \${uid}:\${gid} /home/build/build fi From 616092e0f7ba2674bebcfdd0dc106ce53febf586 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Fri, 24 Oct 2025 09:08:31 +0700 Subject: [PATCH 09/83] fix(web): Copy common keyboards to test-resources --- web/build/test-resources/keyboards/.gitkeep | 0 web/src/test/manual/build.sh | 3 +++ web/src/test/manual/web/chirality/utilities.js | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 web/build/test-resources/keyboards/.gitkeep diff --git a/web/build/test-resources/keyboards/.gitkeep b/web/build/test-resources/keyboards/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/web/src/test/manual/build.sh b/web/src/test/manual/build.sh index b2eed53d0a..be3dcbc869 100755 --- a/web/src/test/manual/build.sh +++ b/web/src/test/manual/build.sh @@ -49,6 +49,9 @@ function do_copy() { mkdir -p "$GESTURE_PROCESSOR_TARGET" cp -a "$GESTURE_PROCESSOR_BUILD" "$GESTURE_PROCESSOR_TARGET" + + # copy common test resources (keyboards) + cp -f "$KEYMAN_ROOT/common/test/resources/keyboards/"*.js "$KEYMAN_ROOT/$DEST/keyboards/" } builder_run_action clean rm -rf "$KEYMAN_ROOT/$DEST" && rm -rf "$GESTURE_PROCESSOR_TARGET" diff --git a/web/src/test/manual/web/chirality/utilities.js b/web/src/test/manual/web/chirality/utilities.js index d9226497f4..16c9caaf02 100644 --- a/web/src/test/manual/web/chirality/utilities.js +++ b/web/src/test/manual/web/chirality/utilities.js @@ -7,7 +7,7 @@ function loadKeyboards() languages:{ id:'en',name:'English',region:'North America' }, - filename:'../../../../../../common/test/resources/keyboards/chirality.js' + filename:'../../../../../build/test-resources/keyboards/chirality.js' }); // A testing keyboard using 10.0 format and the KLS layout specifier From 00b6c71eb4522f33e6bc3b74d69a5cb1efdb7dc9 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Fri, 24 Oct 2025 10:09:46 +0700 Subject: [PATCH 10/83] fix(web): Create test-resources/keyboards dir --- web/build/test-resources/keyboards/.gitkeep | 0 web/src/test/manual/build.sh | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 web/build/test-resources/keyboards/.gitkeep diff --git a/web/build/test-resources/keyboards/.gitkeep b/web/build/test-resources/keyboards/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/web/src/test/manual/build.sh b/web/src/test/manual/build.sh index be3dcbc869..53a784bdf8 100755 --- a/web/src/test/manual/build.sh +++ b/web/src/test/manual/build.sh @@ -41,7 +41,7 @@ GESTURE_PROCESSOR_BUILD="$KEYMAN_ROOT/web/src/engine/osk/gesture-processor/build GESTURE_PROCESSOR_TARGET="$KEYMAN_ROOT/web/build/engine/gesture-processor/lib/" function do_copy() { - mkdir -p "$KEYMAN_ROOT/$DEST" + mkdir -p "$KEYMAN_ROOT/$DEST/keyboards" # The next four lines are needed for the sentry-integration manual test page. cp "$SENTRY_MANAGER_SRC" "$KEYMAN_ROOT/$DEST/sentry-manager.js" From b1fe097a828b739a7d036a6d166badab375bdb06 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 22 Oct 2025 08:10:24 +0700 Subject: [PATCH 11/83] chore(windows): Update platformtest keyboard --- .../platform-rules/platformtest.js | 381 +----------------- .../platform-rules/platformtest.kmn | 5 +- .../platform-rules/platformtest.kmp | Bin 3699 -> 3701 bytes .../platform-rules/platformtest.kmx | Bin 5184 -> 5260 bytes .../platform-rules/platformtest.kpj | 11 +- .../platform-rules/platformtest.kps | 4 +- 6 files changed, 11 insertions(+), 390 deletions(-) diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.js b/windows/src/test/manual-tests/platform-rules/platformtest.js index 0a1c8bfa78..f7d08ad396 100644 --- a/windows/src/test/manual-tests/platform-rules/platformtest.js +++ b/windows/src/test/manual-tests/platform-rules/platformtest.js @@ -1,380 +1 @@ - -KeymanWeb.KR(new Keyboard_platformtest()); - -function Keyboard_platformtest() -{ - - this.KI = "Keyboard_platformtest"; - this.KN = "PlatformTest"; - this.KMINVER = "9.0"; - this.KV = null; - this.KH = ''; - this.KM = 0; - this.KBVER = "1.0"; - this.KMBM = 0x0000; - this.s17 = "touch"; - this.s18 = "hardware"; - this.s21 = "windows"; - this.s22 = "android"; - this.s23 = "ios"; - this.s24 = "macosx"; - this.s25 = "linux"; - this.s28 = "desktop"; - this.s29 = "tablet"; - this.s30 = "phone"; - this.s33 = "native"; - this.s34 = "web"; - this.s37 = "ie"; - this.s38 = "chrome"; - this.s39 = "edge"; - this.s40 = "firefox"; - this.s41 = "safari"; - this.s42 = "opera"; - this.s45 = "touch"; - this.s46 = "hardware"; - this.s49 = "platform-x"; - this.s52 = "WinDOWS"; - this.s53 = "ANDroid"; - this.s54 = "iOS"; - this.s55 = "macOSX"; - this.s56 = "LINUX"; - this.s58 = "touch"; - this.s59 = "hardware"; - this.s60 = "windows"; - this.s61 = "android"; - this.s62 = "ios"; - this.s63 = "macosx"; - this.s64 = "linux"; - this.s65 = "desktop"; - this.s66 = "tablet"; - this.s67 = "phone"; - this.s68 = "native"; - this.s69 = "web"; - this.s70 = "ie"; - this.s71 = "chrome"; - this.s72 = "edge"; - this.s73 = "firefox"; - this.s74 = "safari"; - this.s75 = "opera"; - this.s76 = "touch"; - this.s77 = "hardware"; - this.s78 = "platform-x"; - this.s79 = "WinDOWS"; - this.s80 = "ANDroid"; - this.s81 = "iOS"; - this.s82 = "macOSX"; - this.s83 = "LINUX"; - this.KVER = "10.0.1109.0"; - 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, 65)) { - r = m = 1; - r = this.g1(t, e); - } - if (!m && k.KIK(e)) { - r = 1; - r = this.g9(t, e); - } - return r; - }; - this.g1 = function(t, e) { - var k = KeymanWeb, - r = 1, - m = 0; - if (k.KIFS(31, this.s17, t)) { - m = 1; - k.KO(0, t, "touch"); - } else if (k.KIFS(31, this.s18, t)) { - m = 1; - k.KO(0, t, "hardware"); - } - if (m) { - r = this.g2(t, e); - } - if (!m) { - k.KO(-1, t, "undefined"); - r = this.g2(t, e); - } - return r; - }; - this.g2 = function(t, e) { - var k = KeymanWeb, - r = 1, - m = 0; - if (k.KIFS(31, this.s21, t)) { - m = 1; - k.KO(0, t, " windows"); - } else if (k.KIFS(31, this.s22, t)) { - m = 1; - k.KO(0, t, " android"); - } else if (k.KIFS(31, this.s23, t)) { - m = 1; - k.KO(0, t, " ios"); - } else if (k.KIFS(31, this.s24, t)) { - m = 1; - k.KO(0, t, " macosx"); - } else if (k.KIFS(31, this.s25, t)) { - m = 1; - k.KO(0, t, " linux"); - } - if (m) { - r = this.g3(t, e); - } - if (!m) { - k.KO(-1, t, " undefined"); - r = this.g3(t, e); - } - return r; - }; - this.g3 = function(t, e) { - var k = KeymanWeb, - r = 1, - m = 0; - if (k.KIFS(31, this.s28, t)) { - m = 1; - k.KO(0, t, " desktop"); - } else if (k.KIFS(31, this.s29, t)) { - m = 1; - k.KO(0, t, " tablet"); - } else if (k.KIFS(31, this.s30, t)) { - m = 1; - k.KO(0, t, " phone"); - } - if (m) { - r = this.g4(t, e); - } - if (!m) { - k.KO(-1, t, " undefined"); - r = this.g4(t, e); - } - return r; - }; - this.g4 = function(t, e) { - var k = KeymanWeb, - r = 1, - m = 0; - if (k.KIFS(31, this.s33, t)) { - m = 1; - k.KO(0, t, " native"); - } else if (k.KIFS(31, this.s34, t)) { - m = 1; - k.KO(0, t, " web"); - } - if (m) { - r = this.g5(t, e); - } - if (!m) { - k.KO(-1, t, " undefined"); - r = this.g5(t, e); - } - return r; - }; - this.g5 = function(t, e) { - var k = KeymanWeb, - r = 1, - m = 0; - if (k.KIFS(31, this.s37, t)) { - m = 1; - k.KO(0, t, " ie"); - } else if (k.KIFS(31, this.s38, t)) { - m = 1; - k.KO(0, t, " chrome"); - } else if (k.KIFS(31, this.s39, t)) { - m = 1; - k.KO(0, t, " edge"); - } else if (k.KIFS(31, this.s40, t)) { - m = 1; - k.KO(0, t, " firefox"); - } else if (k.KIFS(31, this.s41, t)) { - m = 1; - k.KO(0, t, " safari"); - } else if (k.KIFS(31, this.s42, t)) { - m = 1; - k.KO(0, t, " opera"); - } - if (m) { - r = this.g6(t, e); - } - if (!m) { - k.KO(-1, t, " undefined"); - r = this.g6(t, e); - } - return r; - }; - this.g6 = function(t, e) { - var k = KeymanWeb, - r = 1, - m = 0; - if (!k.KIFS(31, this.s45, t)) { - m = 1; - k.KO(0, t, " !touch"); - } else if (!k.KIFS(31, this.s46, t)) { - m = 1; - k.KO(0, t, " !hardware"); - } - if (m) { - r = this.g7(t, e); - } - if (!m) { - k.KO(-1, t, " undefined"); - r = this.g7(t, e); - } - return r; - }; - this.g7 = function(t, e) { - var k = KeymanWeb, - r = 1, - m = 0; - if (k.KIFS(31, this.s49, t)) { - m = 1; - k.KO(0, t, " platform-x"); - } - if (m) { - r = this.g8(t, e); - } - if (!m) { - k.KO(-1, t, " undefined"); - r = this.g8(t, e); - } - return r; - }; - this.g8 = function(t, e) { - var k = KeymanWeb, - r = 1, - m = 0; - if (k.KIFS(31, this.s52, t)) { - m = 1; - k.KO(0, t, " windows"); - } else if (k.KIFS(31, this.s53, t)) { - m = 1; - k.KO(0, t, " android"); - } else if (k.KIFS(31, this.s54, t)) { - m = 1; - k.KO(0, t, " ios"); - } else if (k.KIFS(31, this.s55, t)) { - m = 1; - k.KO(0, t, " macosx"); - } else if (k.KIFS(31, this.s56, t)) { - m = 1; - k.KO(0, t, " linux"); - } - if (!m) { - k.KO(-1, t, " undefined"); - } - return r; - }; - this.g9 = function(t, e) { - var k = KeymanWeb, - r = 0, - m = 0; - if (k.KKM(e, 16384, 69) && k.KIFS(31, this.s79, t)) { - r = m = 1; - k.KO(0, t, " Windows"); - } else if (k.KKM(e, 16384, 69) && k.KIFS(31, this.s80, t)) { - r = m = 1; - k.KO(0, t, " Android"); - } else if (k.KKM(e, 16384, 69) && k.KIFS(31, this.s81, t)) { - r = m = 1; - k.KO(0, t, " iOS"); - } else if (k.KKM(e, 16384, 69) && k.KIFS(31, this.s82, t)) { - r = m = 1; - k.KO(0, t, " macOS"); - } else if (k.KKM(e, 16384, 69) && k.KIFS(31, this.s83, t)) { - r = m = 1; - k.KO(0, t, " Linux"); - } else if (k.KKM(e, 16384, 69)) { - r = m = 1; - k.KO(0, t, " [OS Undefined (case insensitive test)]"); - } else if (k.KKM(e, 16384, 73) && k.KIFS(31, this.s65, t)) { - r = m = 1; - k.KO(0, t, " Desktop"); - } else if (k.KKM(e, 16384, 73) && k.KIFS(31, this.s66, t)) { - r = m = 1; - k.KO(0, t, " Tablet"); - } else if (k.KKM(e, 16384, 73) && k.KIFS(31, this.s67, t)) { - r = m = 1; - k.KO(0, t, " Phone"); - } else if (k.KKM(e, 16384, 73)) { - r = m = 1; - k.KO(0, t, " [FF Undefined]"); - } else if (k.KKM(e, 16384, 79) && k.KIFS(31, this.s60, t)) { - r = m = 1; - k.KO(0, t, " Windows"); - } else if (k.KKM(e, 16384, 79) && k.KIFS(31, this.s61, t)) { - r = m = 1; - k.KO(0, t, " Android"); - } else if (k.KKM(e, 16384, 79) && k.KIFS(31, this.s62, t)) { - r = m = 1; - k.KO(0, t, " iOS"); - } else if (k.KKM(e, 16384, 79) && k.KIFS(31, this.s63, t)) { - r = m = 1; - k.KO(0, t, " OSX"); - } else if (k.KKM(e, 16384, 79) && k.KIFS(31, this.s64, t)) { - r = m = 1; - k.KO(0, t, " Linux"); - } else if (k.KKM(e, 16384, 79)) { - r = m = 1; - k.KO(0, t, " [OS Undefined]"); - } else if (k.KKM(e, 16384, 80) && k.KIFS(31, this.s58, t)) { - r = m = 1; - k.KO(0, t, "Touch"); - } else if (k.KKM(e, 16384, 80) && k.KIFS(31, this.s59, t)) { - r = m = 1; - k.KO(0, t, "Hardware"); - } else if (k.KKM(e, 16384, 80)) { - r = m = 1; - k.KO(0, t, "[UI Undefined]"); - } else if (k.KKM(e, 16384, 82) && k.KIFS(31, this.s78, t)) { - r = m = 1; - k.KO(0, t, " Platform-X"); - } else if (k.KKM(e, 16384, 82)) { - r = m = 1; - k.KO(0, t, " [Platform-X Undefined]"); - } else if (k.KKM(e, 16384, 84) && !k.KIFS(31, this.s76, t)) { - r = m = 1; - k.KO(0, t, " !Touch"); - } else if (k.KKM(e, 16384, 84) && !k.KIFS(31, this.s77, t)) { - r = m = 1; - k.KO(0, t, " !Hardware"); - } else if (k.KKM(e, 16384, 84)) { - r = m = 1; - k.KO(0, t, " [Inverted OS Undefined]"); - } else if (k.KKM(e, 16384, 85) && k.KIFS(31, this.s68, t)) { - r = m = 1; - k.KO(0, t, " Native"); - } else if (k.KKM(e, 16384, 85) && k.KIFS(31, this.s69, t)) { - r = m = 1; - k.KO(0, t, " Web"); - } else if (k.KKM(e, 16384, 85)) { - r = m = 1; - k.KO(0, t, " [Nativeness Undefined]"); - } else if (k.KKM(e, 16384, 89) && k.KIFS(31, this.s70, t)) { - r = m = 1; - k.KO(0, t, " IE"); - } else if (k.KKM(e, 16384, 89) && k.KIFS(31, this.s71, t)) { - r = m = 1; - k.KO(0, t, " Chrome"); - } else if (k.KKM(e, 16384, 89) && k.KIFS(31, this.s72, t)) { - r = m = 1; - k.KO(0, t, " Edge"); - } else if (k.KKM(e, 16384, 89) && k.KIFS(31, this.s73, t)) { - r = m = 1; - k.KO(0, t, " Firefox"); - } else if (k.KKM(e, 16384, 89) && k.KIFS(31, this.s74, t)) { - r = m = 1; - k.KO(0, t, " Safari"); - } else if (k.KKM(e, 16384, 89) && k.KIFS(31, this.s75, t)) { - r = m = 1; - k.KO(0, t, " Opera"); - } else if (k.KKM(e, 16384, 89)) { - r = m = 1; - k.KO(0, t, " [Browser Undefined]"); - } - 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_platformtest());}function Keyboard_platformtest(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_platformtest";this.KN="PlatformTest";this.KMINVER="10.0";this.KV=null;this.KDU=0;this.KH='';this.KM=0;this.KBVER="1.0";this.KMBM=0x0;this.s20="touch";this.s21="hardware";this.s24="windows";this.s25="android";this.s26="ios";this.s27="macosx";this.s28="linux";this.s31="desktop";this.s32="tablet";this.s33="phone";this.s36="native";this.s37="web";this.s40="ie";this.s41="chrome";this.s42="edge";this.s43="firefox";this.s44="safari";this.s45="opera";this.s48="touch";this.s49="hardware";this.s52="platform-x";this.s55="WinDOWS";this.s56="ANDroid";this.s57="iOS";this.s58="macOSX";this.s59="LINUX";this.s61="touch";this.s62="hardware";this.s63="windows";this.s64="android";this.s65="ios";this.s66="macosx";this.s67="linux";this.s68="desktop";this.s69="tablet";this.s70="phone";this.s71="native";this.s72="web";this.s73="ie";this.s74="chrome";this.s75="edge";this.s76="firefox";this.s77="safari";this.s78="opera";this.s79="touch";this.s80="hardware";this.s81="platform-x";this.s82="WinDOWS";this.s83="ANDroid";this.s84="iOS";this.s85="macOSX";this.s86="LINUX";this.KVER="18.0.241.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,65)) {if(1){r=m=1;k.KDC(0,t);r=this.g1(t,e);m=2;}}if(!m&&k.KIK(e)) {r=1;k.KDC(-1,t);r=this.g9(t,e);m=2;}return r;};this.g1=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s20,t)){m=1;k.KDC(0,t);k.KO(-1,t,"touch");}else if(k.KIFS(31,this.s21,t)){m=1;k.KDC(0,t);k.KO(-1,t,"hardware");}if(m==1) {k.KDC(-1,t);r=this.g2(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t,"undefined");r=this.g2(t,e);m=2;}return r;};this.g2=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s24,t)){m=1;k.KDC(0,t);k.KO(-1,t," windows");}else if(k.KIFS(31,this.s25,t)){m=1;k.KDC(0,t);k.KO(-1,t," android");}else if(k.KIFS(31,this.s26,t)){m=1;k.KDC(0,t);k.KO(-1,t," ios");}else if(k.KIFS(31,this.s27,t)){m=1;k.KDC(0,t);k.KO(-1,t," macosx");}else if(k.KIFS(31,this.s28,t)){m=1;k.KDC(0,t);k.KO(-1,t," linux");}if(m==1) {k.KDC(-1,t);r=this.g3(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g3(t,e);m=2;}return r;};this.g3=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s31,t)){m=1;k.KDC(0,t);k.KO(-1,t," desktop");}else if(k.KIFS(31,this.s32,t)){m=1;k.KDC(0,t);k.KO(-1,t," tablet");}else if(k.KIFS(31,this.s33,t)){m=1;k.KDC(0,t);k.KO(-1,t," phone");}if(m==1) {k.KDC(-1,t);r=this.g4(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g4(t,e);m=2;}return r;};this.g4=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s36,t)){m=1;k.KDC(0,t);k.KO(-1,t," native");}else if(k.KIFS(31,this.s37,t)){m=1;k.KDC(0,t);k.KO(-1,t," web");}if(m==1) {k.KDC(-1,t);r=this.g5(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g5(t,e);m=2;}return r;};this.g5=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s40,t)){m=1;k.KDC(0,t);k.KO(-1,t," ie");}else if(k.KIFS(31,this.s41,t)){m=1;k.KDC(0,t);k.KO(-1,t," chrome");}else if(k.KIFS(31,this.s42,t)){m=1;k.KDC(0,t);k.KO(-1,t," edge");}else if(k.KIFS(31,this.s43,t)){m=1;k.KDC(0,t);k.KO(-1,t," firefox");}else if(k.KIFS(31,this.s44,t)){m=1;k.KDC(0,t);k.KO(-1,t," safari");}else if(k.KIFS(31,this.s45,t)){m=1;k.KDC(0,t);k.KO(-1,t," opera");}if(m==1) {k.KDC(-1,t);r=this.g6(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g6(t,e);m=2;}return r;};this.g6=function(t,e) {var k=KeymanWeb,r=1,m=0;if(!k.KIFS(31,this.s48,t)){m=1;k.KDC(0,t);k.KO(-1,t," !touch");}else if(!k.KIFS(31,this.s49,t)){m=1;k.KDC(0,t);k.KO(-1,t," !hardware");}if(m==1) {k.KDC(-1,t);r=this.g7(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g7(t,e);m=2;}return r;};this.g7=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s52,t)){m=1;k.KDC(0,t);k.KO(-1,t," platform-x");}if(m==1) {k.KDC(-1,t);r=this.g8(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g8(t,e);m=2;}return r;};this.g8=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s55,t)){m=1;k.KDC(0,t);k.KO(-1,t," windows");}else if(k.KIFS(31,this.s56,t)){m=1;k.KDC(0,t);k.KO(-1,t," android");}else if(k.KIFS(31,this.s57,t)){m=1;k.KDC(0,t);k.KO(-1,t," ios");}else if(k.KIFS(31,this.s58,t)){m=1;k.KDC(0,t);k.KO(-1,t," macosx");}else if(k.KIFS(31,this.s59,t)){m=1;k.KDC(0,t);k.KO(-1,t," linux");}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");}return r;};this.g9=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,69)) {if(k.KIFS(31,this.s82,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Windows");}else if(k.KIFS(31,this.s83,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Android");}else if(k.KIFS(31,this.s84,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," iOS");}else if(k.KIFS(31,this.s85,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," macOS");}else if(k.KIFS(31,this.s86,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Linux");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [OS Undefined (case insensitive test)]");}}else if(k.KKM(e,16384,73)) {if(k.KIFS(31,this.s68,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Desktop");}else if(k.KIFS(31,this.s69,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Tablet");}else if(k.KIFS(31,this.s70,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Phone");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [FF Undefined]");}}else if(k.KKM(e,16384,79)) {if(k.KIFS(31,this.s63,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Windows");}else if(k.KIFS(31,this.s64,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Android");}else if(k.KIFS(31,this.s65,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," iOS");}else if(k.KIFS(31,this.s66,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," OSX");}else if(k.KIFS(31,this.s67,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Linux");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [OS Undefined]");}}else if(k.KKM(e,16384,80)) {if(k.KIFS(31,this.s61,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"Touch");}else if(k.KIFS(31,this.s62,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"Hardware");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"[UI Undefined]");}}else if(k.KKM(e,16384,82)) {if(k.KIFS(31,this.s81,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Platform-X");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [Platform-X Undefined]");}}else if(k.KKM(e,16384,84)) {if(!k.KIFS(31,this.s79,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," !Touch");}else if(!k.KIFS(31,this.s80,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," !Hardware");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [Inverted OS Undefined]");}}else if(k.KKM(e,16384,85)) {if(k.KIFS(31,this.s71,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Native");}else if(k.KIFS(31,this.s72,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Web");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [Nativeness Undefined]");}}else if(k.KKM(e,16384,89)) {if(k.KIFS(31,this.s73,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," IE");}else if(k.KIFS(31,this.s74,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Chrome");}else if(k.KIFS(31,this.s75,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Edge");}else if(k.KIFS(31,this.s76,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Firefox");}else if(k.KIFS(31,this.s77,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Safari");}else if(k.KIFS(31,this.s78,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Opera");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [Browser Undefined]");}}return r;};} \ No newline at end of file diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.kmn b/windows/src/test/manual-tests/platform-rules/platformtest.kmn index b33fe0e763..490f569e3e 100644 --- a/windows/src/test/manual-tests/platform-rules/platformtest.kmn +++ b/windows/src/test/manual-tests/platform-rules/platformtest.kmn @@ -1,5 +1,8 @@ -store(&TARGETS) 'any' +store(&VERSION) '10.0' +store(&TARGETS) 'any' store(&NAME) 'PlatformTest' +store(&KEYBOARDVERSION) '1.0' +store(©RIGHT) '© SIL Global' begin Unicode > use(main) group(main) using keys diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.kmp b/windows/src/test/manual-tests/platform-rules/platformtest.kmp index c6a939f9aed7ee0a711ff44af2ba9a84bc609a93..d60fe88152402ace7557a0f1513857bb070579c3 100644 GIT binary patch literal 3701 zcmZ{nc{CK<8^_0(u_k+@F=I){9TsY*`ay31iDr zS(1GpBTFJfS+eBkJ@41KE>!ldE5dLT|zKM*WmcC zPZhpO+e^P-mY1GU`p>c=$+2SLY$KxL_(pi|b8Ko}ZvqDu>QBAG7>a z^K0T(`bm_$Qq$!7yG>a5vfbR3TQl2_vv$Mgf;XOH2C%!+2QJ5(cO`VAzbh!&Ux0wW z@NW<_3qxwYvJDEI=I9>D2()_@{L4Jgf-eDBIU01TUVp)dY|MuQL@AOOZ@=6;MdgTd zjTm!3ENu;EIIL?ObXK`7eeZFrB5;GNUYC3wxXW-wj9T29%M@x$Hi#$!ktC>U5#ek> zCgk7<;m0aXH_358QP8a5JwmG}NL_-e8_^Ad@&uWa#UnPDLXqSs;IR;O1E|3sWJlH) ziyC9NEqG6hJOhOB)a#M&M946PvRJl^D$q1Vy&2YB_k$k8#Z9z_nWt%MU?0G$^fr8+ zGUEc)_>y>iu+P5u%yOd@w0`eD=%wg!CnPTR}SQ(=$dH9@5y;M*rGE%0;w3XDADJ%ve+axU|VkzY--e5 z)b!k`(Dz7=;5BZMkNWb#Mq__vX$9M6R56vS(jS}BhWftFo8TnF4?=oT>hQZ(0Tf>lUvM)W zIm!*1)eN~AJ|=N9+k?s_9e3ryzt2u8TkEf2M0Dm}%*a$#BK2^YgQxW{awSd|R&%^{ z*Mq#$m#7G}iq1|gyQrzfBi=dB@#^5;T;{^O+(!O0D~{icQ>Na85$|gHW!?`Ju7sBa(b!6d4o00}74k z{yIvx5T=49N<6M=ZoO=!6kA}_4PlB_xf`XWw@Gdku6+uI;fmGQ@OKZ(1UAkFZ@({= zTUUdS)z*S4TWQNLRuQeK2tC7xbt=|Op~Hg}50J`}Qq;<8O-kDFjw0ReV-`*}owc{q z6!%f1GnpP`9^1c1^BNtZxqG z(ux0}l)L|7(g?Q6)?9g|g*%YhCWR#N{hKHJOEu-@SFv-{WuAh~Oqr}oIu}fe_hoyh zku_qR^)scEtlT66nXdeS_)TtdR}&nuZ8Ko-bBs&bcek-_62H&SpEYNp+3ZEd)jgQ~ zTpKFK^J!|*o^$^PX}zx!*fxP%z;=0y-YCzlXy%+OY3{*(KAhdA-*=--qCTZnlAH&sOE%G^YQO{TgGX7>yIz z&x8N~tbfWr3PZHC^`@w@9Z3kXg3seQlE;^XzM&e?#AvjY)RE;Y>vD5h^bP&DCNFF( zjyA>;-#r3dnaw+(b2{klRp|&al0~1d9FWZ9L$3LMkD@CWE|zI$%%T&_8qVsPQf69k z>zb@yd1(fFJ$BHu%o$ld7xSQcoVRRX<_)%^cJe8^kJFN9>{wRwRY%d^zH)|^5Mxfl z%>YwN&mzsH*9SX7j4tT#uAtAdmC(o_?%e0D)e~5yaY>i1tm#2$sQ06_&Yq6rZOK{_ zVRfGSDTwRY8Pe@O96IwPDQ_G@-jRnv-LDd}>r0MMesno8J+>Q|Y%XsS#HOCn7oHmi zt-hb3P+M2yS^5iESGOa#avkH!=2Cm#pwIi+uM!8+iv4VMSkV$bb~-@2qto+gm`Zcu z&7Do=^06OIpM#R2bJ-+i_L%TDi}g-s^0+e#dh$x+!=YT7q`ho|EW^HZfovU_Duv+T zpB;<|4{-{DD7rxx`og7YnBFGLU2r%XJg>zEnfGX?6rB%wS{NVQ-I80SV+}#6Yam|6 zcCp{r(qMdgF6N%d2Z`fVd^WIQg-LWl589`6W|m7NUC2DJo!S>aM8yhq1@*^7kRw`5*2eh23g(N zPq*yIR2I-o6eOA!@p1TGbQG!+y0BIIPN!J%Lc53@`>SZ&TW7f{3l7dHXE`5NL!&jW z&Uao`Mr-I8oSCjs>_Mm=j za!l<<(%IxJZ4Fo1UKy2we9T+Ebobop3F$}E8Zbpj#B+bm`NCf}@i#*u6~b=LM8Q2P zd(B2RPk`o`6af43a_Xc|m#tL*lT}57_`1XcFRxcK-4f^hPYb>Wn=5S9=26~9Ufn|E z12x%tO8j2|WI>6FaBjK?+0Q!+tLrP@&}$siW{lq<0`;^bHA%Zzu(1g}@VyrU_Y>MX z`GHLOM6AF_1s=7_R?>#=mp0%wbTF%|ut*f%xEg^O-^TV$iNFDB6R^h^ zV-jtVL`p>Cd{2Gj%BAjED7wx z7ddV?L?c9t!>)oCDqzxQkvcph6^h;oP)qFuL+W6(zt`Z;iQ*imRmHnLWzQ(2{wPIN z`(vYL&k;ihr%3y+5d(1A*)U7O*PIR+jk3W#1bK?p<91`m;dW8^0VB^Xwgu-w<__{f z_`kK5YUNV9ccQUlz`s7-0DuSjo-_*M?Nwk7M|Q}v%^pbPWhIT=NW0qmT3+C3Nu;}U zTO2HD9dX0rH+BHGs4Rd78Kz=G6B>UwTX2#4`w0)bDO&8E#KgTPql^S`#$8XA!0QE_ z)s%fkY-*u)mSP&KXW!*1j$$8%83$FQB9B|qqff+Vx(c^4gzyr6^b!aoGB#;?tgGaf zAGGVaV8}|!3UWO86f*Jdg;=h#wXRSgg7cHEA`(?*k?S+NG0ZGc=N|t(L9%?6cYPJM zLLl_plYh=6l)lU&o%1R^_st3-yoq1^){7}0utS8Xr>5Ul5}mzU*8}Fs8+e=49(LZd z5XWck8y$WSTsCqK{BP@2janBBomfSe1^}S{uXWtLT$~dPJx+}CXajh}m=l*YrHxcg z9gX-z|3qCnFACihz-3q}P%iju*J4@^*nD5U8XmjuAm0`ZGjDSGAf4RsipaH2qa^Q? zPRS796<=f4rikV@Si;HZJAsT5gIovbxt1hCFFDLGJ6_anOyM2n{*wm?e`rv&c$1@x zg}DFy;!Nvs&PHD-2Iod#nmE>}*I5;Z+_0#)d|Y5_ms+a(teq5~Ao*oKVa+!mJVAfu zK0?3wH#)$|2*2Ij&=lr1k?j%;;#NiQ`NS!E}EefKK|-$r#M? G*Xlp`qo-Q{ literal 3699 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 SQ2s6;zv$mDW`DZhtA7A!4#s={ diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.kmx b/windows/src/test/manual-tests/platform-rules/platformtest.kmx index b9c9de160ea59a315d221139358cbc3ed1d504b1..6d1ff7e97aad5f5abe830504a25757aa4a00a6ec 100644 GIT binary patch literal 5260 zcmeI0Uuc(A7{{MgTCG)PmS)S|*|KSBb6MFkG0o+sY{ShzITJUxr8c**O;Zt(5fUOI zUPz1);e{x8v5V+Jb`c>W5nhBuL`1|cBqY4(O2YMdp7%Z5^E>{2yXm$wp5OcZexGyB zbN;>Oyk{G>H8)AI$fdfv6GAG|AJV%RvaH5Nri+Y|fD`G|tQ0E_b-f;Z+XTJG{f; zJq{mq_?W|=IegaPVTUg}e8u5w4*%%zn8SA+E}k~o$GHyAcev8wl@70Wc)P><96sXk zpu=Yz9(MS$!&e->=I~92e|7i|hwnIi*WqH;URVQj94>db(&04@Z*zE$!-pI`?(k`F zwyb3cyjJ?8Lt15k-*!plQ`rmN1KNOcSoY)VhP@9vh;>Pi^z!UOQ{E^2l<2WM%VdQt zl}fBimdi530+*b+1drxXUF$x~vypnW4V~1~N6cnw?uTpMH0LGaHA$^(I)-57&t8_1OU4WGka5@}AVgeD51fPkXO;8@VpTE0Aqz>DJg*IxTQMjfHJbimEKA!6OJ0H_B zjnTEOZ&L7tvih9CIFw>ORlut;zoy5>XG=l^ zh9}SN5xfkBMd6Slcm5Wr&!-zi`aNpFZTP)ND<d%ENbpP9DGli&+p2?GZT-tSyy$THv1J%Hrc|&ck1N3)CWI`CDDE#;yg`W zouhR352~KI8l5FwFuMADDrZ6$>!iB00=_=dn&G=5tqXoE(oVvMBJBeFYfM*02XR7s z^_w?|POae6Z{Wn&mkVVaZK8Ieu zP@qm^ml9sqDz|^CYZbgP(ssZ*BdrfU7-^^B!&u=RMZZc5??@Rbdq>aLFMA|R#u}HfEzZ+@O*~VsJK1KpxjWxQsYvA>fwjJIT zX@}tFuuZP)7x0lt8-?G-nq9uX;P)b}nC&mYe7?o-o!Dkqb{D)i(vHGUMA}*Sci4xn z>{a*=k@hqER;2w6*UOGCTLPaKX^Y_1kyZn5jBO!&&qy<-IL z+veTN+%7ON>?Ts5BmB1)u!y}Om$Ltyc@V#ojMt2Vip2g;AksAK;wK7C4 zG@374`9h<)z`XHjzG7;)$%K|vn3``S7n-N=NTzLU=Bp{(F+-g%QF1*al6&6_-g3Mx z%uMZ+J&*6bOYF`S>Ub+_TfSUVjb|BeU)6tAR?FI)TXpbNns4329XsgD wOs`@6=ledXGH(+-nY@38lCPVu!QIA#XSsP=WR2ab^?wZM|3>bAC)1VmFFt{wF8}}l literal 5184 zcmeI0Uuf1<7{{NP+FG`3Ev;qt+geM_t!Znege=`g)3FUVn>iDw?@ViMFZLyQ@_e0=M651K9EJ-vD5G+anh4g5H$~m_*@vRF96%Wa4a2pLDSU(IDY({1 zb*=qDhsR<4F4w3iPPs@QyEtk12yY(XjXoDWO-yZ*#u~sgLQZY1M(*Q1ji5~Hr%{hO zrakzfLx=EdO|@MbZJ06+VMFMG7WZH;c;R-YgZ`;@rFB!v03*^a-O@=J??@ZWw!Yoz zaqAWD=B-v~;k{iBFC6v%-u-XAoAezp2(mY`@OSYnfU9Xb2mcg1fw6_mrPYNZGpg}i zGN+2vuvZmfB^XQmT)G3Fz^-Gqoc(NKZ)1%ZpZ#1q`#5tDJC51+E0&2oL|e+!*HJU2 z;hOgFwDsBhM6By?1*UmsXP3CWvscATO4F8cOnq@YMcRT<_YLbeqqAGTCGYWh_4xyN zZ(=r0!KX1ht7m6dN<;*0>-_b@d$k~q!luF7`D>s)n@%tir!kw(!>#QT4RA)Qmc}v_b}|R0qqX z2);4Uw!qs0Z4dk~rZc0D{Jy>=;3(L)yzgn}%kE-c*YiT;zDv8Od9R*)qhN>gK0OIX zIs2XW=($+?EuP!?zdZHXbdC1h4B9ybzwg>vp6B~7kY_0%lJdkgpg^AE4Xuez*Q5~) zrn1!Yp|oKUJ9+L2Cf=caE6WnfL^f%XlK#+7&!qeC#b!-a*K&ASpjE-^18pn314~{} zo~N|r6=jw4hAYYoPR%`0`F83FH2;e7BAzD9r3Tu>XS4#dS_Ql=&>G;|1MNL{D$vsK z&jRgh_-|NCCae&53O*fZGw>olVEf(*cx9l~!aJ~bQ{GN^D$vsK6M=RTem2l9!Y>Ef z_wXBmHVJ=#b(pw+!58rnTdf!#1=@P}c5J7~+X_zwS{i;H>oV_MfL{r;3HW57-G-O2 zXzVh1OW~D)Rtw)8XwC33?0u7W9R7KreFHxiXy3xW3$$zSUjprS_;jGnzzbQ>Y}``# z7A)dCoqMnF^ZN~I8F9|ezXR7h?-AxlC&=e{)2Z1rc-Hfl^R&8H@omKC+2lMuuB3>5 z)p+(q6v-Oa?p{{gKI)@&RiwXqYm4tFx`W2IsI~F| - - - False - True - + id_c1593d698cb624690005787147089dab @@ -14,6 +10,7 @@ .kmn
PlatformTest + © SIL Global
@@ -28,8 +25,8 @@ id_61f04814d427ce02953436f3ea7d7a65 - PlatformTest.kmx - PlatformTest.kmx + platformtest.kmx + platformtest.kmx .kmx id_18e336f9ad890bf821ff56e1a7764478 diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.kps b/windows/src/test/manual-tests/platform-rules/platformtest.kps index 825b0d5607..2418fadd7c 100644 --- a/windows/src/test/manual-tests/platform-rules/platformtest.kps +++ b/windows/src/test/manual-tests/platform-rules/platformtest.kps @@ -20,8 +20,8 @@ - PlatformTest.kmx - Keyboard PlatformTest + platformtest.kmx + Keyboard Platformtest 0 .kmx From 5f021e3884d0a59f29a69bc2bf26c23a5afcd0d5 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Fri, 24 Oct 2025 14:10:57 +0700 Subject: [PATCH 12/83] chore(windows): Beautify platformtest.js --- .../platform-rules/platformtest.js | 500 +++++++++++++++++- 1 file changed, 499 insertions(+), 1 deletion(-) diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.js b/windows/src/test/manual-tests/platform-rules/platformtest.js index f7d08ad396..341447c7a8 100644 --- a/windows/src/test/manual-tests/platform-rules/platformtest.js +++ b/windows/src/test/manual-tests/platform-rules/platformtest.js @@ -1 +1,499 @@ -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_platformtest());}function Keyboard_platformtest(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_platformtest";this.KN="PlatformTest";this.KMINVER="10.0";this.KV=null;this.KDU=0;this.KH='';this.KM=0;this.KBVER="1.0";this.KMBM=0x0;this.s20="touch";this.s21="hardware";this.s24="windows";this.s25="android";this.s26="ios";this.s27="macosx";this.s28="linux";this.s31="desktop";this.s32="tablet";this.s33="phone";this.s36="native";this.s37="web";this.s40="ie";this.s41="chrome";this.s42="edge";this.s43="firefox";this.s44="safari";this.s45="opera";this.s48="touch";this.s49="hardware";this.s52="platform-x";this.s55="WinDOWS";this.s56="ANDroid";this.s57="iOS";this.s58="macOSX";this.s59="LINUX";this.s61="touch";this.s62="hardware";this.s63="windows";this.s64="android";this.s65="ios";this.s66="macosx";this.s67="linux";this.s68="desktop";this.s69="tablet";this.s70="phone";this.s71="native";this.s72="web";this.s73="ie";this.s74="chrome";this.s75="edge";this.s76="firefox";this.s77="safari";this.s78="opera";this.s79="touch";this.s80="hardware";this.s81="platform-x";this.s82="WinDOWS";this.s83="ANDroid";this.s84="iOS";this.s85="macOSX";this.s86="LINUX";this.KVER="18.0.241.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,65)) {if(1){r=m=1;k.KDC(0,t);r=this.g1(t,e);m=2;}}if(!m&&k.KIK(e)) {r=1;k.KDC(-1,t);r=this.g9(t,e);m=2;}return r;};this.g1=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s20,t)){m=1;k.KDC(0,t);k.KO(-1,t,"touch");}else if(k.KIFS(31,this.s21,t)){m=1;k.KDC(0,t);k.KO(-1,t,"hardware");}if(m==1) {k.KDC(-1,t);r=this.g2(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t,"undefined");r=this.g2(t,e);m=2;}return r;};this.g2=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s24,t)){m=1;k.KDC(0,t);k.KO(-1,t," windows");}else if(k.KIFS(31,this.s25,t)){m=1;k.KDC(0,t);k.KO(-1,t," android");}else if(k.KIFS(31,this.s26,t)){m=1;k.KDC(0,t);k.KO(-1,t," ios");}else if(k.KIFS(31,this.s27,t)){m=1;k.KDC(0,t);k.KO(-1,t," macosx");}else if(k.KIFS(31,this.s28,t)){m=1;k.KDC(0,t);k.KO(-1,t," linux");}if(m==1) {k.KDC(-1,t);r=this.g3(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g3(t,e);m=2;}return r;};this.g3=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s31,t)){m=1;k.KDC(0,t);k.KO(-1,t," desktop");}else if(k.KIFS(31,this.s32,t)){m=1;k.KDC(0,t);k.KO(-1,t," tablet");}else if(k.KIFS(31,this.s33,t)){m=1;k.KDC(0,t);k.KO(-1,t," phone");}if(m==1) {k.KDC(-1,t);r=this.g4(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g4(t,e);m=2;}return r;};this.g4=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s36,t)){m=1;k.KDC(0,t);k.KO(-1,t," native");}else if(k.KIFS(31,this.s37,t)){m=1;k.KDC(0,t);k.KO(-1,t," web");}if(m==1) {k.KDC(-1,t);r=this.g5(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g5(t,e);m=2;}return r;};this.g5=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s40,t)){m=1;k.KDC(0,t);k.KO(-1,t," ie");}else if(k.KIFS(31,this.s41,t)){m=1;k.KDC(0,t);k.KO(-1,t," chrome");}else if(k.KIFS(31,this.s42,t)){m=1;k.KDC(0,t);k.KO(-1,t," edge");}else if(k.KIFS(31,this.s43,t)){m=1;k.KDC(0,t);k.KO(-1,t," firefox");}else if(k.KIFS(31,this.s44,t)){m=1;k.KDC(0,t);k.KO(-1,t," safari");}else if(k.KIFS(31,this.s45,t)){m=1;k.KDC(0,t);k.KO(-1,t," opera");}if(m==1) {k.KDC(-1,t);r=this.g6(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g6(t,e);m=2;}return r;};this.g6=function(t,e) {var k=KeymanWeb,r=1,m=0;if(!k.KIFS(31,this.s48,t)){m=1;k.KDC(0,t);k.KO(-1,t," !touch");}else if(!k.KIFS(31,this.s49,t)){m=1;k.KDC(0,t);k.KO(-1,t," !hardware");}if(m==1) {k.KDC(-1,t);r=this.g7(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g7(t,e);m=2;}return r;};this.g7=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s52,t)){m=1;k.KDC(0,t);k.KO(-1,t," platform-x");}if(m==1) {k.KDC(-1,t);r=this.g8(t,e);m=2;}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");r=this.g8(t,e);m=2;}return r;};this.g8=function(t,e) {var k=KeymanWeb,r=1,m=0;if(k.KIFS(31,this.s55,t)){m=1;k.KDC(0,t);k.KO(-1,t," windows");}else if(k.KIFS(31,this.s56,t)){m=1;k.KDC(0,t);k.KO(-1,t," android");}else if(k.KIFS(31,this.s57,t)){m=1;k.KDC(0,t);k.KO(-1,t," ios");}else if(k.KIFS(31,this.s58,t)){m=1;k.KDC(0,t);k.KO(-1,t," macosx");}else if(k.KIFS(31,this.s59,t)){m=1;k.KDC(0,t);k.KO(-1,t," linux");}if(!m) {k.KDC(-1,t);k.KO(-1,t," undefined");}return r;};this.g9=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,69)) {if(k.KIFS(31,this.s82,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Windows");}else if(k.KIFS(31,this.s83,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Android");}else if(k.KIFS(31,this.s84,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," iOS");}else if(k.KIFS(31,this.s85,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," macOS");}else if(k.KIFS(31,this.s86,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Linux");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [OS Undefined (case insensitive test)]");}}else if(k.KKM(e,16384,73)) {if(k.KIFS(31,this.s68,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Desktop");}else if(k.KIFS(31,this.s69,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Tablet");}else if(k.KIFS(31,this.s70,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Phone");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [FF Undefined]");}}else if(k.KKM(e,16384,79)) {if(k.KIFS(31,this.s63,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Windows");}else if(k.KIFS(31,this.s64,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Android");}else if(k.KIFS(31,this.s65,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," iOS");}else if(k.KIFS(31,this.s66,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," OSX");}else if(k.KIFS(31,this.s67,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Linux");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [OS Undefined]");}}else if(k.KKM(e,16384,80)) {if(k.KIFS(31,this.s61,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"Touch");}else if(k.KIFS(31,this.s62,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"Hardware");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"[UI Undefined]");}}else if(k.KKM(e,16384,82)) {if(k.KIFS(31,this.s81,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Platform-X");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [Platform-X Undefined]");}}else if(k.KKM(e,16384,84)) {if(!k.KIFS(31,this.s79,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," !Touch");}else if(!k.KIFS(31,this.s80,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," !Hardware");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [Inverted OS Undefined]");}}else if(k.KKM(e,16384,85)) {if(k.KIFS(31,this.s71,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Native");}else if(k.KIFS(31,this.s72,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Web");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [Nativeness Undefined]");}}else if(k.KKM(e,16384,89)) {if(k.KIFS(31,this.s73,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," IE");}else if(k.KIFS(31,this.s74,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Chrome");}else if(k.KIFS(31,this.s75,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Edge");}else if(k.KIFS(31,this.s76,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Firefox");}else if(k.KIFS(31,this.s77,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Safari");}else if(k.KIFS(31,this.s78,t)){r=m=1;k.KDC(0,t);k.KO(-1,t," Opera");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," [Browser Undefined]");}}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_platformtest()); +} + +function Keyboard_platformtest() { + this._v = (typeof keyman != "undefined" && typeof keyman.version == "string") ? parseInt(keyman.version, 10) : 9; + this.KI = "Keyboard_platformtest"; + this.KN = "PlatformTest"; + this.KMINVER = "10.0"; + this.KV = null; + this.KDU = 0; + this.KH = ''; + this.KM = 0; + this.KBVER = "1.0"; + this.KMBM = 0x0; + this.s20 = "touch"; + this.s21 = "hardware"; + this.s24 = "windows"; + this.s25 = "android"; + this.s26 = "ios"; + this.s27 = "macosx"; + this.s28 = "linux"; + this.s31 = "desktop"; + this.s32 = "tablet"; + this.s33 = "phone"; + this.s36 = "native"; + this.s37 = "web"; + this.s40 = "ie"; + this.s41 = "chrome"; + this.s42 = "edge"; + this.s43 = "firefox"; + this.s44 = "safari"; + this.s45 = "opera"; + this.s48 = "touch"; + this.s49 = "hardware"; + this.s52 = "platform-x"; + this.s55 = "WinDOWS"; + this.s56 = "ANDroid"; + this.s57 = "iOS"; + this.s58 = "macOSX"; + this.s59 = "LINUX"; + this.s61 = "touch"; + this.s62 = "hardware"; + this.s63 = "windows"; + this.s64 = "android"; + this.s65 = "ios"; + this.s66 = "macosx"; + this.s67 = "linux"; + this.s68 = "desktop"; + this.s69 = "tablet"; + this.s70 = "phone"; + this.s71 = "native"; + this.s72 = "web"; + this.s73 = "ie"; + this.s74 = "chrome"; + this.s75 = "edge"; + this.s76 = "firefox"; + this.s77 = "safari"; + this.s78 = "opera"; + this.s79 = "touch"; + this.s80 = "hardware"; + this.s81 = "platform-x"; + this.s82 = "WinDOWS"; + this.s83 = "ANDroid"; + this.s84 = "iOS"; + this.s85 = "macOSX"; + this.s86 = "LINUX"; + this.KVER = "18.0.241.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, 65)) { + if (1) { + r = m = 1; + k.KDC(0, t); + r = this.g1(t, e); + m = 2; + } + } + if (!m && k.KIK(e)) { + r = 1; + k.KDC(-1, t); + r = this.g9(t, e); + m = 2; + } + return r; + }; + this.g1 = function(t, e) { + var k = KeymanWeb, + r = 1, + m = 0; + if (k.KIFS(31, this.s20, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, "touch"); + } else if (k.KIFS(31, this.s21, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, "hardware"); + } + if (m == 1) { + k.KDC(-1, t); + r = this.g2(t, e); + m = 2; + } + if (!m) { + k.KDC(-1, t); + k.KO(-1, t, "undefined"); + r = this.g2(t, e); + m = 2; + } + return r; + }; + this.g2 = function(t, e) { + var k = KeymanWeb, + r = 1, + m = 0; + if (k.KIFS(31, this.s24, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " windows"); + } else if (k.KIFS(31, this.s25, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " android"); + } else if (k.KIFS(31, this.s26, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " ios"); + } else if (k.KIFS(31, this.s27, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " macosx"); + } else if (k.KIFS(31, this.s28, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " linux"); + } + if (m == 1) { + k.KDC(-1, t); + r = this.g3(t, e); + m = 2; + } + if (!m) { + k.KDC(-1, t); + k.KO(-1, t, " undefined"); + r = this.g3(t, e); + m = 2; + } + return r; + }; + this.g3 = function(t, e) { + var k = KeymanWeb, + r = 1, + m = 0; + if (k.KIFS(31, this.s31, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " desktop"); + } else if (k.KIFS(31, this.s32, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " tablet"); + } else if (k.KIFS(31, this.s33, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " phone"); + } + if (m == 1) { + k.KDC(-1, t); + r = this.g4(t, e); + m = 2; + } + if (!m) { + k.KDC(-1, t); + k.KO(-1, t, " undefined"); + r = this.g4(t, e); + m = 2; + } + return r; + }; + this.g4 = function(t, e) { + var k = KeymanWeb, + r = 1, + m = 0; + if (k.KIFS(31, this.s36, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " native"); + } else if (k.KIFS(31, this.s37, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " web"); + } + if (m == 1) { + k.KDC(-1, t); + r = this.g5(t, e); + m = 2; + } + if (!m) { + k.KDC(-1, t); + k.KO(-1, t, " undefined"); + r = this.g5(t, e); + m = 2; + } + return r; + }; + this.g5 = function(t, e) { + var k = KeymanWeb, + r = 1, + m = 0; + if (k.KIFS(31, this.s40, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " ie"); + } else if (k.KIFS(31, this.s41, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " chrome"); + } else if (k.KIFS(31, this.s42, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " edge"); + } else if (k.KIFS(31, this.s43, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " firefox"); + } else if (k.KIFS(31, this.s44, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " safari"); + } else if (k.KIFS(31, this.s45, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " opera"); + } + if (m == 1) { + k.KDC(-1, t); + r = this.g6(t, e); + m = 2; + } + if (!m) { + k.KDC(-1, t); + k.KO(-1, t, " undefined"); + r = this.g6(t, e); + m = 2; + } + return r; + }; + this.g6 = function(t, e) { + var k = KeymanWeb, + r = 1, + m = 0; + if (!k.KIFS(31, this.s48, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " !touch"); + } else if (!k.KIFS(31, this.s49, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " !hardware"); + } + if (m == 1) { + k.KDC(-1, t); + r = this.g7(t, e); + m = 2; + } + if (!m) { + k.KDC(-1, t); + k.KO(-1, t, " undefined"); + r = this.g7(t, e); + m = 2; + } + return r; + }; + this.g7 = function(t, e) { + var k = KeymanWeb, + r = 1, + m = 0; + if (k.KIFS(31, this.s52, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " platform-x"); + } + if (m == 1) { + k.KDC(-1, t); + r = this.g8(t, e); + m = 2; + } + if (!m) { + k.KDC(-1, t); + k.KO(-1, t, " undefined"); + r = this.g8(t, e); + m = 2; + } + return r; + }; + this.g8 = function(t, e) { + var k = KeymanWeb, + r = 1, + m = 0; + if (k.KIFS(31, this.s55, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " windows"); + } else if (k.KIFS(31, this.s56, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " android"); + } else if (k.KIFS(31, this.s57, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " ios"); + } else if (k.KIFS(31, this.s58, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " macosx"); + } else if (k.KIFS(31, this.s59, t)) { + m = 1; + k.KDC(0, t); + k.KO(-1, t, " linux"); + } + if (!m) { + k.KDC(-1, t); + k.KO(-1, t, " undefined"); + } + return r; + }; + this.g9 = function(t, e) { + var k = KeymanWeb, + r = 0, + m = 0; + if (k.KKM(e, 16384, 69)) { + if (k.KIFS(31, this.s82, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Windows"); + } else if (k.KIFS(31, this.s83, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Android"); + } else if (k.KIFS(31, this.s84, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " iOS"); + } else if (k.KIFS(31, this.s85, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " macOS"); + } else if (k.KIFS(31, this.s86, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Linux"); + } else if (1) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " [OS Undefined (case insensitive test)]"); + } + } else if (k.KKM(e, 16384, 73)) { + if (k.KIFS(31, this.s68, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Desktop"); + } else if (k.KIFS(31, this.s69, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Tablet"); + } else if (k.KIFS(31, this.s70, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Phone"); + } else if (1) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " [FF Undefined]"); + } + } else if (k.KKM(e, 16384, 79)) { + if (k.KIFS(31, this.s63, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Windows"); + } else if (k.KIFS(31, this.s64, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Android"); + } else if (k.KIFS(31, this.s65, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " iOS"); + } else if (k.KIFS(31, this.s66, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " OSX"); + } else if (k.KIFS(31, this.s67, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Linux"); + } else if (1) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " [OS Undefined]"); + } + } else if (k.KKM(e, 16384, 80)) { + if (k.KIFS(31, this.s61, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, "Touch"); + } else if (k.KIFS(31, this.s62, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, "Hardware"); + } else if (1) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, "[UI Undefined]"); + } + } else if (k.KKM(e, 16384, 82)) { + if (k.KIFS(31, this.s81, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Platform-X"); + } else if (1) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " [Platform-X Undefined]"); + } + } else if (k.KKM(e, 16384, 84)) { + if (!k.KIFS(31, this.s79, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " !Touch"); + } else if (!k.KIFS(31, this.s80, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " !Hardware"); + } else if (1) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " [Inverted OS Undefined]"); + } + } else if (k.KKM(e, 16384, 85)) { + if (k.KIFS(31, this.s71, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Native"); + } else if (k.KIFS(31, this.s72, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Web"); + } else if (1) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " [Nativeness Undefined]"); + } + } else if (k.KKM(e, 16384, 89)) { + if (k.KIFS(31, this.s73, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " IE"); + } else if (k.KIFS(31, this.s74, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Chrome"); + } else if (k.KIFS(31, this.s75, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Edge"); + } else if (k.KIFS(31, this.s76, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Firefox"); + } else if (k.KIFS(31, this.s77, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Safari"); + } else if (k.KIFS(31, this.s78, t)) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " Opera"); + } else if (1) { + r = m = 1; + k.KDC(0, t); + k.KO(-1, t, " [Browser Undefined]"); + } + } + return r; + }; +} From a51f4ff9659daf55ed2b0ead34f80668c4f57f5f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 24 Oct 2025 11:00:07 +0200 Subject: [PATCH 13/83] fix(mac): ignore non-Unicode key caps when preparing OSK The typeFlags property is used to differentiate Unicode and non-Unicode keys in the array of keys in a .kvk file. All non-Unicode keys should be ignored, as we do not support non-Unicode keyboards on macOS. The reason this fixes #15007, is that the keyboard in question had both ANSI and Unicode sections in its .kvk file, and the ANSI section was stored after the Unicode section, so the font spec for ANSI was overriding the previously (correctly) set Unicode font spec. Fixes: #15007 --- .../KME/OnScreenKeyboard/OSKView.m | 93 ++++++++++--------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKView.m b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKView.m index e98fe60663..e576d000b8 100644 --- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKView.m +++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKView.m @@ -64,7 +64,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; // Custom initialization [self initOSKKeys]; } - + return self; } @@ -76,26 +76,26 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; - (void)drawRect:(NSRect)rect { os_log_debug([KMELogs oskLog], "OSKView drawRect: %{public}@", NSStringFromRect(rect)); - + CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] CGContext]; CGContextSetLineJoin(context, kCGLineJoinRound); CGContextSetLineWidth(context, 1.0); CGColorRef cgClearColor = CGColorGetConstantColor(kCGColorClear); CGContextSetStrokeColorWithColor(context, cgClearColor); CGContextSetFillColorWithColor(context, cgClearColor); - + CGContextBeginPath(context); CGContextAddRect(context, CGRectMake(1.0, 1.0, rect.size.width-1.0, rect.size.height-1.0)); CGContextDrawPath(context, kCGPathStroke); - + CGContextBeginPath(context); CGContextAddRect(context, CGRectMake(1.0, 1.0, rect.size.width-1.0, rect.size.height-1.0)); CGContextClip(context); - + //TODO: gradient from clear to clear -- what does this do? NSColor *bgColor = [NSColor clearColor]; //[NSColor colorWithWhite:0.7 alpha:1.0]; NSColor *bgColor2 = [NSColor clearColor]; //[NSColor colorWithWhite:0.5 alpha:1.0]; - + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); NSArray *gradientColors = [NSArray arrayWithObjects:(id)bgColor.CGColor, bgColor2.CGColor, nil]; CGFloat gradientLocations[] = {0, 1}; @@ -135,11 +135,11 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; - (void)setKvk:(KVKFile *)kvk { os_log_debug([KMELogs oskLog], "OSKView setKvk, forces keyboard to re-layout"); _kvk = kvk; - + // Force the keyboard to re-layout _oskLayout = nil; _oskDefaultNKeys = nil; - + [self updateKeyLabelsForCurrentLayer]; } @@ -173,7 +173,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; } py += keyHeight; } - + [self updateKeyLabelsForCurrentLayer]; } @@ -195,7 +195,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; [[OSKKey alloc] initWithKeyCode:MVK_MINUS caption:@"-" scale:1.0], [[OSKKey alloc] initWithKeyCode:MVK_EQUAL caption:@"=" scale:1.0], [[OSKKey alloc] initWithKeyCode:MVK_BACKSPACE caption:@"⬅︎" scale:1.5], nil]; - + NSArray *row2 = [NSArray arrayWithObjects: [[OSKKey alloc] initWithKeyCode:MVK_TAB caption:@"↹" scale:1.5], [[OSKKey alloc] initWithKeyCode:MVK_Q caption:@"Q" scale:1.0], @@ -211,7 +211,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; [[OSKKey alloc] initWithKeyCode:MVK_LEFT_BRACKET caption:@"[" scale:1.0], [[OSKKey alloc] initWithKeyCode:MVK_RIGHT_BRACKET caption:@"]" scale:1.0], [[OSKKey alloc] initWithKeyCode:MVK_BACKSLASH caption:@"\\" scale:1.0], nil]; - + NSArray *row3 = [NSArray arrayWithObjects: [[OSKKey alloc] initWithKeyCode:MVK_CAPS_LOCK caption:@"Caps Lock" scale:1.75], [[OSKKey alloc] initWithKeyCode:MVK_A caption:@"A" scale:1.0], @@ -226,14 +226,14 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; [[OSKKey alloc] initWithKeyCode:MVK_SEMICOLON caption:@";" scale:1.0], [[OSKKey alloc] initWithKeyCode:MVK_QUOTE caption:@"'" scale:1.0], [[OSKKey alloc] initWithKeyCode:MVK_ENTER caption:@"↵" scale:1.75], nil]; - + NSArray *row4a = [self use102ndKey] ? [NSArray arrayWithObjects: [[OSKKey alloc] initWithKeyCode:MVK_LEFT_SHIFT caption:@"⇧" scale:1.25], [[OSKKey alloc] initWithKeyCode:MVK_OEM102 caption:@"\\" scale:1.0], nil] : [NSArray arrayWithObjects: [[OSKKey alloc] initWithKeyCode:MVK_LEFT_SHIFT caption:@"⇧" scale:2.25], nil]; - + NSArray *row4b = [NSArray arrayWithObjects: [[OSKKey alloc] initWithKeyCode:MVK_Z caption:@"Z" scale:1.0], [[OSKKey alloc] initWithKeyCode:MVK_X caption:@"X" scale:1.0], @@ -246,19 +246,19 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; [[OSKKey alloc] initWithKeyCode:MVK_PERIOD caption:@"." scale:1.0], [[OSKKey alloc] initWithKeyCode:MVK_SLASH caption:@"/" scale:1.0], [[OSKKey alloc] initWithKeyCode:MVK_RIGHT_SHIFT caption:@"⇧" scale:2.25], nil]; - + NSArray *row4 = [row4a arrayByAddingObjectsFromArray:row4b]; - + NSArray *row5 = [NSArray arrayWithObjects: [[OSKKey alloc] initWithKeyCode:MVK_LEFT_CTRL caption:@"Ctrl" scale:1.75], [[OSKKey alloc] initWithKeyCode:MVK_LEFT_ALT caption:@"Alt" scale:1.5], [[OSKKey alloc] initWithKeyCode:MVK_SPACE caption:@"" scale:8.0], [[OSKKey alloc] initWithKeyCode:MVK_RIGHT_ALT caption:@"Alt" scale:1.5], [[OSKKey alloc] initWithKeyCode:MVK_RIGHT_CTRL caption:@"Ctrl" scale:1.75], nil]; - + _oskLayout = [NSArray arrayWithObjects:row1, row2, row3, row4, row5, nil]; } - + return _oskLayout; } @@ -266,7 +266,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; if (_oskDefaultNKeys == nil) { os_log_debug([KMELogs oskLog], "oskDefaultNKeys -> creating new arrays of default number OSKKey objects"); NSMutableArray *defNKeys = [[NSMutableArray alloc] initWithCapacity:0]; - + // row 1 NKey *nkey1 = [[NKey alloc] init]; nkey1.typeFlags = 2; nkey1.modifierFlags = 0; nkey1.keyCode = VK_GRAVE; nkey1.text = @"`"; nkey1.bitmap = nil; NKey *nkey2 = [[NKey alloc] init]; nkey2.typeFlags = 2; nkey2.modifierFlags = 1; nkey2.keyCode = VK_GRAVE; nkey2.text = @"~"; nkey2.bitmap = nil; @@ -307,7 +307,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; nkey1 = [[NKey alloc] init]; nkey1.typeFlags = 2; nkey1.modifierFlags = 0; nkey1.keyCode = VK_EQUAL; nkey1.text = @"="; nkey1.bitmap = nil; nkey2 = [[NKey alloc] init]; nkey2.typeFlags = 2; nkey2.modifierFlags = 1; nkey2.keyCode = VK_EQUAL; nkey2.text = @"+"; nkey2.bitmap = nil; [defNKeys addObjectsFromArray:@[nkey1, nkey2]]; - + // row 2 nkey1 = [[NKey alloc] init]; nkey1.typeFlags = 2; nkey1.modifierFlags = 0; nkey1.keyCode = VK_KEY_Q; nkey1.text = @"q"; nkey1.bitmap = nil; nkey2 = [[NKey alloc] init]; nkey2.typeFlags = 2; nkey2.modifierFlags = 1; nkey2.keyCode = VK_KEY_Q; nkey2.text = @"Q"; nkey2.bitmap = nil; @@ -348,7 +348,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; nkey1 = [[NKey alloc] init]; nkey1.typeFlags = 2; nkey1.modifierFlags = 0; nkey1.keyCode = VK_BACKSLASH; nkey1.text = @"\\"; nkey1.bitmap = nil; nkey2 = [[NKey alloc] init]; nkey2.typeFlags = 2; nkey2.modifierFlags = 1; nkey2.keyCode = VK_BACKSLASH; nkey2.text = @"|"; nkey2.bitmap = nil; [defNKeys addObjectsFromArray:@[nkey1, nkey2]]; - + // row 3 nkey1 = [[NKey alloc] init]; nkey1.typeFlags = 2; nkey1.modifierFlags = 0; nkey1.keyCode = VK_KEY_A; nkey1.text = @"a"; nkey1.bitmap = nil; nkey2 = [[NKey alloc] init]; nkey2.typeFlags = 2; nkey2.modifierFlags = 1; nkey2.keyCode = VK_KEY_A; nkey2.text = @"A"; nkey2.bitmap = nil; @@ -383,7 +383,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; nkey1 = [[NKey alloc] init]; nkey1.typeFlags = 2; nkey1.modifierFlags = 0; nkey1.keyCode = VK_QUOTE; nkey1.text = @"'"; nkey1.bitmap = nil; nkey2 = [[NKey alloc] init]; nkey2.typeFlags = 2; nkey2.modifierFlags = 1; nkey2.keyCode = VK_QUOTE; nkey2.text = @"\""; nkey2.bitmap = nil; [defNKeys addObjectsFromArray:@[nkey1, nkey2]]; - + if([self use102ndKey]) { nkey1 = [[NKey alloc] init]; nkey1.typeFlags = 2; nkey1.modifierFlags = 0; nkey1.keyCode = VK_OEM_102; nkey1.text = @"\\"; nkey1.bitmap = nil; nkey2 = [[NKey alloc] init]; nkey2.typeFlags = 2; nkey2.modifierFlags = 1; nkey2.keyCode = VK_OEM_102; nkey2.text = @"|"; nkey2.bitmap = nil; @@ -420,10 +420,10 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; nkey1 = [[NKey alloc] init]; nkey1.typeFlags = 2; nkey1.modifierFlags = 0; nkey1.keyCode = VK_SLASH; nkey1.text = @"/"; nkey1.bitmap = nil; nkey2 = [[NKey alloc] init]; nkey2.typeFlags = 2; nkey2.modifierFlags = 1; nkey2.keyCode = VK_SLASH; nkey2.text = @"?"; nkey2.bitmap = nil; [defNKeys addObjectsFromArray:@[nkey1, nkey2]]; - + _oskDefaultNKeys = [[NSArray alloc] initWithArray:defNKeys]; } - + return _oskDefaultNKeys; } @@ -471,7 +471,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; CGEventPostToPid(processId, keyUpEvent); CFRelease(keyDownEvent); CFRelease(keyUpEvent); - + CFRelease(source); } else { @@ -501,7 +501,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; BOOL shift = self.physicalShiftState | self.oskShiftState; BOOL option = self.physicalOptionState | self.oskOptionState; BOOL control = self.physicalControlState | self.oskControlState; - + return [self getEventModifierFlags:shift optionFlag:option controlFlag:control]; } @@ -510,7 +510,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; */ - (NSEventModifierFlags)getEventModifierFlags:(BOOL)shift optionFlag:(BOOL)option controlFlag:(BOOL)control { NSEventModifierFlags modifierFlags = 0; - + if (shift) { modifierFlags = modifierFlags | NSEventModifierFlagShift; } @@ -524,7 +524,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; if (control) { modifierFlags = modifierFlags | NSEventModifierFlagControl; } - + return modifierFlags; } @@ -551,7 +551,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; NSView *view = [self viewWithTag:event.keyCode|0x1000]; if (view == nil || ![view isKindOfClass:[KeyView class]]) return; - + KeyView *keyView = (KeyView *)view; if (event.type == NSEventTypeKeyDown) [keyView setKeyPressed:YES]; @@ -570,7 +570,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; BOOL shift = self.physicalShiftState | self.oskShiftState; BOOL option = self.physicalOptionState | self.oskOptionState; BOOL control = self.physicalControlState | self.oskControlState; - + return [self getKeymanModifierFlags:shift optionFlag:option controlFlag:control]; } @@ -592,7 +592,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; if (control) { flags |= KVKS_RCTRL; } - + return flags; } @@ -602,15 +602,15 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; */ - (void)updateKeyLabelsForCurrentLayer { os_log_debug([KMELogs oskLog], "OSKView updateKeyLabelsForState, phsyical modifiers [shift: %d, option: %d, control: %d]\nosk modifiers [shift: %d, option: %d, control: %d]", self.physicalShiftState, self.physicalOptionState, self.physicalControlState, self.oskShiftState, self.oskOptionState, self.oskControlState); - + [self resetKeyLabels]; NSMutableArray *mKeys = [[self keyTags] mutableCopy]; NSArray *nkeys = [self.kvk keys]; if (nkeys == nil) nkeys = self.oskDefaultNKeys; - + WORD keymanFlagsForCurrentLayer = [self getKeymanModifierFlagsForCurrentLayer]; - + NSString *ansiFont = [self ansiFont]; NSString *unicodeFont = [self unicodeFont]; unsigned short keyCode; @@ -622,9 +622,8 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; NSView *view = [self viewWithTag:keyCode|0x1000]; if (view == nil || ![view isKindOfClass:[KeyView class]]) continue; - + KeyView *keyView = (KeyView *)view; - [keyView setLabelFont:ansiFont]; if (nkey.typeFlags & KVKK_UNICODE) { [keyView setLabelText:nkey.text]; NSString* label = nkey.text; @@ -632,12 +631,16 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; os_log_debug([KMELogs keyLog], "setLabelText to %{public}@, utf8data %{public}@", label, data); [keyView setLabelFont:unicodeFont]; [mKeys removeObject:[NSNumber numberWithInteger:(keyCode|0x1000)]]; + } else { + // This means it is a key definition for a non-Unicode layout. + // We do not support non-Unicode keyboards in Keyman for macOS. + continue; } - + if (nkey.typeFlags & KVKK_BITMAP) { [keyView setBitmap:nkey.bitmap]; } - + [keyView setNeedsDisplay:YES]; } } @@ -647,7 +650,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; NSView *view = [self viewWithTag:[t integerValue]|0x1000]; if (view == nil || ![view isKindOfClass:[KeyView class]]) continue; - + KeyView *keyView = (KeyView *)view; [keyView setLabelText:@""]; }*/ @@ -659,10 +662,10 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; for (NSView *view in views) { if (![view isKindOfClass:[KeyView class]]) continue; - + [keyTags addObject:[NSNumber numberWithInteger:[view tag]]]; } - + return keyTags; } @@ -671,7 +674,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; for (NSView *view in views) { if (![view isKindOfClass:[KeyView class]]) continue; - + [(KeyView *)view setKey:[(KeyView *)view key]]; [(KeyView *)view setBitmap:nil]; [(KeyView *)view setNeedsDisplay:YES]; @@ -687,7 +690,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; * The state of the physical key overrides the modifier key clicked in the OSK. */ _oskShiftState = NO; - + os_log_debug([KMELogs oskLog], "hardware shift key released"); [self updateKeyLabelsForCurrentLayer]; [self updateShiftKeysForState]; @@ -705,7 +708,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; - (void)setPhysicalOptionState:(BOOL)state { if (_physicalOptionState != state) { _physicalOptionState = state; - + /** * When setting the physical option state, clear the OSK option state * The state of the physical key overrides the modifier key clicked in the OSK. @@ -727,7 +730,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; - (void)setPhysicalControlState:(BOOL)state { if (_physicalControlState != state) { _physicalControlState = state; - + /** * When setting the physical control state, clear the OSK control state * The state of the physical key overrides the modifier key clicked in the OSK. @@ -793,7 +796,7 @@ const int64_t OSK_EVENT_MODIFIER_MASK = 0x00000000FFFFFFFF; break; } } - + return keyCode; } From cbaae084f7ae7cbee9d9dc69b1c44d497ae41dd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20V=C3=B6lker?= Date: Fri, 24 Oct 2025 13:31:15 +0200 Subject: [PATCH 14/83] test(kmc-analyze): add warnings coverage tests for AnalyzeOskCharacterUse --- .../test/osk-character-use-warnings.tests.ts | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 developer/src/kmc-analyze/test/osk-character-use-warnings.tests.ts diff --git a/developer/src/kmc-analyze/test/osk-character-use-warnings.tests.ts b/developer/src/kmc-analyze/test/osk-character-use-warnings.tests.ts new file mode 100644 index 0000000000..e1cfdf35f0 --- /dev/null +++ b/developer/src/kmc-analyze/test/osk-character-use-warnings.tests.ts @@ -0,0 +1,52 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + */ +import * as fs from 'fs'; +import { assert } from 'chai'; +import 'mocha'; +import { AnalyzeOskCharacterUse } from '../src/osk-character-use/index.js'; +import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; +import { AnalyzerMessages } from '../src/analyzer-messages.js'; + +describe('AnalyzeOskCharacterUse warnings', function() { + const callbacks = new TestCompilerCallbacks(); + const TMP_NO_COUNTS = '/tmp/mock-map-no-counts.json'; + const TMP_WITH_COUNTS = '/tmp/mock-map-with-counts.json'; + + before(() => { + fs.writeFileSync(TMP_NO_COUNTS, JSON.stringify({ + map: [{ usages: ['U+1780', 'U+1781'] }] + })); + fs.writeFileSync(TMP_WITH_COUNTS, JSON.stringify({ + map: [{ usages: [{ char: 'U+1780', count: 2 }] }] + })); + }); + + beforeEach(() => callbacks.clear()); + + it('warns if previous map did not include counts but includeCounts=true', function() { + const a = new AnalyzeOskCharacterUse(callbacks, { + includeCounts: true + }); + + a.unitTestEndPoints.loadPreviousMap(TMP_NO_COUNTS); + + assert.isTrue( + callbacks.hasMessage(AnalyzerMessages.WARN_PreviousMapDidNotIncludeCounts), + 'Expected Warn_PreviousMapDidNotIncludeCounts warning' + ); + }); + + it('warns if previous map did include counts but includeCounts=false', function() { + const a = new AnalyzeOskCharacterUse(callbacks, { + includeCounts: false + }); + + a.unitTestEndPoints.loadPreviousMap(TMP_WITH_COUNTS); + + assert.isTrue( + callbacks.hasMessage(AnalyzerMessages.WARN_PreviousMapDidIncludeCounts), + 'Expected Warn_PreviousMapDidIncludeCounts warning' + ); + }); +}); From 55d6efe4822e0ee1e2eff42d37ee2c1fdea590b2 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 24 Oct 2025 14:45:17 +0200 Subject: [PATCH 15/83] fix(developer): prevent ANSI keyboards crashing debugger Note: #11909 has some additional future cleanup we could do, but these code paths are not currently accessible, so in the interest of moving forward, am leaving them for now. Fixes: #11909 Test-bot: skip --- core/src/kmx/kmx_processevent.cpp | 4 ++++ .../src/tike/debug/Keyman.System.Debug.DebugEvent.pas | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/core/src/kmx/kmx_processevent.cpp b/core/src/kmx/kmx_processevent.cpp index 921e8d9212..09ebcdd4cd 100644 --- a/core/src/kmx/kmx_processevent.cpp +++ b/core/src/kmx/kmx_processevent.cpp @@ -107,10 +107,14 @@ KMX_BOOL KMX_ProcessEvent::ProcessEvent( if (kbd->StartGroup[BEGIN_UNICODE] == (KMX_DWORD) -1) { DebugLog("Non-Unicode keyboards are not supported."); + DeleteInternalDebugItems(); + state->debug_items().push_end(m_actions.Length(), 0); m_core_state = nullptr; return FALSE; } + // TODO: what about debug_item state for all shortcut return paths below? + // TODO: this needs to be cleaned up; see #11909 switch (vkey) { case KM_CORE_VKEY_CAPS: if (KeyCapsLockPress(modifiers, isKeyDown)) diff --git a/developer/src/tike/debug/Keyman.System.Debug.DebugEvent.pas b/developer/src/tike/debug/Keyman.System.Debug.DebugEvent.pas index a5853faba0..426a556b56 100644 --- a/developer/src/tike/debug/Keyman.System.Debug.DebugEvent.pas +++ b/developer/src/tike/debug/Keyman.System.Debug.DebugEvent.pas @@ -342,8 +342,18 @@ var action_index: Integer; begin Result := True; + + if not Assigned(state) then + raise Exception.Create('TDebugEventList.AddStateItems: expected state not to be nil'); + debug := km_core_state_debug_items(state, nil); + if not Assigned(debug) then + raise Exception.Create('TDebugEventList.AddStateItems: expected debug not to be nil'); + action := km_core_state_action_items(state, nil); + if not Assigned(action) then + raise Exception.Create('TDebugEventList.AddStateItems: expected action not to be nil'); + action_index := 0; while debug._type <> KM_CORE_DEBUG_END do begin From fc87ef38aa8a9f1e383ba73bd769b30601d30639 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 24 Oct 2025 13:01:38 -0500 Subject: [PATCH 16/83] auto: increment master version to 19.0.146 Test-bot: skip Build-bot: skip --- HISTORY.md | 6 ++++++ VERSION.md | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index cc860acc0b..73ccc5f7d5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,11 @@ # Keyman Version History +## 19.0.145 alpha 2025-10-24 + +* fix(developer): do not treat backslash as a string escape in syntax highlighting (#15001) +* fix(developer): handle missing `begin Unicode` in KMW compiler (#15002) +* test(developer): add test to kmc-analyze for Warn_PreviousMapFileCouldNotBeLoaded (#14038) + ## 19.0.144 alpha 2025-10-23 * chore(deps-dev): bump playwright from 1.46.1 to 1.56.1 (#14984) diff --git a/VERSION.md b/VERSION.md index d4ef205909..f0ebf516cf 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.145 \ No newline at end of file +19.0.146 \ No newline at end of file From 07c13e81ac032b9d1257aad3f0d485747c1da691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20V=C3=B6lker?= Date: Sat, 25 Oct 2025 07:34:31 +0200 Subject: [PATCH 17/83] test(kmc-analyze): add message coverage tests for AnalyzeOskCharacterUse --- .../osk-character-use/mock-map-no-counts.json | 10 ++++ .../mock-map-with-counts.json | 12 ++++ .../test/osk-character-use-messages.tests.ts | 58 +++++++++++++++++++ .../test/osk-character-use-warnings.tests.ts | 52 ----------------- 4 files changed, 80 insertions(+), 52 deletions(-) create mode 100644 developer/src/kmc-analyze/test/fixtures/osk-character-use/mock-map-no-counts.json create mode 100644 developer/src/kmc-analyze/test/fixtures/osk-character-use/mock-map-with-counts.json create mode 100644 developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts delete mode 100644 developer/src/kmc-analyze/test/osk-character-use-warnings.tests.ts diff --git a/developer/src/kmc-analyze/test/fixtures/osk-character-use/mock-map-no-counts.json b/developer/src/kmc-analyze/test/fixtures/osk-character-use/mock-map-no-counts.json new file mode 100644 index 0000000000..713091194b --- /dev/null +++ b/developer/src/kmc-analyze/test/fixtures/osk-character-use/mock-map-no-counts.json @@ -0,0 +1,10 @@ +{ + "map": [ + { + "usages": [ + "U+1780", + "U+1781" + ] + } + ] +} \ No newline at end of file diff --git a/developer/src/kmc-analyze/test/fixtures/osk-character-use/mock-map-with-counts.json b/developer/src/kmc-analyze/test/fixtures/osk-character-use/mock-map-with-counts.json new file mode 100644 index 0000000000..bec0e8727b --- /dev/null +++ b/developer/src/kmc-analyze/test/fixtures/osk-character-use/mock-map-with-counts.json @@ -0,0 +1,12 @@ +{ + "map": [ + { + "usages": [ + { + "char": "U+1780", + "count": 2 + } + ] + } + ] +} \ No newline at end of file diff --git a/developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts b/developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts new file mode 100644 index 0000000000..c3c59a8260 --- /dev/null +++ b/developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts @@ -0,0 +1,58 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + */ +import { assert } from 'chai'; +import 'mocha'; +import { AnalyzeOskCharacterUse } from './osk-character-use/index.js'; +import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; +import { AnalyzerMessages } from './analyzer-messages.js'; +import { makePathToFixture } from './helpers/index.js'; + +describe('AnalyzeOskCharacterUse warnings', function() { + const callbacks = new TestCompilerCallbacks(); + + const MOCK_MAP_NO_COUNTS = makePathToFixture( + 'osk-character-use', + 'mock-map-no-counts.json' + ); + const MOCK_MAP_WITH_COUNTS = makePathToFixture( + 'osk-character-use', + 'mock-map-with-counts.json' + ); + + this.beforeEach(function() { + callbacks.clear(); + }); + + this.afterEach(function() { + if (this.currentTest?.isFailed()) { + callbacks.printMessages(); + } + }); + + it('warns if previous map did not include counts but includeCounts=true', function() { + const a = new AnalyzeOskCharacterUse(callbacks, { + includeCounts: true + }); + + a.unitTestEndPoints.loadPreviousMap(MOCK_MAP_NO_COUNTS); + + assert.isTrue( + callbacks.hasMessage(AnalyzerMessages.WARN_PreviousMapDidNotIncludeCounts), + 'Expected Warn_PreviousMapDidNotIncludeCounts warning' + ); + }); + + it('warns if previous map did include counts but includeCounts=false', function() { + const a = new AnalyzeOskCharacterUse(callbacks, { + includeCounts: false + }); + + a.unitTestEndPoints.loadPreviousMap(MOCK_MAP_WITH_COUNTS); + + assert.isTrue( + callbacks.hasMessage(AnalyzerMessages.WARN_PreviousMapDidIncludeCounts), + 'Expected Warn_PreviousMapDidIncludeCounts warning' + ); + }); +}); diff --git a/developer/src/kmc-analyze/test/osk-character-use-warnings.tests.ts b/developer/src/kmc-analyze/test/osk-character-use-warnings.tests.ts deleted file mode 100644 index e1cfdf35f0..0000000000 --- a/developer/src/kmc-analyze/test/osk-character-use-warnings.tests.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Keyman is copyright (C) SIL Global. MIT License. - */ -import * as fs from 'fs'; -import { assert } from 'chai'; -import 'mocha'; -import { AnalyzeOskCharacterUse } from '../src/osk-character-use/index.js'; -import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; -import { AnalyzerMessages } from '../src/analyzer-messages.js'; - -describe('AnalyzeOskCharacterUse warnings', function() { - const callbacks = new TestCompilerCallbacks(); - const TMP_NO_COUNTS = '/tmp/mock-map-no-counts.json'; - const TMP_WITH_COUNTS = '/tmp/mock-map-with-counts.json'; - - before(() => { - fs.writeFileSync(TMP_NO_COUNTS, JSON.stringify({ - map: [{ usages: ['U+1780', 'U+1781'] }] - })); - fs.writeFileSync(TMP_WITH_COUNTS, JSON.stringify({ - map: [{ usages: [{ char: 'U+1780', count: 2 }] }] - })); - }); - - beforeEach(() => callbacks.clear()); - - it('warns if previous map did not include counts but includeCounts=true', function() { - const a = new AnalyzeOskCharacterUse(callbacks, { - includeCounts: true - }); - - a.unitTestEndPoints.loadPreviousMap(TMP_NO_COUNTS); - - assert.isTrue( - callbacks.hasMessage(AnalyzerMessages.WARN_PreviousMapDidNotIncludeCounts), - 'Expected Warn_PreviousMapDidNotIncludeCounts warning' - ); - }); - - it('warns if previous map did include counts but includeCounts=false', function() { - const a = new AnalyzeOskCharacterUse(callbacks, { - includeCounts: false - }); - - a.unitTestEndPoints.loadPreviousMap(TMP_WITH_COUNTS); - - assert.isTrue( - callbacks.hasMessage(AnalyzerMessages.WARN_PreviousMapDidIncludeCounts), - 'Expected Warn_PreviousMapDidIncludeCounts warning' - ); - }); -}); From 469149e72d606f4632b5cb15b19e0dc7528a0d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20V=C3=B6lker?= Date: Mon, 27 Oct 2025 08:36:56 +0100 Subject: [PATCH 18/83] test(kmc-analyze): add message coverage tests for AnalyzeOskCharacterUse --- .../kmc-analyze/test/osk-character-use-messages.tests.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts b/developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts index c3c59a8260..1e4cc66a40 100644 --- a/developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts +++ b/developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts @@ -35,8 +35,9 @@ describe('AnalyzeOskCharacterUse warnings', function() { includeCounts: true }); - a.unitTestEndPoints.loadPreviousMap(MOCK_MAP_NO_COUNTS); - + const result = a.unitTestEndPoints.loadPreviousMap(MOCK_MAP_NO_COUNTS); + assert.isNotNull(result, 'Expected map to be loaded successfully'); + assert.isTrue( callbacks.hasMessage(AnalyzerMessages.WARN_PreviousMapDidNotIncludeCounts), 'Expected Warn_PreviousMapDidNotIncludeCounts warning' @@ -48,7 +49,8 @@ describe('AnalyzeOskCharacterUse warnings', function() { includeCounts: false }); - a.unitTestEndPoints.loadPreviousMap(MOCK_MAP_WITH_COUNTS); + const result = a.unitTestEndPoints.loadPreviousMap(MOCK_MAP_WITH_COUNTS); + assert.isNotNull(result, 'Expected map to be loaded successfully'); assert.isTrue( callbacks.hasMessage(AnalyzerMessages.WARN_PreviousMapDidIncludeCounts), From 1d223908ffe101f4c4589033a1131946e1b998c5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 27 Oct 2025 09:10:33 +0100 Subject: [PATCH 19/83] maint(mac): minor tweaks to mac setup, using build.sh Build-bot: skip Test-bot: skip --- mac/README.md | 16 +++++----------- resources/devbox/macos/keyman.macos.env.sh | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/mac/README.md b/mac/README.md index ef4c0d4b41..f15997e827 100644 --- a/mac/README.md +++ b/mac/README.md @@ -27,8 +27,8 @@ keyboard input. You have two options for local builds: Keyman must be signed then notarized by Apple, even for local test builds. This requires additional configuration for your build environment. -1. First, open XCode, Preferences, Accounts, and select Manage Certificates for the identity - you wish to use for signing. Click **+** and select **Developer ID Application**. A +1. First, open XCode, Settings, Accounts, and select Manage Certificates for the identity + you wish to use for signing. Click **+** and select **Apple Development**. A certificate will then be generated and listed in your Keychain. 2. Find the SHA-1 hash. To find the certificate in terminal: @@ -64,23 +64,17 @@ configuration for your build environment. To build Keyman for macOS, do the following: 1. Open a Terminal window. -2. cd to **keyman/mac**. **build.sh** must be run in the directory containing the script. -3. Build using `./build.sh -no-codesign`. Run `./build.sh -help` to see all options. - * If you have signing credentials from the core development team, you can build a signed - version by omitting `-no-codesign`. Somewhat misleadingly, `-no-codesign` only stops - automatic signing using the certificate maintained by the core development team! - * If you want to deploy, you will need to also add `-config Release`, as a Debug build cannot be notarized. +2. Build using `mac/build.sh clean configure build` Note: If Carthage prompts you to allow it access to your github credentials, it's fine to click Deny. ### Running Keyman -1. Deploy Keyman locally using `./build.sh -deploy local -deploy-only`. +1. Deploy Keyman locally using `mac/build.sh install`. * This will notarize the app, signing with your local credentials if not already signed, and copy **keyman/mac/Keyman4MacIM/build/Debug/Keyman.app** to **~/Library/Input Methods** 2. If running for the first time, follow the installation instructions at [Install Keyman for macOS]. -You can also use `./build.sh -no-codesign -deploy local` to do a single-step build, notarize, -and deploy (see above for faster options). +You can also use `mac/build.sh build install` to do a single-step build, notarize, and deploy (see above for faster options). ### Compiling from Xcode diff --git a/resources/devbox/macos/keyman.macos.env.sh b/resources/devbox/macos/keyman.macos.env.sh index 5ffb36eaaf..3c6a93634c 100755 --- a/resources/devbox/macos/keyman.macos.env.sh +++ b/resources/devbox/macos/keyman.macos.env.sh @@ -15,7 +15,7 @@ export PATH=$ANDROID_HOME/platform-tools:$PATH export PATH=$ANDROID_HOME/cmdline-tools/latest/bin:$PATH export PATH=$ANDROID_HOME/build-tools/30.0.3:$PATH -if [ -z "$HOMEBREW_PREFIX" ]; then +if [ -z "${HOMEBREW_PREFIX+x}" ]; then HOMEBREW_PREFIX=`brew --prefix` fi From 368766acdc990b891f3a4ced1f1f86b21bc3f9e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20V=C3=B6lker?= Date: Mon, 27 Oct 2025 14:05:13 +0100 Subject: [PATCH 20/83] test(kmc-analyze): fix import paths and order --- .../src/kmc-analyze/test/osk-character-use-messages.tests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts b/developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts index 1e4cc66a40..540ef3cb41 100644 --- a/developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts +++ b/developer/src/kmc-analyze/test/osk-character-use-messages.tests.ts @@ -3,9 +3,9 @@ */ import { assert } from 'chai'; import 'mocha'; -import { AnalyzeOskCharacterUse } from './osk-character-use/index.js'; import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; -import { AnalyzerMessages } from './analyzer-messages.js'; +import { AnalyzeOskCharacterUse } from '../src/osk-character-use/index.js'; +import { AnalyzerMessages } from '../src/analyzer-messages.js'; import { makePathToFixture } from './helpers/index.js'; describe('AnalyzeOskCharacterUse warnings', function() { From ba411774f60923b34afec5d43fe9b85de4272383 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 27 Oct 2025 10:50:32 +0100 Subject: [PATCH 21/83] maint(resources): move NPM package publishing to GitHub Actions Due to recent changes in NPM package publishing security requirements, we have to move from TeamCity build to a GitHub Action to publish our NPM packages, so we can take advantage of trusted publishing. This change also consolidates and centralizes the npm publishing into resources/build/ci/npm-publish.sh, which removes a lot of boilerplate from each of the build.sh scripts, and ensures consistency. Packages will be `npm pack`ed on PR and test builds, and published in release builds. Ref: https://docs.npmjs.com/trusted-publishers Ref: https://github.blog/changelog/2025-09-29-strengthening-npm-security-important-changes-to-authentication-and-token-management/ Fixes: #14963 Test-bot: skip Build-bot: release:developer --- .github/workflows/npm-publish.yml | 81 +++++++++++++++++++ common/web/keyman-version/build.sh | 7 +- common/web/langtags/build.sh | 7 +- common/web/types/build.sh | 7 +- core/include/ldml/build.sh | 7 +- developer/src/build.sh | 64 +-------------- developer/src/common/web/utils/build.sh | 7 +- developer/src/kmc-analyze/build.sh | 6 +- developer/src/kmc-copy/build.sh | 7 +- developer/src/kmc-generate/build.sh | 6 +- developer/src/kmc-keyboard-info/build.sh | 9 +-- developer/src/kmc-kmn/build.sh | 10 +-- developer/src/kmc-ldml/build.sh | 11 +-- developer/src/kmc-model-info/build.sh | 11 +-- developer/src/kmc-model/build.sh | 8 +- developer/src/kmc-package/build.sh | 8 +- developer/src/kmc/README.md | 8 -- developer/src/kmc/build.sh | 9 +-- docs/npm-packages.md | 49 ++++------- .../ci/cancel-builds/trigger_definitions.mjs | 2 +- resources/build/ci/ci-publish.inc.sh | 45 +++-------- .../build/ci/npm-packages.inc.sh | 5 +- resources/build/ci/npm-publish.sh | 59 ++++++++++++++ resources/build/ci/trigger-definitions.inc.sh | 10 +-- .../developer/keyman-developer-release.sh | 2 +- .../keyman-developer-test-windows.sh | 8 +- windows/src/desktop/build.sh | 1 - 27 files changed, 197 insertions(+), 257 deletions(-) create mode 100644 .github/workflows/npm-publish.yml rename developer/src/packages.inc.sh => resources/build/ci/npm-packages.inc.sh (78%) create mode 100755 resources/build/ci/npm-publish.sh diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 0000000000..11425148f9 --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,81 @@ +# +# Keyman is copyright (C) SIL Global. MIT License. +# +# Created by mcdurdin on 2025-10-27 +# +# This workflow publishes all our NPM packages using Trusted Publishers OIDC +# permissions. It is triggered by a repository_dispatch event with the types +# `npm-publish:*`, from the trigger-builds infrastructure. For test builds, this +# does a `npm pack` only. +# +# Inputs: +# buildSha: The SHA of the commit to build, e.g. of the branch or +# refs/pull/1234/head for PR +# user: The user that triggered the build or created the PR +# isTestBuild: false for Releases, otherwise true + +name: "NPM publish" +run-name: "NPM publish - sha: ${{ github.event.client_payload.buildSha }}, user: @${{ github.event.client_payload.user }}, isTestBuild: ${{ github.event.client_payload.isTestBuild }}" +on: + repository_dispatch: + types: ['npm-publish:*'] + +permissions: + id-token: write # Required for OIDC + contents: read + +env: + GH_TOKEN: ${{ github.token }} + STATUS_CONTEXT: 'NPM Pack' + +jobs: + npm-publish: + name: Publish or pack @keymanapp packages + if: github.repository == 'keymanapp/keyman' || github.event.client_payload.force + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + with: + ref: '${{ github.event.client_payload.buildSha }}' + + - name: Upgrade npm to 11.6.2 + run: | + echo "Initial npm version" + npm -v + echo "Upgrading npm to 11.6.2" + npm install --global npm@11.6.2 + echo "Current npm version" + npm -v + + - name: Set pending status on PR builds + id: set_status + if: github.event.client_payload.isTestBuild == 'true' + shell: bash + run: | + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + /repos/$GITHUB_REPOSITORY/statuses/${{ github.event.client_payload.buildSha }} \ + -f state='pending' \ + -f target_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" \ + -f description='NPM pack started' \ + -f context="$STATUS_CONTEXT" + + - name: NPM pack + if: github.event.client_payload.isTestBuild == 'true' + run: | + if [[ -f ./resources/build/ci/npm-publish.sh ]]; then + ./resources/build/ci/npm-publish.sh pack + else + echo WARNING: npm-publish.sh is not yet available on this branch + fi + + - name: NPM publish + if: github.event.client_payload.isTestBuild == 'false' + run: | + if [[ -f ./resources/build/ci/npm-publish.sh ]]; then + ./resources/build/ci/npm-publish.sh publish + else + echo WARNING: npm-publish.sh is not yet available on this branch + fi diff --git a/common/web/keyman-version/build.sh b/common/web/keyman-version/build.sh index 781c63bbec..9e165e8662 100755 --- a/common/web/keyman-version/build.sh +++ b/common/web/keyman-version/build.sh @@ -7,7 +7,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" ################################ Main script ################################ @@ -15,10 +14,7 @@ builder_describe "Build the include script for current Keyman version" \ configure \ clean \ build \ - test \ - "publish publish to npm" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + test builder_describe_outputs \ configure "/node_modules" \ @@ -56,4 +52,3 @@ export default KEYMAN_VERSION; builder_run_action clean rm -rf version.inc.ts keyman-version.mts build/ builder_run_action configure node_select_version_and_npm_ci builder_run_action build do_build -builder_run_action publish ci_publish_npm diff --git a/common/web/langtags/build.sh b/common/web/langtags/build.sh index 4eec3d2c6a..c4db9e1061 100755 --- a/common/web/langtags/build.sh +++ b/common/web/langtags/build.sh @@ -7,16 +7,12 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" builder_describe "Build Keyman langtags.js common module" \ "clean" \ "configure" \ "build" \ - "test" \ - "publish publish to npm" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + "test" builder_describe_outputs \ configure /common/web/langtags/src/imports/langtags.js \ @@ -43,4 +39,3 @@ builder_run_action clean rm -rf ./build ./src/imports ./node_modules builder_run_action configure do_configure builder_run_action build tsc --build builder_run_action test echo 'no tests for langtags' -builder_run_action publish ci_publish_npm diff --git a/common/web/types/build.sh b/common/web/types/build.sh index 518f531dd4..08419fa35d 100755 --- a/common/web/types/build.sh +++ b/common/web/types/build.sh @@ -8,7 +8,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" . "$KEYMAN_ROOT/resources/build/typescript.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" builder_describe "Build Keyman common file types module" \ "@/core/include/ldml" \ @@ -16,10 +15,7 @@ builder_describe "Build Keyman common file types module" \ "configure" \ "build" \ "clean" \ - "test" \ - "publish publish to npm" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + "test" builder_describe_outputs \ configure /common/web/types/src/schemas/kpj.schema.ts \ @@ -87,4 +83,3 @@ builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo ./src/schem builder_run_action configure do_configure builder_run_action build tsc --build builder_run_action test typescript_run_eslint_mocha_tests 60 -builder_run_action publish ci_publish_npm diff --git a/core/include/ldml/build.sh b/core/include/ldml/build.sh index 4029d732ce..8adf30773e 100755 --- a/core/include/ldml/build.sh +++ b/core/include/ldml/build.sh @@ -10,17 +10,13 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" builder_describe "Keyman ldml-keyboard-constants package" \ "@/common/web/keyman-version" \ "clean" \ "configure" \ "build" \ - "test" \ - "publish publish to npm" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + "test" builder_describe_outputs \ configure /node_modules \ @@ -34,4 +30,3 @@ builder_run_action clean rm -rf ./build/ builder_run_action configure node_select_version_and_npm_ci builder_run_action build tsc --build # builder_run_action test # no tests at this time -builder_run_action publish ci_publish_npm diff --git a/developer/src/build.sh b/developer/src/build.sh index fae0699748..8b57719d87 100755 --- a/developer/src/build.sh +++ b/developer/src/build.sh @@ -6,8 +6,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" ## END STANDARD BUILD SCRIPT INCLUDE . "$KEYMAN_ROOT/resources/build/utils.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" -. "$KEYMAN_ROOT/developer/src/packages.inc.sh" builder_describe \ "Keyman Developer" \ @@ -17,7 +15,7 @@ builder_describe \ build \ test \ "api Analyze API and prepare API documentation" \ - "publish Prepare files for distribution, publish symbols, publish or pack npm packages, and build installer" \ + "publish Prepare files for distribution, publish symbols, and build installer" \ "install Install built programs locally" \ ":common Developer common files" \ ":ext Third party components" \ @@ -42,9 +40,7 @@ builder_describe \ ":setup Keyman Developer setup bootstrap" \ ":test=test/auto Various older tests (others in each module)" \ ":tike Keyman Developer IDE" \ - ":inst Bundled installers" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n+ Don't actually publish anything to external endpoints, just dry run" + ":inst Bundled installers" builder_describe_platform \ :ext win,delphi \ @@ -76,25 +72,6 @@ fi function do_prepublish() { builder_heading "prepublish - verify environment before build" - # - # Make sure that package*.json have not been modified before - # - - pushd "$KEYMAN_ROOT" >/dev/null - if git status --porcelain | grep -qP 'package(-lock)?\.json'; then - builder_echo "The following package.json files have been modified:" - git status --porcelain | grep -P 'package(-lock)?\.json' - builder_die "The publish action will not run until these files are checked in or reverted." - fi - popd - - # - # To ensure that we cache the top-level package.json, we must call this before - # the global publish - # - - ci_publish_cleanup - # # Verify that the Delphi environment is correct for a release build # @@ -138,44 +115,7 @@ builder_run_action api api-documenter markdown -i ../build/api -o .. #------------------------------------------------------------------------------------------------------------------- -function do_publish() { - #-------------------------------------------------------- - # TODO: Hard-coded calls to /common packages which need - # publishing; this should be able to be removed once we - # move the publish call to the top-level - - local DRY_RUN= NPM_PUBLISH= - - if builder_has_option --npm-publish; then - NPM_PUBLISH=--npm-publish - fi - - if builder_has_option --dry-run; then - DRY_RUN=--dry-run - fi - - ./common/web/utils/build.sh publish $DRY_RUN $NPM_PUBLISH - ../../common/web/keyman-version/build.sh publish $DRY_RUN $NPM_PUBLISH - ../../common/web/langtags/build.sh publish $DRY_RUN $NPM_PUBLISH - ../../common/web/types/build.sh publish $DRY_RUN $NPM_PUBLISH - ../../core/include/ldml/build.sh publish $DRY_RUN $NPM_PUBLISH - # end TODO - #-------------------------------------------------------- - - builder_echo info "Cleaning up package.json after 'npm version'" - # And then cleanup the mess - ci_publish_cleanup - # Restore all the package.json files and package-lock.json files that - # were clobbered by 'npm version' - pushd "$KEYMAN_ROOT" >/dev/null - git checkout package.json package-lock.json '**/package.json' - popd - - # TODO: Copy ../build/docs {from api action} to help.keyman.com and open PR -} - builder_run_child_actions publish -builder_run_action publish do_publish #------------------------------------------------------------------------------------------------------------------- diff --git a/developer/src/common/web/utils/build.sh b/developer/src/common/web/utils/build.sh index 0f5aacbac5..293b772af8 100755 --- a/developer/src/common/web/utils/build.sh +++ b/developer/src/common/web/utils/build.sh @@ -8,7 +8,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" . "$KEYMAN_ROOT/resources/build/typescript.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" builder_describe "Build Keyman Developer web utility module" \ "@/common/web/types" \ @@ -16,10 +15,7 @@ builder_describe "Build Keyman Developer web utility module" \ "configure" \ "build" \ "api analyze API and prepare API documentation (no-op for now)" \ - "test" \ - publish \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + "test" builder_describe_outputs \ configure /node_modules \ @@ -52,4 +48,3 @@ builder_run_action clean rm -rf ./build/ builder_run_action configure node_select_version_and_npm_ci builder_run_action build do_build builder_run_action test typescript_run_eslint_mocha_tests 45 -builder_run_action publish ci_publish_npm diff --git a/developer/src/kmc-analyze/build.sh b/developer/src/kmc-analyze/build.sh index 152756df27..f28c822b5a 100755 --- a/developer/src/kmc-analyze/build.sh +++ b/developer/src/kmc-analyze/build.sh @@ -8,15 +8,12 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" . "$KEYMAN_ROOT/resources/build/typescript.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" builder_describe "Keyman Developer Compiler Analysis Tools" \ "@/common/web/types" \ "@/developer/src/kmc-kmn" \ "@/developer/src/common/web/utils" \ - clean configure build api test publish \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + clean configure build api test builder_describe_outputs \ configure /node_modules \ @@ -32,4 +29,3 @@ builder_run_action configure node_select_version_and_npm_ci builder_run_action build tsc --build builder_run_action api api-extractor run --local --verbose builder_run_action test typescript_run_eslint_mocha_tests 75 -builder_run_action publish ci_publish_npm diff --git a/developer/src/kmc-copy/build.sh b/developer/src/kmc-copy/build.sh index 45e9029f09..fe9ffc1086 100755 --- a/developer/src/kmc-copy/build.sh +++ b/developer/src/kmc-copy/build.sh @@ -11,16 +11,13 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" . "$KEYMAN_ROOT/resources/build/typescript.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" builder_describe "Build Keyman kmc-copy module" \ "@/common/web/keyman-version" \ "@/common/web/types" \ "@/developer/src/common/web/test-helpers" \ "@/developer/src/common/web/utils" \ - clean configure build api test publish \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + clean configure build api test builder_describe_outputs \ configure /node_modules \ @@ -42,5 +39,3 @@ builder_run_action api api-extractor run --local --verbose # note: `export TEST_SAVE_FIXTURES=1` to get a copy of cloud-based fixtures saved to online/ # TODO: -skip-full builder_run_action test typescript_run_eslint_mocha_tests 75 - -builder_run_action publish ci_publish_npm diff --git a/developer/src/kmc-generate/build.sh b/developer/src/kmc-generate/build.sh index c02a7ed26a..d67cbaf21a 100755 --- a/developer/src/kmc-generate/build.sh +++ b/developer/src/kmc-generate/build.sh @@ -11,7 +11,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" . "$KEYMAN_ROOT/resources/build/typescript.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" builder_describe "Build Keyman kmc-generate module" \ "@/common/web/keyman-version" \ @@ -19,9 +18,7 @@ builder_describe "Build Keyman kmc-generate module" \ "@/common/web/types" \ "@/developer/src/common/web/test-helpers" \ "@/developer/src/common/web/utils" \ - clean configure build api test publish \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + clean configure build api test builder_describe_outputs \ configure /node_modules \ @@ -44,4 +41,3 @@ builder_run_action configure node_select_version_and_npm_ci builder_run_action build do_build builder_run_action api api-extractor run --local --verbose builder_run_action test typescript_run_eslint_mocha_tests -builder_run_action publish ci_publish_npm diff --git a/developer/src/kmc-keyboard-info/build.sh b/developer/src/kmc-keyboard-info/build.sh index 36a840212f..fe8ecfac58 100755 --- a/developer/src/kmc-keyboard-info/build.sh +++ b/developer/src/kmc-keyboard-info/build.sh @@ -18,10 +18,7 @@ builder_describe "Build Keyman kmc keyboard-info Compiler module" \ "configure" \ "build" \ "api analyze API and prepare API documentation" \ - "test" \ - "publish publish to npm" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + "test" builder_describe_outputs \ configure /node_modules \ @@ -39,7 +36,3 @@ builder_run_action api api-extractor run --local --verbose builder_run_action test typescript_run_eslint_mocha_tests #------------------------------------------------------------------------------------------------------------------- - -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" - -builder_run_action publish ci_publish_npm diff --git a/developer/src/kmc-kmn/build.sh b/developer/src/kmc-kmn/build.sh index 7d94f880df..27fb958486 100755 --- a/developer/src/kmc-kmn/build.sh +++ b/developer/src/kmc-kmn/build.sh @@ -11,7 +11,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" . "$KEYMAN_ROOT/resources/build/typescript.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" builder_describe "Keyman Developer Compiler Module for .kmn to .kmx" \ "@/common/web/keyman-version" \ @@ -23,10 +22,7 @@ builder_describe "Keyman Developer Compiler Module for .kmn to .kmx" \ "build" \ "clean" \ "api analyze API and prepare API documentation" \ - "test" \ - "publish publish to npm" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + "test" builder_describe_outputs \ configure /node_modules \ @@ -71,7 +67,3 @@ function do_test() { builder_run_action build do_build builder_run_action api api-extractor run --local --verbose builder_run_action test do_test - -#------------------------------------------------------------------------------------------------------------------- - -builder_run_action publish ci_publish_npm diff --git a/developer/src/kmc-ldml/build.sh b/developer/src/kmc-ldml/build.sh index 2f3eb01bc2..708a4c9b3d 100755 --- a/developer/src/kmc-ldml/build.sh +++ b/developer/src/kmc-ldml/build.sh @@ -23,10 +23,7 @@ builder_describe "Keyman kmc Keyboard Compiler module" \ "api analyze API and prepare API documentation" \ "clean" \ "test" \ - "build-fixtures builds test fixtures for manual examination" \ - "publish publish to npm" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + "build-fixtures builds test fixtures for manual examination" builder_describe_outputs \ configure /developer/src/kmc-ldml/src/util/abnf/46/transform-from-required.js \ @@ -90,9 +87,3 @@ builder_run_action build do_build builder_run_action build-fixtures do_build_fixtures builder_run_action api api-extractor run --local --verbose builder_run_action test typescript_run_eslint_mocha_tests 90 - -#------------------------------------------------------------------------------------------------------------------- - -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" - -builder_run_action publish ci_publish_npm diff --git a/developer/src/kmc-model-info/build.sh b/developer/src/kmc-model-info/build.sh index 00983ae6ea..fb4743700f 100755 --- a/developer/src/kmc-model-info/build.sh +++ b/developer/src/kmc-model-info/build.sh @@ -15,10 +15,7 @@ builder_describe "Build Keyman kmc Lexical Model model-info Compiler module" \ "configure" \ "build" \ "api analyze API and prepare API documentation" \ - "test" \ - "publish publish to npm" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + "test" builder_describe_outputs \ configure /node_modules \ @@ -34,9 +31,3 @@ builder_run_action configure node_select_version_and_npm_ci builder_run_action build tsc --build builder_run_action api api-extractor run --local --verbose builder_run_action test typescript_run_eslint_mocha_tests 55 - -#------------------------------------------------------------------------------------------------------------------- - -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" - -builder_run_action publish ci_publish_npm diff --git a/developer/src/kmc-model/build.sh b/developer/src/kmc-model/build.sh index bd758b18f9..4b5f15cc30 100755 --- a/developer/src/kmc-model/build.sh +++ b/developer/src/kmc-model/build.sh @@ -8,7 +8,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" . "$KEYMAN_ROOT/resources/build/typescript.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" builder_describe "Keyman kmc Lexical Model Compiler module" \ "@/common/web/keyman-version" \ @@ -18,10 +17,7 @@ builder_describe "Keyman kmc Lexical Model Compiler module" \ "configure" \ "build" \ "api analyze API and prepare API documentation" \ - "test" \ - "publish publish to npm" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + "test" builder_describe_outputs \ configure /node_modules \ @@ -42,5 +38,3 @@ builder_run_action configure node_select_version_and_npm_ci builder_run_action build do_build builder_run_action api api-extractor run --local --verbose builder_run_action test typescript_run_eslint_mocha_tests -builder_run_action publish ci_publish_npm - diff --git a/developer/src/kmc-package/build.sh b/developer/src/kmc-package/build.sh index 66f430ceb4..f1d6ba8dcc 100755 --- a/developer/src/kmc-package/build.sh +++ b/developer/src/kmc-package/build.sh @@ -11,7 +11,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" . "$KEYMAN_ROOT/resources/build/typescript.inc.sh" -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" builder_describe "Build Keyman kmc Package Compiler module" \ "@/common/web/keyman-version" \ @@ -21,10 +20,8 @@ builder_describe "Build Keyman kmc Package Compiler module" \ "build" \ "api analyze API and prepare API documentation" \ "clean" \ - "test" \ - "publish publish to npm" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + "test" + builder_describe_outputs \ configure /node_modules \ build /developer/src/kmc-package/build/src/main.js \ @@ -39,4 +36,3 @@ builder_run_action configure node_select_version_and_npm_ci builder_run_action build tsc --build builder_run_action api api-extractor run --local --verbose builder_run_action test typescript_run_eslint_mocha_tests -builder_run_action publish ci_publish_npm diff --git a/developer/src/kmc/README.md b/developer/src/kmc/README.md index 2ab17f67e7..0490998e4d 100644 --- a/developer/src/kmc/README.md +++ b/developer/src/kmc/README.md @@ -175,14 +175,6 @@ The temp_path must be a path outside the repository to avoid npm getting confused by the root package.json. This is called by inst/download.in.mak normally when building the Keyman Developer installer. -## Publishing to NPM - -```shell -./build.sh publish [--dry-run] -``` - -Publishes the current release to NPM. This should only be run from CI. - [kmc]: https://help.keyman.com/developer/current-version/reference/kmc/cli [file-layout]: https://help.keyman.com/developer/current-version/reference/file-layout diff --git a/developer/src/kmc/build.sh b/developer/src/kmc/build.sh index e784a441cc..81cc94dcca 100755 --- a/developer/src/kmc/build.sh +++ b/developer/src/kmc/build.sh @@ -8,11 +8,10 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh" ## END STANDARD BUILD SCRIPT INCLUDE -. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" . "$KEYMAN_ROOT/resources/build/utils.inc.sh" . "$KEYMAN_ROOT/resources/build/node.inc.sh" . "$KEYMAN_ROOT/resources/build/typescript.inc.sh" -. "$KEYMAN_ROOT/developer/src/packages.inc.sh" +. "$KEYMAN_ROOT/resources/build/ci/npm-packages.inc.sh" builder_describe "Build Keyman Keyboard Compiler kmc" \ "@/common/include" \ @@ -35,10 +34,7 @@ builder_describe "Build Keyman Keyboard Compiler kmc" \ "bundle creates a bundled version of kmc" \ "api prepare compiler error documentation" \ "test run automated tests for kmc" \ - publish \ - "--build-path=BUILD_PATH build directory for bundle" \ - "--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \ - "--dry-run,-n don't actually publish, just dry run" + "--build-path=BUILD_PATH build directory for bundle" builder_describe_outputs \ configure /node_modules \ @@ -114,4 +110,3 @@ builder_run_action build do_build builder_run_action test do_test builder_run_action api do_api builder_run_action bundle do_bundle -builder_run_action publish ci_publish_npm diff --git a/docs/npm-packages.md b/docs/npm-packages.md index 8306130d36..9cee3696f6 100644 --- a/docs/npm-packages.md +++ b/docs/npm-packages.md @@ -3,16 +3,21 @@ This is a guide for how the various Keyman `npm` packages are developed and published. -`npm` packages are published on the CI (continuous integration) server. -Currently, we're using TeamCity for this. +`npm` packages are published through CI (continuous integration). This is done +through the `.github/workflows/npm-publish.yml` GitHub Action. Packages are **never** published from a developer's machine. ## List of current published npm packages +* See `resources/build/ci/npm-packages.inc.sh` for an authoritative list. + * `@keymanapp/common-types` -- located at `common/web/types` * `@keymanapp/keyman-version` -- located at `common/web/keyman-version` * `@keymanapp/kmc` -- located at `developer/src/kmc` +* `@keymanapp/kmc-analyze` -- located at `developer/src/kmc-analyze` +* `@keymanapp/kmc-copy` -- located at `developer/src/kmc-copy` +* `@keymanapp/kmc-generate` -- located at `developer/src/kmc-generate` * `@keymanapp/kmc-keyboard-info` -- located at `developer/src/kmc-keyboard-unfo` * `@keymanapp/kmc-kmn` -- located at `developer/src/kmc-kmn` * `@keymanapp/kmc-ldml` -- located at `developer/src/kmc-ldml` @@ -20,6 +25,7 @@ Packages are **never** published from a developer's machine. * `@keymanapp/kmc-model-info` -- located at `developer/src/kmc-model-info` * `@keymanapp/kmc-package` -- located at `developer/src/kmc-package` * `@keymanapp/langtags` -- located at `common/web/langtags` +* `@keymanapp/ldml-keyboard-constants` -- located at `core/include/dml` ### Deprecated npm packages @@ -34,22 +40,16 @@ Packages are **never** published from a developer's machine. ### In general -Before publishing, a package must be **built** and **tested** on the CI -server. - -This is typically done with: +Before publishing, a package must be **built** and **tested**. This is typically +done with: ```bash ./build.sh configure build test ``` -Once the build succeeds and the tests pass, you can publish! Use the following -script for this (**only on the CI server**!); during this, the version is set in -`package.json`: - -```bash -./build.sh publish -``` +Once the build succeeds and the tests pass, you can publish! Add the package to +`resources/build/ci/npm-packages.inc.sh` and it will be published in the next +alpha release build. It is then uploaded to the npm package directory. **Ensure that the compiled sources are included in the tarball**. For example: @@ -94,26 +94,5 @@ npm notice 740B tsconfig.json npm notice 449B tsconfig.kmc-base.json ``` -For every release of **Keyman Developer**, the CI publishes a release of -`@keymanapp/kmc`. The version number is locked with the particular version of -Keyman Developer. +For every release build, CI publishes a release of all packages. -### `builder_publish_npm` - -Publishes the package in `cwd` to npm - -If the `--dry-run` option is available and specified as a command-line -parameter, will do a dry run - -Note that `package.json` will be dirty after this command, as the `version` -field will be added to it, and @keymanapp dependency versions will also be -modified. This change should not be committed to the repository. - -If --npm-publish is set: -* then builder_publish_npm publishes to the public registry -* else builder_publish_npm creates a local tarball which can be used to test - -```bash - . "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" - builder_publish_npm -``` diff --git a/resources/build/ci/cancel-builds/trigger_definitions.mjs b/resources/build/ci/cancel-builds/trigger_definitions.mjs index f6acdf91bb..aef0526688 100644 --- a/resources/build/ci/cancel-builds/trigger_definitions.mjs +++ b/resources/build/ci/cancel-builds/trigger_definitions.mjs @@ -6,7 +6,7 @@ export const testBuildConfigurations = { 'mac': ['Keyman_KeymanMac_PullRequests', 'Keyman_Common_KPAPI_TestPullRequests_macOS'], 'windows': ['KeymanDesktop_TestPullRequests', 'KeymanDesktop_TestPrRenderOnScreenKeyboards', 'Keyman_Common_KPAPI_TestPullRequests_Windows'], 'web': ['Keymanweb_TestPullRequests', 'Keyman_Common_KPAPI_TestPullRequests_WASM'], - 'developer': ['Keyman_Developer_Test'], + 'developer': ['Keyman_Developer_Test', 'npm-publish_GitHub'], 'common_web': ['Keyman_Test_Common_Web'], 'common_windows': ['Keyman_Test_Common_Windows'], diff --git a/resources/build/ci/ci-publish.inc.sh b/resources/build/ci/ci-publish.inc.sh index d8fc1e77a2..2785fead35 100644 --- a/resources/build/ci/ci-publish.inc.sh +++ b/resources/build/ci/ci-publish.inc.sh @@ -8,39 +8,10 @@ . "$KEYMAN_ROOT/resources/build/jq.inc.sh" -# -# Publishes the package in `cwd` to npm -# -# If the `--dry-run` option is available and specified as a command-line -# parameter, will do a dry run -# -# Note that `package.json` will be dirty after this command, as the `version` -# field will be added to it, and @keymanapp dependency versions will also be -# modified. This change should not be committed to the repository. -# -# If --npm-publish is set: -# * then ci_publish_npm publishes to the public registry -# * else ci_publish_npm creates a local tarball which can be used to test -# -# Usage: -# ```bash -# ci_publish_npm -# ``` -# -function ci_publish_npm() { - if builder_has_option --npm-publish; then - # Require --dry-run if local or test to avoid accidentally clobbering npm packages - if [[ $KEYMAN_VERSION_ENVIRONMENT =~ local|test ]] && ! builder_has_option --dry-run; then - builder_die "publish --npm-publish must use --dry-run flag for local or test builds" - fi - _ci_publish_npm_package publish - else - _ci_publish_npm_package pack - fi -} - -function _ci_publish_npm_package() { - local action=$1 +# Used only by npm-publish.sh +function ci_publish_npm_package() { + local action="$1" + local package="$2" local dist_tag=$KEYMAN_TIER dry_run= if [[ $KEYMAN_TIER == stable ]]; then @@ -51,6 +22,8 @@ function _ci_publish_npm_package() { dry_run=--dry-run fi + pushd "${KEYMAN_ROOT}/${package}" >/dev/null + _ci_publish_cache_package_json _ci_write_npm_version _ci_prepublish @@ -62,12 +35,14 @@ function _ci_publish_npm_package() { if [[ $action == pack ]]; then # We can use --publish-to-pack to locally test a package # before publishing to the package registry - echo "Packing $dry_run npm package $THIS_SCRIPT_IDENTIFIER with tag $dist_tag" + echo "Packing $dry_run npm package ${package} with tag $dist_tag" npm pack $dry_run --access public --tag $dist_tag else # $action == publish - echo "Publishing $dry_run npm package $THIS_SCRIPT_IDENTIFIER with tag $dist_tag" + echo "Publishing $dry_run npm package ${package} with tag $dist_tag" npm publish $dry_run --access public --tag $dist_tag fi + + popd >/dev/null } function _ci_write_npm_version() { diff --git a/developer/src/packages.inc.sh b/resources/build/ci/npm-packages.inc.sh similarity index 78% rename from developer/src/packages.inc.sh rename to resources/build/ci/npm-packages.inc.sh index 62993c5ab9..a1c4eecd8b 100644 --- a/developer/src/packages.inc.sh +++ b/resources/build/ci/npm-packages.inc.sh @@ -1,7 +1,8 @@ +# +# Keyman is copyright (C) SIL Global. MIT License. +# # List of all NPM packages that need to be published # -# TODO: this should really be somewhere else, but right now Developer CI is -# responsible for pulling the publish lever readonly PACKAGES=( common/web/keyman-version diff --git a/resources/build/ci/npm-publish.sh b/resources/build/ci/npm-publish.sh new file mode 100755 index 0000000000..6e39838fbd --- /dev/null +++ b/resources/build/ci/npm-publish.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# +# Keyman is copyright (C) SIL Global. MIT License. +# +# Publish all the @keymanapp packages listed in npm-packages.inc.sh +# +# If the `--dry-run` option is available and specified as a command-line +# parameter, will do a dry run +# +# Note that `package.json` will be dirty after this command, as the `version` +# field will be added to it, and @keymanapp dependency versions will also be +# modified. This change should not be committed to the repository. +# +# If `publish` is called: +# * then ci_publish_npm publishes to the public registry +# * else ci_publish_npm creates a local tarball which can be used to test +# +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh" +. "$KEYMAN_ROOT/resources/build/ci/npm-packages.inc.sh" + +builder_describe \ + "Publish @keymanapp packages to NPM" \ + "pack Pack NPM packages to a .tgz for verification" \ + "publish Publish NPM packages to the NPM Registry" \ + "--dry-run Don't publish/pack anything, just dry run" + +builder_parse "$@" + +#------------------------------------------------------------------------------------------------------------------- + +function do_pack() { + local npm_package_path + for npm_package_path in "${PACKAGES[@]}"; do + builder_heading "Packing $npm_package_path" + ci_publish_npm_package pack "$npm_package_path" + done +} + +function do_publish() { + local npm_package_path + + if [[ $KEYMAN_VERSION_ENVIRONMENT =~ local|test ]] && ! builder_has_option --dry-run; then + builder_die "publish must use --dry-run flag for local or test builds" + fi + + for npm_package_path in "${PACKAGES[@]}"; do + builder_heading "Publishing $npm_package_path" + ci_publish_npm_package publish "$npm_package_path" + done +} + +builder_run_action pack do_pack +builder_run_action publish do_publish diff --git a/resources/build/ci/trigger-definitions.inc.sh b/resources/build/ci/trigger-definitions.inc.sh index 7492138434..ab08734804 100644 --- a/resources/build/ci/trigger-definitions.inc.sh +++ b/resources/build/ci/trigger-definitions.inc.sh @@ -89,7 +89,7 @@ bc_test_linux=(KeymanLinux_TestPullRequests Keyman_Linux_Test_Integration Keyman bc_test_mac=(Keyman_KeymanMac_PullRequests Keyman_Common_KPAPI_TestPullRequests_macOS) bc_test_windows=(KeymanDesktop_TestPullRequests KeymanDesktop_TestPrRenderOnScreenKeyboards Keyman_Common_KPAPI_TestPullRequests_Windows) bc_test_web=(Keymanweb_TestPullRequests Keyman_Common_KPAPI_TestPullRequests_WASM) -bc_test_developer=(Keyman_Developer_Test Keyman_Test_Developer_Mac Keyman_Test_Developer_Linux) +bc_test_developer=(Keyman_Developer_Test Keyman_Test_Developer_Mac Keyman_Test_Developer_Linux npm-publish_GitHub) bc_test_common_web=(Keyman_Test_Common_Web) bc_test_common_windows=(Keyman_Test_Common_Windows) @@ -116,7 +116,7 @@ bc_master_linux=(KeymanLinux_Master deb-release-packaging_GitHub build-test-publ bc_master_mac=(KeymanMac_Master) bc_master_windows=(Keyman_Build) bc_master_web=(Keymanweb_Build) -bc_master_developer=(Keyman_Developer_Release) +bc_master_developer=(Keyman_Developer_Release npm-publish_GitHub) vcs_master=HttpsGithubComKeymanappKeyman @@ -128,7 +128,7 @@ bc_beta_linux=(KeymanLinux_Master deb-release-packaging_GitHub) bc_beta_mac=(KeymanMac_Master) bc_beta_windows=(Keyman_Build) bc_beta_web=(Keymanweb_Build) -bc_beta_developer=(Keyman_Developer_Release) +bc_beta_developer=(Keyman_Developer_Release npm-publish_GitHub) vcs_beta=HttpsGithubComKeymanappKeyman @@ -140,7 +140,7 @@ bc_stable_18_0_linux=(KeymanLinux_Master deb-release-packaging_GitHub) bc_stable_18_0_mac=(KeymanMac_Master) bc_stable_18_0_windows=(Keyman_Build) bc_stable_18_0_web=(Keymanweb_Build) -bc_stable_18_0_developer=(Keyman_Developer_Release) +bc_stable_18_0_developer=(Keyman_Developer_Release npm-publish_GitHub) vcs_stable_18_0=HttpsGithubComKeymanappKeyman @@ -152,6 +152,6 @@ bc_stable_19_0_linux=(KeymanLinux_Master deb-release-packaging_GitHub) bc_stable_19_0_mac=(KeymanMac_Master) bc_stable_19_0_windows=(Keyman_Build) bc_stable_19_0_web=(Keymanweb_Build) -bc_stable_19_0_developer=(Keyman_Developer_Release) +bc_stable_19_0_developer=(Keyman_Developer_Release npm-publish_GitHub) vcs_stable_19_0=HttpsGithubComKeymanappKeyman diff --git a/resources/teamcity/developer/keyman-developer-release.sh b/resources/teamcity/developer/keyman-developer-release.sh index b24978de0d..7bf2e02553 100755 --- a/resources/teamcity/developer/keyman-developer-release.sh +++ b/resources/teamcity/developer/keyman-developer-release.sh @@ -41,7 +41,7 @@ cd "${KEYMAN_ROOT}/developer/src" function _build_developer() { builder_echo start "build developer" "Building Keyman Developer" - ./build.sh configure build test api publish --npm-publish + ./build.sh configure build test api publish builder_echo end "build developer" success "Finished building Keyman Developer" } diff --git a/resources/teamcity/developer/keyman-developer-test-windows.sh b/resources/teamcity/developer/keyman-developer-test-windows.sh index 668e7a9c04..5bd7961c46 100755 --- a/resources/teamcity/developer/keyman-developer-test-windows.sh +++ b/resources/teamcity/developer/keyman-developer-test-windows.sh @@ -55,12 +55,12 @@ function _build_testkeyboards() { } function publish_sentry_action() { - builder_echo start "publish" "Dry-run publish and api" - ./build.sh api publish --dry-run - builder_echo end "publish" "Dry-run publish and api" + builder_echo start "publish" "publish modules locally and prep api" + ./build.sh api publish + builder_echo end "publish" "publish modules locally and prep api" builder_echo start "publish sentry" "Publishing debug information files to Sentry" - # TODO: move this into build.sh publish? re-scope --dry-run into build.sh? + # TODO: move this into build.sh publish? "${KEYMAN_ROOT}/developer/src/tools/sentry-upload-difs.sh" builder_echo end "publish sentry" success "Finished publishing debug information files to Sentry" } diff --git a/windows/src/desktop/build.sh b/windows/src/desktop/build.sh index f5401e22b5..aea7a2d8f9 100755 --- a/windows/src/desktop/build.sh +++ b/windows/src/desktop/build.sh @@ -6,7 +6,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" ## END STANDARD BUILD SCRIPT INCLUDE . "$KEYMAN_ROOT/resources/build/utils.inc.sh" -. "$KEYMAN_ROOT/developer/src/packages.inc.sh" builder_describe \ "Keyman for Windows (app)" \ From e06ac524fb6500b8a0b5df59e46576d9d2014098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20V=C3=B6lker?= Date: Mon, 27 Oct 2025 17:45:44 +0100 Subject: [PATCH 22/83] test(kmc-analyze): add tests for AnalyzeOskCharacterUse output formats --- .../test/osk-character-use-format.tests.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 developer/src/kmc-analyze/test/osk-character-use-format.tests.ts diff --git a/developer/src/kmc-analyze/test/osk-character-use-format.tests.ts b/developer/src/kmc-analyze/test/osk-character-use-format.tests.ts new file mode 100644 index 0000000000..6d1f1a85d6 --- /dev/null +++ b/developer/src/kmc-analyze/test/osk-character-use-format.tests.ts @@ -0,0 +1,53 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + */ +import { assert } from 'chai'; +import 'mocha'; +import { AnalyzeOskCharacterUse } from '../src/osk-character-use/index.js'; +import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; + +describe('AnalyzeOskCharacterUse output formats', function () { + const callbacks = new TestCompilerCallbacks(); + + const dummyStrings = { + 'a': [{ filename: 'file1.kvks', count: 1 }], + 'b': [{ filename: 'file2.kvks', count: 2 }] + }; + + this.beforeEach(function() { + callbacks.clear(); + }); + + this.afterEach(function() { + if(this.currentTest?.isFailed()) { + callbacks.printMessages(); + } + }); + + it('generates .txt format correctly', function() { + const a = new AnalyzeOskCharacterUse(callbacks, { includeCounts: true }); + (a as any)._strings = dummyStrings; + const txt = a.getStrings('.txt'); + assert.isTrue(txt.some(line => line.includes('U+'))); + }); + + it('generates .md format correctly', function() { + const a = new AnalyzeOskCharacterUse(callbacks, { includeCounts: true }); + (a as any)._strings = dummyStrings; + const md = a.getStrings('.md'); + assert.isTrue(md[0].includes('PUA') && md[2].includes('|')); + }); + + it('generates .json format correctly', function() { + const a = new AnalyzeOskCharacterUse(callbacks, { includeCounts: true }); + (a as any)._strings = dummyStrings; + const json = a.getStrings('.json').join('\n'); + const parsed = JSON.parse(json); + assert.isArray(parsed.map); + }); + + it('converts strings to Unicode sequences correctly', function() { + const seq = (AnalyzeOskCharacterUse as any).stringToUnicodeSequence('ab'); + assert.equal(seq, 'U+0061 U+0062'); + }); +}); \ No newline at end of file From d7d2a2810c2b01d82e3cf2929ae3ed913d848eb3 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Mon, 27 Oct 2025 13:01:50 -0500 Subject: [PATCH 23/83] auto: increment master version to 19.0.147 Test-bot: skip Build-bot: skip --- HISTORY.md | 6 ++++++ VERSION.md | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 73ccc5f7d5..984700a2b4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,11 @@ # Keyman Version History +## 19.0.146 alpha 2025-10-27 + +* fix(mac): ignore non-Unicode key caps when preparing OSK (#15008) +* fix(developer): prevent ANSI keyboards crashing debugger (#15022) +* test(developer): add coverage tests for warning messages in kmc-analyze/AnalyzeOskCharacterUse (#15021) + ## 19.0.145 alpha 2025-10-24 * fix(developer): do not treat backslash as a string escape in syntax highlighting (#15001) diff --git a/VERSION.md b/VERSION.md index f0ebf516cf..a82718a352 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.146 \ No newline at end of file +19.0.147 \ No newline at end of file From ac6d305b79c538523862b2d61edd8b2516a0e237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20V=C3=B6lker?= Date: Mon, 27 Oct 2025 19:10:40 +0100 Subject: [PATCH 24/83] format update --- .../src/kmc-analyze/test/osk-character-use-format.tests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/src/kmc-analyze/test/osk-character-use-format.tests.ts b/developer/src/kmc-analyze/test/osk-character-use-format.tests.ts index 6d1f1a85d6..f4a8d6b7a1 100644 --- a/developer/src/kmc-analyze/test/osk-character-use-format.tests.ts +++ b/developer/src/kmc-analyze/test/osk-character-use-format.tests.ts @@ -6,7 +6,7 @@ import 'mocha'; import { AnalyzeOskCharacterUse } from '../src/osk-character-use/index.js'; import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; -describe('AnalyzeOskCharacterUse output formats', function () { +describe('AnalyzeOskCharacterUse output formats', function() { const callbacks = new TestCompilerCallbacks(); const dummyStrings = { From 5bf5a5941f800f70e286e3d3adc474267187de84 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Fri, 24 Oct 2025 14:12:56 +0700 Subject: [PATCH 25/83] chore(common): Move platformtest to common/test/keyboards --- .../app/src/main/assets/keyboardharness.kmp | Bin 217932 -> 218131 bytes .../app/src/main/assets/keyboardharness.kps | 2 +- .../platform-rules/platform-results.xlsx | Bin .../keyboards}/platform-rules/platformtest.js | 0 .../platform-rules/platformtest.kmn | 0 .../platform-rules/platformtest.kmp | Bin 3701 -> 3701 bytes .../platform-rules/platformtest.kmx | Bin .../platform-rules/platformtest.kpj | 0 .../platform-rules/platformtest.kps | 0 9 files changed, 1 insertion(+), 1 deletion(-) rename {windows/src/test/manual-tests => common/test/keyboards}/platform-rules/platform-results.xlsx (100%) rename {windows/src/test/manual-tests => common/test/keyboards}/platform-rules/platformtest.js (100%) rename {windows/src/test/manual-tests => common/test/keyboards}/platform-rules/platformtest.kmn (100%) rename {windows/src/test/manual-tests => common/test/keyboards}/platform-rules/platformtest.kmp (86%) rename {windows/src/test/manual-tests => common/test/keyboards}/platform-rules/platformtest.kmx (100%) rename {windows/src/test/manual-tests => common/test/keyboards}/platform-rules/platformtest.kpj (100%) rename {windows/src/test/manual-tests => common/test/keyboards}/platform-rules/platformtest.kps (100%) diff --git a/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kmp b/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kmp index 9785ed733811c1938d1125c34725a47b5bd2897a..a9bda34bba11fd3a7b5f576a0d294b9a4d06f7c9 100644 GIT binary patch delta 1812 zcmZ9Nc{JOJ7RM96L`H}uQ&PKDtqt``l$Mqa|#lR|!%ea!vAz0+}>%}T9CjkPEAE;L?%*Zl;Ss)Tg&?;h;E$+n3_hKElG&x%f_ z>=r~n~wdCeQSk95@Y!f*>-X^ahSmVKR5%j#i5Owl%gt(6aK_1MIQRn0-~s7fSD;^ zrP<1jrmeeHY(hTQ;MhMVN-*>_ub1`rfz6~md-M6dQSWk>7^qus1k*Aklg(WN2f4DV z8!t$|bAIPsc`Ix8g!qT<;L{wx#?|{!i?BFWGs1DrYin9g@yxp&v!H)3jQWf5a~WtQD-ePA0Uzg+7W z-#S+1p=-dKMNnC|%=_D^&D4;>@`MVsJL!IUnu^;lr9y=n7!kfcn(M)5`spm`^>R@2 zj+1%r4k2o(0ybna!&WjjRdDTDo=QeU|A+NiT?Kbh4QjVWpj7Okmg;_k<#byCUTsHk zKrprUM7dIMgDwX_yB@ceIej!Z=uDCl(+UUkK4&zkJ#R5-Z;gxC7F_cV(0D~6I}|a^ z#={GMs5f3aJniF>n=_m0E*i?b$|DPP13q=M4fkqVfm2m>rQ@Lvg|O$AZ~YJAZ4mZ@ zpRXqmULDJ8THbgyJ2jrQ$2nJOg%bvD33HHk7@~AbRVTDzMIIrvw9j&o8LEn1d|r7hsGj~U?Y z2I;kjJwH#~e8P}h5Tw5x-n$;Qv#4D3%QLP6`iV5<*uyWF;FW#S_82LC^C}Jg2!@(O zv%z$)&}L<>r+42ne@I36As}bkVu!(0(Q4A1Ful~wpNyXhVEXngEFJVVv+lY6=3Fo> z+B{V1GgME%w5VNnK4dxN@N+YvYGg9$*YOxx$IT!=hQD#lxvpFG#Gvu!jgf8*JsTrA_#Zm4+}J#y)L!fMBNZDd>*WaE&$M~d{Pu@=qg8vM-6=EJ zX#@}u>oT`uNbTrX|8-YX-9A&&Wc5B;7Y@&u{n%t>l6GVf5;@_LHntAUL{Z&LR>Jzc z$mcm!_HXszw>v-r1)|`YWA6U~aZ8nCaVHBZi0s)nZMOBfO5Y~L{A)Kiw#~4QY`U5m z-EvTGO!ouFCI|KQe9j4s-#>fWA(=@=VNmCo=!J-#b9{M4qW_N@L1Kt%mQ??n&X z7FRXZ4lI@gBU3|kR%WE~>0ldri6pdQ?m~BhP=PAQm{d;bmOcF5nSdnT5 z%MiSKP?-402B|r1Qaj3MkDBfM#biZ2qs(aXIiy2Sl~I;@QSZUKZfQa81AU~^Ayv|k zt*_+Ltk{eNH8>o3L)}TZ7p7U5x3$91(ii0}wGEW|Qj@r8>00-Xem=i&fLa_r?(}Se z0ERYvG%S%`4W@(qLN1)7A7A(ep0I+kOc$~*YTBjQ zo6C{~i&LVLB@1+00AhG_COQI%u&-*(9iV`}s&r3)@Kw>?c>$+n|IQei84fsM{nzYB zhPo2P0sw87!9X%%?))zZVhmj(L`0r6G5LpaQc{#B7A$cH^j~t(=r}-C0_{X&;{cVv oKGNpI1JxQ20CYJnL5wUy{Qo=Ty~U1GUNj?bKv}XL2Z(?D2~_<*2><{9 delta 1635 zcmY+Fe>~H99LK-gHxiq+$;Y`Qg{VAKrk&z3|`` zO#lEifQy~J&2X=6TvZR;`J<@YObq}UECB$a+A^a;6T%sB(FxS}1Z#S{^!O<8g*}qv zHo>)VjB50$`$(`z*ez3QtxF^9&ED(Tk361;Yu)BS>ZqSp{&nz-u2Ithrkh-Xo|>Fe zBtLpJIZ4(=xUP*-^+(4Q${9Rb7U=^UMu*xfmRq?RZ`oI@~vqgD2Q|a72{JguG@hXVVF2ld=Em)@~eR?;cRb)4_i`D-$>|2VJ zp7?&QbWE}Oj)=s%Mo%?-y#9dmW-gncq$1^k*zgahIHe6Y5Zx@S6AU3mJq^uzeW1tm z7MF#TUt!4#EyFY?1B!8WvQxU`d=Ue4D#?JrpWk^h_9FEQ>E1!7+r7;9g=k`Sgws>q zKld?5#*3nLdit^3?dqG&Z(<%+(gvMt8<)SgJDQ@`%r~!{#THuzXiZX$>w*(7`$4Z+AVY5#z9d=TQZzPrin(BD>M!1Y>{*9Sv@~tsnz!CR~nMp+p4kD zU0AwLr+R0mWES2&u>vo}q>xPsqZ60<+tMdi4D&E4enx~*U0mO)G;akg;$l9fdI?j% zM$$s!qz3-RvFZncg_RahP$`v+V)YU!H#}WzA7sx)j9Y)W+ssEx*DZ2-YGpD?r!siK zE@Q<`9-8&lC4+rD%3n`hL)`~yvI53s_#0gO0DC^y)z5GkdxN%>fMCb8Wsp-Y{SsLk zlgnr?7PB6U2SP6w%#3gye9pn$3?I7ba8ryFXJ_U4ud(D8yc@*`o`8Qj`aR{*;Ka=Z z-#5wrzc?)FOIIjjJpDB;DK8Y_4nWz@W3QaHx(yj>AE0Z$8+?J>kPPeiOYIzU!yM~v zPeY7z+Qns=fqTsKYwR0+(qaN^gmW`wS#v06>Puf4Gem#7oZA4K>MTWl~D5Rr=dL}VR~JK$Dx;?J|UpIw(FTXES$UushXb09Va1cTZNz8d(^`lTDp#D zAF_$ai!;<`CZZvN3U_dE(R@r~tmR^L9)8qsnuRw|FKnC{@!TPSysVouuE_=)F8m%? zwI3$Z89L$3O?CL=#REcqg?nN}8~|IUkCI)%H z824xzLJa&O(h@J>9B;wFoUT2U`<5A$M7QCNBc8JUE22M^o1pr=QMfy zejFKy^*edZ+vmh@CCl_Rl&_R}vW${*-j!+_K_9QTecV2f-F8Pog5K**EYNfLmXPj1 z96D~^umS!LvuVi)UNQory3n>{1lWNARm^QWcI?15k;mxR*b>F1oApnpD1prmze~Re^0+G>7>xh_eFT9%i Q=0;t0j;YLJ-k@sw8?RdGYXATM diff --git a/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kps b/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kps index 9d03ec759b..73a8e740ac 100644 --- a/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kps +++ b/android/Tests/KeyboardHarness/app/src/main/assets/keyboardharness.kps @@ -26,7 +26,7 @@ .js - ..\..\..\..\..\..\..\web\src\test\manual\web\platform\platformtest.js + ../../../../../../../common/test/keyboards/platform-rules/platformtest.js File platformtest.js 0 .js diff --git a/windows/src/test/manual-tests/platform-rules/platform-results.xlsx b/common/test/keyboards/platform-rules/platform-results.xlsx similarity index 100% rename from windows/src/test/manual-tests/platform-rules/platform-results.xlsx rename to common/test/keyboards/platform-rules/platform-results.xlsx diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.js b/common/test/keyboards/platform-rules/platformtest.js similarity index 100% rename from windows/src/test/manual-tests/platform-rules/platformtest.js rename to common/test/keyboards/platform-rules/platformtest.js diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.kmn b/common/test/keyboards/platform-rules/platformtest.kmn similarity index 100% rename from windows/src/test/manual-tests/platform-rules/platformtest.kmn rename to common/test/keyboards/platform-rules/platformtest.kmn diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.kmp b/common/test/keyboards/platform-rules/platformtest.kmp similarity index 86% rename from windows/src/test/manual-tests/platform-rules/platformtest.kmp rename to common/test/keyboards/platform-rules/platformtest.kmp index d60fe88152402ace7557a0f1513857bb070579c3..ecef09c75cd43faa05f21e49145c5f6ca96eb436 100644 GIT binary patch delta 80 zcmew=^Hqj7z?+$ci-CcGgJH_P=#9KzSeb$JW)`+g2%~^onh_*2xsT^NnC{@U2GhrQ Pt-v%hpD~!WXAGt-`D_5zJrT(O diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.kmx b/common/test/keyboards/platform-rules/platformtest.kmx similarity index 100% rename from windows/src/test/manual-tests/platform-rules/platformtest.kmx rename to common/test/keyboards/platform-rules/platformtest.kmx diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.kpj b/common/test/keyboards/platform-rules/platformtest.kpj similarity index 100% rename from windows/src/test/manual-tests/platform-rules/platformtest.kpj rename to common/test/keyboards/platform-rules/platformtest.kpj diff --git a/windows/src/test/manual-tests/platform-rules/platformtest.kps b/common/test/keyboards/platform-rules/platformtest.kps similarity index 100% rename from windows/src/test/manual-tests/platform-rules/platformtest.kps rename to common/test/keyboards/platform-rules/platformtest.kps From 02619c2ef5ae62a3343bf43ba1c3be92b23c2852 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Tue, 28 Oct 2025 11:31:13 +0700 Subject: [PATCH 26/83] fix(web): Update manual test page to use common platformtest.js --- web/src/test/manual/build.sh | 3 +- web/src/test/manual/web/platform/index.html | 10 +- .../test/manual/web/platform/platformtest.js | 380 ------------------ web/src/test/manual/web/platform/utilities.js | 2 +- 4 files changed, 8 insertions(+), 387 deletions(-) delete mode 100644 web/src/test/manual/web/platform/platformtest.js diff --git a/web/src/test/manual/build.sh b/web/src/test/manual/build.sh index 53a784bdf8..85cb2c4c7d 100755 --- a/web/src/test/manual/build.sh +++ b/web/src/test/manual/build.sh @@ -50,7 +50,8 @@ function do_copy() { mkdir -p "$GESTURE_PROCESSOR_TARGET" cp -a "$GESTURE_PROCESSOR_BUILD" "$GESTURE_PROCESSOR_TARGET" - # copy common test resources (keyboards) + # copy common test (resources) keyboards + cp -f "$KEYMAN_ROOT/common/test/keyboards/platform-rules/platformtest.js" "$KEYMAN_ROOT/$DEST/keyboards/" cp -f "$KEYMAN_ROOT/common/test/resources/keyboards/"*.js "$KEYMAN_ROOT/$DEST/keyboards/" } diff --git a/web/src/test/manual/web/platform/index.html b/web/src/test/manual/web/platform/index.html index c528862ead..7f007561fd 100644 --- a/web/src/test/manual/web/platform/index.html +++ b/web/src/test/manual/web/platform/index.html @@ -53,12 +53,12 @@

KeymanWeb Sample Page - Platform Testing

-

This page is designed to test the Platform statement for consistency. - Refer to PR #969. - See also /windows/src/test/manual-tests/platform-rules/platform-results.xlsx. +

This page is designed to test the Platform statement for consistency. + Refer to PR #969.
+ See also /common/test/keyboards/platform-rules/platform-results.xlsx.
To run the test, just press [a]. This can be pasted into the above spreadsheet.

-

Be sure to reference the developer console for additional feedback.

-
+

Be sure to reference the developer console for additional feedback.

+