From ad303ae63c9d076625a92a30002cbeb7cf510259 Mon Sep 17 00:00:00 2001 From: A Shuai Date: Thu, 30 May 2024 10:55:11 +0800 Subject: [PATCH 1/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Ddisappear=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E6=B4=BE=E5=8F=91=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/src/main/ets/cordova/CordovaWebViewImpl.ets | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/src/main/ets/cordova/CordovaWebViewImpl.ets b/library/src/main/ets/cordova/CordovaWebViewImpl.ets index 67ad9e01..1dd36459 100644 --- a/library/src/main/ets/cordova/CordovaWebViewImpl.ets +++ b/library/src/main/ets/cordova/CordovaWebViewImpl.ets @@ -118,6 +118,10 @@ export class CordovaWebViewImpl implements CordovaWebView { } handleDisappear(): void { + if (this.isInitialized()) { + this.engine.setPaused(true) + this.pluginManager!.onAboutToDisappear() + } } handlePageShow(keepRunning: boolean): void { -- Gitee From 06e1573fa36c3a9f6a261dc3b2363447e33a502c Mon Sep 17 00:00:00 2001 From: A Shuai Date: Fri, 23 Aug 2024 09:37:05 +0800 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=81=B6=E7=8E=B0?= =?UTF-8?q?=E7=9A=84Ark=E5=8E=9F=E7=94=9F=E7=BB=99h5=E5=9B=9E=E8=B0=83Cord?= =?UTF-8?q?ova=E7=BB=93=E6=9E=9C=E6=97=B6=E6=8A=A5controller=E6=9C=AA?= =?UTF-8?q?=E5=85=B3=E8=81=94=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/BuildProfile.ets | 19 +++++++++++++++---- .../cordova/engine/SystemWebViewEngine.ets | 17 ++++++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/library/BuildProfile.ets b/library/BuildProfile.ets index 22c25dbe..cf3cef7b 100644 --- a/library/BuildProfile.ets +++ b/library/BuildProfile.ets @@ -1,6 +1,17 @@ +/** + * Use these variables when you tailor your ArkTS code. They must be of the const type. + */ +export const HAR_VERSION = '0.0.1'; +export const BUILD_MODE_NAME = 'debug'; +export const DEBUG = true; +export const TARGET_NAME = 'default'; + +/** + * BuildProfile Class is used only for compatibility purposes. + */ export default class BuildProfile { - static readonly HAR_VERSION = '0.0.1'; - static readonly BUILD_MODE_NAME = 'debug'; - static readonly DEBUG = true; - static readonly TARGET_NAME = 'default'; + static readonly HAR_VERSION = HAR_VERSION; + static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; + static readonly DEBUG = DEBUG; + static readonly TARGET_NAME = TARGET_NAME; } \ No newline at end of file diff --git a/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets b/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets index 311864c7..e423d84b 100644 --- a/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets +++ b/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets @@ -7,7 +7,9 @@ import { Client, CordovaWebViewEngine } from '../CordovaWebViewEngine' import { NativeToJsMessageQueue } from '../NativeToJsMessageQueue' import { PluginManager } from '../PluginManager' import { SystemExposedJsApi } from './SystemExposedJsApi' -import { Preconditions } from '../../utils/Index' +import { CordovaLog, Preconditions, StringUtils } from '../../utils/Index' +import { TAG } from '../../utils/Constants' +import { convertString } from '../../utils/StringUtils' /** * @@ -106,9 +108,14 @@ export class SystemWebViewEngine implements CordovaWebViewEngine { } evaluateJavascript(script: string): void { - this.controller.runJavaScript(script) - .catch((e: Error) => { - // do nothing - }) + // 捕获偶现的 17100001 错误 + try { + this.controller.runJavaScript(script) + .catch((e: Error) => { + // do nothing + }) + } catch (e) { + CordovaLog.d(TAG, `run javaScript error --> ${StringUtils.convertString(e)}`) + } } } \ No newline at end of file -- Gitee From 46f4ecefbcd3a8d4c24f9eff8c99fb6dffe8a0d2 Mon Sep 17 00:00:00 2001 From: A Shuai Date: Fri, 23 Aug 2024 09:47:35 +0800 Subject: [PATCH 3/6] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96CordovaWeb?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8A=A0=E8=BD=BD=EF=BC=8C=E5=89=94=E9=99=A4?= =?UTF-8?q?=E4=BD=BF=E7=94=A8blank=E9=A1=B5=E9=9D=A2=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=EF=BC=8C=E9=81=BF=E5=85=8Dweb=20history=E6=A0=88?= =?UTF-8?q?=E5=86=97=E4=BD=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/ets/components/CordovaWeb.ets | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/library/src/main/ets/components/CordovaWeb.ets b/library/src/main/ets/components/CordovaWeb.ets index 38b9ea10..c06dd13f 100644 --- a/library/src/main/ets/components/CordovaWeb.ets +++ b/library/src/main/ets/components/CordovaWeb.ets @@ -5,9 +5,7 @@ import { AlertEvent, ConfirmEvent, PromptEvent, ErrorEvent, SslErrorEvent, LoadI import { IWebContainer } from '../cordova/model/IWebContainer' import { BridgePermission } from '../model/BridgePermission' import { CordovaContext } from '../CordovaContext' -import { Constants, CordovaLog } from '../utils/Index' - -const INIT_URL = 'about:blank' +import { Constants, CordovaLog, StringUtils } from '../utils/Index' // CordovaWeb所属的页面需要通知的事件 export interface OnEventListener { @@ -140,6 +138,7 @@ export struct Index { private onInterceptRequest?: (event?: OnInterceptRequestEvent) => WebResourceResponse | null | undefined /** * Web页面加载状态回调监听 + * 接入方使用该监听自行处理Loader和Error的展示 */ private onLoadStateChanged?: (loadState: PageLoadState) => void /** @@ -183,15 +182,20 @@ export struct Index { this.systemWebView?.onAboutToDisappear() } + /** + * 待Controller和WebView关联后开始异步加载Url + */ + private startLoad() { + this.loadState = PageLoadState.LOADING + this.initWeb() + .catch(() => { + // do nothing + }) + } + onPageEnd(url?: string) { CordovaLog.e(Constants.TAG, `onPageEnd url: ${url}`) - if (this.loadState === PageLoadState.INIT && url === INIT_URL) { - this.loadState = PageLoadState.LOADING - this.initWeb() - .catch(() => { - // do nothing - }) - } else if (this.loadState === PageLoadState.LOADING && url !== INIT_URL) { + if (this.loadState === PageLoadState.LOADING) { this.loadState = PageLoadState.COMPLETE } } @@ -253,9 +257,11 @@ export struct Index { } } onHttpErrorReceive = (event?: HttpErrorEvent): void => { + if (event?.request.getRequestUrl() !== this.url || this.loadState === PageLoadState.COMPLETE) { + return + } if ((event?.response.getResponseCode() === 404 || event?.response.getResponseCode() === 500) && this.loadState === PageLoadState.LOADING) { - CordovaLog.e(Constants.TAG, - `onHttpErrorReceive url:${event?.request.getRequestUrl()}, reason message: ${event?.response.getReasonMessage()}, response code: ${event?.response.getResponseCode()}`) + CordovaLog.e(Constants.TAG, `onHttpErrorReceive url:${event?.request.getRequestUrl()}, reason message: ${event?.response.getReasonMessage()}, response code: ${event?.response.getResponseCode()}`) this.loadState = PageLoadState.ERROR } } @@ -274,13 +280,13 @@ export struct Index { private async initWeb() { this.mixedMode = this.enableMixedMode ? MixedMode.All : MixedMode.None this.systemWebView = new SystemWebView(this.controller, this.page ?? this, this) - const originUA = this.controller.getUserAgent() + const originUA = StringUtils.wrapEmptyString(this.controller.getCustomUserAgent(), this.controller.getUserAgent()) this.controller.setCustomUserAgent(`${originUA} ${CordovaContext.getCustomUserAgent()}}`) this.systemWebView.loadUrl(this.url) } build() { - Web({ src: INIT_URL, controller: this.controller, incognitoMode: this.incognitoMode }) + Web({ src: '', controller: this.controller, incognitoMode: this.incognitoMode }) .width('100%') .height('100%') .id(this.webId) @@ -310,5 +316,8 @@ export struct Index { .onHttpErrorReceive(this.onHttpErrorReceive) .onSslErrorEventReceive(this.onSslErrorReceive) .visibility(this.loadState === PageLoadState.ERROR ? Visibility.Hidden : Visibility.Visible) + .onControllerAttached(() => { + this.startLoad() + }) } } -- Gitee From ff157f5cef34680a534b4dd178f01ef2bbc74f4a Mon Sep 17 00:00:00 2001 From: A Shuai Date: Fri, 23 Aug 2024 10:24:00 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96CordovaWeb?= =?UTF-8?q?=E4=B8=AD=E5=AE=B9=E5=99=A8=E7=9A=84=E5=AE=9A=E4=B9=89=E5=92=8C?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=A4=84=E7=90=86=EF=BC=8C=E5=8C=85=E6=8B=AC?= =?UTF-8?q?CordovaWeb=E5=AE=B9=E5=99=A8=E5=92=8C=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=AE=B9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entry/src/main/ets/pages/Test.ets | 44 ++++++---- library/Index.ets | 16 +++- .../src/main/ets/components/CordovaWeb.ets | 88 ++++++++----------- .../src/main/ets/cordova/CordovaWebView.ets | 4 +- .../main/ets/cordova/CordovaWebViewImpl.ets | 6 +- ...Container.ets => ICordovaWebContainer.ets} | 23 ++++- .../main/ets/cordova/model/IPageContainer.ets | 27 ++++++ 7 files changed, 129 insertions(+), 79 deletions(-) rename library/src/main/ets/cordova/model/{IWebContainer.ets => ICordovaWebContainer.ets} (49%) create mode 100644 library/src/main/ets/cordova/model/IPageContainer.ets diff --git a/entry/src/main/ets/pages/Test.ets b/entry/src/main/ets/pages/Test.ets index a90363d0..db9d4135 100644 --- a/entry/src/main/ets/pages/Test.ets +++ b/entry/src/main/ets/pages/Test.ets @@ -1,6 +1,7 @@ import router from '@ohos.router' -import { CordovaWeb, OnEventListener } from '@ohos/cordova/Index' import List from '@ohos.util.List' +import { CordovaWeb, ICordovaWebContainer, IPageContainer } from '@ohos/cordova/Index' + /** * 测试Cordova * @@ -19,41 +20,53 @@ struct Index { ["test.html", "text/html"], ["cordova.harmony.js", "text/javascript"], ]) - - // 一个页面支持有多个CordovaWeb容器 - private readonly listeners: List = new List() + /** + * 一个页面支持有多个CordovaWeb容器,使用集合记录 + */ + private readonly cordovaWebList: List = new List() onPageShow(): void { // 通知当前页面下的所有CordovaWeb容器页面显示 - this.listeners.forEach(it => it.onPageShow && it.onPageShow()) + this.cordovaWebList.forEach(it => it.onPageShow && it.onPageShow()) } onPageHide(): void { // 通知当前页面下的所有CordovaWeb容器页面隐藏 - this.listeners.forEach(it => it.onPageHide && it.onPageHide()) + this.cordovaWebList.forEach(it => it.onPageHide && it.onPageHide()) } onBackPress(): boolean | void { // 优先派发返回按钮点击事件给CordovaWeb容器 - for (let index = 0; index < this.listeners.length; index++) { - if (this.listeners.get(index).onBackPress && this.listeners.get(index).onBackPress!()) { + for (let index = 0; index < this.cordovaWebList.length; index++) { + if (this.cordovaWebList.get(index).onBackPress && this.cordovaWebList.get(index).onBackPress!()) { // Web组件消费了返回事件 return true } } - // 如果Web组件没有消费返回事件,则自行处理 + // 如果CordovaWeb组件没有消费返回事件,则页面自行处理,即页面本身退栈 router.back() return true } - registerOnEventListener(listener: OnEventListener) { - if (!this.listeners.has(listener)) { - this.listeners.add(listener) + /** + * CordovaWeb挂载的页面需要实现的 {@link IPageContainer} 的接口 + * + * @param cordovaWeb 新创建的CordovaWeb实例 + */ + onCordovaWebAppear(cordovaWeb: ICordovaWebContainer): void { + // 记录CordovaWeb实例,用于通知onBackPress、onPageShow、onPageHide等事件 + if (!this.cordovaWebList.has(cordovaWeb)) { + this.cordovaWebList.add(cordovaWeb) } } - unregisterOnEventListener(listener: OnEventListener) { - this.listeners.remove(listener) + /** + * CordovaWeb挂载的页面需要实现的 {@link IPageContainer} 的接口 + * + * @param cordovaWeb 即将销毁的CordovaWeb实例 + */ + onCordovaWebDisappear(cordovaWeb: ICordovaWebContainer): void { + this.cordovaWebList.remove(cordovaWeb) } build() { @@ -90,7 +103,7 @@ struct Index { CordovaWeb({ page: this, url: 'https://www.baidu.com/js/test.html', - parent: this, + parent: this as IPageContainer, bridges: [ { name: 'HelloBridge', @@ -116,6 +129,7 @@ struct Index { .width('100%') .height('100%') } + private async loadResponse(url: string, response: WebResourceResponse): Promise { try { const path = this.schemeMap.get(url) diff --git a/library/Index.ets b/library/Index.ets index 4a8f4a81..4001c99e 100644 --- a/library/Index.ets +++ b/library/Index.ets @@ -1,6 +1,6 @@ import { CordovaConfig } from './src/main/ets/CordovaConfig' import { CordovaManager } from './src/main/ets/CordovaManager' -import { OnEventListener, WebParent, PageLoadState, Index as CordovaWeb } from './src/main/ets/components/CordovaWeb' +import { PageLoadState, Index as CordovaWeb } from './src/main/ets/components/CordovaWeb' import { BridgePermission } from './src/main/ets/model/BridgePermission' import { CordovaBridgeAlias } from './src/main/ets/model/CordovaBridgeAlias' import { CordovaBridgeEntry } from './src/main/ets/model/CordovaBridgeEntry' @@ -13,12 +13,12 @@ import { PluginEntry } from './src/main/ets/cordova/PluginEntry' import { PluginResult } from './src/main/ets/cordova/PluginResult' import { MessageStatus } from './src/main/ets/cordova/enumeration/MessageStatus' import { MessageType } from './src/main/ets/cordova/enumeration/MessageType' +import { IPageContainer } from './src/main/ets/cordova/model/IPageContainer' +import { ICordovaWebContainer } from './src/main/ets/cordova/model/ICordovaWebContainer' export { CordovaConfig, CordovaManager, - OnEventListener, - WebParent, PageLoadState, CordovaWeb, BridgePermission, @@ -32,5 +32,13 @@ export { PluginEntry, PluginResult, MessageStatus, - MessageType + MessageType, + /** + * CordovaWeb挂载的Page页面应当实现的接口 + */ + IPageContainer, + /** + * CordovaWeb组件本身实现的接口 + */ + ICordovaWebContainer } \ No newline at end of file diff --git a/library/src/main/ets/components/CordovaWeb.ets b/library/src/main/ets/components/CordovaWeb.ets index c06dd13f..b5541447 100644 --- a/library/src/main/ets/components/CordovaWeb.ets +++ b/library/src/main/ets/components/CordovaWeb.ets @@ -2,30 +2,11 @@ import util from '@ohos.util' import webview from '@ohos.web.webview' import { SystemWebView } from '../cordova/engine/SystemWebView' import { AlertEvent, ConfirmEvent, PromptEvent, ErrorEvent, SslErrorEvent, LoadInterceptEvent, HttpErrorEvent, ShowFileSelectorEvent, OnTitleReceiveEvent, OnInterceptRequestEvent } from '../model/HarmonyWebModel' -import { IWebContainer } from '../cordova/model/IWebContainer' +import { ICordovaWebContainer } from '../cordova/model/ICordovaWebContainer' import { BridgePermission } from '../model/BridgePermission' import { CordovaContext } from '../CordovaContext' import { Constants, CordovaLog, StringUtils } from '../utils/Index' - -// CordovaWeb所属的页面需要通知的事件 -export interface OnEventListener { - - onBackPress?: () => boolean - onPageShow?: () => void - onPageHide?: () => void - -} - -/** - * CordovaWeb所属的页面需要实现的接口,不需要继承 - * 使用Js鸭式编程思想,保证页面有同名方法即可 - */ -export interface WebParent { - - registerOnEventListener: (listener: OnEventListener) => void - unregisterOnEventListener: (listener: OnEventListener) => void - -} +import { IPageContainer } from '../cordova/model/IPageContainer' // 网页加载状态 export enum PageLoadState { @@ -51,11 +32,18 @@ export struct Index { /** * 所属页面,必填 */ + @Require private page?: object /** - * 待加载的url,必填 + * 当前CordovaWeb组件挂载的Page页面,必填 + */ + @Require + private parent?: IPageContainer + /** + * 待加载的url,必填,不得为空 */ @Prop + @Require private url: string /** * 当前页面加载状态 @@ -66,11 +54,7 @@ export struct Index { /** * 当前Web组件的唯一Id */ - private webId: string = util.generateRandomUUID() - /** - * 当前Web组件所属页面容器需要提供的2个实例方法 - */ - private parent?: WebParent + private readonly webId: string = util.generateRandomUUID() /** * 当前加载Web页面可用桥权限配置 */ @@ -122,7 +106,7 @@ export struct Index { /** * 控制器 */ - private controller: webview.WebviewController = new webview.WebviewController() + private readonly controller: webview.WebviewController = new webview.WebviewController() /** * Web加载收到title标签事件 */ @@ -145,32 +129,9 @@ export struct Index { * Cordova框架基于Web组件二次封装 */ private systemWebView?: SystemWebView - /** - * 接受页面容器通知的事件 - */ - private eventListener: OnEventListener = { - /** - * 返回按钮点击事件 - */ - onBackPress: () => { - return this.systemWebView?.onBackPress() ?? false - }, - /** - * 页面展示事件 - */ - onPageShow: () => { - this.systemWebView?.onPageShow() - }, - /** - * 页面隐藏事件 - */ - onPageHide: () => { - this.systemWebView?.onPageHide() - } - } aboutToAppear() { - this.parent?.registerOnEventListener(this.eventListener) + this.parent?.onCordovaWebAppear(this as ICordovaWebContainer) this.systemWebView?.onAboutToAppear() if (CordovaContext.enableInspect()) { webview.WebviewController.setWebDebuggingAccess(true) @@ -178,10 +139,31 @@ export struct Index { } aboutToDisappear() { - this.parent?.unregisterOnEventListener(this.eventListener) + this.parent?.onCordovaWebDisappear(this as ICordovaWebContainer) this.systemWebView?.onAboutToDisappear() } + /** + * 返回按钮点击事件 + */ + onBackPress(): boolean { + return this.systemWebView?.onBackPress() ?? false + } + + /** + * 页面展示事件 + */ + onPageShow(): void { + this.systemWebView?.onPageShow() + } + + /** + * 页面隐藏事件 + */ + onPageHide(): void { + this.systemWebView?.onPageHide() + } + /** * 待Controller和WebView关联后开始异步加载Url */ diff --git a/library/src/main/ets/cordova/CordovaWebView.ets b/library/src/main/ets/cordova/CordovaWebView.ets index 6a1fc173..28b40635 100644 --- a/library/src/main/ets/cordova/CordovaWebView.ets +++ b/library/src/main/ets/cordova/CordovaWebView.ets @@ -5,7 +5,7 @@ import { PluginManager } from './PluginManager' import { PluginResult } from './PluginResult' import webview from '@ohos.web.webview' import { CordovaWebViewEngine } from './CordovaWebViewEngine' -import { IWebContainer } from './model/IWebContainer' +import { ICordovaWebContainer } from './model/ICordovaWebContainer' /** * Cordova封装接管的WebView容器 @@ -62,7 +62,7 @@ export interface CordovaWebView { getPage(): object - getWebContainer(): IWebContainer + getWebContainer(): ICordovaWebContainer getContext(): common.UIAbilityContext diff --git a/library/src/main/ets/cordova/CordovaWebViewImpl.ets b/library/src/main/ets/cordova/CordovaWebViewImpl.ets index 1dd36459..f48cd2a8 100644 --- a/library/src/main/ets/cordova/CordovaWebViewImpl.ets +++ b/library/src/main/ets/cordova/CordovaWebViewImpl.ets @@ -13,7 +13,7 @@ import { KeyEvent } from '@ohos.multimodalInput.keyEvent' import { CoreHarmony } from './CoreHarmony' import { KeyCode } from '@ohos.multimodalInput.keyCode' import { CordovaPlugin } from './CordovaPlugin' -import { IWebContainer } from './model/IWebContainer' +import { ICordovaWebContainer } from './model/ICordovaWebContainer' const LEGAL_PLUMBED_KEY_CODE: HashSet = new HashSet() LEGAL_PLUMBED_KEY_CODE.add(KeyCode.KEYCODE_BACK) @@ -191,8 +191,8 @@ export class CordovaWebViewImpl implements CordovaWebView { return this.engine.getPage() } - getWebContainer(): IWebContainer { - return this.engine.getWeb() as IWebContainer + getWebContainer(): ICordovaWebContainer { + return this.engine.getWeb() as ICordovaWebContainer } getContext(): common.UIAbilityContext { diff --git a/library/src/main/ets/cordova/model/IWebContainer.ets b/library/src/main/ets/cordova/model/ICordovaWebContainer.ets similarity index 49% rename from library/src/main/ets/cordova/model/IWebContainer.ets rename to library/src/main/ets/cordova/model/ICordovaWebContainer.ets index be239f1a..b8fed22a 100644 --- a/library/src/main/ets/cordova/model/IWebContainer.ets +++ b/library/src/main/ets/cordova/model/ICordovaWebContainer.ets @@ -1,13 +1,32 @@ import { BridgePermission } from '../../model/BridgePermission' /** - * Cordova所关联的WebView容器 + * CordovaWeb容器应实现的接口 * * @author kexin * @email zkx2590372_xa@bank-of-china.com * @date 2024/4/1 10:35 */ -export interface IWebContainer { +export interface ICordovaWebContainer { + + /** + * 用于接受CordovaWeb所属的Page页面通知Back按钮点击事件 + * + * @returns true表示CordovaWeb消费了此事件,否则页面容器自行处理 + */ + onBackPress(): boolean + + /** + * 用于接受CordovaWeb所属的Page页面通知onPageShow事件 + * 此事件后续将继续分发给Cordova Plugin + */ + onPageShow(): void + + /** + * 用于接受CordovaWeb所属的Page页面通知onPageHide事件 + * 此事件后续将继续分发给Cordova Plugin + */ + onPageHide(): void /** * 获取当前Cordova所关联的WebView容器Id diff --git a/library/src/main/ets/cordova/model/IPageContainer.ets b/library/src/main/ets/cordova/model/IPageContainer.ets new file mode 100644 index 00000000..4e34834f --- /dev/null +++ b/library/src/main/ets/cordova/model/IPageContainer.ets @@ -0,0 +1,27 @@ +import { ICordovaWebContainer } from './ICordovaWebContainer' + +/** + * CordovaWeb容器挂载的Page页面应实现的接口 + * 注意:该接口为鸭式编程接口,Page Component组件可以无需显示继承 + */ +export interface IPageContainer { + + /** + * 通知创建CordovaWeb实例引用 + * 请务必使用该引用向CordovaWeb派发onBackPress、onPageShow、onPageHide等事件 + * 该接口定义方便页面挂载多个CordovaWeb实例 + * + * @param cordovaWeb 创建好的CordovaWeb实例引用,不为空 + */ + onCordovaWebAppear(cordovaWeb: ICordovaWebContainer): void + + /** + * 通知销毁CordovaWeb实例引用 + * 当CordovaWeb实例销毁后,不得再向其派发onBackPress、onPageShow、onPageHide等事件 + * 该接口定义方便页面挂载多个CordovaWeb实例 + * + * @param cordovaWeb 已经销毁的CordovaWeb实例引用,不为空 + */ + onCordovaWebDisappear(cordovaWeb: ICordovaWebContainer): void + +} \ No newline at end of file -- Gitee From 26cb37622d4b23542cf8ceeb7b38131705d42239 Mon Sep 17 00:00:00 2001 From: A Shuai Date: Fri, 23 Aug 2024 10:39:06 +0800 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96CordovaWeb?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E7=9A=84Page=E5=8F=82=E6=95=B0=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entry/src/main/ets/pages/Test.ets | 2 +- library/src/main/ets/components/CordovaWeb.ets | 7 ++++--- library/src/main/ets/cordova/CordovaInterface.ets | 2 +- .../src/main/ets/cordova/CordovaInterfaceImpl.ets | 14 ++++++-------- library/src/main/ets/cordova/CordovaWebView.ets | 2 +- .../src/main/ets/cordova/CordovaWebViewEngine.ets | 2 +- .../src/main/ets/cordova/CordovaWebViewImpl.ets | 2 +- .../src/main/ets/cordova/engine/SystemWebView.ets | 4 ++-- .../ets/cordova/engine/SystemWebViewEngine.ets | 4 ++-- 9 files changed, 19 insertions(+), 20 deletions(-) diff --git a/entry/src/main/ets/pages/Test.ets b/entry/src/main/ets/pages/Test.ets index db9d4135..97278891 100644 --- a/entry/src/main/ets/pages/Test.ets +++ b/entry/src/main/ets/pages/Test.ets @@ -101,7 +101,7 @@ struct Index { CordovaWeb({ - page: this, + page: () => this, url: 'https://www.baidu.com/js/test.html', parent: this as IPageContainer, bridges: [ diff --git a/library/src/main/ets/components/CordovaWeb.ets b/library/src/main/ets/components/CordovaWeb.ets index b5541447..dc2d20ed 100644 --- a/library/src/main/ets/components/CordovaWeb.ets +++ b/library/src/main/ets/components/CordovaWeb.ets @@ -5,7 +5,7 @@ import { AlertEvent, ConfirmEvent, PromptEvent, ErrorEvent, SslErrorEvent, LoadI import { ICordovaWebContainer } from '../cordova/model/ICordovaWebContainer' import { BridgePermission } from '../model/BridgePermission' import { CordovaContext } from '../CordovaContext' -import { Constants, CordovaLog, StringUtils } from '../utils/Index' +import { Constants, CordovaLog, Preconditions, StringUtils } from '../utils/Index' import { IPageContainer } from '../cordova/model/IPageContainer' // 网页加载状态 @@ -31,9 +31,10 @@ export enum PageLoadState { export struct Index { /** * 所属页面,必填 + * 使用函数定义便于后续升级使用NodeContainer创建离线CordovaWeb */ @Require - private page?: object + private page?: () => object /** * 当前CordovaWeb组件挂载的Page页面,必填 */ @@ -261,7 +262,7 @@ export struct Index { */ private async initWeb() { this.mixedMode = this.enableMixedMode ? MixedMode.All : MixedMode.None - this.systemWebView = new SystemWebView(this.controller, this.page ?? this, this) + this.systemWebView = new SystemWebView(this.controller, Preconditions.checkNonNull(this.page), this) const originUA = StringUtils.wrapEmptyString(this.controller.getCustomUserAgent(), this.controller.getUserAgent()) this.controller.setCustomUserAgent(`${originUA} ${CordovaContext.getCustomUserAgent()}}`) this.systemWebView.loadUrl(this.url) diff --git a/library/src/main/ets/cordova/CordovaInterface.ets b/library/src/main/ets/cordova/CordovaInterface.ets index 2d2f8fba..a090866d 100644 --- a/library/src/main/ets/cordova/CordovaInterface.ets +++ b/library/src/main/ets/cordova/CordovaInterface.ets @@ -13,7 +13,7 @@ export interface CordovaInterface { getWeb(): object - getAbilityContext(): common.UIAbilityContext + getContext(): common.Context onMessage(id: string, data: object | null): object | null diff --git a/library/src/main/ets/cordova/CordovaInterfaceImpl.ets b/library/src/main/ets/cordova/CordovaInterfaceImpl.ets index a86993d8..a298ee2f 100644 --- a/library/src/main/ets/cordova/CordovaInterfaceImpl.ets +++ b/library/src/main/ets/cordova/CordovaInterfaceImpl.ets @@ -1,6 +1,6 @@ import common from '@ohos.app.ability.common' -import { CordovaInterface } from './CordovaInterface' import router from '@ohos.router' +import { CordovaInterface } from './CordovaInterface' import { PluginManager } from './PluginManager' import { CoreHarmony } from './CoreHarmony' import { PluginResult } from './PluginResult' @@ -15,29 +15,27 @@ import { ObjectUtils } from '../utils/Index' * @date 2023/12/26 10:13 */ export class CordovaInterfaceImpl implements CordovaInterface { - private readonly page: object + private readonly page: () => object private readonly web: object - private readonly abilityContext: common.UIAbilityContext private pluginManager?: PluginManager private destroyed: boolean = false private savedResult?: Object - constructor(page: object, web: object) { + constructor(page: () => object, web: object) { this.page = page - this.abilityContext = getContext(page) as common.UIAbilityContext this.web = web } getPage(): object { - return this.page + return this.page() } getWeb(): object { return this.web } - getAbilityContext(): common.UIAbilityContext { - return this.abilityContext + getContext(): common.Context { + return getContext(this.page()) } onMessage(id: string, data: object): object | null { diff --git a/library/src/main/ets/cordova/CordovaWebView.ets b/library/src/main/ets/cordova/CordovaWebView.ets index 28b40635..2050bba9 100644 --- a/library/src/main/ets/cordova/CordovaWebView.ets +++ b/library/src/main/ets/cordova/CordovaWebView.ets @@ -64,7 +64,7 @@ export interface CordovaWebView { getWebContainer(): ICordovaWebContainer - getContext(): common.UIAbilityContext + getContext(): common.Context postMessage(id: string, data: object | null): object | null | undefined diff --git a/library/src/main/ets/cordova/CordovaWebViewEngine.ets b/library/src/main/ets/cordova/CordovaWebViewEngine.ets index 0bd6ade1..45ae7431 100644 --- a/library/src/main/ets/cordova/CordovaWebViewEngine.ets +++ b/library/src/main/ets/cordova/CordovaWebViewEngine.ets @@ -43,7 +43,7 @@ export interface CordovaWebViewEngine { getWeb(): object - getContext(): common.UIAbilityContext + getContext(): common.Context getCordovaWebView(): CordovaWebView diff --git a/library/src/main/ets/cordova/CordovaWebViewImpl.ets b/library/src/main/ets/cordova/CordovaWebViewImpl.ets index f48cd2a8..0f11c6ed 100644 --- a/library/src/main/ets/cordova/CordovaWebViewImpl.ets +++ b/library/src/main/ets/cordova/CordovaWebViewImpl.ets @@ -195,7 +195,7 @@ export class CordovaWebViewImpl implements CordovaWebView { return this.engine.getWeb() as ICordovaWebContainer } - getContext(): common.UIAbilityContext { + getContext(): common.Context { return this.engine.getContext() } diff --git a/library/src/main/ets/cordova/engine/SystemWebView.ets b/library/src/main/ets/cordova/engine/SystemWebView.ets index 867e99e8..cba8fd9a 100644 --- a/library/src/main/ets/cordova/engine/SystemWebView.ets +++ b/library/src/main/ets/cordova/engine/SystemWebView.ets @@ -17,12 +17,12 @@ import { ObjectUtils } from '../../utils/Index' */ export class SystemWebView { private readonly controller: webview.WebviewController - private readonly page: object + private readonly page: () => object private readonly engine: SystemWebViewEngine private readonly webView: CordovaWebView private readonly cordovaInterface: CordovaInterfaceImpl - constructor(controller: webview.WebviewController, page: object, web: object) { + constructor(controller: webview.WebviewController, page: () => object, web: object) { this.controller = controller this.page = page this.engine = new SystemWebViewEngine(controller) diff --git a/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets b/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets index e423d84b..9db0a3b4 100644 --- a/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets +++ b/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets @@ -49,8 +49,8 @@ export class SystemWebViewEngine implements CordovaWebViewEngine { return this.cordova!.getWeb() } - getContext(): common.UIAbilityContext { - return this.cordova!.getAbilityContext() + getContext(): common.Context { + return this.cordova!.getContext() } getCordovaWebView(): CordovaWebView { -- Gitee From cefc8126bc561db3681146fc1e5cb5f5ea591568 Mon Sep 17 00:00:00 2001 From: A Shuai Date: Fri, 23 Aug 2024 10:58:15 +0800 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DCordovaWeb=20Back?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entry/src/main/ets/pages/Test.ets | 2 +- library/src/main/ets/components/CordovaWeb.ets | 6 +++++- library/src/main/ets/cordova/engine/SystemWebView.ets | 8 +++++++- .../src/main/ets/cordova/engine/SystemWebViewEngine.ets | 1 - 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/entry/src/main/ets/pages/Test.ets b/entry/src/main/ets/pages/Test.ets index 97278891..b472430c 100644 --- a/entry/src/main/ets/pages/Test.ets +++ b/entry/src/main/ets/pages/Test.ets @@ -36,7 +36,7 @@ struct Index { } onBackPress(): boolean | void { - // 优先派发返回按钮点击事件给CordovaWeb容器 + // 优先派发返回按钮点击事件给CordovaWeb容器(Cordova优先交给H5处理,其次自行退history栈) for (let index = 0; index < this.cordovaWebList.length; index++) { if (this.cordovaWebList.get(index).onBackPress && this.cordovaWebList.get(index).onBackPress!()) { // Web组件消费了返回事件 diff --git a/library/src/main/ets/components/CordovaWeb.ets b/library/src/main/ets/components/CordovaWeb.ets index dc2d20ed..2f71e83a 100644 --- a/library/src/main/ets/components/CordovaWeb.ets +++ b/library/src/main/ets/components/CordovaWeb.ets @@ -148,7 +148,11 @@ export struct Index { * 返回按钮点击事件 */ onBackPress(): boolean { - return this.systemWebView?.onBackPress() ?? false + // 如果页面已经在加载中或者加载完成,则将back事件派发给Web处理,否则由页面自行处理 + if (this.loadState === PageLoadState.LOADING || this.loadState === PageLoadState.COMPLETE) { + return this.systemWebView?.onBackPress() ?? false + } + return false } /** diff --git a/library/src/main/ets/cordova/engine/SystemWebView.ets b/library/src/main/ets/cordova/engine/SystemWebView.ets index cba8fd9a..51518363 100644 --- a/library/src/main/ets/cordova/engine/SystemWebView.ets +++ b/library/src/main/ets/cordova/engine/SystemWebView.ets @@ -98,6 +98,12 @@ export class SystemWebView { } onBackPress(): boolean { - return this.engine.client?.onBackPress() ?? false + // 如果H5通过Cordova注册back事件拦截,则将事件派发给H5处理 + const consumed = this.engine.client?.onBackPress() ?? false + if (!consumed) { + // 其次检查H5 history是否可退栈 + return this.engine.goBack() + } + return true } } \ No newline at end of file diff --git a/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets b/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets index 9db0a3b4..f1c4ccaa 100644 --- a/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets +++ b/library/src/main/ets/cordova/engine/SystemWebViewEngine.ets @@ -9,7 +9,6 @@ import { PluginManager } from '../PluginManager' import { SystemExposedJsApi } from './SystemExposedJsApi' import { CordovaLog, Preconditions, StringUtils } from '../../utils/Index' import { TAG } from '../../utils/Constants' -import { convertString } from '../../utils/StringUtils' /** * -- Gitee