From 6a95d3324b7982d989027f7d359eb8f19092ceac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E5=8B=A4=E6=B0=91?= Date: Mon, 17 Feb 2025 11:55:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(XWebview):=20=E6=96=B0=E5=A2=9E=20JavaScri?= =?UTF-8?q?pt=20=E4=BB=A3=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了在 XWebview 中使用 JavaScript代理的功能 - 添加了 JSSdkClsManager 类来处理 JS SDK 的调用 - 更新了 XWebHelper 和 XWebManager 以支持 JS 代理 - 新增了类型定义文件 types.ets来规范接口和数据结构 --- BuildProfile.ets | 4 ++-- src/main/ets/pages/ClasTest.ets | 17 ++++++++++++++ src/main/ets/pages/XWebview.ets | 30 +++++++++++++++++++++--- src/main/ets/utils/XWebHelper.ets | 37 +++++++++++++++++++++++++----- src/main/ets/utils/XWebManager.ets | 19 +++++++++++++++ 5 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 src/main/ets/pages/ClasTest.ets diff --git a/BuildProfile.ets b/BuildProfile.ets index c4eaa9c..761a945 100644 --- a/BuildProfile.ets +++ b/BuildProfile.ets @@ -2,8 +2,8 @@ * Use these variables when you tailor your ArkTS code. They must be of the const type. */ export const HAR_VERSION = '1.0.6'; -export const BUILD_MODE_NAME = 'release'; -export const DEBUG = false; +export const BUILD_MODE_NAME = 'debug'; +export const DEBUG = true; export const TARGET_NAME = 'default'; /** diff --git a/src/main/ets/pages/ClasTest.ets b/src/main/ets/pages/ClasTest.ets new file mode 100644 index 0000000..e43d0cd --- /dev/null +++ b/src/main/ets/pages/ClasTest.ets @@ -0,0 +1,17 @@ +import { ToolsHelper } from "../utils/ToolsHelper"; + +export class ClasTest{ + constructor() { + } + + test(): string { + return "ArkUI Web Component"; + } + + toString(): void { + console.log('Web Component toString'); + } + postMsg(res: string): void { + ToolsHelper.showMessage(res) + } +} \ No newline at end of file diff --git a/src/main/ets/pages/XWebview.ets b/src/main/ets/pages/XWebview.ets index 517b817..8c7c079 100644 --- a/src/main/ets/pages/XWebview.ets +++ b/src/main/ets/pages/XWebview.ets @@ -6,7 +6,7 @@ import { XDialogList } from '../dialog/XDialogList'; import { picker } from '@kit.CoreFileKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { ToolsHelper } from '../utils/ToolsHelper'; -import { XWebController, XWebParams } from '../utils/XWebHelper'; +import { JsParams, XWebController, XWebParams } from '../utils/XWebHelper'; import { WindowHelper } from '../utils/WindowHelper'; import { SZYXLocalStorageHelper } from '../utils/SZYXLocalStorageHelper'; import { SZYXLocalStorageKeys } from '../utils/SZYXLocalStorageKeys'; @@ -18,10 +18,12 @@ export struct XWebview { // 手机号 @State headers?: Array = (router.getParams() as XWebParams).headers @State url?: string = (router.getParams() as XWebParams).url + @State jsParams?: JsParams = (router.getParams() as XWebParams).jsParams @State zoomAccess?: boolean = (router.getParams() as XWebParams).zoomAccess @State content?: string = (router.getParams() as XWebParams).content @State title?: string = (router.getParams() as XWebParams).title @State xController?: XWebController = (router.getParams() as XWebParams).controller + // @State xJsController?: XWebController = (router.getParams() as XWebParams).jsController @State closeTag?: string = (router.getParams() as XWebParams).closeTag @State showMenu: boolean = (router.getParams() as XWebParams).showMenu ?? false @State errorInfo: string | null = null @@ -35,7 +37,6 @@ export struct XWebview { aboutToAppear(): void { SZYXLocalStorageHelper.storage.setOrCreate(SZYXLocalStorageKeys.XWebViewCLose, undefined) webview.WebviewController.setWebDebuggingAccess(true); - if (this._uuidToHtml) { XWebManager.addOnMessageToHtml(this._uuidToHtml, (msg) => { if (this.ports && this.ports[1]) { @@ -43,6 +44,11 @@ export struct XWebview { } }) } + if (this.jsParams?.controller && this._uuidToHtml) { + XWebManager.addOnMessageToWeb(this._uuidToHtml, (msg) => { + this.controller.runJavaScript(msg) + }) + } } aboutToDisappear(): void { @@ -51,6 +57,14 @@ export struct XWebview { } XWebManager.removeOnMessage(this._uuid) XWebManager.removeOnMessageToHtml(this._uuidToHtml) + if (this._uuidToHtml) { + XWebManager.objs.delete(this._uuidToHtml) + } + try { + this.controller.deleteJavaScriptRegister(this.jsParams?.name); + } catch (error) { + console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); + } } onBackPress(): boolean | void { @@ -118,6 +132,12 @@ export struct XWebview { Web({ src: this.url ?? 'www.example.com', controller: this.controller }) .javaScriptAccess(true) + .javaScriptProxy({ + object: XWebManager.objs.get(this._uuidToHtml), + name: this.jsParams?.name, + methodList: this.jsParams?.methodList, + controller: this.controller + }) .domStorageAccess(true) .geolocationAccess(true) .width('100%') @@ -312,7 +332,11 @@ export struct XWebview { values: ['刷新', '浏览器打开', '分享', '复制地址'], // 用户选择事件 onSelected: (index: number, value: string) => { - ToolsHelper.showMessage(`用户选择了第${index}个,内容为:${value}`) + if (index === 0) { + this.controller.refresh() + } else { + ToolsHelper.showMessage(`用户选择了第${index}个,内容为:${value}`) + } }, // 用户取消事件 onCancel: () => { diff --git a/src/main/ets/utils/XWebHelper.ets b/src/main/ets/utils/XWebHelper.ets index eed0856..e7dde0c 100644 --- a/src/main/ets/utils/XWebHelper.ets +++ b/src/main/ets/utils/XWebHelper.ets @@ -12,19 +12,31 @@ export interface XWebController { sendMessage: (message: string) => void } +export interface XWebJsController { + sendMessage: (message: string) => void +} + +export interface JsParams { + obj: object; + name: string; + methodList: Array; + controller?: XWebJsController +} + export interface XWebParams { url?: string - zoomAccess?: boolean content?: string title?: string - showMenu?: boolean - closeTag?: string watermarkTxt?: string - _uuid?: string - _uuidToHtml?: string + showMenu?: boolean + jsParams?: JsParams + closeTag?: string + headers?: Array onMessage?: (message: string) => void controller?: XWebController - headers?: Array + zoomAccess?: boolean + _uuid?: string + _uuidToHtml?: string } export class XWebHelper { @@ -46,6 +58,19 @@ export class XWebHelper { } } + if (params.jsParams && params.jsParams.obj) { + if (!params._uuidToHtml) { + params._uuidToHtml = ToolsHelper.getUuid() + } + XWebManager.objs.set(params._uuidToHtml, params.jsParams.obj) + + if (params.jsParams?.controller) { + params.jsParams.controller.sendMessage = (msg) => { + XWebManager.sendMessageToWeb(msg) + } + } + } + return new Promise((resolve) => { router.pushNamedRoute({ name: 'XWebview', diff --git a/src/main/ets/utils/XWebManager.ets b/src/main/ets/utils/XWebManager.ets index be82c37..a072086 100644 --- a/src/main/ets/utils/XWebManager.ets +++ b/src/main/ets/utils/XWebManager.ets @@ -2,6 +2,7 @@ import { ToolsHelper } from './ToolsHelper'; export class XWebManager { private static MapEventListener = new Map void>(); + static objs:Map = new Map() static addOnMessage(listener: (msg: string) => void): string { const id = ToolsHelper.getUuid() @@ -38,4 +39,22 @@ export class XWebManager { item(message) } } + + private static MapEventListenerToWeb = new Map void>(); + + static addOnMessageToWeb(id: string, listener: (msg: string) => void) { + XWebManager.MapEventListenerToWeb.set(id, listener) + } + + static removeOnMessageToWeb(id?: string) { + if (id) { + XWebManager.MapEventListenerToWeb.delete(id) + } + } + + static sendMessageToWeb(message: string) { + for (let item of XWebManager.MapEventListenerToWeb.values()) { + item(message) + } + } } \ No newline at end of file