feat(web): app/browser - initial compilation, though incomplete

This commit is contained in:
Joshua A. Horton 2023-04-27 10:05:33 +07:00
parent df9950a3a4
commit 57ec36d9b8
10 changed files with 93 additions and 17 deletions

View file

@ -29,6 +29,7 @@ builder_describe "Builds engine modules for Keyman Engine for Web (KMW)." \
"configure" \
"build" \
"test" \
":app/browser The form of Keyman Engine for Web for use on websites" \
":app/webview A puppetable version of KMW designed for use in a host app's WebView" \
":engine/attachment Subset used for detecting valid page contexts for use in text editing " \
":engine/device-detect Subset used for device-detection " \
@ -95,12 +96,13 @@ builder_run_child_actions build:engine/package-cache
# Uses engine/paths, engine/device-detect, engine/package-cache, & engine/osk
builder_run_child_actions build:engine/main
# Uses all but engine/element-wrappers
# Uses all but engine/element-wrappers and engine/attachment
builder_run_child_actions build:app/webview
# Uses literally everything `engine/` above
# Is not yet compilable due to unmodularized components.
# builder_run_child_actions build:app/browser
builder_run_child_actions build:app/browser
builder_run_child_actions test
if builder_has_action build:app/browser; then
builder_die "Modularization work is not yet complete; builds dependent on this will fail."
@ -110,8 +112,6 @@ if builder_has_action build:app/ui; then
builder_die "Modularization work is not yet complete; builds dependent on this will fail."
fi
builder_run_child_actions test
if builder_start_action test; then
./test.sh :engine

View file

@ -7,6 +7,28 @@
import esbuild from 'esbuild';
import { spawn } from 'child_process';
import fs from 'fs';
/*
* Refer to https://github.com/microsoft/TypeScript/issues/13721#issuecomment-307259227 -
* the `@class` emit comment-annotation is designed to facilitate tree-shaking for ES5-targeted
* down-level emits. `esbuild` doesn't look for it by default... but we can override that with
* this plugin.
*/
let es5ClassAnnotationAsPurePlugin = {
name: '@class -> __PURE__',
setup(build) {
build.onLoad({filter: /\.js$/ }, async (args) => {
let source = await fs.promises.readFile(args.path, 'utf8');
return {
// Marks any classes compiled by TS (as per the /** @class */ annotation)
// as __PURE__ in order to facilitate tree-shaking.
contents: source.replace('/** @class */', '/* @__PURE__ */ /** @class */'),
loader: 'js'
}
});
}
}
await esbuild.build({
bundle: true,
@ -14,9 +36,29 @@ await esbuild.build({
format: "iife",
nodePaths: ['../../../../node_modules'],
entryPoints: {
'index': '../../../build/app/webview/obj/main.js',
'index': '../../../build/app/browser/obj/debug-main.js',
},
outdir: '../../../build/app/webview/lib/',
tsconfig: './tsconfig.json',
target: "es5"
outfile: '../../../build/app/browser/debug/keymanweb.js',
plugins: [ es5ClassAnnotationAsPurePlugin ],
target: "es5",
treeShaking: true,
tsconfig: './tsconfig.json'
});
await esbuild.build({
bundle: true,
sourcemap: true,
minifyWhitespace: true,
minifySyntax: true,
minifyIdentifiers: false,
format: "iife",
nodePaths: ['../../../../node_modules'],
entryPoints: {
'index': '../../../build/app/browser/obj/release-main.js',
},
outfile: '../../../build/app/browser/release/keymanweb.js',
plugins: [ es5ClassAnnotationAsPurePlugin ],
target: "es5",
treeShaking: true,
tsconfig: './tsconfig.json'
});

View file

@ -38,11 +38,16 @@ builder_describe "Builds the Keyman Engine for Web's website-integrating version
# Possible TODO?s
# "upload-symbols Uploads build product to Sentry for error report symbolification. Only defined for $DOC_BUILD_EMBED_WEB" \
builder_parse "$@"
config=release
if builder_is_debug_build; then
config=debug
fi
builder_describe_outputs \
configure /node_modules \
build /web/build/$SUBPROJECT_NAME/lib/index.js
builder_parse "$@"
build /web/build/$SUBPROJECT_NAME/$config/keymanweb.js
#### Build action definitions ####

View file

@ -1,6 +1,6 @@
import { DomEventTracker } from 'keyman/engine/events';
import { KeymanEngine } from "../keymanEngine.js";
import KeymanEngine from "../keymanEngine.js";
import { FocusAssistant } from './focusAssistant.js';
// Note: in the future, it'd probably be best to have an instance per iframe window as

View file

@ -0,0 +1,15 @@
import KeymanEngine from './keymanEngine.js'
import { SourcemappedWorker } from '@keymanapp/lexical-model-layer/web'
/**
* Determine path and protocol of executing script, setting them as
* construction defaults.
*
* This can only be done during load when the active script will be the
* last script loaded. Otherwise the script must be identified by name.
*/
var scripts = document.getElementsByTagName('script');
var ss = scripts[scripts.length-1].src;
var sPath = ss.substr(0,ss.lastIndexOf('/')+1);
window['keyman'] = new KeymanEngine(SourcemappedWorker.constructInstance(), sPath);

View file

@ -14,7 +14,7 @@ import { PageIntegrationHandlers } from './context/pageIntegrationHandlers.js';
import { LanguageMenu } from './languageMenu.js';
import { setupOskListeners } from './oskConfiguration.js';
export class KeymanEngine extends KeymanEngineBase<BrowserConfiguration, ContextManager, HardwareEventKeyboard> {
export default class KeymanEngine extends KeymanEngineBase<BrowserConfiguration, ContextManager, HardwareEventKeyboard> {
touchLanguageMenu?: LanguageMenu;
private pageIntegration: PageIntegrationHandlers;

View file

@ -2,7 +2,7 @@
import { getAbsoluteX, landscapeView } from "keyman/engine/dom-utils";
import { KeyboardStub } from "keyman/engine/package-cache";
import { KeymanEngine } from "./keymanEngine.js";
import KeymanEngine from "./keymanEngine.js";
import * as util from "./utils/index.js";
// Used by 'native'-mode KMW only - the Android and iOS embedding apps implement their own menus.

View file

@ -1 +0,0 @@
import ContextManager from './contextManager.js';

View file

@ -1,7 +1,7 @@
import { type KeyElement, OSKView, VisualKeyboard } from "keyman/engine/osk";
import { KEYMAN_VERSION } from "@keymanapp/keyman-version";
import ContextManager from "./contextManager.js";
import { KeymanEngine } from "./keymanEngine.js";
import KeymanEngine from "./keymanEngine.js";
import { LanguageMenu } from "./languageMenu.js";
export function setupOskListeners(engine: KeymanEngine, osk: OSKView, contextManager: ContextManager) {

View file

@ -0,0 +1,15 @@
import KeymanEngine from './keymanEngine.js'
import { Worker } from '@keymanapp/lexical-model-layer/web'
/**
* Determine path and protocol of executing script, setting them as
* construction defaults.
*
* This can only be done during load when the active script will be the
* last script loaded. Otherwise the script must be identified by name.
*/
var scripts = document.getElementsByTagName('script');
var ss = scripts[scripts.length-1].src;
var sPath = ss.substr(0,ss.lastIndexOf('/')+1);
window['keyman'] = new KeymanEngine(Worker.constructInstance(), sPath);