mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-05 00:15:32 +00:00
Merge branch 'epic/kmc-convert' into feat/developer/kmc-convert
Some checks failed
Keyman Build Summary / Summarize build status checks (push) Has been cancelled
Some checks failed
Keyman Build Summary / Summarize build status checks (push) Has been cancelled
This commit is contained in:
commit
c53456ddc5
140 changed files with 1376 additions and 1415 deletions
|
|
@ -119,7 +119,7 @@ jobs:
|
|||
- name: Install meson
|
||||
shell: bash
|
||||
run: |
|
||||
pip3 install --user meson==1.10.1
|
||||
pip3 install --user meson==1.11.0
|
||||
|
||||
- name: Run test
|
||||
shell: bash
|
||||
|
|
|
|||
4
.github/workflows/labeler.yml
vendored
4
.github/workflows/labeler.yml
vendored
|
|
@ -8,12 +8,12 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Update labels based on changed files
|
||||
uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1
|
||||
uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
- name: Update labels based on PR title
|
||||
id: labeler
|
||||
uses: fuxingloh/multi-labeler@f5bd7323b53b0833c1e4ed8d7b797ae995ef75b4 # v2.0.1
|
||||
uses: fuxingloh/multi-labeler@bcd50af464202999e57f556b4aefcf05a34abf85 # v5.0.0
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
config-path: .github/multi-labeler.yml
|
||||
|
|
|
|||
43
HISTORY.md
43
HISTORY.md
|
|
@ -1,5 +1,48 @@
|
|||
# Keyman Version History
|
||||
|
||||
## 19.0.247 alpha 2026-06-16
|
||||
|
||||
* chore: update multi-labeler to 5.0.0 (#16100)
|
||||
|
||||
## 19.0.246 alpha 2026-06-15
|
||||
|
||||
* feat(developer): run project validation from IDE (#16076)
|
||||
* fix(core): use meson subsystem and needs_exe_wrapper for cross builds on Windows (#16088)
|
||||
* docs(windows): add context documentation for additional Advanced options (#16089)
|
||||
|
||||
## 19.0.245 alpha 2026-06-10
|
||||
|
||||
* chore(web): hide KMX keyboard test page (#16083)
|
||||
* docs(web): remove unnecessary mentioning of Keyman 17 from docs (#16085)
|
||||
* chore(web): remove outdated `*_load.js` files (#16086)
|
||||
* fix(web): fix `KeyboardStub.validateForCustomKeyboard` (#16067)
|
||||
|
||||
## 19.0.244 alpha 2026-06-09
|
||||
|
||||
* refactor(web): extract function, rename variables (#16063)
|
||||
* refactor(web): reformatting of files (#16066)
|
||||
* chore(web): improve the KeymanWeb integration documentation (#16064)
|
||||
* chore(web): more improvements to documentation (#16070)
|
||||
|
||||
## 19.0.243 alpha 2026-06-08
|
||||
|
||||
* fix(developer): reduce km_core_keyboard_attrs size to 12 (#16075)
|
||||
* chore(deps): bump minimatch in /core/tests/unit/wasm (#16045)
|
||||
* chore(deps): bump glob from 10.4.5 to 10.5.0 in /core/tests/unit/wasm (#16046)
|
||||
* chore(deps-dev): bump js-yaml from 4.1.0 to 4.2.0 in /core/tests/unit/wasm (#16047)
|
||||
* chore(deps-dev): bump picomatch from 2.3.1 to 2.3.2 in /core/tests/unit/wasm (#16048)
|
||||
* chore(deps): bump qs and express (#16009)
|
||||
|
||||
## 19.0.242 alpha 2026-06-03
|
||||
|
||||
* fix(web): fix displaying of keyboard menu (#16061)
|
||||
|
||||
## 19.0.241 alpha 2026-06-02
|
||||
|
||||
* chore(web): web-core preflight - strip core references (#16040)
|
||||
* docs: add note on how to use composer on dockerized websites (#16029)
|
||||
* fix(web): fix race displaying active keyboard in menu (#16042)
|
||||
|
||||
## 19.0.240 alpha 2026-05-28
|
||||
|
||||
* chore(web): add filename to link text of manual web tests (#16019)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
19.0.241
|
||||
19.0.248
|
||||
|
|
@ -36,22 +36,20 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
(function(kmw) {
|
||||
kmw.init({
|
||||
attachType:'auto'
|
||||
}).then(function() {
|
||||
kmw.addKeyboards({
|
||||
id:'test_8568_deadkeys',
|
||||
name:'Testcase for deadkeys bug (#8568)',
|
||||
languages:{
|
||||
id:'en',
|
||||
name:'English'
|
||||
},
|
||||
filename:'./test_8568_deadkeys.js'
|
||||
});
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(async function() {
|
||||
await keyman.addKeyboards({
|
||||
id:'test_8568_deadkeys',
|
||||
name:'Testcase for deadkeys bug (#8568)',
|
||||
languages:{
|
||||
id:'en',
|
||||
name:'English'
|
||||
},
|
||||
filename:'./test_8568_deadkeys.js'
|
||||
});
|
||||
})(keyman);
|
||||
</script>
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
[host_machine]
|
||||
system = 'windows'
|
||||
subsystem = 'windows'
|
||||
cpu_family = 'aarch64'
|
||||
cpu = 'arm64'
|
||||
endian = 'little'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
[host_machine]
|
||||
system = 'windows'
|
||||
subsystem = 'windows'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
|
|
@ -11,3 +12,6 @@ ar = 'lib'
|
|||
ld = 'link'
|
||||
strip = 'llvm-strip'
|
||||
pkgconfig = 'pkg-config'
|
||||
|
||||
[properties]
|
||||
needs_exe_wrapper = false
|
||||
|
|
|
|||
49
core/tests/unit/wasm/package-lock.json
generated
49
core/tests/unit/wasm/package-lock.json
generated
|
|
@ -133,9 +133,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz",
|
||||
"integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
@ -538,9 +538,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "10.4.5",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
||||
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
|
||||
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
|
||||
"deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
|
@ -572,13 +573,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/glob/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
"brace-expansion": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
|
|
@ -710,10 +711,20 @@
|
|||
}
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz",
|
||||
"integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/puzrin"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/nodeca"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
|
|
@ -770,9 +781,9 @@
|
|||
"license": "ISC"
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"version": "5.1.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
|
||||
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
|
@ -932,9 +943,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
|
||||
"integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ hamburger menu in the Keyman app.
|
|||
**Web**: copy khmer_angkor.js to your website, then [load it with KeymanWeb][load-keymanweb-keyboard]:
|
||||
|
||||
```js
|
||||
keyman.addKeyboards({
|
||||
await keyman.addKeyboards({
|
||||
id:'khmer_angkor', // The keyboard's unique identification code.
|
||||
name:'Khmer Angkor', // The keyboard's user-readable name.
|
||||
language:{
|
||||
|
|
|
|||
|
|
@ -198,6 +198,13 @@ The following parameters are available:
|
|||
project (which can also be controlled at a project level with the
|
||||
`skipMetadataFiles` option). This option is only valid for compiling projects.
|
||||
|
||||
`--publish-only`
|
||||
|
||||
: Skip building component files within a project, and only run the validation
|
||||
step. Must be combined with `--for-publishing` in order to have an effect.
|
||||
This option is only valid for compiling projects, and is mostly intended for
|
||||
use by the IDE. Will fail if build artifacts for components are not present.
|
||||
|
||||
### Examples
|
||||
|
||||
```shell
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ hamburger menu in the Keyman app.
|
|||
**Web**: copy khmer_angkor.js to your website, then [load it with KeymanWeb][load-keymanweb-keyboard]:
|
||||
|
||||
```js
|
||||
keyman.addKeyboards({
|
||||
await keyman.addKeyboards({
|
||||
id:'khmer_angkor', // The keyboard's unique identification code.
|
||||
name:'Khmer Angkor', // The keyboard's user-readable name.
|
||||
language:{
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ export function declareBuild(program: Command) {
|
|||
buildCommand.command('file [infile...]', {isDefault: true})
|
||||
.description(`Compile one or more source files or projects ('file' subcommand is default).`)
|
||||
.option('--for-publishing', 'Verify that project meets @keymanapp repository requirements')
|
||||
.option('--publish-only', 'Only run the for-publishing validation, skip all other build steps')
|
||||
.addHelpText('after', `
|
||||
Supported file types:
|
||||
* folder: Keyman project in folder
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ export class BuildKeyboardInfo extends BuildActivity {
|
|||
sourcePath: calculateSourcePath(infile),
|
||||
lastCommitDate,
|
||||
forPublishing: !!options.forPublishing,
|
||||
publishOnly: !!options.publishOnly,
|
||||
};
|
||||
// Note: should we always ignore the passed-in output filename for .keyboard_info?
|
||||
const outputFilename = project.getOutputFilePath(KeymanFileTypes.Binary.KeyboardInfo);
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ export class BuildModelInfo extends BuildActivity {
|
|||
kpsFilename: project.resolveInputFilePath(kps),
|
||||
lastCommitDate,
|
||||
forPublishing: !!options.forPublishing,
|
||||
publishOnly: !!options.publishOnly,
|
||||
};
|
||||
|
||||
// Note: should we always ignore the passed-in output filename for .model_info?
|
||||
|
|
|
|||
|
|
@ -51,15 +51,17 @@ class ProjectBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
// Go through the various file types and build them
|
||||
for(const builder of buildActivities) {
|
||||
if(builder.sourceExtension == KeymanFileTypes.Source.Project) {
|
||||
// We don't support nested projects
|
||||
continue;
|
||||
}
|
||||
if(!this.options.publishOnly) {
|
||||
// Go through the various file types and build them
|
||||
for(const builder of buildActivities) {
|
||||
if(builder.sourceExtension == KeymanFileTypes.Source.Project) {
|
||||
// We don't support nested projects
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!await this.buildProjectTargets(builder)) {
|
||||
return false;
|
||||
if(!await this.buildProjectTargets(builder)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +115,11 @@ class ProjectBuilder {
|
|||
|
||||
const buildFilename = path.relative(process.cwd(), infile).replace(/\\/g, '/');
|
||||
const callbacks = new CompilerFileCallbacks(buildFilename, options, this.callbacks);
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_BuildingFile({filename: infile, relativeFilename:buildFilename}));
|
||||
if(activity.sourceExtension == KeymanFileTypes.Source.Project) {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_ValidatingProject({filename: infile, relativeFilename:buildFilename}));
|
||||
} else {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_BuildingFile({filename: infile, relativeFilename:buildFilename}));
|
||||
}
|
||||
|
||||
fs.mkdirSync(path.dirname(outfile), {recursive:true});
|
||||
|
||||
|
|
@ -123,12 +129,19 @@ class ProjectBuilder {
|
|||
// note: command line option here, if set, overrides project setting
|
||||
result = result && !callbacks.hasFailureMessage(this.options.compilerWarningsAsErrors ?? this.project.options.compilerWarningsAsErrors);
|
||||
|
||||
if(result) {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_FileBuiltSuccessfully({filename: infile, relativeFilename:buildFilename}));
|
||||
if(activity.sourceExtension == KeymanFileTypes.Source.Project) {
|
||||
if(result) {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_ProjectValidatedSuccessfully({filename: infile, relativeFilename:buildFilename}));
|
||||
} else {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_ProjectNotValidatedSuccessfully({filename: infile, relativeFilename:buildFilename}));
|
||||
}
|
||||
} else {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_FileNotBuiltSuccessfully({filename: infile, relativeFilename: buildFilename}));
|
||||
if(result) {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_FileBuiltSuccessfully({filename: infile, relativeFilename:buildFilename}));
|
||||
} else {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_FileNotBuiltSuccessfully({filename: infile, relativeFilename: buildFilename}));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -197,5 +197,26 @@ export class InfrastructureMessages {
|
|||
`Failed to generate new project '${def(o.id)}'.`,
|
||||
)});
|
||||
|
||||
// For this message, we override the filename with the passed-in file. A bit of a hack but does the job
|
||||
static INFO_ValidatingProject = SevInfo | 0x0029;
|
||||
static Info_ValidatingProject = (o:{filename:string,relativeFilename:string}) => ({filename:o.filename, ...m(
|
||||
this.INFO_ValidatingProject,
|
||||
`Validating ${def(o.relativeFilename)}`,
|
||||
)});
|
||||
|
||||
// For this message, we override the filename with the passed-in file. A bit of a hack but does the job
|
||||
static INFO_ProjectValidatedSuccessfully = SevInfo | 0x002A;
|
||||
static Info_ProjectValidatedSuccessfully = (o:{filename:string,relativeFilename:string}) => ({filename:o.filename, ...m(
|
||||
this.INFO_ProjectValidatedSuccessfully,
|
||||
`${def(o.relativeFilename)} validated successfully.`,
|
||||
)});
|
||||
|
||||
// For this message, we override the filename with the passed-in file. A bit of a hack but does the job
|
||||
static INFO_ProjectNotValidatedSuccessfully = SevInfo | 0x002B;
|
||||
static Info_ProjectNotValidatedSuccessfully = (o:{filename:string,relativeFilename:string}) => ({filename:o.filename, ...m(
|
||||
this.INFO_ProjectNotValidatedSuccessfully,
|
||||
`${def(o.relativeFilename)} failed to validate.`
|
||||
)});
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -242,22 +242,26 @@ export class NodeCompilerCallbacks implements CompilerCallbacks {
|
|||
* We treat a few certain infrastructure messages with special colours
|
||||
* @param event
|
||||
* @returns
|
||||
* Keep in sync with: UfrmMessages.pas, TfrmMessages.Add
|
||||
*/
|
||||
messageSpecialColor(event: CompilerEvent) {
|
||||
switch(event.code) {
|
||||
case InfrastructureMessages.INFO_BuildingFile:
|
||||
case InfrastructureMessages.INFO_CopyingProject:
|
||||
case InfrastructureMessages.INFO_GeneratingProject:
|
||||
case InfrastructureMessages.INFO_ValidatingProject:
|
||||
return color.whiteBright;
|
||||
case InfrastructureMessages.INFO_FileNotBuiltSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectNotBuiltSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectNotCopiedSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectNotGeneratedSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectNotValidatedSuccessfully:
|
||||
return color.red;
|
||||
case InfrastructureMessages.INFO_FileBuiltSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectBuiltSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectCopiedSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectGeneratedSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectValidatedSuccessfully:
|
||||
return color.green;
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ export interface ExtendedCompilerOptions extends CompilerOptions {
|
|||
* MIT
|
||||
*/
|
||||
forPublishing?: boolean;
|
||||
/**
|
||||
* Do not build components, just do the publish phase for the project. This is
|
||||
* used mostly by Keyman Developer IDE, which will run the .keyboard_info /
|
||||
* .package_info validation and compilation step if skipMetadataFiles is true.
|
||||
*/
|
||||
publishOnly?: boolean;
|
||||
/**
|
||||
* Overrides for message reporting
|
||||
*/
|
||||
|
|
@ -198,6 +204,7 @@ export function commanderOptionsToCompilerOptions(options: any, callbacks: Compi
|
|||
warnDeprecatedCode: options.warnDeprecatedCode,
|
||||
// ExtendedOptions
|
||||
forPublishing: options.forPublishing,
|
||||
publishOnly: options.publishOnly,
|
||||
messageOverrides: overrides,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
"@ngrok/ngrok": "^1.7.0",
|
||||
"@sentry/node": "^7.57.0",
|
||||
"chalk": "^4.1.2",
|
||||
"express": "^4.22.1",
|
||||
"express": "^4.22.2",
|
||||
"multer": "^2.1.1",
|
||||
"open": "^8.4.0",
|
||||
"restructure": "^3.0.1",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ type
|
|||
function Run(const parameters: TArray<string>; const path, logFilename: string; Callback: TUtilExecuteCallbackEvent): Boolean;
|
||||
public
|
||||
function Compile(ProjectFile: TProjectFile; const infile, outfile: string; debug: Boolean; Callback: TUtilExecuteCallbackEvent = nil): Boolean;
|
||||
function CompileForPublishing(ProjectFile: TProjectFile; const projectFilename: string; debug: Boolean; Callback: TUtilExecuteCallbackEvent = nil): Boolean;
|
||||
function Copy(const source, dest, cwd: string; relocateExternal: Boolean; Callback: TUtilExecuteCallbackEvent = nil): Boolean;
|
||||
end;
|
||||
|
||||
|
|
@ -39,6 +40,39 @@ uses
|
|||
|
||||
{ TKmcWrapper }
|
||||
|
||||
function TKmcWrapper.CompileForPublishing(
|
||||
ProjectFile: TProjectFile;
|
||||
const projectFilename: string;
|
||||
debug: Boolean;
|
||||
Callback: TUtilExecuteCallbackEvent
|
||||
): Boolean;
|
||||
var
|
||||
cmdline: TArray<string>;
|
||||
begin
|
||||
cmdline := [
|
||||
'build',
|
||||
'--log-format', 'tsv',
|
||||
'--log-level', 'info',
|
||||
'--for-publishing',
|
||||
'--publish-only',
|
||||
projectFilename
|
||||
];
|
||||
|
||||
if Assigned(FGlobalProject) and (FGlobalProject.Options.CompilerWarningsAsErrors) then
|
||||
cmdline := cmdline + ['--compiler-warnings-as-errors']
|
||||
else
|
||||
cmdline := cmdline + ['--no-compiler-warnings-as-errors'];
|
||||
|
||||
if Assigned(FGlobalProject) and (not FGlobalProject.Options.WarnDeprecatedCode) then
|
||||
cmdline := cmdline + ['--no-warn-deprecated-code'];
|
||||
|
||||
if debug then
|
||||
cmdline := cmdline + ['--debug'];
|
||||
|
||||
Result := Run(cmdline, ExtractFileDir(projectFilename), projectFilename, Callback);
|
||||
end;
|
||||
|
||||
|
||||
function TKmcWrapper.Compile(
|
||||
ProjectFile: TProjectFile;
|
||||
const infile: string;
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ type
|
|||
km_core_keyboard_attrs = record
|
||||
version_string: pkm_core_cu;
|
||||
id: pkm_core_cu;
|
||||
default_optons: pkm_core_option_item
|
||||
default_options: pkm_core_option_item
|
||||
end;
|
||||
|
||||
pkm_core_keyboard_attrs = ^km_core_keyboard_attrs;
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ initialization
|
|||
Assert(sizeof(km_core_context_item) = 8);
|
||||
Assert(sizeof(km_core_action_item) = 12);
|
||||
Assert(sizeof(km_core_option_item) = 12);
|
||||
Assert(sizeof(km_core_keyboard_attrs) = 16);
|
||||
Assert(sizeof(km_core_keyboard_attrs) = 12);
|
||||
Assert(sizeof(km_core_attr) = 16);
|
||||
|
||||
//keyman_core_api_debug.h:
|
||||
|
|
|
|||
|
|
@ -170,6 +170,12 @@ const // ABGR - text on white bg, Colors similar to Light+ VSCode color theme
|
|||
INFO_FileNotBuiltSuccessfully = NAMESPACE_Infrastructure or $0007;
|
||||
INFO_ProjectBuiltSuccessfully = NAMESPACE_Infrastructure or $000B;
|
||||
INFO_ProjectNotBuiltSuccessfully = NAMESPACE_Infrastructure or $000C;
|
||||
INFO_ProjectCopiedSuccessfully = NAMESPACE_Infrastructure or $0024;
|
||||
INFO_ProjectNotCopiedSuccessfully = NAMESPACE_Infrastructure or $0025;
|
||||
INFO_ProjectGeneratedSuccessfully = NAMESPACE_Infrastructure or $0027;
|
||||
INFO_ProjectNotGeneratedSuccessfully = NAMESPACE_Infrastructure or $0028;
|
||||
INFO_ProjectValidatedSuccessfully = NAMESPACE_Infrastructure or $002A;
|
||||
INFO_ProjectNotValidatedSuccessfully = NAMESPACE_Infrastructure or $002B;
|
||||
|
||||
Segment_Filename = 0;
|
||||
Segment_Filename_Separator = 1;
|
||||
|
|
@ -254,12 +260,18 @@ begin
|
|||
FColor := clBlack;
|
||||
FTextColor := Color_Text;
|
||||
|
||||
// Override formatting for 4 known messages
|
||||
// Override formatting for known messages -- keep in sync with messageSpecialColor() in NodeCompilerCallbacks.ts
|
||||
if (MsgCode = INFO_FileBuiltSuccessfully) or
|
||||
(MsgCode = INFO_ProjectBuiltSuccessfully) then
|
||||
(MsgCode = INFO_ProjectBuiltSuccessfully) or
|
||||
(MsgCode = INFO_ProjectCopiedSuccessfully) or
|
||||
(MsgCode = INFO_ProjectGeneratedSuccessfully) or
|
||||
(MsgCode = INFO_ProjectValidatedSuccessfully) then
|
||||
state := plsSuccess
|
||||
else if (MsgCode = INFO_FileNotBuiltSuccessfully) or
|
||||
(MsgCode = INFO_ProjectNotBuiltSuccessfully) then
|
||||
(MsgCode = INFO_ProjectNotBuiltSuccessfully) or
|
||||
(MsgCode = INFO_ProjectNotCopiedSuccessfully) or
|
||||
(MsgCode = INFO_ProjectNotGeneratedSuccessfully) or
|
||||
(MsgCode = INFO_ProjectNotValidatedSuccessfully) then
|
||||
state := plsFailure;
|
||||
|
||||
case state of
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ begin
|
|||
w := TKmcWrapper.Create;
|
||||
try
|
||||
Result := w.Compile(Self, FileName, TargetFilename, False);
|
||||
if not OwnerProject.Options.SkipMetadataFiles then
|
||||
Result := Result and w.CompileForPublishing(Self, OwnerProject.FileName, False);
|
||||
// TODO(lowpri): FDebug flag
|
||||
finally
|
||||
w.Free;
|
||||
|
|
|
|||
|
|
@ -419,11 +419,6 @@
|
|||
<p>Choose a help file to include in the keyboard</p>
|
||||
</Control>
|
||||
|
||||
<Control Name="cmdCompileKeymanWeb" Title="Compile to Web">
|
||||
<p>Compiles the keyboard for KeymanWeb. Two output files will be generated: [filename].js and [filename]_load.js. The KeymanWeb Tutorial
|
||||
contains more information about the difference between the two output files.</p>
|
||||
</Control>
|
||||
|
||||
<Control Name="cmdTestKeymanWeb" Title="Test KeymanWeb Keyboard">
|
||||
<p>Tests your KeymanWeb keyboard in an Internet Explorer embedded window</p>
|
||||
</Control>
|
||||
|
|
|
|||
147
package-lock.json
generated
147
package-lock.json
generated
|
|
@ -1232,7 +1232,7 @@
|
|||
"@ngrok/ngrok": "^1.7.0",
|
||||
"@sentry/node": "^7.57.0",
|
||||
"chalk": "^4.1.2",
|
||||
"express": "^4.22.1",
|
||||
"express": "^4.22.2",
|
||||
"multer": "^2.1.1",
|
||||
"open": "^8.4.0",
|
||||
"restructure": "^3.0.1",
|
||||
|
|
@ -5301,22 +5301,23 @@
|
|||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "1.20.3",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
|
||||
"version": "1.20.5",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz",
|
||||
"integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"bytes": "~3.1.2",
|
||||
"content-type": "~1.0.5",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"destroy": "1.2.0",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "2.4.1",
|
||||
"qs": "6.13.0",
|
||||
"raw-body": "2.5.2",
|
||||
"destroy": "~1.2.0",
|
||||
"http-errors": "~2.0.1",
|
||||
"iconv-lite": "~0.4.24",
|
||||
"on-finished": "~2.4.1",
|
||||
"qs": "~6.15.1",
|
||||
"raw-body": "~2.5.3",
|
||||
"type-is": "~1.6.18",
|
||||
"unpipe": "1.0.0"
|
||||
"unpipe": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8",
|
||||
|
|
@ -5327,6 +5328,7 @@
|
|||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
|
|
@ -5335,14 +5337,60 @@
|
|||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser/node_modules/http-errors": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"depd": "~2.0.0",
|
||||
"inherits": "~2.0.4",
|
||||
"setprototypeof": "~1.2.0",
|
||||
"statuses": "~2.0.2",
|
||||
"toidentifier": "~1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/body-parser/node_modules/raw-body": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz",
|
||||
"integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bytes": "~3.1.2",
|
||||
"http-errors": "~2.0.1",
|
||||
"iconv-lite": "~0.4.24",
|
||||
"unpipe": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser/node_modules/statuses": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
|
|
@ -5600,6 +5648,7 @@
|
|||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
|
|
@ -6372,6 +6421,7 @@
|
|||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
|
|
@ -7832,14 +7882,14 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.22.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz",
|
||||
"integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
|
||||
"version": "4.22.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz",
|
||||
"integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "~1.20.3",
|
||||
"body-parser": "~1.20.5",
|
||||
"content-disposition": "~0.5.4",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "~0.7.1",
|
||||
|
|
@ -7858,7 +7908,7 @@
|
|||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "~0.1.12",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "~6.14.0",
|
||||
"qs": "~6.15.1",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.2.1",
|
||||
"send": "~0.19.0",
|
||||
|
|
@ -7908,40 +7958,6 @@
|
|||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/express/node_modules/qs": {
|
||||
"version": "6.14.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz",
|
||||
"integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/express/node_modules/side-channel": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
||||
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"object-inspect": "^1.13.3",
|
||||
"side-channel-list": "^1.0.0",
|
||||
"side-channel-map": "^1.0.1",
|
||||
"side-channel-weakmap": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/express/node_modules/statuses": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||
|
|
@ -8666,6 +8682,7 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0"
|
||||
},
|
||||
|
|
@ -11784,12 +11801,12 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||
"version": "6.15.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
|
||||
"integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.6"
|
||||
"side-channel": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
|
|
@ -11844,6 +11861,7 @@
|
|||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
||||
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"http-errors": "2.0.0",
|
||||
|
|
@ -12272,6 +12290,7 @@
|
|||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
|
|
@ -12339,14 +12358,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/side-channel": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
|
||||
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
||||
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.7",
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"object-inspect": "^1.13.1"
|
||||
"object-inspect": "^1.13.3",
|
||||
"side-channel-list": "^1.0.0",
|
||||
"side-channel-map": "^1.0.1",
|
||||
"side-channel-weakmap": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
|
|
@ -14256,7 +14277,7 @@
|
|||
"@sentry/cli": "^2.31.0",
|
||||
"@zip.js/zip.js": "^2.7.32",
|
||||
"c8": "^7.12.0",
|
||||
"express": "^4.19.2",
|
||||
"express": "^4.22.2",
|
||||
"jsdom": "^23.0.1",
|
||||
"promise-status-async": "^1.2.10",
|
||||
"tsx": "^4.19.0"
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ There are multiple ways to add and install keyboards into your KeymanWeb install
|
|||
|
||||
The most efficient way to utilize a keyboard is to obtain a local copy of it and place this copy in a static location on your website. Once this is done, it can be directly linked into KeymanWeb as follows.
|
||||
|
||||
```c
|
||||
keyman.addKeyboards({
|
||||
```typescript
|
||||
await keyman.addKeyboards({
|
||||
id:'us', // The keyboard's unique identification code.
|
||||
name:'English', // The keyboard's user-readable name.
|
||||
language:{
|
||||
|
|
@ -22,7 +22,7 @@ keyman.addKeyboards({
|
|||
|
||||
Custom fonts may also be utilized via the `language.font` property. For example:
|
||||
|
||||
```c
|
||||
```typescript
|
||||
font:{
|
||||
family:'LaoWeb',
|
||||
source:['../font/saysettha_web.ttf','../font/saysettha_web.woff','../font/saysettha_web.eot']
|
||||
|
|
@ -33,16 +33,16 @@ font:{
|
|||
|
||||
To obtain the default Keyman keyboard for a given language, call the following function.
|
||||
|
||||
```c
|
||||
keyman.addKeyboardsForLanguage('Dzongkha');
|
||||
```typescript
|
||||
await keyman.addKeyboardsForLanguage('Dzongkha');
|
||||
```
|
||||
|
||||
This example would find the default keyboard for the Dzongkha language. This method will fail if the name doesn't perfectly match any language found in the CDN's repository.
|
||||
|
||||
Alternatively, languages may be looked up via their BCP 47 language code as follows:
|
||||
|
||||
```c
|
||||
keyman.addKeyboards('@he')
|
||||
```typescript
|
||||
await keyman.addKeyboards('@he');
|
||||
```
|
||||
|
||||
The `@` prefix indicates the use of the BCP 47 language code, which in this case corresponds with Hebrew.
|
||||
|
|
@ -51,8 +51,8 @@ The `@` prefix indicates the use of the BCP 47 language code, which in this case
|
|||
|
||||
To obtain a specific keyboard by name or by keyboard name and language code as a pair, see the following:
|
||||
|
||||
```c
|
||||
keyman.addKeyboards('french','sil_euro_latin@sv','sil_euro_latin@no')
|
||||
```typescript
|
||||
await keyman.addKeyboards('french', 'sil_euro_latin@sv', 'sil_euro_latin@no');
|
||||
```
|
||||
|
||||
This will install three keyboards - one for French (named, quite simply, "French") and two copies of the EuroLatin keyboard - one for Swedish and one for Norwegian.
|
||||
|
|
|
|||
|
|
@ -1,20 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src='https://s.keyman.com/kmw/engine/17.0.331/keymanweb.js'></script>
|
||||
<script>var kmw = keyman;</script>
|
||||
|
||||
<script>
|
||||
window.addEventListener('load', function () {
|
||||
keyman.init().then(function() {
|
||||
keyman.addKeyboards({
|
||||
id:'laokeys',
|
||||
name:'Lao (Phonetic)',
|
||||
languages:{
|
||||
id:'lo',
|
||||
name:'Lao'
|
||||
},
|
||||
filename:'./js/laokeys.js'
|
||||
});
|
||||
keyman.init().then(async function() {
|
||||
await keyman.addKeyboards({
|
||||
id:'laokeys',
|
||||
name:'Lao (Phonetic)',
|
||||
languages:{
|
||||
id:'lo',
|
||||
name:'Lao'
|
||||
},
|
||||
filename:'./js/laokeys.js'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
@ -28,4 +25,4 @@
|
|||
|
||||
<a href="automatic-control">Back to Document</a>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,35 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<script src='https://s.keyman.com/kmw/engine/17.0.331/keymanweb.js'></script>
|
||||
<script>var kmw = keyman;</script>
|
||||
<script src='https://s.keyman.com/kmw/engine/17.0.331/kmwuitoggle.js'></script>
|
||||
|
||||
<script type='text/javascript' src='js/unified_loader.js'></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function SetupDocument() {
|
||||
keyman.init({
|
||||
root: './', // Note - if drawing the latest version of KeymanWeb from the CDN, this will
|
||||
// default to the source folder on our servers.
|
||||
ui: 'toggle',
|
||||
resources: './'
|
||||
}).then(function() {
|
||||
// Load the keyboards of your choice here.
|
||||
loadKeyboards();
|
||||
keyman.init({
|
||||
root: './', // Note - if drawing the latest version of KeymanWeb from the CDN, this will
|
||||
// default to the source folder on our servers.
|
||||
ui: 'toggle',
|
||||
resources: './'
|
||||
}).then(async function() {
|
||||
// Load the keyboards of your choice here.
|
||||
await loadKeyboards();
|
||||
|
||||
/* Disable KeymanWeb interaction on the 'Email to' TEXT control */
|
||||
keyman.disableControl(document.f.address);
|
||||
/* Set the default keyboard for the 'Subject' TEXT control to 'off' (i.e. default browser keyboard) */
|
||||
/* As KeymanWeb relies on the on-screen keyboard to change languages for touch-based devices, this will
|
||||
* not work for them and will default to the first language added to KeymanWeb after initialization. */
|
||||
keyman.setKeyboardForControl(document.f.subject, '', '');
|
||||
/* Set the default keyboard for the 'Message body' TEXTAREA to the LaoKeys keyboard */
|
||||
keyman.setKeyboardForControl(document.f.text, 'Keyboard_laokeys', 'lo');
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener( 'load' , SetupDocument );
|
||||
// Disable KeymanWeb interaction on the 'Email to' TEXT control
|
||||
keyman.disableControl(document.f.address);
|
||||
// Set the default keyboard for the 'Subject' TEXT control to 'off' (i.e.
|
||||
// default browser keyboard). As KeymanWeb relies on the on-screen keyboard
|
||||
// to change languages for touch-based devices, this will not work for them
|
||||
// and will default to the first language added to KeymanWeb after
|
||||
// initialization.
|
||||
keyman.setKeyboardForControl(document.f.subject, '', '');
|
||||
// Set the default keyboard for the 'Message body' TEXTAREA to the LaoKeys keyboard
|
||||
keyman.setKeyboardForControl(document.f.text, 'Keyboard_laokeys', 'lo');
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -38,7 +36,7 @@
|
|||
|
||||
<p>Email to <span class='note'>(KeymanWeb not enabled)</span><br /><input type='text' name='address' size="40" placeholder="id = address"/></p>
|
||||
|
||||
<p>Subject <span class='note'>(Defaults to 'English' or 'off' unless on a touch-based device)</span><br /><input type='text' name='subject' size="40" placeholder="id = subject"/></p>
|
||||
<p>Subject <span class='note'>(Defaults to '(System keyboard)' or 'off' unless on a touch-based device)</span><br /><input type='text' name='subject' size="40" placeholder="id = subject"/></p>
|
||||
|
||||
<p>Message body <span class='note'>(Defaults to 'LaoKeys')</span><br /><textarea name='text' cols='40' rows='10' placeholder="id = text"></textarea></p>
|
||||
|
||||
|
|
@ -46,4 +44,4 @@
|
|||
|
||||
<a href="control-by-control">Back to Document</a>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -6,15 +6,14 @@
|
|||
|
||||
<!-- Start of Code -->
|
||||
<script src='https://s.keyman.com/kmw/engine/17.0.331/keymanweb.js'></script>
|
||||
<script>var kmw = keyman;</script>
|
||||
<script src='https://s.keyman.com/kmw/engine/17.0.331/kmwuitoggle.js'></script>
|
||||
<script>
|
||||
(function() {
|
||||
keyman.init({attachType:'auto'}).then(function() {
|
||||
keyman.addKeyboards('@en'); // Loads default English keyboard from Keyman Cloud (CDN)
|
||||
keyman.addKeyboards('@th'); // Loads default Thai keyboard from Keyman Cloud (CDN)
|
||||
});
|
||||
})(keyman);
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(async function() {
|
||||
await keyman.addKeyboards('@en'); // Loads default English keyboard from Keyman Cloud (CDN)
|
||||
await keyman.addKeyboards('@th'); // Loads default Thai keyboard from Keyman Cloud (CDN)
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -23,4 +22,4 @@
|
|||
|
||||
<a href="index">Back to Document</a>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,45 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<script src='https://s.keyman.com/kmw/engine/17.0.331/keymanweb.js'></script>
|
||||
<script>var kmw = keyman;</script>
|
||||
|
||||
<script type='text/javascript' src='js/unified_loader.js'></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var KWControl = null;
|
||||
|
||||
function SetupDocument()
|
||||
{
|
||||
keyman.init().then(function(){
|
||||
// Load the keyboards of your choice here.
|
||||
loadKeyboards();
|
||||
keyman.init().then(async function() {
|
||||
// Load the keyboards of your choice here.
|
||||
await loadKeyboards();
|
||||
|
||||
KWControl = document.getElementById('KWControl');
|
||||
var kbds = keyman.getKeyboards();
|
||||
for(var kbd in kbds)
|
||||
{
|
||||
var opt = document.createElement('OPTION');
|
||||
opt.value = kbds[kbd].InternalName + "$$" + kbds[kbd].LanguageCode;
|
||||
opt.innerHTML = kbds[kbd].Name;
|
||||
KWControl.appendChild(opt);
|
||||
}
|
||||
document.f.multilingual.focus();
|
||||
KWControl = document.getElementById('KWControl');
|
||||
var kbds = keyman.getKeyboards();
|
||||
for(var kbd in kbds)
|
||||
{
|
||||
var opt = document.createElement('OPTION');
|
||||
opt.value = kbds[kbd].InternalName + "$$" + kbds[kbd].LanguageCode;
|
||||
opt.innerHTML = kbds[kbd].Name;
|
||||
KWControl.appendChild(opt);
|
||||
}
|
||||
document.f.multilingual.focus();
|
||||
|
||||
keyman.setActiveKeyboard('', '');
|
||||
});
|
||||
}
|
||||
keyman.setActiveKeyboard('', '');
|
||||
});
|
||||
|
||||
function KWControlChange()
|
||||
{
|
||||
function KWControlChange() {
|
||||
var name = KWControl.value.substr(0, KWControl.value.indexOf("$$"));
|
||||
var languageCode = KWControl.value.substr(KWControl.value.indexOf("$$") + 2);
|
||||
keyman.setActiveKeyboard(name, languageCode);
|
||||
document.f.multilingual.focus();
|
||||
}
|
||||
|
||||
window.addEventListener( 'load' , SetupDocument );
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -1,29 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src='https://s.keyman.com/kmw/engine/17.0.331/keymanweb.js'></script>
|
||||
<script>var kmw = keyman;</script>
|
||||
|
||||
<script type='text/javascript' src='js/laokeys_load.js'></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function SetupDocument()
|
||||
{
|
||||
keyman.init().then(function() {
|
||||
keyman.setActiveKeyboard('laokeys');
|
||||
keyman.osk.hide();
|
||||
keyman.init().then(async function() {
|
||||
await keyman.addKeyboards({
|
||||
id: "laokeys",
|
||||
name: "Lao (Phonetic)",
|
||||
languages: { id: 'lo', name: 'Lao' },
|
||||
filename: "./js/laokeys.js"
|
||||
});
|
||||
}
|
||||
keyman.setActiveKeyboard('laokeys');
|
||||
keyman.osk.hide();
|
||||
});
|
||||
|
||||
function KWControlClick()
|
||||
{
|
||||
function KWControlClick() {
|
||||
if(keyman.osk.isEnabled()) {
|
||||
keyman.osk.hide();
|
||||
} else {
|
||||
keyman.osk.show(true); // Specifies that the OSK should display whenever a valid control has focus, re-enabling the default behavior.
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', SetupDocument);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -38,4 +36,4 @@
|
|||
<a href="manual-control">Back to Document</a>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -2,28 +2,28 @@
|
|||
title: Automatic Mode Example
|
||||
---
|
||||
|
||||
This page shows how to include a local keyboard from an arbitrary location in your website's file structure.
|
||||
This page shows how to include a local keyboard from an arbitrary location
|
||||
in your website's file structure.
|
||||
|
||||
In this example, we use only the LaoKey keyboard. Please click [this link](./__auto-control.html) to open the test page.
|
||||
In this example, we use only the LaoKey keyboard. Please click
|
||||
[this link](./__auto-control.html) to open the test page.
|
||||
|
||||
## Code Walkthrough
|
||||
|
||||
```html
|
||||
<head>
|
||||
<!-- Start of Code -->
|
||||
<script src="js/keymanweb.js" type="text/javascript"></script>
|
||||
<script src="https://s.keyman.com/kmw/engine/17.0.331/keymanweb.js" type="text/javascript"></script>
|
||||
<script>
|
||||
window.addEventListener('load', function () {
|
||||
keyman.init().then(function() {
|
||||
keyman.addKeyboards({
|
||||
id:'laokeys',
|
||||
name:'Lao (Phonetic)',
|
||||
languages:{
|
||||
id:'lo',
|
||||
name:'Lao'
|
||||
},
|
||||
filename:'./js/laokeys.js'
|
||||
});
|
||||
keyman.init().then(async function() {
|
||||
await keyman.addKeyboards({
|
||||
id:'laokeys',
|
||||
name:'Lao (Phonetic)',
|
||||
languages:{
|
||||
id:'lo',
|
||||
name:'Lao'
|
||||
},
|
||||
filename:'./js/laokeys.js'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
@ -31,8 +31,6 @@ In this example, we use only the LaoKey keyboard. Please click [this link](./__a
|
|||
</head>
|
||||
```
|
||||
|
||||
As you can see above, the second line in the code snippet above references the LaoKey keyboard loader JavaScript file. This is a small stub file, typically less than 200 bytes, that defines the name and actual location of the real keyboard file (in this case, **laokeys.js**). When a page may reference many keyboards, this saves downloading potentially hundreds of kilobytes of unused Javascript keyboards - the keyboard is downloaded when it is first selected by the user.
|
||||
|
||||
## API References
|
||||
|
||||
On initialization: [`keyman.init()`](../../reference/core/init).
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
title: Control-by-Control Example
|
||||
---
|
||||
|
||||
In this example, a simulated webmail form, the default and permissible keyboard for each control is managed by the web page. We use the automatic mode for simplicity of demonstration. We also link to the CDN for KeymanWeb in this example. Please click [this link](__control-by-control.html) to open the test page.
|
||||
In this example, a simulated webmail form, the default and permissible keyboard for each control
|
||||
is managed by the web page. We use the automatic mode for simplicity of demonstration. We also
|
||||
link to the CDN for KeymanWeb in this example. Please click [this link](__control-by-control.html)
|
||||
to open the test page.
|
||||
|
||||
## Code Walkthrough
|
||||
|
||||
|
|
@ -10,28 +13,23 @@ Include the following script in the HEAD of your page:
|
|||
|
||||
```js
|
||||
<script type="text/javascript">
|
||||
function SetupDocument() {
|
||||
keyman.init({
|
||||
root: './', // Note - if drawing the latest version of KeymanWeb from the CDN, this will
|
||||
// default to the source folder on our servers.
|
||||
ui: 'toggle',
|
||||
resources: './'
|
||||
}).then(function() {
|
||||
// Load the keyboards of your choice here.
|
||||
loadKeyboards();
|
||||
keyman.init({
|
||||
root: './', // Note - if drawing the latest version of KeymanWeb from the CDN, this will
|
||||
// default to the source folder on our servers.
|
||||
ui: 'toggle',
|
||||
resources: './'
|
||||
}).then(async function() {
|
||||
// Load the keyboards of your choice here.
|
||||
await loadKeyboards();
|
||||
|
||||
/* Disable KeymanWeb interaction on the 'Email to' TEXT control */
|
||||
keyman.disableControl(document.f.address);
|
||||
/* Set the default keyboard for the 'Subject' TEXT control to 'off' (i.e. default browser keyboard) */
|
||||
/* As KeymanWeb relies on the on-screen keyboard to change languages for touch-based devices, this will
|
||||
* not work for them and will default to the first language added to KeymanWeb after initialization. */
|
||||
keyman.setKeyboardForControl(document.f.subject, '', '');
|
||||
/* Set the default keyboard for the 'Message body' TEXTAREA to the LaoKeys keyboard */
|
||||
keyman.setKeyboardForControl(document.f.text, 'Keyboard_laokeys', 'lo');
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener( 'load' , SetupDocument );
|
||||
// Disable KeymanWeb interaction on the 'Email to' TEXT control
|
||||
keyman.disableControl(document.f.address);
|
||||
// Set the default keyboard for the 'Subject' TEXT control to 'off' (i.e. default
|
||||
// browser keyboard)
|
||||
keyman.setKeyboardForControl(document.f.subject, '', '');
|
||||
// Set the default keyboard for the 'Message body' TEXTAREA to the LaoKeys keyboard
|
||||
keyman.setKeyboardForControl(document.f.text, 'Keyboard_laokeys', 'lo');
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
|
|
@ -40,18 +38,18 @@ Also include the following HTML code:
|
|||
```html
|
||||
<head>
|
||||
<!-- Load the KeymanWeb engine -->
|
||||
<script src="js/keymanweb.js" type="text/javascript"></script>
|
||||
<script src="js/kmwuitoggle.js" type="text/javascript"></script>
|
||||
<script src="https://s.keyman.com/kmw/engine/17.0.331/keymanweb.js" type="text/javascript"></script>
|
||||
<script src="https://s.keyman.com/kmw/engine/17.0.331/kmwuitoggle.js" type="text/javascript"></script>
|
||||
<!-- // Also be sure to load your keyboards. Note that stubs will not work with this
|
||||
// example without detailing paths precisely in the init() call's parameter.-->
|
||||
</head>
|
||||
|
||||
|
||||
<!-- When the page has finished loading, advise KeymanWeb of control settings, see above -->
|
||||
<body onload="SetupDocument()">
|
||||
```
|
||||
|
||||
---
|
||||
**Note:** In this example we disabled the first element (`document.f.address`) by API call. A later API call can re-enable KeymanWeb for this control should it fit the page's design. Alternatively, this can be done by instead adding the class `'kmw-disabled'` to the control. This will permanently block KeymanWeb from handling its input.
|
||||
**Note:** In this example we disabled the first element (`document.f.address`) by API call. A
|
||||
later API call can re-enable KeymanWeb for this control should it fit the page's design.
|
||||
Alternatively, this can be done by instead adding the class `'kmw-disabled'` to the control. This
|
||||
will permanently block KeymanWeb from handling its input.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
title: Manual Control - Custom Interface
|
||||
---
|
||||
|
||||
In this example, the web page designer has opted for their own user interface instead of the KeymanWeb interface. The keyboards in the selector are populated from the KeymanWeb list of keyboards. Please click [this link](__full-manual-control.html) to open the test page.
|
||||
In this example, the web page designer has opted for their own user interface instead of the
|
||||
KeymanWeb interface. The keyboards in the selector are populated from the KeymanWeb list of
|
||||
keyboards. Please click [this link](__full-manual-control.html) to open the test page.
|
||||
|
||||
## Code Walkthrough
|
||||
|
||||
|
|
@ -12,31 +14,25 @@ Include the following script in the HEAD of your page:
|
|||
<script>
|
||||
var KWControl = null;
|
||||
|
||||
/* SetupDocument: Called when the page finishes loading */
|
||||
function SetupDocument()
|
||||
{
|
||||
keyman.init().then(function(){
|
||||
// Load the keyboards of your choice here.
|
||||
loadKeyboards();
|
||||
keyman.init().then(async function() {
|
||||
// Load the keyboards of your choice here.
|
||||
await loadKeyboards();
|
||||
|
||||
KWControl = document.getElementById('KWControl');
|
||||
var kbds = keyman.getKeyboards();
|
||||
for(var kbd in kbds)
|
||||
{
|
||||
var opt = document.createElement('OPTION');
|
||||
opt.value = kbds[kbd].InternalName + "$$" + kbds[kbd].LanguageCode;
|
||||
opt.innerHTML = kbds[kbd].Name;
|
||||
KWControl.appendChild(opt);
|
||||
}
|
||||
document.f.multilingual.focus();
|
||||
KWControl = document.getElementById('KWControl');
|
||||
var kbds = keyman.getKeyboards();
|
||||
for(var kbd in kbds) {
|
||||
var opt = document.createElement('OPTION');
|
||||
opt.value = kbds[kbd].InternalName + "$$" + kbds[kbd].LanguageCode;
|
||||
opt.innerHTML = kbds[kbd].Name;
|
||||
KWControl.appendChild(opt);
|
||||
}
|
||||
document.f.multilingual.focus();
|
||||
|
||||
keyman.setActiveKeyboard('', '');
|
||||
});
|
||||
}
|
||||
keyman.setActiveKeyboard('', '');
|
||||
});
|
||||
|
||||
/* KWControlChange: Called when user selects an item in the KWControl SELECT */
|
||||
function KWControlChange()
|
||||
{
|
||||
function KWControlChange() {
|
||||
/* Select the keyboard in KeymanWeb */
|
||||
var name = KWControl.value.substr(0, KWControl.value.indexOf("$$"));
|
||||
var languageCode = KWControl.value.substr(KWControl.value.indexOf("$$"+2));
|
||||
|
|
@ -52,14 +48,11 @@ Also include the following HTML code:
|
|||
```html
|
||||
<head>
|
||||
<!-- Load the KeymanWeb engine -->
|
||||
<script src="keymanweb.js" type="text/javascript"></script>
|
||||
<script src="https://s.keyman.com/kmw/engine/17.0.331/keymanweb.js" type="text/javascript"></script>
|
||||
<!-- Load the your keyboard stubs here -->
|
||||
<script src="unified_loader.js" type="text/javascript"></script>
|
||||
<!-- ... -->
|
||||
</head>
|
||||
|
||||
<!-- When the page has finished loading, populate the keyboard selector, see above -->
|
||||
<body onload="SetupDocument()">
|
||||
```
|
||||
|
||||
- File: [unified_loader.js](js/unified_loader.js)
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
/*(C) Copyright 1994-2006 Tavultesoft Pty Ltd. All Rights Reserved. Details: keymanweb.com*/
|
||||
KeymanWeb.KRS(new Stub_Keyboard_devanagari_inscript()); function Stub_Keyboard_devanagari_inscript() {this.KF="devanagari_inscript.js";this.KI="Keyboard_devanagari_inscript";this.KN="Devanagari (INSCRIPT)";}
|
||||
|
|
@ -1 +0,0 @@
|
|||
KeymanWeb.KRS(new Stub_Keyboard_european2()); function Stub_Keyboard_european2() {this.KF="european2-1.6.js";this.KI="Keyboard_european2";this.KN="EuroLatin2 Keyboard";}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
/*(C) Copyright 1994-2006 Tavultesoft Pty Ltd. All Rights Reserved. Details: keymanweb.com*/
|
||||
KeymanWeb.KRS(new Stub_Keyboard_hebrew()); function Stub_Keyboard_hebrew() {this.KF="hebrew.js";this.KI="Keyboard_hebrew";this.KN="Hebrew";}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
/*(C) Copyright 1994-2006 Tavultesoft Pty Ltd. All Rights Reserved. Details: keymanweb.com*/
|
||||
KeymanWeb.KRS(new Stub_Keyboard_keymanwebtest()); function Stub_Keyboard_keymanwebtest() {this.KF="keymanwebtest.js";this.KI="Keyboard_keymanwebtest";this.KN="KeymanWeb Test";}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
/*(C) Copyright 1994-2006 Tavultesoft Pty Ltd. All Rights Reserved. Details: keymanweb.com*/
|
||||
KeymanWeb.KRS(new Stub_Keyboard_korean_korda()); function Stub_Keyboard_korean_korda() {this.KF="korean_korda.js";this.KI="Keyboard_korean_korda";this.KN="Korean (KORDA) - 30 Day Evaluation";}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
/*(C) Copyright 1994-2006 Tavultesoft Pty Ltd. All Rights Reserved. Details: keymanweb.com*/
|
||||
KeymanWeb.KRS(new Stub_Keyboard_korean_morse()); function Stub_Keyboard_korean_morse() {this.KF="korean_morse.js";this.KI="Keyboard_korean_morse";this.KN="Korean (Morse) - 30 Day Evaluation";}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
/*(C) Copyright 1994-2021 SIL International. All Rights Reserved. Details: keymanweb.com*/
|
||||
keyman.addKeyboards({
|
||||
id: "laokeys",
|
||||
name: "Lao (Phonetic)",
|
||||
languages:{id:'lo',name:'Lao'},
|
||||
filename: "./js/laokeys.js"
|
||||
});
|
||||
|
|
@ -1,16 +1,18 @@
|
|||
/*(C) Copyright 2021 SIL International. All Rights Reserved. Details: keymanweb.com*/
|
||||
function loadKeyboards() {
|
||||
// Uses an older type of keyboard stub definition.
|
||||
var KWK={
|
||||
"devanagari_inscript":{KN:"Devanagari (INSCRIPT)", KLC:"hi", KL:"Hindi"},
|
||||
"european2":{KN:"EuroLatin2", KLC:"en", KL:"English"},
|
||||
"hebrew":{KN:"Hebrew", KLC:"he", KL:"Hebrew"},
|
||||
"korean_korda":{KN:"Korean (KORDA) - 30 Day Evaluation", KLC:"ko", KL:"Korean"},
|
||||
"korean_morse":{KN:"Korean (Morse) - 30 Day Evaluation", KLC:"ko", KL:"Korean"},
|
||||
"laokeys":{KN:"Lao (Phonetic)", KLC:"lo", KL:"Lao"}
|
||||
};
|
||||
/*
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*/
|
||||
async function loadKeyboards() {
|
||||
const keyboardList = [
|
||||
{ id: 'devanagari_inscript', name: 'Devanagari (INSCRIPT)', languages: { id: 'hi', name: 'Hindi' }, filename: './js/devanagari_inscript.js' },
|
||||
{ id: 'european2', name: 'EuroLatin2', languages: { id: 'en', name: 'English' }, filename: './js/european2.js' },
|
||||
{ id: 'hebrew', name: 'Hebrew', languages: { id: 'he', name: 'Hebrew' }, filename: './js/hebrew.js' },
|
||||
{ id: 'korean_korda', name: 'Korean (KORDA)', languages: { id: 'ko', name: 'Korean' }, filename: './js/korean_korda.js' },
|
||||
{ id: 'korean_morse', name: 'Korean (Morse)', languages: { id: 'ko', name: 'Korean' }, filename: './js/korean_morse.js' },
|
||||
// using a KeyboardStub would allow to customize e.g. which font the keyboard uses
|
||||
{ KF: "./js/laokeys.js", KI: "Keyboard_laokeys", KN: "Lao (Phonetic)", KL: "Lao", KLC: "lo" }
|
||||
];
|
||||
|
||||
for(var n in KWK) {
|
||||
KeymanWeb.registerStub({KF:"./js/" + n+".js", KI:"Keyboard_"+n, KN:KWK[n].KN, KL:KWK[n].KL, KLC:KWK[n].KLC});
|
||||
}
|
||||
return keyman.addKeyboards(keyboardList).catch(function(err) {
|
||||
console.error('keyman.addKeyboards failed with '+errToString(err)+' for '+JSON.stringify(keyboardList));
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,21 +10,19 @@ Include the following script in the HEAD of your page:
|
|||
|
||||
```js
|
||||
<script>
|
||||
/* SetupDocument: Called when the page finishes loading */
|
||||
function SetupDocument()
|
||||
{
|
||||
/* Make sure that Keyman is initialized (we can't guarantee initialization order) */
|
||||
keyman.init().then(function () {
|
||||
/* Prevents automatic display of the onscreen keyboard. (default automatic) */
|
||||
keyman.osk.hide();
|
||||
/* Select the LaoKeys keyboard */
|
||||
keyman.init().then(async function() {
|
||||
await keyman.addKeyboards({
|
||||
id: "laokeys",
|
||||
name: "Lao (Phonetic)",
|
||||
languages:{id:'lo',name:'Lao'},
|
||||
filename: "./js/laokeys.js"
|
||||
});
|
||||
keyman.setActiveKeyboard('laokeys');
|
||||
keyman.osk.hide();
|
||||
});
|
||||
}
|
||||
|
||||
/* KWControlClick: Called when user clicks on the KWControl IMG */
|
||||
function KWControlClick()
|
||||
{
|
||||
function KWControlClick() {
|
||||
if(keyman.osk.isEnabled()) {
|
||||
keyman.osk.hide();
|
||||
} else {
|
||||
|
|
@ -40,17 +38,10 @@ Also include the following HTML code:
|
|||
```html
|
||||
<head>
|
||||
<!-- Load the KeymanWeb engine -->
|
||||
<script src="keymanweb.js" type="text/javascript"></script>
|
||||
<!-- Load the LaoKeys keyboard stub -->
|
||||
<script src="laokeys_load.js" type="text/javascript"></script>
|
||||
<script src="https://s.keyman.com/kmw/engine/17.0.331/keymanweb.js" type="text/javascript"></script>
|
||||
</head>
|
||||
|
||||
<!-- When the page has finished loading, activate the LaoKeys keyboard, see above -->
|
||||
<body onload="SetupDocument()">
|
||||
```
|
||||
|
||||
- File: [laokeys_load.js](js/laokeys_load.js)
|
||||
|
||||
And finally, include the control img for KeymanWeb:
|
||||
|
||||
```html
|
||||
|
|
@ -61,9 +52,11 @@ And finally, include the control img for KeymanWeb:
|
|||
## API References
|
||||
|
||||
On programmatically setting the keyboard:
|
||||
|
||||
- [`keyman.setActiveKeyboard()`](../../reference/core/setActiveKeyboard).
|
||||
|
||||
On managing the visibility of the OSK:
|
||||
|
||||
- [`keyman.osk.hide()`](../../reference/osk/hide)
|
||||
- [`keyman.osk.show()`](../../reference/osk/show).
|
||||
|
||||
|
|
|
|||
|
|
@ -22,12 +22,10 @@ The source code for the page may be seen below.
|
|||
<script src='https://s.keyman.com/kmw/engine/18.0.245/keymanweb.js'></script>
|
||||
<script src='https://s.keyman.com/kmw/engine/18.0.245/kmwuitoggle.js'></script>
|
||||
<script>
|
||||
(function() {
|
||||
keyman.init({attachType:'auto'}).then(function() {
|
||||
keyman.addKeyboards('@en'); // Loads default English keyboard from Keyman Cloud (CDN)
|
||||
keyman.addKeyboards('@th'); // Loads default Thai keyboard from Keyman Cloud (CDN)
|
||||
});
|
||||
})(keyman);
|
||||
keyman.init({attachType:'auto'}).then(async function() {
|
||||
await keyman.addKeyboards('@en'); // Loads default English keyboard from Keyman Cloud (CDN)
|
||||
await keyman.addKeyboards('@th'); // Loads default Thai keyboard from Keyman Cloud (CDN)
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ Adds keyboards to KeymanWeb.
|
|||
## Syntax
|
||||
|
||||
```js
|
||||
keyman.addKeyboards(spec[, spec...])
|
||||
await keyman.addKeyboards([spec...])
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
|
@ -179,3 +179,7 @@ The `spec.languages.font` object contains the following members:
|
|||
: `string` <span class="optional">optional</span>
|
||||
|
||||
Font size (in CSS dimensions). If not specified, then `1em` is used.
|
||||
|
||||
### Not passing any parameter
|
||||
|
||||
Not passing any parameter will obtain all Keyman keyboards from the CDN.
|
||||
|
|
@ -9,7 +9,7 @@ Add default or all keyboards for a given language to KeymanWeb.
|
|||
## Syntax
|
||||
|
||||
```js
|
||||
keyman.addKeyboardsForLanguage(spec[, spec...])
|
||||
await keyman.addKeyboardsForLanguage(spec[, spec...])
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Get keyboard meta data for the selected keyboard and language.
|
|||
|
||||
## Syntax
|
||||
|
||||
```c
|
||||
```js
|
||||
keyman.getKeyboard(keyboardName, languageCode)
|
||||
```
|
||||
|
||||
|
|
@ -75,5 +75,5 @@ The `keyboard` object contains the following members:
|
|||
: `string` *optional*
|
||||
: The font packaged with the keyboard to properly display specialized OSK characters.
|
||||
|
||||
## See also
|
||||
## See also
|
||||
- [keyman.addKeyboards()](addKeyboards) and its documentation about keyboard specification objects.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Get details of currently installed keyboards.
|
|||
|
||||
## Syntax
|
||||
|
||||
```c
|
||||
```js
|
||||
keyman.getKeyboards()
|
||||
```
|
||||
|
||||
|
|
@ -25,5 +25,5 @@ None.
|
|||
|
||||
See [keyman.getKeyboard()](getKeyboard) for detail on the returned keyboard specification objects.
|
||||
|
||||
## See also
|
||||
## See also
|
||||
- [keyman.addKeyboards()](addKeyboards)
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ Registers the keyboard stub or returns true if already registered.
|
|||
|
||||
## Syntax
|
||||
|
||||
```c
|
||||
```js
|
||||
keyman.interface.registerStub(Pstub);
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```c
|
||||
```js
|
||||
KeymanWeb.KRS(Pstub); // Shorthand
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -2,4 +2,6 @@
|
|||
title: Layout Designer
|
||||
---
|
||||
|
||||
One of the main features of *KeymanWeb 17* is its ability to support distinct, user-customizable layouts for touch-screen keyboards on phones and tablets. *Keyman Developer 17* includes a layout designer to simplify the process of creating custom layouts for any keyboard.
|
||||
One of the main features of *KeymanWeb* is its ability to support distinct, user-customizable
|
||||
layouts for touch-screen keyboards on phones and tablets. *Keyman Developer* includes a layout
|
||||
designer to simplify the process of creating custom layouts for any keyboard.
|
||||
|
|
|
|||
|
|
@ -2,13 +2,19 @@
|
|||
title: Layout Specifications
|
||||
---
|
||||
|
||||
Touch-screen layouts for *KeymanWeb 17* are specified as JSON objects containing a member object for each specified device type. Currently supported device types are *tablet* and *phone*. Layouts for *desktop* computers may also be specified but desktop on-screen keyboard design is normally managed by the
|
||||
standard *Keyman Developer* on-screen keyboard tool rather than the keyboard layout designer. If the same
|
||||
layout is appropriate for both *tablet* and *phone* devices only one need be specified, and will be used for either type of device.
|
||||
Touch-screen layouts for *KeymanWeb* are specified as JSON objects containing a member object for
|
||||
each specified device type. Currently supported device types are *tablet* and *phone*. Layouts
|
||||
for *desktop* computers may also be specified but desktop on-screen keyboard design is normally
|
||||
managed by the standard *Keyman Developer* on-screen keyboard tool rather than the keyboard
|
||||
layout designer. If the same layout is appropriate for both *tablet* and *phone* devices only one
|
||||
need be specified, and will be used for either type of device.
|
||||
|
||||
File encoding for manually-created layout files may use either UTF-8 or 7-bit ANSI coding, but must not include a BOM. For easier editing and management without requiring special fonts, embedded Unicode characters with values above 127 may use the *\uXXXX* notation.
|
||||
File encoding for manually-created layout files may use either UTF-8 or 7-bit ANSI coding, but
|
||||
must not include a BOM. For easier editing and management without requiring special fonts,
|
||||
embedded Unicode characters with values above 127 may use the *\uXXXX* notation.
|
||||
|
||||
For details of the JSON specification, see [The JSON Data Interchange Format(ECMA-404)](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
|
||||
For details of the JSON specification, see [The JSON Data Interchange
|
||||
Format(ECMA-404)](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
|
||||
|
||||
<table data-border="1">
|
||||
<thead>
|
||||
|
|
@ -249,7 +255,7 @@ Details of key member specifications are given below:
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<tr>
|
||||
<td class="rowhead" style="text-align: left;">id</td>
|
||||
<td style="text-align: left;">Each key id must start with <i>>K_</i> , for keys mapped to standard Keyman virtual key names, e.g. <i>K_HYPHEN</i> , or either <i>U_</i> or <i>T_</i> for user-defined names. Keys identified as <i>U_xxxx[_xxxx...]</i> specify one or more Unicode characters in hex format, e.g. <i>U_1363</i> for the Ethiopic Comma character, and will insert those characters if the key id is not matched by a rule. Other user-defined keys, such as <i>T_ZZZ</i> , will be ignored unless matched by a rule. The key id is required except for key styles 9 or 10 (blank or spacer keys).</td>
|
||||
</tr>
|
||||
|
|
@ -330,7 +336,11 @@ Details of key member specifications are given below:
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
For many keyboards, it is helpful to associate some keyboard layers with physical keyboard modifier states. This is reflected in the layer name, where a layer name of *shift* means that when a key in that layer is touched, the keystroke will be processed as if the keyboard Shift key is held.
|
||||
For many keyboards, it is helpful to associate some keyboard layers with physical keyboard
|
||||
modifier states. This is reflected in the layer name, where a layer name of *shift* means that
|
||||
when a key in that layer is touched, the keystroke will be processed as if the keyboard Shift key
|
||||
is held.
|
||||
|
||||
|
||||
The special layer names of:
|
||||
*leftalt* ,
|
||||
|
|
@ -364,7 +374,9 @@ The following special key identifiers have been added to simplify layer selectio
|
|||
| K_SHIFTED | 264 |
|
||||
| K_ALTGR | 265 |
|
||||
|
||||
A special font is used to provide easily recognizable key graphics for various special purpose keys. The following key text strings will be recognized and cause the appropriate graphic to be used for the key cap instead of the actual text:
|
||||
A special font is used to provide easily recognizable key graphics for various special purpose
|
||||
keys. The following key text strings will be recognized and cause the appropriate graphic to be
|
||||
used for the key cap instead of the actual text:
|
||||
|
||||
| Text string | Key purpose |
|
||||
|:------------------|:--------------------------------------------------------|
|
||||
|
|
|
|||
|
|
@ -4,11 +4,14 @@ title: Overview
|
|||
|
||||
*KeymanWeb* is a cross-browser JavaScript input method solution.
|
||||
|
||||
The *KeymanWeb 17 API* provides JavaScript functions to allow a website developer to integrate the use of
|
||||
*KeymanWeb* multi-lingual keyboard mapping into a website, using either a standard or a custom-designed user-interface. The functions are exposed as API calls to the *KeymanWeb* core, the
|
||||
*On-Screen Keyboard* module, a *Utility function* library, or one of the standard *User Interface* modules.
|
||||
The *KeymanWeb API* provides JavaScript functions to allow a website developer to integrate the
|
||||
use of *KeymanWeb* multi-lingual keyboard mapping into a website, using either a standard or a
|
||||
custom-designed user-interface. The functions are exposed as API calls to the *KeymanWeb* core,
|
||||
the *On-Screen Keyboard* module, a *Utility function* library, or one of the standard *User
|
||||
Interface* modules.
|
||||
|
||||
A *KeymanWeb* instance is automatically constructed when you include the compiled KeymanWeb script (kmw-release.js) in your web page source.
|
||||
A *KeymanWeb* instance is automatically constructed when you include the compiled KeymanWeb
|
||||
script (kmw-release.js) in your web page source.
|
||||
|
||||
The *KeymanWeb API* comprises the following objects:
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@
|
|||
"@sentry/cli": "^2.31.0",
|
||||
"@zip.js/zip.js": "^2.7.32",
|
||||
"c8": "^7.12.0",
|
||||
"express": "^4.19.2",
|
||||
"express": "^4.22.2",
|
||||
"jsdom": "^23.0.1",
|
||||
"promise-status-async": "^1.2.10",
|
||||
"tsx": "^4.19.0"
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
; applies to all files
|
||||
[*]
|
||||
indent_style = space
|
||||
|
||||
[*.{java, js, ts, sh, css, html, xml}]
|
||||
indent_size = 2
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ export class FocusAssistant extends EventEmitter<EventMap> {
|
|||
* @param {(boolean|number)} state Activate (true,false)
|
||||
*/
|
||||
setMaintainingFocus(state: boolean) {
|
||||
this.maintainingFocus = state ? true : false;
|
||||
this.maintainingFocus = !!state;
|
||||
}
|
||||
|
||||
setFocusTimer(): void {
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ export class KeymanEngine extends KeymanEngineBase<BrowserConfiguration, Context
|
|||
* activationPending (bool): KMW being activated
|
||||
* activated (bool): KMW active
|
||||
*
|
||||
* See https://help.keyman.com/developer/engine/web/16.0/reference/core/getUIState
|
||||
* See https://help.keyman.com/developer/engine/web/current-version/reference/core/getUIState
|
||||
*/
|
||||
public getUIState(): FocusStateAPIObject {
|
||||
return this.contextManager.focusAssistant.getUIState();
|
||||
|
|
@ -266,7 +266,7 @@ export class KeymanEngine extends KeymanEngineBase<BrowserConfiguration, Context
|
|||
/**
|
||||
* Set or clear the IsActivatingKeymanWebUI flag (exposed function)
|
||||
*
|
||||
* See https://help.keyman.com/developer/engine/web/16.0/reference/core/activatingUI
|
||||
* See https://help.keyman.com/developer/engine/web/current-version/reference/core/activatingUI
|
||||
*
|
||||
* @param {(boolean|number)} state Activate (true,false)
|
||||
*/
|
||||
|
|
@ -275,35 +275,41 @@ export class KeymanEngine extends KeymanEngineBase<BrowserConfiguration, Context
|
|||
}
|
||||
|
||||
/**
|
||||
* Function setKeyboardForControl
|
||||
* Scope Public
|
||||
* @param {Element} Pelem Control element
|
||||
* @param {string|null=} Pkbd JSKeyboard (Clears the set keyboard if set to null.)
|
||||
* @param {string|null=} Plc Language Code
|
||||
* Description Set default keyboard for the control
|
||||
* Associate control with independent keyboard settings initialized to a specific keyboard.
|
||||
* The pair of `keyboard` and `languageCode` (if not `null`) must refer to a
|
||||
* registered keyboard stub.
|
||||
*
|
||||
* See https://help.keyman.com/developer/engine/web/current-version/reference/core/setKeyboardForControl
|
||||
*
|
||||
* @param {Element} elem The control element to be managed manually
|
||||
* @param {string|null=} keyboard The id of a keyboard, consisting of the word
|
||||
* `Keyboard_` followed by the internal keyboard
|
||||
* name. For a keyboard with the internal name
|
||||
* `laokeys` this would be `Keyboard_laokeys`.
|
||||
* If `null` clears the set keyboard.
|
||||
* @param {string|null=} languageCode A BCP47 language code which was used when
|
||||
* registering the keyboard stub.
|
||||
*/
|
||||
public setKeyboardForControl(Pelem: HTMLElement, Pkbd?: string, Plc?: string): void {
|
||||
if(Pelem instanceof Pelem.ownerDocument.defaultView.HTMLIFrameElement) {
|
||||
public setKeyboardForControl(elem: HTMLElement, keyboard?: string, languageCode?: string): void {
|
||||
if(elem instanceof elem.ownerDocument.defaultView.HTMLIFrameElement) {
|
||||
console.warn("'keymanweb.setKeyboardForControl' cannot set keyboard on iframes.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!this.isAttached(Pelem)) {
|
||||
console.error("KeymanWeb is not attached to element " + Pelem);
|
||||
if(!this.isAttached(elem)) {
|
||||
console.error("KeymanWeb is not attached to element " + elem);
|
||||
return;
|
||||
}
|
||||
|
||||
let stub = null;
|
||||
if(Pkbd) {
|
||||
stub = this.keyboardRequisitioner.cache.getStub(Pkbd, Plc);
|
||||
if(keyboard) {
|
||||
stub = this.keyboardRequisitioner.cache.getStub(keyboard, languageCode);
|
||||
if(!stub) {
|
||||
throw new Error(`No keyboard has been registered with id ${Pkbd} and language code ${Plc}.`);
|
||||
throw new Error(`No keyboard has been registered with id ${keyboard} and language code ${languageCode}.`);
|
||||
}
|
||||
}
|
||||
|
||||
this.contextManager.setKeyboardForTextStore(Pelem._kmwAttachment.textStore, Pkbd, Plc);
|
||||
this.contextManager.setKeyboardForTextStore(elem._kmwAttachment.textStore, keyboard, languageCode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -400,7 +406,7 @@ export class KeymanEngine extends KeymanEngineBase<BrowserConfiguration, Context
|
|||
*/
|
||||
// TODO-web-core: check each property of Lstub for KMXKeyboard availability
|
||||
private _GetKeyboardDetail(Lstub: KeyboardStub, Lkbd: Keyboard): KeyboardDetails { // I2078 - Full keyboard detail
|
||||
return {
|
||||
return Lstub && {
|
||||
Name: Lstub.KN,
|
||||
InternalName: Lstub.KI,
|
||||
LanguageName: Lstub.KL, // I1300 - Add support for language names
|
||||
|
|
@ -461,12 +467,7 @@ export class KeymanEngine extends KeymanEngineBase<BrowserConfiguration, Context
|
|||
const stub = this.keyboardRequisitioner.cache.getStub(id, langCode);
|
||||
const keyboard = this.keyboardRequisitioner.cache.getKeyboardForStub(stub);
|
||||
|
||||
if (keyboard instanceof JSKeyboard) {
|
||||
return stub && this._GetKeyboardDetail(stub, keyboard);
|
||||
} else {
|
||||
// TODO-web-core: do this work in _GetKeyboardDetail (implement for KMX keyboards)
|
||||
return null;
|
||||
}
|
||||
return this._GetKeyboardDetail(stub, keyboard);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -483,11 +484,9 @@ export class KeymanEngine extends KeymanEngineBase<BrowserConfiguration, Context
|
|||
const keyboardStubs = cache.getStubList()
|
||||
for (const stub of keyboardStubs) {
|
||||
const keyboard = cache.getKeyboardForStub(stub);
|
||||
if (keyboard instanceof JSKeyboard) {
|
||||
const keyboardDetails = this._GetKeyboardDetail(stub, keyboard);
|
||||
const keyboardDetails = this._GetKeyboardDetail(stub, keyboard);
|
||||
if (keyboardDetails) {
|
||||
detailsForAllKeyboards.push(keyboardDetails);
|
||||
} else {
|
||||
// TODO-web-core: do this work in _GetKeyboardDetail (implement for KMX keyboards if needed)
|
||||
}
|
||||
}
|
||||
return detailsForAllKeyboards;
|
||||
|
|
|
|||
|
|
@ -261,12 +261,19 @@ if(!keymanweb) {
|
|||
}
|
||||
this.updateList = false;
|
||||
|
||||
// Set the menu selector to the currently saved keyboard
|
||||
const sk = keymanweb.getSavedKeyboard().split(':');
|
||||
if(sk.length < 2) {
|
||||
sk[1] = '';
|
||||
// Set the menu selector to the last active keyboard
|
||||
let activeKeyboard = keymanweb.getActiveKeyboard();
|
||||
let activeLanguage = '';
|
||||
if (activeKeyboard) {
|
||||
activeLanguage = keymanweb.getActiveLanguage();
|
||||
} else {
|
||||
// savedKeyboard is only correct if we use global keyboard settings,
|
||||
// otherwise it's set to the first keyboard in the list
|
||||
const savedKeyboard = keymanweb.getSavedKeyboard().split(':');
|
||||
activeKeyboard = savedKeyboard[0];
|
||||
activeLanguage = savedKeyboard.length < 2 ? '' : savedKeyboard[1];
|
||||
}
|
||||
this.updateMenu(sk[0],sk[1]);
|
||||
this.updateMenu(activeKeyboard, activeLanguage);
|
||||
|
||||
// Redisplay the UI to correct width for any new language entries
|
||||
if(keymanweb.getLastActiveElement()) {
|
||||
|
|
|
|||
|
|
@ -152,12 +152,12 @@ if(!keymanweb) {
|
|||
}
|
||||
|
||||
osk.addEventListener('show', (oskPosition) => {
|
||||
// Ensure that the ui.controller is visible if help is displayed
|
||||
this.controller.style.display = 'block';
|
||||
this.oskButton._setSelected(true);
|
||||
// Ensure that the ui.controller is visible if help is displayed
|
||||
this.controller.style.display = 'block';
|
||||
this.oskButton._setSelected(true);
|
||||
|
||||
return oskPosition;
|
||||
});
|
||||
return oskPosition;
|
||||
});
|
||||
|
||||
osk.addEventListener('hide', (byUser) => {
|
||||
if(byUser['HiddenByUser']) {
|
||||
|
|
@ -542,8 +542,18 @@ if(!keymanweb) {
|
|||
}
|
||||
|
||||
// Highlight the last active keyboard
|
||||
const sk=keymanweb.getSavedKeyboard().split(':');
|
||||
this.updateMenu(sk[0],sk[1]);
|
||||
let activeKeyboard = keymanweb.getActiveKeyboard();
|
||||
let activeLanguage = '';
|
||||
if (activeKeyboard) {
|
||||
activeLanguage = keymanweb.getActiveLanguage();
|
||||
} else {
|
||||
// savedKeyboard is only correct if we use global keyboard settings,
|
||||
// otherwise it's set to the first keyboard in the list
|
||||
const savedKeyboard = keymanweb.getSavedKeyboard().split(':');
|
||||
activeKeyboard = savedKeyboard[0];
|
||||
activeLanguage = savedKeyboard[1];
|
||||
}
|
||||
this.updateMenu(activeKeyboard, activeLanguage);
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
|
|
@ -555,24 +565,24 @@ if(!keymanweb) {
|
|||
/**
|
||||
* Function selecKbd
|
||||
* Scope Private
|
||||
* @param {number} _kbd
|
||||
* @param {number} kbdIndex
|
||||
* Description Select a keyboard from the drop down menu
|
||||
**/
|
||||
private async selectKbd(_kbd: number): Promise<boolean> {
|
||||
let _name,_lgCode;
|
||||
if(_kbd < 0) {
|
||||
_name = '';
|
||||
_lgCode='';
|
||||
private async selectKbd(kbdIndex: number): Promise<boolean> {
|
||||
let name: string, languageCode: string;
|
||||
if (kbdIndex < 0) {
|
||||
name = '';
|
||||
languageCode = '';
|
||||
} else {
|
||||
_name = this.keyboards[_kbd]._InternalName;
|
||||
_lgCode = this.keyboards[_kbd]._LanguageCode;
|
||||
name = this.keyboards[kbdIndex]._InternalName;
|
||||
languageCode = this.keyboards[kbdIndex]._LanguageCode;
|
||||
}
|
||||
|
||||
await keymanweb.setActiveKeyboard(_name,_lgCode);
|
||||
await keymanweb.setActiveKeyboard(name, languageCode);
|
||||
keymanweb.focusLastActiveElement();
|
||||
this.kbdButton._setSelected(_name != '');
|
||||
if(_kbd >= 0) {
|
||||
this.lastActiveKeyboard = _kbd;
|
||||
this.kbdButton._setSelected(name != '');
|
||||
if (kbdIndex >= 0) {
|
||||
this.lastActiveKeyboard = kbdIndex;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -687,6 +697,22 @@ if(!keymanweb) {
|
|||
`;
|
||||
}
|
||||
|
||||
private createMenuItem(index: number, id: string, name: string, isSelected: boolean): { li: HTMLLIElement, a: HTMLAnchorElement } {
|
||||
const li = util.createElement('li');
|
||||
const a = util.createElement('a');
|
||||
a.innerHTML = name;
|
||||
a.href = "#";
|
||||
a.onclick = ((x) => {
|
||||
return () => this.selectKbd(x);
|
||||
})(index);
|
||||
a.id = id;
|
||||
if (isSelected) {
|
||||
a.className = 'selected';
|
||||
}
|
||||
li.appendChild(a);
|
||||
return { li, a };
|
||||
}
|
||||
|
||||
/**
|
||||
* Function createMenu
|
||||
* Scope Private
|
||||
|
|
@ -701,38 +727,29 @@ if(!keymanweb) {
|
|||
this.keyboardMenu.innerHTML = ''; // I2403 - Allow toggle design to be loaded twice
|
||||
}
|
||||
|
||||
const _li = util.createElement('li');
|
||||
const _a = util.createElement('a');
|
||||
_a.innerHTML='(System keyboard)';
|
||||
_a.href="#";
|
||||
_a.onclick = () => {
|
||||
return this.selectKbd(-1);
|
||||
};
|
||||
_a.id='KMWSel_$';
|
||||
_a.className='selected';
|
||||
_li.appendChild(_a);
|
||||
// Add the default (system) keyboard as the first entry in the menu
|
||||
const { li, a } = this.createMenuItem(-1, 'KMWSel_$', '(System keyboard)', true);
|
||||
this.selectedMenuItem = a;
|
||||
this.keyboardMenu.appendChild(li);
|
||||
|
||||
this.selectedMenuItem=_a;
|
||||
this.keyboardMenu.appendChild(_li);
|
||||
|
||||
const _kbds=keymanweb.getKeyboards(), _added: Record<string, number> = {};
|
||||
// Add loaded keyboards to the menu
|
||||
this.keyboards = [];
|
||||
for(let _kbd = 0; _kbd < _kbds.length; _kbd++) {
|
||||
const _li1=util.createElement('li');
|
||||
const _a1=util.createElement('a');
|
||||
_a1.innerHTML=_kbds[_kbd].LanguageName + ' - ' + _kbds[_kbd].Name;
|
||||
if(!_added[_kbds[_kbd].InternalName]) _added[_kbds[_kbd].InternalName]=0;
|
||||
_added[_kbds[_kbd].InternalName]++;
|
||||
const keyboards = keymanweb.getKeyboards();
|
||||
const added: Record<string, number> = {};
|
||||
for (let kbdIndex = 0; kbdIndex < keyboards.length; kbdIndex++) {
|
||||
if (!added[keyboards[kbdIndex].InternalName]) {
|
||||
added[keyboards[kbdIndex].InternalName] = 0;
|
||||
}
|
||||
added[keyboards[kbdIndex].InternalName]++;
|
||||
|
||||
const _n=_added[_kbds[_kbd].InternalName];
|
||||
this.keyboards.push({_InternalName: _kbds[_kbd].InternalName, _LanguageCode:_kbds[_kbd].LanguageCode, _Index: _n});
|
||||
const kbdInstanceCount = added[keyboards[kbdIndex].InternalName];
|
||||
this.keyboards.push({ _InternalName: keyboards[kbdIndex].InternalName, _LanguageCode: keyboards[kbdIndex].LanguageCode, _Index: kbdInstanceCount });
|
||||
|
||||
_a1.href="#";
|
||||
_a1.onclick = ((x) => { return () => this.selectKbd(x); })(this.keyboards.length-1);
|
||||
_a1.id='KMWSel_'+_kbds[_kbd].InternalName+'$'+_n;
|
||||
|
||||
_li1.appendChild(_a1);
|
||||
this.keyboardMenu.appendChild(_li1);
|
||||
const { li } = this.createMenuItem(this.keyboards.length - 1,
|
||||
`KMWSel_${keyboards[kbdIndex].InternalName}\$${kbdInstanceCount}`,
|
||||
`${keyboards[kbdIndex].LanguageName} - ${keyboards[kbdIndex].Name}`,
|
||||
false);
|
||||
this.keyboardMenu.appendChild(li);
|
||||
}
|
||||
|
||||
//if(!ui.initialized) // I2403 - Allow toggle design to be loaded twice
|
||||
|
|
@ -740,7 +757,6 @@ if(!keymanweb) {
|
|||
this.kbdButton.getElem().appendChild(this.keyboardMenu);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -795,4 +811,4 @@ if(!keymanweb) {
|
|||
ui.initialize();
|
||||
|
||||
} catch(ex){}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1150,8 +1150,8 @@ if(!keymanweb) {
|
|||
internalName: string,
|
||||
languageCode: string
|
||||
}) => { // Uses a different format than .getKeyboards(), b/c why not?
|
||||
// https://help.keyman.com/developer/engine/web/16.0/reference/core/getKeyboards vs
|
||||
// https://help.keyman.com/developer/engine/web/16.0/reference/events/kmw.keyboardchange
|
||||
// https://help.keyman.com/developer/engine/web/current-version/reference/core/getKeyboards vs
|
||||
// https://help.keyman.com/developer/engine/web/current-version/reference/events/kmw.keyboardchange
|
||||
this.lastSelectedKeyboard = null;
|
||||
const kbName=p.internalName,
|
||||
lgName=keymanweb.util.getLanguageCodes(p.languageCode)[0];
|
||||
|
|
|
|||
|
|
@ -182,9 +182,9 @@ export class KeyboardStub extends KeyboardProperties {
|
|||
}
|
||||
}
|
||||
|
||||
public validateForCustomKeyboard(): Error {
|
||||
if(super.validateForCustomKeyboard() || !this.KF || !this.KR) {
|
||||
return new Error('To use a custom keyboard, you must specify file name, keyboard id, keyboard name, language, language code, and region.');
|
||||
public validateForCustomKeyboard(): Error|null {
|
||||
if(super.validateForCustomKeyboard() || !this.KF) {
|
||||
return new Error('To use a custom keyboard, you must specify file name, keyboard id, keyboard name, language and language code.');
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ export class KeyboardProperties implements KeyboardInternalPropertySpec {
|
|||
return null;
|
||||
}
|
||||
|
||||
public validateForCustomKeyboard(): Error {
|
||||
public validateForCustomKeyboard(): Error|null {
|
||||
if(!this.KI || !this.KN || !this.KL || !this.KLC) {
|
||||
return new Error("To use a custom keyboard, you must specify keyboard id, keyboard name, language and language code.");
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@ export class KeyboardInterfaceBase<ContextManagerType extends ContextManagerBase
|
|||
//
|
||||
// It may also be used by documented legacy API:
|
||||
// https://help.keyman.com/developer/engine/web/2.0/guide/examples/manual-control
|
||||
// (See: referenced laokeys_load.js)
|
||||
//
|
||||
// The mobile apps typically have fully-preconfigured paths, but Developer's
|
||||
// test-host page does not.
|
||||
|
|
@ -123,4 +122,4 @@ export class KeyboardInterfaceBase<ContextManagerType extends ContextManagerBase
|
|||
|
||||
(function() {
|
||||
KeyboardInterfaceBase.__publishShorthandAPI();
|
||||
}());
|
||||
}());
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
root: '..',
|
||||
// Operates from the configured root set above - the 'root' folder for this sample.
|
||||
resources: '/resources',
|
||||
|
|
@ -45,9 +44,9 @@
|
|||
// KMW will look for them here - two folders up from root, which is the base sample directory.
|
||||
keyboards: '/../../',
|
||||
attachType:'auto'
|
||||
}).then(function() {
|
||||
}).then(async function() {
|
||||
// Loads keyboards from the base sample folder
|
||||
keyman.addKeyboards({
|
||||
await keyman.addKeyboards({
|
||||
id:'us',
|
||||
name:'English',
|
||||
languages: {
|
||||
|
|
@ -58,7 +57,7 @@
|
|||
filename: 'us-1.0.js'
|
||||
});
|
||||
// For contrast:
|
||||
keyman.addKeyboards({
|
||||
await keyman.addKeyboards({
|
||||
id:'lao_2008_basic',
|
||||
name:'Lao Basic',
|
||||
languages: {
|
||||
|
|
@ -74,12 +73,12 @@
|
|||
// 1. keyboard name ('french'),
|
||||
// 2. keyboard name and language code ('sil_euro_latin@no,sv'),
|
||||
// 3. or just the BCP-47 language code ('@he').
|
||||
kmw.addKeyboards('french', 'sil_euro_latin@no,sv', '@he');
|
||||
await keyman.addKeyboards('french', 'sil_euro_latin@no,sv', '@he');
|
||||
|
||||
// Add a keyboard by language name. Note that the name must be spelled
|
||||
// correctly, or the keyboard will not be found. (Using BCP-47 codes is
|
||||
// usually easier.)
|
||||
doAddKeyboardsForLanguage('Dzongkha');
|
||||
await doAddKeyboardsForLanguage('Dzongkha');
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,51 +1,62 @@
|
|||
// JavaScript Document samplehdr.js: Keyboard management for KeymanWeb demonstration pages
|
||||
/*
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*
|
||||
* Keyboard management for KeymanWeb demonstration pages
|
||||
*/
|
||||
|
||||
/*
|
||||
The keyboard name and/or BCP-47 language code must be specified for each keyboard that is to be available.
|
||||
If the same keyboard is used for several languages, it must be listed for each
|
||||
language, but the keyboard itself will only be loaded once.
|
||||
If two (or more) keyboards are to be available for a given language, both must be listed.
|
||||
Any number of keyboards may be specified in one or more calls.
|
||||
Keyboard paths may be absolute (with respect to the server root) or relative to the keyboards option path.
|
||||
The actual keyboard object will be downloaded asynchronously when first selected for use.
|
||||
The keyboard name and/or BCP-47 language code must be specified for
|
||||
each keyboard that is to be available. If the same keyboard is used
|
||||
for several languages, it must be listed for each language, but the
|
||||
keyboard itself will only be loaded once. If two (or more) keyboards
|
||||
are to be available for a given language, both must be listed. Any
|
||||
number of keyboards may be specified in one or more calls. Keyboard
|
||||
paths may be absolute (with respect to the server root) or relative
|
||||
to the keyboards option path. The actual keyboard object will be
|
||||
downloaded asynchronously when first selected for use.
|
||||
|
||||
Each argument to addKeyboards() is a string, for example:
|
||||
european2 loads the current version of the Eurolatin 2 keyboard (for its default language)
|
||||
european2@fr loads the current version of the Eurolatin 2 keyboard for French
|
||||
european2@fr@1.2 loads version 1.2 of the Eurolatin 2 keyboard for French
|
||||
Each argument to addKeyboards() is a string, for example: european2
|
||||
loads the current version of the Eurolatin 2 keyboard (for its
|
||||
default language) european2@fr loads the current version of
|
||||
the Eurolatin 2 keyboard for French european2@fr@1.2 loads
|
||||
version 1.2 of the Eurolatin 2 keyboard for French
|
||||
|
||||
Argument syntax also supports the following extensions:
|
||||
@fr load the current version of the default keyboard for French
|
||||
@fr$ load all available keyboards (current version) for French
|
||||
Argument syntax also supports the following extensions: @fr
|
||||
load the current version of the default keyboard for French @fr$
|
||||
load all available keyboards (current version) for French
|
||||
|
||||
Each call to addKeyboards() requires a single call to the remote server,
|
||||
(unless all keyboards listed are local and fully specified) so it is better
|
||||
to use multiple arguments rather than separate function calls.
|
||||
Each call to addKeyboards() requires a single call to the remote
|
||||
server, (unless all keyboards listed are local and fully specified)
|
||||
so it is better to use multiple arguments rather than separate
|
||||
function calls.
|
||||
|
||||
Calling addKeyboards() with no arguments returns a list of *all* available keyboards.
|
||||
The Toolbar (desktop browser) UI is best suited for allowing users to select
|
||||
the appropriate language and keyboard in this case.
|
||||
Calling addKeyboards() with no arguments returns a list of *all*
|
||||
available keyboards. The Toolbar (desktop browser) UI is best suited
|
||||
for allowing users to select the appropriate language and keyboard
|
||||
in this case.
|
||||
|
||||
Keyboards may also be specified by language name using addKeyboardsForLanguage()
|
||||
for example:
|
||||
keymanweb.addKeyboardsForLanguage('Burmese');
|
||||
Keyboards may also be specified by language name using
|
||||
addKeyboardsForLanguage() for example:
|
||||
keymanweb.addKeyboardsForLanguage('Burmese');
|
||||
|
||||
Appending $ to the language name will again cause all available keyboards for that
|
||||
language to be loaded rather than the default keyboard.
|
||||
Appending $ to the language name will again cause all available
|
||||
keyboards for that language to be loaded rather than the default
|
||||
keyboard.
|
||||
|
||||
The first call to addKeyboardsForLanguage() makes an additional call to the
|
||||
keyman API to load the current list of keyboard/language associations.
|
||||
The first call to addKeyboardsForLanguage() makes an additional call
|
||||
to the keyman API to load the current list of keyboard/language
|
||||
associations.
|
||||
|
||||
In this example, the following function loads the indicated keyboards,
|
||||
and is called when the page loads.
|
||||
In this example, the following function loads the indicated
|
||||
keyboards, and is called when the page loads.
|
||||
*/
|
||||
|
||||
function errToString(err) {
|
||||
// Painful? Kinda. But needed on un-updated Android API 21!
|
||||
if(Array.isArray(err)) {
|
||||
var result = '';
|
||||
for(var i = 0; i < err.length; i++) {
|
||||
var e = err[i];
|
||||
let result = '';
|
||||
for(let i = 0; i < err.length; i++) {
|
||||
const e = err[i];
|
||||
if(e.error instanceof Error) {
|
||||
result += e.error.message + '\n';
|
||||
} else {
|
||||
|
|
@ -72,44 +83,42 @@
|
|||
});
|
||||
}
|
||||
|
||||
function loadKeyboards(nestLevel) {
|
||||
var kmw=keyman;
|
||||
|
||||
var base_prefix = '../';
|
||||
var prefix = './'; // The default - when prefix == 0.
|
||||
async function loadKeyboards(nestLevel) {
|
||||
const base_prefix = '../';
|
||||
let prefix = './'; // The default - when prefix == 0.
|
||||
|
||||
if(nestLevel !== undefined && nestLevel > 0) {
|
||||
prefix = '';
|
||||
for(var i=0; i < nestLevel; i++) {
|
||||
prefix = prefix + base_prefix;
|
||||
for(let i=0; i < nestLevel; i++) {
|
||||
prefix += base_prefix;
|
||||
}
|
||||
}
|
||||
|
||||
// The first keyboard added will be the default keyboard for touch devices.
|
||||
// For faster loading, it may be best for the default keyboard to be
|
||||
// locally sourced.
|
||||
doAddKeyboards({id:'us',name:'English',languages:{id:'en',name:'English'},
|
||||
await doAddKeyboards({id:'us',name:'English',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'us-1.0.js')});
|
||||
|
||||
// Add more keyboards to the language menu by:
|
||||
// 1. keyboard name ('french'),
|
||||
// 2. keyboard name and language code ('sil_euro_latin@no,sv'),
|
||||
// 3. or just the BCP-47 language code ('@he').
|
||||
kmw.addKeyboards('french', 'sil_euro_latin@no,sv', '@he');
|
||||
await keyman.addKeyboards('french', 'sil_euro_latin@no,sv', '@he');
|
||||
|
||||
// Add a keyboard by language name. Note that the name must be spelled
|
||||
// correctly, or the keyboard will not be found. (Using BCP-47 codes is
|
||||
// usually easier.)
|
||||
doAddKeyboardsForLanguage('Dzongkha');
|
||||
await doAddKeyboardsForLanguage('Dzongkha');
|
||||
|
||||
// Add a fully-specified, locally-sourced, keyboard with custom font
|
||||
doAddKeyboards({
|
||||
id:'lao_2008_basic',
|
||||
name:'Lao Basic',
|
||||
await doAddKeyboards({
|
||||
id: 'lao_2008_basic',
|
||||
name: 'Lao Basic',
|
||||
languages: {
|
||||
id:'lo',name:'Lao',region:'Asia',
|
||||
id: 'lo', name: 'Lao', region: 'Asia'
|
||||
},
|
||||
filename:(prefix + 'lao_2008_basic-1.2.js')
|
||||
filename: (prefix + 'lao_2008_basic-1.2.js')
|
||||
});
|
||||
|
||||
// Note that locally specified keyboards will be listed before keyboards
|
||||
|
|
@ -118,29 +127,31 @@
|
|||
}
|
||||
|
||||
// Script to allow a user to add any keyboard to the keyboard menu
|
||||
function addKeyboard(n) {
|
||||
var sKbd;
|
||||
async function addKeyboard(n) {
|
||||
let sKbd;
|
||||
switch(n) {
|
||||
case 1:
|
||||
sKbd=document.getElementById('kbd_id1').value;
|
||||
doAddKeyboards(sKbd);
|
||||
await doAddKeyboards(sKbd);
|
||||
break;
|
||||
case 2:
|
||||
sKbd=document.getElementById('kbd_id2').value.toLowerCase();
|
||||
doAddKeyboards('@'+sKbd);
|
||||
await doAddKeyboards('@'+sKbd);
|
||||
break;
|
||||
case 3:
|
||||
// Add keyboard for comma-separated language name(s)
|
||||
sKbd=document.getElementById('kbd_id3').value;
|
||||
doAddKeyboardsForLanguage(sKbd);
|
||||
await doAddKeyboardsForLanguage(sKbd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add keyboard on Enter (as well as pressing button)
|
||||
function clickOnEnter(e,id)
|
||||
async function clickOnEnter(e,id)
|
||||
{
|
||||
e = e || window.event;
|
||||
if(e.keyCode == 13) addKeyboard(id);
|
||||
if (e.keyCode == 13) {
|
||||
await addKeyboard(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(function() {
|
||||
// Loads the common keyboards from the previous folder
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(function() {
|
||||
// Loads the common keyboards from the previous folder
|
||||
|
|
|
|||
|
|
@ -28,11 +28,10 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(function() {
|
||||
loadKeyboards();
|
||||
}).then(async function() {
|
||||
await loadKeyboards();
|
||||
});
|
||||
</script>
|
||||
<!--
|
||||
|
|
@ -44,10 +43,9 @@
|
|||
Keyboard paths may be absolute (with respect to the server root) or relative to the keyboards option path.
|
||||
-->
|
||||
<script>
|
||||
function loadKeyboards() {
|
||||
keyman.addKeyboards().then(function() {
|
||||
keyman.setActiveKeyboard('basic_kbdus','en');
|
||||
});
|
||||
async function loadKeyboards() {
|
||||
await keyman.addKeyboards();
|
||||
await keyman.setActiveKeyboard('basic_kbdus','en');
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ describe('LanguageProcessor', function() {
|
|||
assert.isTrue(languageProcessor.mayPredict);
|
||||
|
||||
// Some aspects of initialization must wait until after construction and overall
|
||||
// load of the core. See /web/source/kmwbase.ts, in the final IIFE.
|
||||
// load of the core.
|
||||
assert.isOk(languageProcessor.lmEngine);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,9 +40,10 @@
|
|||
const attachType = (new URLSearchParams(window.location.search)).get("mode");
|
||||
var attachText = attachType ? attachType : "default";
|
||||
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType: attachType ? attachType : ''
|
||||
}).then(function() {
|
||||
loadKeyboards(1);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -56,7 +57,7 @@
|
|||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body onload='loadKeyboards(1);'>
|
||||
<body>
|
||||
<h2>KeymanWeb Sample Page - Attachment API Testing</h2>
|
||||
<p>This page is designed to stress-test the new attachment/enablement API model and its functions.</p>
|
||||
<p id="modeSelect">You are currently testing under the <em id="mode"> </em> attachment mode. Two other modes are available:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Page-global variable definitions.
|
||||
{
|
||||
var inputCounter = 0;
|
||||
var kmw = keyman;
|
||||
}
|
||||
|
||||
function generateDiagnosticDiv(elem) {
|
||||
|
|
@ -23,8 +22,8 @@ function generateDiagnosticDiv(elem) {
|
|||
attachBtn.type = 'button';
|
||||
attachBtn.id = 'attach_' + elemId;
|
||||
attachBtn.onclick = function() {
|
||||
kmw.attachToControl(document.getElementById(elemId));
|
||||
var attached = kmw.isAttached(elem);
|
||||
keyman.attachToControl(document.getElementById(elemId));
|
||||
var attached = keyman.isAttached(elem);
|
||||
document.getElementById('attachment_' + elemId).textContent = " Currently " + (attached ? "attached." : "detached.");
|
||||
const indepLabel = document.getElementById("independence_" + elemId);
|
||||
// does not exist for iframes
|
||||
|
|
@ -40,8 +39,8 @@ function generateDiagnosticDiv(elem) {
|
|||
detachBtn.type = 'button';
|
||||
detachBtn.id = 'detach_' + elemId;
|
||||
detachBtn.onclick = function() {
|
||||
kmw.detachFromControl(document.getElementById(elemId));
|
||||
var attached = kmw.isAttached(elem);
|
||||
keyman.detachFromControl(document.getElementById(elemId));
|
||||
var attached = keyman.isAttached(elem);
|
||||
document.getElementById('attachment_' + elemId).textContent = " Currently " + (attached ? "attached." : "detached.");
|
||||
const indepLabel = document.getElementById("independence_" + elemId);
|
||||
// does not exist for iframes
|
||||
|
|
@ -58,7 +57,7 @@ function generateDiagnosticDiv(elem) {
|
|||
var attachLabel = document.createElement("a");
|
||||
attachLabel.id = 'attachment_' + elemId;
|
||||
window.setTimeout(function() {
|
||||
attachLabel.textContent = " Currently " + (kmw.isAttached(elem) ? "attached." : "detached.");
|
||||
attachLabel.textContent = " Currently " + (keyman.isAttached(elem) ? "attached." : "detached.");
|
||||
}, attachTimer);
|
||||
div.appendChild(attachLabel);
|
||||
|
||||
|
|
@ -69,7 +68,7 @@ function generateDiagnosticDiv(elem) {
|
|||
enableBtn.type = 'button';
|
||||
enableBtn.id = 'enable_' + elemId;
|
||||
enableBtn.onclick = function() {
|
||||
kmw.enableControl(document.getElementById(elemId));
|
||||
keyman.enableControl(document.getElementById(elemId));
|
||||
};
|
||||
enableBtn.value = 'Enable';
|
||||
div.appendChild(enableBtn);
|
||||
|
|
@ -79,7 +78,7 @@ function generateDiagnosticDiv(elem) {
|
|||
disableBtn.type = 'button';
|
||||
disableBtn.id = 'disable_' + elemId;
|
||||
disableBtn.onclick = function() {
|
||||
kmw.disableControl(document.getElementById(elemId));
|
||||
keyman.disableControl(document.getElementById(elemId));
|
||||
};
|
||||
disableBtn.value = 'Disable';
|
||||
div.appendChild(disableBtn);
|
||||
|
|
@ -107,9 +106,9 @@ function generateDiagnosticDiv(elem) {
|
|||
setBtn.type = 'button';
|
||||
setBtn.id = 'set_' + elemId;
|
||||
setBtn.onclick = function() {
|
||||
kmw.setKeyboardForControl(document.getElementById(elemId), 'dzongkha', 'dz');
|
||||
keyman.setKeyboardForControl(document.getElementById(elemId), 'dzongkha', 'dz');
|
||||
|
||||
if(kmw.isAttached(elem)) {
|
||||
if(keyman.isAttached(elem)) {
|
||||
kbdLabel.textContent = " Using independently-tracked keyboard.";
|
||||
}
|
||||
};
|
||||
|
|
@ -121,9 +120,9 @@ function generateDiagnosticDiv(elem) {
|
|||
clearBtn.type = 'button';
|
||||
clearBtn.id = 'clear_' + elemId;
|
||||
clearBtn.onclick = function() {
|
||||
kmw.setKeyboardForControl(document.getElementById(elemId), null, null);
|
||||
keyman.setKeyboardForControl(document.getElementById(elemId), null, null);
|
||||
|
||||
if(kmw.isAttached(elem)) {
|
||||
if(keyman.isAttached(elem)) {
|
||||
kbdLabel.textContent = " Using globally-selected keyboard.";
|
||||
}
|
||||
};
|
||||
|
|
@ -133,8 +132,8 @@ function generateDiagnosticDiv(elem) {
|
|||
var kbdLabel = document.createElement("a");
|
||||
kbdLabel.id = 'independence_' + elemId;
|
||||
window.setTimeout(function () {
|
||||
if(kmw.isAttached(elem)) {
|
||||
var attached = kmw.isAttached(elem);
|
||||
if(keyman.isAttached(elem)) {
|
||||
var attached = keyman.isAttached(elem);
|
||||
kbdLabel.textContent = attached ? " Using globally-selected keyboard." : '';
|
||||
}
|
||||
}, 1);
|
||||
|
|
|
|||
|
|
@ -36,8 +36,9 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init();
|
||||
keyman.init().then(function() {
|
||||
loadKeyboards(1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Add keyboard management script for local selection of keyboards to use -->
|
||||
|
|
@ -46,7 +47,7 @@
|
|||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body onload='loadKeyboards(1);'>
|
||||
<body>
|
||||
<h2>KeymanWeb: Test IFrame connectivity</h2>
|
||||
|
||||
<div id='DynamicTextboxes'>
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
|
||||
var platform = 'desktop';
|
||||
|
||||
keyman.getOskWidth = function() {
|
||||
|
|
@ -51,7 +49,7 @@
|
|||
platform == 'phone' ? 240 : 360;
|
||||
};
|
||||
|
||||
let shadowfy = function(container) {
|
||||
function shadowfy(container) {
|
||||
const shadow = container.attachShadow({ mode: "open" });
|
||||
const docBase = container.children[0];
|
||||
|
||||
|
|
@ -67,7 +65,7 @@
|
|||
shadow.appendChild(docBase);
|
||||
}
|
||||
|
||||
let documentKeyboard = async function(kbdid, langid, formFactor, layer) {
|
||||
async function documentKeyboard(kbdid, langid, formFactor, layer) {
|
||||
let docTarget = document.getElementById("docTarget");
|
||||
label = document.createElement('h3');
|
||||
docTarget.appendChild(label);
|
||||
|
|
@ -77,8 +75,8 @@
|
|||
|
||||
const container = document.createElement('div');
|
||||
|
||||
await kmw.addKeyboards(`${kbdid}@${langid}`);
|
||||
await kmw.setActiveKeyboard(kbdid, langid);
|
||||
await keyman.addKeyboards(`${kbdid}@${langid}`);
|
||||
await keyman.setActiveKeyboard(kbdid, langid);
|
||||
docBase = keyman.BuildVisualKeyboard(kbdid, 1, formFactor, layer);
|
||||
|
||||
label.textContent = `${keyman.getKeyboard(kbdid).Name} - ${formFactor} - ${layer} layer`;
|
||||
|
|
@ -95,7 +93,8 @@
|
|||
shadowfy(container);
|
||||
}
|
||||
|
||||
kmw.init().then(async function() {
|
||||
keyman.init().then(async function() {
|
||||
await loadKeyboards(1);
|
||||
await documentKeyboard("gff_amharic", "am", "phone", "default");
|
||||
await documentKeyboard("sil_euro_latin", "no", "phone", "shift");
|
||||
await documentKeyboard("lao_2008_basic", "lo", "tablet", "default");
|
||||
|
|
@ -111,7 +110,7 @@
|
|||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body onload='loadKeyboards(1);'>
|
||||
<body>
|
||||
<h2>KeymanWeb: Keyboard documentation rendering</h2>
|
||||
|
||||
<div id='DynamicTextboxes'>
|
||||
|
|
@ -121,15 +120,12 @@
|
|||
(It is ignored by other User Interfaces.)
|
||||
-->
|
||||
<div id='KeymanWebControl'></div>
|
||||
<h3>This test page exists for testing KMW's keyboard-documentation rendering system.</h3>
|
||||
<!--<iframe src="hello-world.html" height=100></iframe>-->
|
||||
<hr>
|
||||
<div id="docTarget"></div>
|
||||
</div>
|
||||
<h3><a href="../">Return to testing home page</a></h3>
|
||||
|
||||
|
||||
|
||||
<h3>This test page exists for testing KMW's keyboard-documentation rendering system.</h3>
|
||||
<!--<iframe src="hello-world.html" height=100></iframe>-->
|
||||
<hr>
|
||||
<div id="docTarget"></div>
|
||||
</div>
|
||||
<h3><a href="../">Return to testing home page</a></h3>
|
||||
</body>
|
||||
|
||||
<!--
|
||||
|
|
|
|||
|
|
@ -36,10 +36,9 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType: 'auto'
|
||||
});
|
||||
}).then(loadKeyboards);
|
||||
</script>
|
||||
|
||||
<!-- Add keyboard management script for local selection of keyboards to use -->
|
||||
|
|
@ -51,7 +50,7 @@
|
|||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body onload='loadKeyboards();'>
|
||||
<body>
|
||||
<h2>KeymanWeb Sample Page - Chirality Testing</h2>
|
||||
<p>This page is designed to stress-test the new support for chiral modifiers and state keys.</p>
|
||||
<p>Be sure to reference the developer console for additional feedback. </p>
|
||||
|
|
|
|||
|
|
@ -1,19 +1,17 @@
|
|||
function loadKeyboards()
|
||||
{
|
||||
var kmw=keyman;
|
||||
|
||||
async function loadKeyboards()
|
||||
{
|
||||
// A testing keyboard handwritten with chirality information.
|
||||
kmw.addKeyboards({id:'chirality',name:'Chirality Testing',
|
||||
await keyman.addKeyboards({id:'chirality',name:'Chirality Testing',
|
||||
languages:{
|
||||
id:'en',name:'English',region:'North America'
|
||||
},
|
||||
filename:'../../../../../build/test-resources/keyboards/chirality.js'
|
||||
});
|
||||
|
||||
|
||||
// A testing keyboard using 10.0 format and the KLS layout specifier
|
||||
// without the 'shift' layer properly defined.
|
||||
// Add a fully-specified, locally-sourced, keyboard with custom font
|
||||
kmw.addKeyboards({id:'halfDefined',name:'Undefined Shift Layer Keyboard',
|
||||
// Add a fully-specified, locally-sourced, keyboard with custom font
|
||||
await keyman.addKeyboards({id:'halfDefined',name:'Undefined Shift Layer Keyboard',
|
||||
languages:{
|
||||
id:'en',name:'English',region:'North America'
|
||||
},
|
||||
|
|
|
|||
|
|
@ -30,10 +30,9 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType: 'auto'
|
||||
});
|
||||
}).then(loadKeyboards);
|
||||
</script>
|
||||
|
||||
<!-- Add keyboard management script for local selection of keyboards to use -->
|
||||
|
|
@ -44,7 +43,7 @@
|
|||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body onload='loadKeyboards();'>
|
||||
<body>
|
||||
<h2>KeymanWeb Sample Page - Test CKEditor Integration</h2>
|
||||
|
||||
<p>Test CKEditor Integration</p>
|
||||
|
|
|
|||
|
|
@ -30,10 +30,9 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType: 'auto'
|
||||
});
|
||||
}).then(loadKeyboards);
|
||||
</script>
|
||||
|
||||
<!-- Add keyboard management script for local selection of keyboards to use -->
|
||||
|
|
@ -44,7 +43,7 @@
|
|||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body onload='loadKeyboards();'>
|
||||
<body>
|
||||
<h2>KeymanWeb Sample Page - Test CKEditor Integration</h2>
|
||||
|
||||
<p>Test CKEditor Integration</p>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
function loadKeyboards()
|
||||
async function loadKeyboards()
|
||||
{
|
||||
var kmw=keyman;
|
||||
|
||||
// Add more keyboards to the language menu, by keyboard name,
|
||||
// keyboard name and language code, or just the BCP-47 language code.
|
||||
// We use a different loading pattern here than in the samples version to provide a slightly different set of test cases.
|
||||
kmw.addKeyboards('french','@he');
|
||||
kmw.addKeyboards({id:'sil_euro_latin', name:'SIL EuroLatin', languages: [{id:'no'}, {id:'sv'}]}); // Loads from partial stub instead of the compact string.
|
||||
await keyman.addKeyboards('french', '@he',
|
||||
{ id: 'sil_euro_latin', name: 'SIL EuroLatin', languages: [{ id: 'no' }, { id: 'sv' }] }); // Loads from partial stub instead of the compact string.
|
||||
|
||||
// Add a keyboard by language name. Note that the name must be spelled
|
||||
// correctly, or the keyboard will not be found. (Using BCP-47 codes is
|
||||
// usually easier.)
|
||||
kmw.addKeyboardsForLanguage('Dzongkha');
|
||||
await keyman.addKeyboardsForLanguage('Dzongkha');
|
||||
}
|
||||
|
|
@ -1,172 +1,122 @@
|
|||
// JavaScript Document samplehdr.js: Keyboard management for KeymanWeb demonstration pages
|
||||
|
||||
/*
|
||||
The keyboard name and/or BCP-47 language code must be specified for each keyboard that is to be available.
|
||||
If the same keyboard is used for several languages, it must be listed for each
|
||||
language, but the keyboard itself will only be loaded once.
|
||||
If two (or more) keyboards are to be available for a given language, both must be listed.
|
||||
Any number of keyboards may be specified in one or more calls.
|
||||
Keyboard paths may be absolute (with respect to the server root) or relative to the keyboards option path.
|
||||
The actual keyboard object will be downloaded asynchronously when first selected for use.
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*/
|
||||
|
||||
Each argument to addKeyboards() is a string, for example:
|
||||
european2 loads the current version of the Eurolatin 2 keyboard (for its default language)
|
||||
european2@fr loads the current version of the Eurolatin 2 keyboard for French
|
||||
european2@fr@1.2 loads version 1.2 of the Eurolatin 2 keyboard for French
|
||||
|
||||
Argument syntax also supports the following extensions:
|
||||
@fr load the current version of the default keyboard for French
|
||||
@fr$ load all available keyboards (current version) for French
|
||||
|
||||
Each call to addKeyboards() requires a single call to the remote server,
|
||||
(unless all keyboards listed are local and fully specified) so it is better
|
||||
to use multiple arguments rather than separate function calls.
|
||||
|
||||
Calling addKeyboards() with no arguments returns a list of *all* available keyboards.
|
||||
The Toolbar (desktop browser) UI is best suited for allowing users to select
|
||||
the appropriate language and keyboard in this case.
|
||||
|
||||
Keyboards may also be specified by language name using addKeyboardsForLanguage()
|
||||
for example:
|
||||
keymanweb.addKeyboardsForLanguage('Burmese');
|
||||
|
||||
Appending $ to the language name will again cause all available keyboards for that
|
||||
language to be loaded rather than the default keyboard.
|
||||
|
||||
The first call to addKeyboardsForLanguage() makes an additional call to the
|
||||
keyman API to load the current list of keyboard/language associations.
|
||||
|
||||
In this example, the following function loads the indicated keyboards,
|
||||
and is called when the page loads.
|
||||
*/
|
||||
|
||||
function errToString(err) {
|
||||
// Painful? Kinda. But needed on un-updated Android API 21!
|
||||
if(Array.isArray(err)) {
|
||||
var result = '';
|
||||
for(var i = 0; i < err.length; i++) {
|
||||
var e = err[i];
|
||||
if(e.error instanceof Error) {
|
||||
result += e.error.message + '\n';
|
||||
} else {
|
||||
result += JSON.stringify(e) + '\n';
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if(err instanceof Error) {
|
||||
return err.message;
|
||||
}
|
||||
return JSON.stringify(err);
|
||||
}
|
||||
|
||||
function doAddKeyboards(data) {
|
||||
return keyman.addKeyboards(data).catch(function(err) {
|
||||
console.error('keyman.addKeyboards failed with '+errToString(err)+' for '+JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
function doAddKeyboardsForLanguage(data) {
|
||||
return keyman.addKeyboardsForLanguage(data).catch(function(err) {
|
||||
console.error('keyman.addKeyboardsForLanguage failed with '+errToString(err)+' for '+JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
function loadKeyboards(nestLevel)
|
||||
{
|
||||
var kmw=keyman;
|
||||
|
||||
var base_prefix = '../';
|
||||
var prefix = './'; // The default - when prefix == 0.
|
||||
|
||||
if(nestLevel !== undefined && nestLevel > 0) {
|
||||
prefix = '';
|
||||
for(var i=0; i < nestLevel; i++) {
|
||||
prefix = prefix + base_prefix;
|
||||
function errToString(err) {
|
||||
// Painful? Kinda. But needed on un-updated Android API 21!
|
||||
if(Array.isArray(err)) {
|
||||
let result = '';
|
||||
for(let i = 0; i < err.length; i++) {
|
||||
const e = err[i];
|
||||
if(e.error instanceof Error) {
|
||||
result += e.error.message + '\n';
|
||||
} else {
|
||||
result += JSON.stringify(e) + '\n';
|
||||
}
|
||||
}
|
||||
|
||||
// The first keyboard added will be the default keyboard for touch devices.
|
||||
// For faster loading, it may be best for the default keyboard to be
|
||||
// locally sourced.
|
||||
doAddKeyboards({id:'us',name:'English',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'us-1.0.js')});
|
||||
|
||||
doAddKeyboards({id:'web_context_tests',name:'Web Context Tests',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'web_context_tests.js')});
|
||||
|
||||
doAddKeyboards({id:'test_chirality',name:'test_chirality',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'test_chirality.js')});
|
||||
|
||||
doAddKeyboards({id:'obolo_chwerty_6351',name:'obolo_chwerty_6351',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'obolo_chwerty_6351.js')});
|
||||
|
||||
doAddKeyboards({id:'gesture_prototyping',name:'Gesture Prototyping',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/gesture_prototyping/build/gesture_prototyping.js')});
|
||||
|
||||
doAddKeyboards({id:'diacritic_rota',name:'Diacritic 10-key Rota',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/diacritic_rota/build/diacritic_rota.js')});
|
||||
|
||||
doAddKeyboards({id:'ye_old_ten_key',name:'Classic 10-key',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/ye_old_ten_key/build/ye_old_ten_key.js')});
|
||||
|
||||
// Add more keyboards to the language menu, by keyboard name,
|
||||
// keyboard name and language code, or just the BCP-47 language code.
|
||||
// We use a different loading pattern here than in the samples version to provide a slightly different set of test cases.
|
||||
doAddKeyboards('french','@he');
|
||||
doAddKeyboards('khmer_angkor','@km');
|
||||
doAddKeyboards({id:'sil_euro_latin', name:'SIL EuroLatin', languages: [{id:'no'}, {id:'sv'}]}); // Loads from partial stub instead of the compact string.
|
||||
|
||||
// Add a keyboard by language name. Note that the name must be spelled
|
||||
// correctly, or the keyboard will not be found. (Using BCP-47 codes is
|
||||
// usually easier.)
|
||||
doAddKeyboardsForLanguage('Dzongkha');
|
||||
|
||||
// Add a fully-specified, locally-sourced, keyboard with custom font
|
||||
doAddKeyboards({id:'lao_2008_basic',name:'Lao Basic',
|
||||
languages: {
|
||||
id:'lo',name:'Lao',region:'Asia',
|
||||
},
|
||||
filename:(prefix + 'lao_2008_basic-1.2.js')
|
||||
});
|
||||
|
||||
// The following two optional calls should be delayed until language menus are fully loaded:
|
||||
// (a) a specific mapped input element input is focused, to ensure that the OSK appears
|
||||
// (b) a specific keyboard is loaded, rather than the keyboard last used.
|
||||
//window.setTimeout(function(){kmw.setActiveElement('ta1',true);},2500);
|
||||
//window.setTimeout(function(){kmw.setActiveKeyboard('Keyboard_french','fr');},3000);
|
||||
|
||||
// Note that locally specified keyboards will be listed before keyboards
|
||||
// requested from the remote server by user interfaces that do not order
|
||||
// keyboards alphabetically by language.
|
||||
return result;
|
||||
}
|
||||
if(err instanceof Error) {
|
||||
return err.message;
|
||||
}
|
||||
return JSON.stringify(err);
|
||||
}
|
||||
|
||||
// Script to allow a user to add any keyboard to the keyboard menu
|
||||
function addKeyboard(n)
|
||||
{
|
||||
var sKbd,kmw=keyman;
|
||||
switch(n)
|
||||
{
|
||||
case 1:
|
||||
sKbd=document.getElementById('kbd_id1').value;
|
||||
doAddKeyboards(sKbd);
|
||||
break;
|
||||
case 2:
|
||||
sKbd=document.getElementById('kbd_id2').value.toLowerCase();
|
||||
doAddKeyboards('@'+sKbd);
|
||||
break;
|
||||
case 3:
|
||||
// Add keyboard for comma-separated language name(s)
|
||||
sKbd=document.getElementById('kbd_id3').value;
|
||||
doAddKeyboardsForLanguage(sKbd);
|
||||
break;
|
||||
function doAddKeyboards(data) {
|
||||
return keyman.addKeyboards(data).catch(function(err) {
|
||||
console.error('keyman.addKeyboards failed with '+errToString(err)+' for '+JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
function doAddKeyboardsForLanguage(data) {
|
||||
return keyman.addKeyboardsForLanguage(data).catch(function(err) {
|
||||
console.error('keyman.addKeyboardsForLanguage failed with '+errToString(err)+' for '+JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
async function loadKeyboards(nestLevel) {
|
||||
const base_prefix = '../';
|
||||
let prefix = './'; // The default - when prefix == 0.
|
||||
|
||||
if(nestLevel !== undefined && nestLevel > 0) {
|
||||
prefix = '';
|
||||
for(let i=0; i < nestLevel; i++) {
|
||||
prefix += base_prefix;
|
||||
}
|
||||
}
|
||||
|
||||
// Add keyboard on Enter (as well as pressing button)
|
||||
function clickOnEnter(e,id)
|
||||
{
|
||||
e = e || window.event;
|
||||
if(e.keyCode == 13) addKeyboard(id);
|
||||
}
|
||||
// The first keyboard added will be the default keyboard for touch devices.
|
||||
// For faster loading, it may be best for the default keyboard to be
|
||||
// locally sourced.
|
||||
await doAddKeyboards({id:'us',name:'English',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'us-1.0.js')});
|
||||
|
||||
await doAddKeyboards({id:'web_context_tests',name:'Web Context Tests',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'web_context_tests.js')});
|
||||
|
||||
await doAddKeyboards({id:'test_chirality',name:'test_chirality',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'test_chirality.js')});
|
||||
|
||||
await doAddKeyboards({id:'obolo_chwerty_6351',name:'obolo_chwerty_6351',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'obolo_chwerty_6351.js')});
|
||||
|
||||
await doAddKeyboards({id:'gesture_prototyping',name:'Gesture Prototyping',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/gesture_prototyping/build/gesture_prototyping.js')});
|
||||
|
||||
await doAddKeyboards({id:'diacritic_rota',name:'Diacritic 10-key Rota',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/diacritic_rota/build/diacritic_rota.js')});
|
||||
|
||||
await doAddKeyboards({id:'ye_old_ten_key',name:'Classic 10-key',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/ye_old_ten_key/build/ye_old_ten_key.js')});
|
||||
|
||||
// Add more keyboards to the language menu, by keyboard name,
|
||||
// keyboard name and language code, or just the BCP-47 language code.
|
||||
// We use a different loading pattern here than in the samples version to provide a slightly different set of test cases.
|
||||
await doAddKeyboards('french','@he');
|
||||
await doAddKeyboards('khmer_angkor','@km');
|
||||
await doAddKeyboards({id:'sil_euro_latin', name:'SIL EuroLatin', languages: [{id:'no'}, {id:'sv'}]}); // Loads from partial stub instead of the compact string.
|
||||
|
||||
// Add a keyboard by language name. Note that the name must be spelled
|
||||
// correctly, or the keyboard will not be found. (Using BCP-47 codes is
|
||||
// usually easier.)
|
||||
await doAddKeyboardsForLanguage('Dzongkha');
|
||||
|
||||
// Add a fully-specified, locally-sourced, keyboard with custom font
|
||||
await doAddKeyboards({
|
||||
id: 'lao_2008_basic',
|
||||
name: 'Lao Basic',
|
||||
languages: {
|
||||
id: 'lo', name: 'Lao', region: 'Asia'
|
||||
},
|
||||
filename: (prefix + 'lao_2008_basic-1.2.js')
|
||||
});
|
||||
}
|
||||
|
||||
// Script to allow a user to add any keyboard to the keyboard menu
|
||||
async function addKeyboard(n) {
|
||||
let sKbd;
|
||||
switch(n) {
|
||||
case 1:
|
||||
sKbd=document.getElementById('kbd_id1').value;
|
||||
await doAddKeyboards(sKbd);
|
||||
break;
|
||||
case 2:
|
||||
sKbd=document.getElementById('kbd_id2').value.toLowerCase();
|
||||
await doAddKeyboards('@'+sKbd);
|
||||
break;
|
||||
case 3:
|
||||
// Add keyboard for comma-separated language name(s)
|
||||
sKbd=document.getElementById('kbd_id3').value;
|
||||
await doAddKeyboardsForLanguage(sKbd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add keyboard on Enter (as well as pressing button)
|
||||
async function clickOnEnter(e,id) {
|
||||
e = e || window.event;
|
||||
if (e.keyCode == 13) {
|
||||
await addKeyboard(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,11 +36,10 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(function() {
|
||||
kmw.addKeyboards({id:'default_subkey',name:'English',languages:{id:'en',name:'English'}, filename:'./default_subkey.js'});
|
||||
}).then(async function() {
|
||||
await keyman.addKeyboards({id:'default_subkey',name:'English',languages:{id:'en',name:'English'}, filename:'./default_subkey.js'});
|
||||
|
||||
var pageRef = (window.location.protocol == 'file:')
|
||||
? window.location.href.substr(0, window.location.href.lastIndexOf('/')+1)
|
||||
|
|
|
|||
|
|
@ -39,8 +39,7 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(function() {
|
||||
loadKeyboards(1);
|
||||
|
|
|
|||
|
|
@ -39,8 +39,7 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(function() {
|
||||
loadKeyboards(1);
|
||||
|
|
|
|||
|
|
@ -39,9 +39,8 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
attachType:'auto'
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(function() {
|
||||
loadKeyboards(1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -36,15 +36,16 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(async function () {
|
||||
await keyman.addKeyboards();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body onload='kmw.addKeyboards();'>
|
||||
<body>
|
||||
<h2>KeymanWeb Testing Page - Desktop UI module Testing</h2>
|
||||
<p>This page is designed to facilitate testing of various aspects of the Toolbar UI for
|
||||
KeymanWeb. Originally developed to help address issue #1275.
|
||||
|
|
|
|||
|
|
@ -36,18 +36,16 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType: 'auto'
|
||||
}).then(function() {
|
||||
// A testing keyboard with empty rows on each layer
|
||||
kmw.addKeyboards({id:'empty_row', name: 'Empty Row',
|
||||
keyman.addKeyboards({id:'empty_row', name: 'Empty Row',
|
||||
languages:{
|
||||
id:'en', name:'English'
|
||||
},
|
||||
filename: 'empty_row-1.0.js'
|
||||
});
|
||||
kmw.addKeyboards({id:'afghan_turkmen', name:'Afghan Turkmen',
|
||||
}, {id:'afghan_turkmen', name:'Afghan Turkmen',
|
||||
languages:{
|
||||
id:'tk-Arab', name:'Turkmen (Arabic)'
|
||||
},
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<h1>KeymanWeb 19 Testing</h1>
|
||||
<!--
|
||||
<h1>KeymanWeb 20 Testing</h1>
|
||||
<h2><a href="./kmxkeyboard.html">Test KMX keyboard loaded in Keymanweb (kmxkeyboard)</a></h2>
|
||||
-->
|
||||
|
||||
<h1>KeymanWeb 17 Testing</h1>
|
||||
<h2><a href="./unminified.html">Test unminified Keymanweb (unminified)</a></h2>
|
||||
|
|
|
|||
|
|
@ -36,9 +36,8 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
window.setTimeout(() => {
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto',
|
||||
}).then(function() {
|
||||
loadKeyboards(1);
|
||||
|
|
|
|||
|
|
@ -49,8 +49,7 @@
|
|||
document.getElementById('ta1').focus();
|
||||
}
|
||||
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(function() {
|
||||
setOSK('windows');
|
||||
|
|
|
|||
|
|
@ -1,124 +1,63 @@
|
|||
// JavaScript Document samplehdr.js: Keyboard management for KeymanWeb demonstration pages
|
||||
|
||||
/*
|
||||
The keyboard name and/or BCP-47 language code must be specified for each keyboard that is to be available.
|
||||
If the same keyboard is used for several languages, it must be listed for each
|
||||
language, but the keyboard itself will only be loaded once.
|
||||
If two (or more) keyboards are to be available for a given language, both must be listed.
|
||||
Any number of keyboards may be specified in one or more calls.
|
||||
Keyboard paths may be absolute (with respect to the server root) or relative to the keyboards option path.
|
||||
The actual keyboard object will be downloaded asynchronously when first selected for use.
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*/
|
||||
async function loadKeyboards()
|
||||
{
|
||||
await keyman.addKeyboards({id:'us',name:'English',languages:{id:'en',name:'English'},
|
||||
filename:'../us-1.0.js'});
|
||||
await keyman.addKeyboards('french','european2@sv','european2@no','@he');
|
||||
await keyman.addKeyboardsForLanguage('Dzongkha');
|
||||
await keyman.addKeyboards({id:'lao_2008_basic',name:'Lao Basic',
|
||||
languages:{
|
||||
id:'lo',name:'Lao',region:'Asia',
|
||||
font:{family:'LaoWeb',source:['../font/saysettha_web.ttf','../font/saysettha_web.woff','../font/saysettha_web.eot']}
|
||||
},
|
||||
filename:'../lao_2008_basic-1.2.js'
|
||||
});
|
||||
}
|
||||
|
||||
Each argument to addKeyboards() is a string, for example:
|
||||
european2 loads the current version of the Eurolatin 2 keyboard (for its default language)
|
||||
european2@fr loads the current version of the Eurolatin 2 keyboard for French
|
||||
european2@fr@1.2 loads version 1.2 of the Eurolatin 2 keyboard for French
|
||||
|
||||
Argument syntax also supports the following extensions:
|
||||
@fr load the current version of the default keyboard for French
|
||||
@fr$ load all available keyboards (current version) for French
|
||||
|
||||
Each call to addKeyboards() requires a single call to the remote server,
|
||||
(unless all keyboards listed are local and fully specified) so it is better
|
||||
to use multiple arguments rather than separate function calls.
|
||||
|
||||
Calling addKeyboards() with no arguments returns a list of *all* available keyboards.
|
||||
The Toolbar (desktop browser) UI is best suited for allowing users to select
|
||||
the appropriate language and keyboard in this case.
|
||||
|
||||
Keyboards may also be specified by language name using addKeyboardsForLanguage()
|
||||
for example:
|
||||
keymanweb.addKeyboardsForLanguage('Burmese');
|
||||
|
||||
Appending $ to the language name will again cause all available keyboards for that
|
||||
language to be loaded rather than the default keyboard.
|
||||
|
||||
The first call to addKeyboardsForLanguage() makes an additional call to the
|
||||
keyman API to load the current list of keyboard/language associations.
|
||||
|
||||
In this example, the following function loads the indicated keyboards,
|
||||
and is called when the page loads.
|
||||
*/
|
||||
|
||||
function loadKeyboards()
|
||||
// Script to allow a user to add any keyboard to the keyboard menu
|
||||
async function addKeyboard(n)
|
||||
{
|
||||
let sKbd;
|
||||
switch(n)
|
||||
{
|
||||
var kmw=window['keyman'] ? keyman : tavultesoft.keymanweb;
|
||||
|
||||
// The first keyboard added will be the default keyboard for touch devices.
|
||||
// For faster loading, it may be best for the default keyboard to be
|
||||
// locally sourced.
|
||||
kmw.addKeyboards({id:'us',name:'English',languages:{id:'en',name:'English'},
|
||||
filename:'../us-1.0.js'});
|
||||
|
||||
// Add more keyboards to the language menu, by keyboard name,
|
||||
// keyboard name and language code, or just the BCP-47 language code.
|
||||
kmw.addKeyboards('french','european2@sv','european2@no','@he');
|
||||
|
||||
// Add a keyboard by language name. Note that the name must be spelled
|
||||
// correctly, or the keyboard will not be found. (Using BCP-47 codes is
|
||||
// usually easier.)
|
||||
kmw.addKeyboardsForLanguage('Dzongkha');
|
||||
|
||||
// Add a fully-specified, locally-sourced, keyboard with custom font
|
||||
kmw.addKeyboards({id:'lao_2008_basic',name:'Lao Basic',
|
||||
languages:{
|
||||
id:'lo',name:'Lao',region:'Asia',
|
||||
font:{family:'LaoWeb',source:['../font/saysettha_web.ttf','../font/saysettha_web.woff','../font/saysettha_web.eot']}
|
||||
},
|
||||
filename:'../lao_2008_basic-1.2.js'
|
||||
});
|
||||
|
||||
// The following two optional calls should be delayed until language menus are fully loaded:
|
||||
// (a) a specific mapped input element input is focused, to ensure that the OSK appears
|
||||
// (b) a specific keyboard is loaded, rather than the keyboard last used.
|
||||
//window.setTimeout(function(){kmw.setActiveElement('ta1',true);},2500);
|
||||
//window.setTimeout(function(){kmw.setActiveKeyboard('Keyboard_french','fr');},3000);
|
||||
|
||||
// Note that locally specified keyboards will be listed before keyboards
|
||||
// requested from the remote server by user interfaces that do not order
|
||||
// keyboards alphabetically by language.
|
||||
case 1:
|
||||
sKbd=document.getElementById('kbd_id1').value;
|
||||
await keyman.addKeyboards(sKbd);
|
||||
break;
|
||||
case 2:
|
||||
sKbd=document.getElementById('kbd_id2').value.toLowerCase();
|
||||
await keyman.addKeyboards('@'+sKbd);
|
||||
break;
|
||||
case 3:
|
||||
sKbd=document.getElementById('kbd_id3').value;
|
||||
await keyman.addKeyboardsForLanguage(sKbd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Script to allow a user to add any keyboard to the keyboard menu
|
||||
function addKeyboard(n)
|
||||
{
|
||||
var sKbd, kmw=window['keyman'] ? keyman : tavultesoft.keymanweb;
|
||||
switch(n)
|
||||
{
|
||||
case 1:
|
||||
sKbd=document.getElementById('kbd_id1').value;
|
||||
kmw.addKeyboards(sKbd);
|
||||
break;
|
||||
case 2:
|
||||
sKbd=document.getElementById('kbd_id2').value.toLowerCase();
|
||||
kmw.addKeyboards('@'+sKbd);
|
||||
break;
|
||||
case 3:
|
||||
sKbd=document.getElementById('kbd_id3').value;
|
||||
kmw.addKeyboardsForLanguage(sKbd);
|
||||
break;
|
||||
}
|
||||
// Add keyboard on Enter (as well as pressing button)
|
||||
async function clickOnEnter(e,id)
|
||||
{
|
||||
e = e || window.event;
|
||||
if (e.keyCode == 13) {
|
||||
await addKeyboard(id);
|
||||
}
|
||||
}
|
||||
|
||||
// Add keyboard on Enter (as well as pressing button)
|
||||
function clickOnEnter(e,id)
|
||||
{
|
||||
e = e || window.event;
|
||||
if(e.keyCode == 13) addKeyboard(id);
|
||||
}
|
||||
|
||||
function removeKeyboard() {
|
||||
var kmw=window['keyman'] ? keyman : tavultesoft.keymanweb;
|
||||
|
||||
var sKbd = document.getElementById('kbd_id4').value;
|
||||
var result = kmw.removeKeyboards(sKbd);
|
||||
|
||||
console.log("Keyboard '" + sKbd + "' removal success: " + result);
|
||||
}
|
||||
|
||||
// Removes keyboard on Enter (as well as pressing button)
|
||||
function removeOnEnter(e)
|
||||
{
|
||||
e = e || window.event;
|
||||
if(e.keyCode == 13) removeKeyboard();
|
||||
async function removeKeyboard() {
|
||||
let sKbd = document.getElementById('kbd_id4').value;
|
||||
let result = await keyman.removeKeyboards(sKbd);
|
||||
|
||||
console.log("Keyboard '" + sKbd + "' removal success: " + result);
|
||||
}
|
||||
|
||||
// Removes keyboard on Enter (as well as pressing button)
|
||||
async function removeOnEnter(e)
|
||||
{
|
||||
e = e || window.event;
|
||||
if(e.keyCode == 13) {
|
||||
await removeKeyboard();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,12 +34,14 @@
|
|||
-->
|
||||
<script src="../../../../../build/publish/debug/kmwuitoggle.js"></script>
|
||||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
});
|
||||
</script>
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
keyman.init({
|
||||
attachType: 'auto'
|
||||
}).then(function () {
|
||||
loadKeyboards();
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Add keyboard management script for local selection of keyboards to use -->
|
||||
<script src="./header.js"></script>
|
||||
|
|
@ -47,7 +49,7 @@
|
|||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body onload='loadKeyboards();'>
|
||||
<body>
|
||||
<h2>KeymanWeb: 'Test case' for proper implementation of the removeKeyboards API function</h2>
|
||||
|
||||
<div id='DynamicTextboxes'>
|
||||
|
|
|
|||
|
|
@ -36,10 +36,11 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
});
|
||||
}).then(async function () {
|
||||
await loadKeyboards();
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Add keyboard management script for local selection of keyboards to use -->
|
||||
|
|
@ -48,7 +49,7 @@
|
|||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body onload='loadKeyboards();'>
|
||||
<body>
|
||||
<h2>KeymanWeb Sample Page - Keyboard Registration Check</h2>
|
||||
<p>
|
||||
This page is designed to test KeymanWeb's behavior when being told to load a keyboard multiple times, both via
|
||||
|
|
|
|||
|
|
@ -1,70 +1,64 @@
|
|||
// Modified version of commonHeader - contains repeated requests for the same language.
|
||||
/*
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*
|
||||
* Modified version of commonHeader.js - contains repeated requests for the same language.
|
||||
*/
|
||||
|
||||
function loadKeyboards()
|
||||
{
|
||||
var kmw=keyman;
|
||||
|
||||
// The first keyboard added will be the default keyboard for touch devices.
|
||||
// For faster loading, it may be best for the default keyboard to be
|
||||
// locally sourced.
|
||||
kmw.addKeyboards({id:'us',name:'English',languages:{id:'en',name:'English'},
|
||||
filename:'../us-1.0.js'});
|
||||
|
||||
// Add more keyboards to the language menu, by keyboard name,
|
||||
// keyboard name and language code, or just the BCP-47 language code.
|
||||
kmw.addKeyboards('french','european2@sv','european2@sv','european2@sv','european2@sv','european2@sv','european2@sv','european2@no','@he');
|
||||
kmw.addKeyboards('@he');
|
||||
kmw.addKeyboards('@he');
|
||||
|
||||
// Add a keyboard by language name. Note that the name must be spelled
|
||||
// correctly, or the keyboard will not be found. (Using BCP-47 codes is
|
||||
// usually easier.)
|
||||
kmw.addKeyboardsForLanguage('Dzongkha');
|
||||
|
||||
// Add a fully-specified, locally-sourced, keyboard with custom font
|
||||
kmw.addKeyboards({id:'lao_2008_basic',name:'Lao Basic',
|
||||
languages:{
|
||||
id:'lo',name:'Lao',region:'Asia'
|
||||
},
|
||||
filename:'../lao_2008_basic.js'
|
||||
});
|
||||
async function loadKeyboards() {
|
||||
await keyman.addKeyboards({id:'us',name:'English',languages:{id:'en',name:'English'},
|
||||
filename:'../us-1.0.js'});
|
||||
|
||||
// The following two optional calls should be delayed until language menus are fully loaded:
|
||||
// (a) a specific mapped input element input is focused, to ensure that the OSK appears
|
||||
// (b) a specific keyboard is loaded, rather than the keyboard last used.
|
||||
//window.setTimeout(function(){kmw.setActiveElement('ta1',true);},2500);
|
||||
//window.setTimeout(function(){kmw.setActiveKeyboard('Keyboard_french','fr');},3000);
|
||||
|
||||
// Note that locally specified keyboards will be listed before keyboards
|
||||
// requested from the remote server by user interfaces that do not order
|
||||
// keyboards alphabetically by language.
|
||||
}
|
||||
|
||||
// Script to allow a user to add any keyboard to the keyboard menu
|
||||
function addKeyboard(n)
|
||||
{
|
||||
var sKbd,kmw=keyman;
|
||||
switch(n)
|
||||
{
|
||||
case 1:
|
||||
sKbd=document.getElementById('kbd_id1').value;
|
||||
kmw.addKeyboards(sKbd);
|
||||
break;
|
||||
case 2:
|
||||
sKbd=document.getElementById('kbd_id2').value.toLowerCase();
|
||||
kmw.addKeyboards('@'+sKbd);
|
||||
break;
|
||||
case 3:
|
||||
sKbd=document.getElementById('kbd_id3').value;
|
||||
kmw.addKeyboardsForLanguage(sKbd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add keyboard on Enter (as well as pressing button)
|
||||
function clickOnEnter(e,id)
|
||||
{
|
||||
e = e || window.event;
|
||||
if(e.keyCode == 13) addKeyboard(id);
|
||||
}
|
||||
// Intentionally request the same keyboard multiple times to test that it
|
||||
// is not added multiple times and doesn't cause an error.
|
||||
await keyman.addKeyboards('french', 'european2@sv', 'european2@sv', 'european2@sv',
|
||||
'european2@sv', 'european2@sv', 'european2@sv', 'european2@no', '@he');
|
||||
await keyman.addKeyboards('@he');
|
||||
await keyman.addKeyboards('@he'); // intentional duplicate
|
||||
|
||||
// Add a keyboard by language name. Note that the name must be spelled
|
||||
// correctly, or the keyboard will not be found. (Using BCP-47 codes is
|
||||
// usually easier.)
|
||||
await keyman.addKeyboardsForLanguage('Dzongkha');
|
||||
|
||||
// Add a fully-specified, locally-sourced, keyboard with custom font
|
||||
await keyman.addKeyboards({
|
||||
id: 'lao_2008_basic',
|
||||
name: 'Lao Basic',
|
||||
languages:{
|
||||
id: 'lo',
|
||||
name: 'Lao',
|
||||
region: 'Asia'
|
||||
},
|
||||
filename: '../lao_2008_basic.js'
|
||||
});
|
||||
}
|
||||
|
||||
// Script to allow a user to add any keyboard to the keyboard menu
|
||||
async function addKeyboard(n)
|
||||
{
|
||||
let sKbd;
|
||||
switch(n)
|
||||
{
|
||||
case 1:
|
||||
sKbd=document.getElementById('kbd_id1').value;
|
||||
await keyman.addKeyboards(sKbd);
|
||||
break;
|
||||
case 2:
|
||||
sKbd=document.getElementById('kbd_id2').value.toLowerCase();
|
||||
await keyman.addKeyboards('@'+sKbd);
|
||||
break;
|
||||
case 3:
|
||||
sKbd=document.getElementById('kbd_id3').value;
|
||||
await keyman.addKeyboardsForLanguage(sKbd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add keyboard on Enter (as well as pressing button)
|
||||
async function clickOnEnter(e,id) {
|
||||
e = e || window.event;
|
||||
if (e.keyCode == 13) {
|
||||
await addKeyboard(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,11 +36,10 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
});
|
||||
kmw.addKeyboards({id:'issue115a',name:'Issue 115',languages:{id:'en',name:'English'},
|
||||
keyman.addKeyboards({id:'issue115a',name:'Issue 115',languages:{id:'en',name:'English'},
|
||||
filename:'./issue115a.js'});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
}).then(function() {
|
||||
keyman.addKeyboards({id:'next_layer_tests',name:'Issue 116',languages:{id:'en',name:'English'},
|
||||
filename:'./next_layer_tests.js'});
|
||||
});
|
||||
kmw.addKeyboards({id:'next_layer_tests',name:'Issue 116',languages:{id:'en',name:'English'},
|
||||
filename:'./next_layer_tests.js'});
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,9 +40,8 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
attachType:'auto',
|
||||
keyman.init({
|
||||
attachType:'auto',
|
||||
});
|
||||
|
||||
// Note: explicitly NOT deferred or waiting on the `init` Promise. This is
|
||||
|
|
|
|||
|
|
@ -1,171 +1,107 @@
|
|||
// JavaScript Document samplehdr.js: Keyboard management for KeymanWeb demonstration pages
|
||||
|
||||
/*
|
||||
The keyboard name and/or BCP-47 language code must be specified for each keyboard that is to be available.
|
||||
If the same keyboard is used for several languages, it must be listed for each
|
||||
language, but the keyboard itself will only be loaded once.
|
||||
If two (or more) keyboards are to be available for a given language, both must be listed.
|
||||
Any number of keyboards may be specified in one or more calls.
|
||||
Keyboard paths may be absolute (with respect to the server root) or relative to the keyboards option path.
|
||||
The actual keyboard object will be downloaded asynchronously when first selected for use.
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*/
|
||||
|
||||
Each argument to addKeyboards() is a string, for example:
|
||||
european2 loads the current version of the Eurolatin 2 keyboard (for its default language)
|
||||
european2@fr loads the current version of the Eurolatin 2 keyboard for French
|
||||
european2@fr@1.2 loads version 1.2 of the Eurolatin 2 keyboard for French
|
||||
|
||||
Argument syntax also supports the following extensions:
|
||||
@fr load the current version of the default keyboard for French
|
||||
@fr$ load all available keyboards (current version) for French
|
||||
|
||||
Each call to addKeyboards() requires a single call to the remote server,
|
||||
(unless all keyboards listed are local and fully specified) so it is better
|
||||
to use multiple arguments rather than separate function calls.
|
||||
|
||||
Calling addKeyboards() with no arguments returns a list of *all* available keyboards.
|
||||
The Toolbar (desktop browser) UI is best suited for allowing users to select
|
||||
the appropriate language and keyboard in this case.
|
||||
|
||||
Keyboards may also be specified by language name using addKeyboardsForLanguage()
|
||||
for example:
|
||||
keymanweb.addKeyboardsForLanguage('Burmese');
|
||||
|
||||
Appending $ to the language name will again cause all available keyboards for that
|
||||
language to be loaded rather than the default keyboard.
|
||||
|
||||
The first call to addKeyboardsForLanguage() makes an additional call to the
|
||||
keyman API to load the current list of keyboard/language associations.
|
||||
|
||||
In this example, the following function loads the indicated keyboards,
|
||||
and is called when the page loads.
|
||||
*/
|
||||
|
||||
function errToString(err) {
|
||||
// Painful? Kinda. But needed on un-updated Android API 21!
|
||||
if(Array.isArray(err)) {
|
||||
var result = '';
|
||||
for(var i = 0; i < err.length; i++) {
|
||||
var e = err[i];
|
||||
if(e.error instanceof Error) {
|
||||
result += e.error.message + '\n';
|
||||
} else {
|
||||
result += JSON.stringify(e) + '\n';
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if(err instanceof Error) {
|
||||
return err.message;
|
||||
}
|
||||
return JSON.stringify(err);
|
||||
}
|
||||
|
||||
function doAddKeyboards(data) {
|
||||
return keyman.addKeyboards(data).catch(function(err) {
|
||||
console.error('keyman.addKeyboards failed with '+errToString(err)+' for '+JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
function doAddKeyboardsForLanguage(data) {
|
||||
return keyman.addKeyboardsForLanguage(data).catch(function(err) {
|
||||
console.error('keyman.addKeyboardsForLanguage failed with '+errToString(err)+' for '+JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
function loadKeyboards(nestLevel)
|
||||
{
|
||||
var kmw=keyman;
|
||||
|
||||
var base_prefix = '../';
|
||||
var prefix = './'; // The default - when prefix == 0.
|
||||
|
||||
if(nestLevel !== undefined && nestLevel > 0) {
|
||||
prefix = '';
|
||||
for(var i=0; i < nestLevel; i++) {
|
||||
prefix = prefix + base_prefix;
|
||||
function errToString(err) {
|
||||
// Painful? Kinda. But needed on un-updated Android API 21!
|
||||
if(Array.isArray(err)) {
|
||||
let result = '';
|
||||
for(let i = 0; i < err.length; i++) {
|
||||
const e = err[i];
|
||||
if(e.error instanceof Error) {
|
||||
result += e.error.message + '\n';
|
||||
} else {
|
||||
result += JSON.stringify(e) + '\n';
|
||||
}
|
||||
}
|
||||
|
||||
// The first keyboard added will be the default keyboard for touch devices.
|
||||
// For faster loading, it may be best for the default keyboard to be
|
||||
// locally sourced.
|
||||
// doAddKeyboards({id:'us',name:'English',languages:{id:'en',name:'English'},
|
||||
// filename:(prefix + 'us-1.0.js')});
|
||||
|
||||
// Do NOT link the us-1.0 keyboard here!
|
||||
|
||||
doAddKeyboards({id:'test_chirality',name:'test_chirality',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'test_chirality.js')});
|
||||
|
||||
doAddKeyboards({id:'obolo_chwerty_6351',name:'obolo_chwerty_6351',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'obolo_chwerty_6351.js')});
|
||||
|
||||
doAddKeyboards({id:'gesture_prototyping',name:'Gesture Prototyping',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/gesture_prototyping/build/gesture_prototyping.js')});
|
||||
|
||||
doAddKeyboards({id:'diacritic_rota',name:'Diacritic 10-key Rota',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/diacritic_rota/build/diacritic_rota.js')});
|
||||
|
||||
doAddKeyboards({id:'ye_old_ten_key',name:'Classic 10-key',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/ye_old_ten_key/build/ye_old_ten_key.js')});
|
||||
|
||||
// Add more keyboards to the language menu, by keyboard name,
|
||||
// keyboard name and language code, or just the BCP-47 language code.
|
||||
// We use a different loading pattern here than in the samples version to provide a slightly different set of test cases.
|
||||
doAddKeyboards('french','@he');
|
||||
doAddKeyboards('khmer_angkor','@km');
|
||||
doAddKeyboards({id:'sil_euro_latin', name:'SIL EuroLatin', languages: [{id:'no'}, {id:'sv'}]}); // Loads from partial stub instead of the compact string.
|
||||
|
||||
// Add a keyboard by language name. Note that the name must be spelled
|
||||
// correctly, or the keyboard will not be found. (Using BCP-47 codes is
|
||||
// usually easier.)
|
||||
doAddKeyboardsForLanguage('Dzongkha');
|
||||
|
||||
// Add a fully-specified, locally-sourced, keyboard with custom font
|
||||
doAddKeyboards({id:'lao_2008_basic',name:'Lao Basic',
|
||||
languages: {
|
||||
id:'lo',name:'Lao',region:'Asia',
|
||||
},
|
||||
filename:(prefix + 'lao_2008_basic-1.2.js')
|
||||
});
|
||||
|
||||
// The following two optional calls should be delayed until language menus are fully loaded:
|
||||
// (a) a specific mapped input element input is focused, to ensure that the OSK appears
|
||||
// (b) a specific keyboard is loaded, rather than the keyboard last used.
|
||||
//window.setTimeout(function(){kmw.setActiveElement('ta1',true);},2500);
|
||||
//window.setTimeout(function(){kmw.setActiveKeyboard('Keyboard_french','fr');},3000);
|
||||
|
||||
// Note that locally specified keyboards will be listed before keyboards
|
||||
// requested from the remote server by user interfaces that do not order
|
||||
// keyboards alphabetically by language.
|
||||
return result;
|
||||
}
|
||||
if(err instanceof Error) {
|
||||
return err.message;
|
||||
}
|
||||
return JSON.stringify(err);
|
||||
}
|
||||
|
||||
// Script to allow a user to add any keyboard to the keyboard menu
|
||||
function addKeyboard(n)
|
||||
{
|
||||
var sKbd,kmw=keyman;
|
||||
switch(n)
|
||||
{
|
||||
case 1:
|
||||
sKbd=document.getElementById('kbd_id1').value;
|
||||
doAddKeyboards(sKbd);
|
||||
break;
|
||||
case 2:
|
||||
sKbd=document.getElementById('kbd_id2').value.toLowerCase();
|
||||
doAddKeyboards('@'+sKbd);
|
||||
break;
|
||||
case 3:
|
||||
// Add keyboard for comma-separated language name(s)
|
||||
sKbd=document.getElementById('kbd_id3').value;
|
||||
doAddKeyboardsForLanguage(sKbd);
|
||||
break;
|
||||
async function doAddKeyboards(data) {
|
||||
return keyman.addKeyboards(data).catch(function(err) {
|
||||
console.error('keyman.addKeyboards failed with '+errToString(err)+' for '+JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
async function doAddKeyboardsForLanguage(data) {
|
||||
return keyman.addKeyboardsForLanguage(data).catch(function(err) {
|
||||
console.error('keyman.addKeyboardsForLanguage failed with '+errToString(err)+' for '+JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
async function loadKeyboards(nestLevel) {
|
||||
const base_prefix = '../';
|
||||
let prefix = './'; // The default - when prefix == 0.
|
||||
|
||||
if(nestLevel !== undefined && nestLevel > 0) {
|
||||
prefix = '';
|
||||
for(let i=0; i < nestLevel; i++) {
|
||||
prefix += base_prefix;
|
||||
}
|
||||
}
|
||||
|
||||
// Add keyboard on Enter (as well as pressing button)
|
||||
function clickOnEnter(e,id)
|
||||
{
|
||||
e = e || window.event;
|
||||
if(e.keyCode == 13) addKeyboard(id);
|
||||
}
|
||||
// Do NOT link the us-1.0 keyboard here!
|
||||
|
||||
await doAddKeyboards({id:'test_chirality',name:'test_chirality',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'test_chirality.js')});
|
||||
|
||||
await doAddKeyboards({id:'obolo_chwerty_6351',name:'obolo_chwerty_6351',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'obolo_chwerty_6351.js')});
|
||||
|
||||
await doAddKeyboards({id:'gesture_prototyping',name:'Gesture Prototyping',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/gesture_prototyping/build/gesture_prototyping.js')});
|
||||
|
||||
await doAddKeyboards({id:'diacritic_rota',name:'Diacritic 10-key Rota',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/diacritic_rota/build/diacritic_rota.js')});
|
||||
|
||||
await doAddKeyboards({id:'ye_old_ten_key',name:'Classic 10-key',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'keyboards/ye_old_ten_key/build/ye_old_ten_key.js')});
|
||||
|
||||
await doAddKeyboards('french', '@he');
|
||||
await doAddKeyboards('khmer_angkor','@km');
|
||||
await doAddKeyboards({id:'sil_euro_latin', name:'SIL EuroLatin', languages: [{id:'no'}, {id:'sv'}]}); // Loads from partial stub instead of the compact string.
|
||||
|
||||
await doAddKeyboardsForLanguage('Dzongkha');
|
||||
|
||||
await doAddKeyboards({
|
||||
id: 'lao_2008_basic', name: 'Lao Basic',
|
||||
languages: {
|
||||
id:'lo',name:'Lao',region:'Asia',
|
||||
},
|
||||
filename:(prefix + 'lao_2008_basic-1.2.js')
|
||||
});
|
||||
}
|
||||
|
||||
// Script to allow a user to add any keyboard to the keyboard menu
|
||||
async function addKeyboard(n) {
|
||||
let sKbd;
|
||||
switch(n)
|
||||
{
|
||||
case 1:
|
||||
sKbd=document.getElementById('kbd_id1').value;
|
||||
await doAddKeyboards(sKbd);
|
||||
break;
|
||||
case 2:
|
||||
sKbd=document.getElementById('kbd_id2').value.toLowerCase();
|
||||
await doAddKeyboards('@'+sKbd);
|
||||
break;
|
||||
case 3:
|
||||
// Add keyboard for comma-separated language name(s)
|
||||
sKbd=document.getElementById('kbd_id3').value;
|
||||
await doAddKeyboardsForLanguage(sKbd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add keyboard on Enter (as well as pressing button)
|
||||
async function clickOnEnter(e,id) {
|
||||
e = e || window.event;
|
||||
if (e.keyCode == 13) {
|
||||
await addKeyboard(id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
function loadKeyboards()
|
||||
{
|
||||
var kmw=keyman;
|
||||
|
||||
// Add a fully-specified, locally-sourced, keyboard with custom font
|
||||
kmw.addKeyboards({id:'sil_cameroon_qwerty',name:'Cameroon QWERTY (SIL)',
|
||||
function loadKeyboards()
|
||||
{
|
||||
// Add a fully-specified, locally-sourced, keyboard with custom font
|
||||
keyman.addKeyboards({id:'sil_cameroon_qwerty',name:'Cameroon QWERTY (SIL)',
|
||||
languages:{
|
||||
id:'aal-Latn',name:'Afade (Latin)',region:'Africa',
|
||||
font:{family:'AndikaAfr',source:['./ANDIKAAFR-R.TTF']}
|
||||
},
|
||||
filename:'./sil_cameroon_qwerty.js'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,10 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType: 'auto'
|
||||
}).then(function() {
|
||||
loadKeyboards();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
@ -49,7 +50,7 @@
|
|||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body onload='loadKeyboards();'>
|
||||
<body>
|
||||
<h2>KeymanWeb Sample Page - Mixed Case of TTF font files</h2>
|
||||
<p>Previously, KMW was not applying .TTF fonts on mobile devices.</p>
|
||||
<p>See <a href='https://github.com/keymanapp/keyman/issues/1332'>issue #1332</a>
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
});
|
||||
kmw.addKeyboards({
|
||||
id:'issue160',name:'Issue 160',languages:{id:'en',name:'English'}, filename:'./issue160.js'
|
||||
}).then(function() {
|
||||
keyman.addKeyboards({
|
||||
id: 'issue160', name: 'Issue 160', languages: { id: 'en', name: 'English' }, filename: './issue160.js'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
var kmw=window.keyman;
|
||||
kmw.init({
|
||||
keyman.init({
|
||||
attachType:'auto'
|
||||
});
|
||||
kmw.addKeyboards({
|
||||
id:'issue266',name:'Issue 266',languages:{id:'en',name:'English'}, filename:'./issue266.js'
|
||||
}).then(function() {
|
||||
keyman.addKeyboards({
|
||||
id:'issue266',name:'Issue 266',languages:{id:'en',name:'English'}, filename:'./issue266.js'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue