From 522e0e8e80cc3d989cb2413d9cfcba636e00210c Mon Sep 17 00:00:00 2001 From: LeenHawk Date: Sun, 4 Oct 2026 14:42:46 +0800 Subject: [PATCH] fix(webview): preserve document-start script order on API 15+ --- crates/plugin-webview/README.md | 9 ++++++++ .../webview/src/main/ets/WebviewPlugin.ets | 22 +++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/crates/plugin-webview/README.md b/crates/plugin-webview/README.md index 1041bae8..360e4162 100644 --- a/crates/plugin-webview/README.md +++ b/crates/plugin-webview/README.md @@ -197,6 +197,15 @@ initial navigation. Use `custom_protocol_async`/`WebviewProtocolResponder` for a See the [plugin development standard](../../docs/plugin-development-standard.md) for type names, reverse events, threading, mounting and acceptance rules. +## Document-start scripts + +Document-start scripts use `runJavaScriptOnDocumentStart` on API 15 and newer. +Each array entry remains a separate script and runs in array order, so an exception +in one entry does not prevent the following entries from running. On API 12–14, +the existing `javaScriptOnDocumentStart` component API is retained; it does not +guarantee execution order. Both direct and drag-overlay WebViews retain the +scripts supplied by `keySynthesisScripts`, including the main-window keyboard shim. + ## License Choose either [MIT](LICENSE-MIT) or [Apache-2.0](LICENSE-APACHE). diff --git a/plugins/webview/src/main/ets/WebviewPlugin.ets b/plugins/webview/src/main/ets/WebviewPlugin.ets index f783f14a..de284d8d 100644 --- a/plugins/webview/src/main/ets/WebviewPlugin.ets +++ b/plugins/webview/src/main/ets/WebviewPlugin.ets @@ -94,6 +94,24 @@ function enableWebDebuggingIfAvailable(): void { setWebDebuggingAccessIfAvailable(true); } +/** Resolve the API-15 Web attribute dynamically to retain the API-12 baseline. */ +interface OrderedDocumentStartAttribute { + runJavaScriptOnDocumentStart?: (scripts: ScriptItem[]) => void; +} + +class DocumentStartScriptsModifier implements AttributeModifier { + constructor(private scripts: ScriptItem[]) {} + + applyNormalAttribute(instance: WebAttribute): void { + const ordered = instance as ESObject as OrderedDocumentStartAttribute; + if (typeof ordered.runJavaScriptOnDocumentStart === "function") { + ordered.runJavaScriptOnDocumentStart(this.scripts); + } else { + instance.javaScriptOnDocumentStart(this.scripts); + } + } +} + interface WebviewStyle { x?: number | string | null; y?: number | string | null; @@ -1335,7 +1353,7 @@ function BuildWebview(data: ManagedWebview) { .javaScriptAccess(data.javascriptEnabled ?? true) .domStorageAccess(data.domStorageAccess ?? true) .mediaPlayGestureAccess(data.autoplay === true ? false : true) - .javaScriptOnDocumentStart(keySynthesisScripts(data)) + .attributeModifier(new DocumentStartScriptsModifier(keySynthesisScripts(data))) .multiWindowAccess(data.eventOptions.newWindow === true) .allowWindowOpenMethod(data.eventOptions.newWindow === true) .onControllerAttached(() => { @@ -1409,7 +1427,7 @@ function BuildWebview(data: ManagedWebview) { .javaScriptAccess(data.javascriptEnabled ?? true) .domStorageAccess(data.domStorageAccess ?? true) .mediaPlayGestureAccess(data.autoplay === true ? false : true) - .javaScriptOnDocumentStart(keySynthesisScripts(data)) + .attributeModifier(new DocumentStartScriptsModifier(keySynthesisScripts(data))) .multiWindowAccess(data.eventOptions.newWindow === true) .allowWindowOpenMethod(data.eventOptions.newWindow === true) .onControllerAttached(() => {