@react-native-ohos/react-native-webview 13.15.1 → 13.16.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@
6
6
  "name": "@react-native-ohos/react-native-webview",
7
7
  "description": "main cpai architecture",
8
8
  "main": "index.ets",
9
- "version": "13.15.1",
9
+ "version": "13.16.1-rc.1",
10
10
  "dependencies": {
11
11
  "@rnoh/react-native-openharmony": "../react_native_openharmony.har"
12
12
  }
@@ -47,6 +47,7 @@ class BaseReactNativeWebviewPackageEventEmitRequestHandler : public EventEmitReq
47
47
  "customMenuSelection",
48
48
  "fileDownload",
49
49
  "loadingError",
50
+ "loadingSubResourceError",
50
51
  "loadingFinish",
51
52
  "loadingProgress",
52
53
  "loadingStart",
@@ -105,6 +105,7 @@ class RNCWebViewJSIBinder : public ViewComponentJSIBinder {
105
105
  events.setProperty(rt, "topCustomMenuSelection", createDirectEvent(rt, "onCustomMenuSelection"));
106
106
  events.setProperty(rt, "topFileDownload", createDirectEvent(rt, "onFileDownload"));
107
107
  events.setProperty(rt, "topLoadingError", createDirectEvent(rt, "onLoadingError"));
108
+ events.setProperty(rt, "topLoadingSubResourceError", createDirectEvent(rt, "onLoadingSubResourceError"));
108
109
  events.setProperty(rt, "topLoadingFinish", createDirectEvent(rt, "onLoadingFinish"));
109
110
  events.setProperty(rt, "topLoadingProgress", createDirectEvent(rt, "onLoadingProgress"));
110
111
  events.setProperty(rt, "topLoadingStart", createDirectEvent(rt, "onLoadingStart"));
@@ -87,6 +87,23 @@ $payload.setProperty(runtime, "description", $event.description);
87
87
  }
88
88
 
89
89
 
90
+ void RNCWebViewEventEmitter::onLoadingSubResourceError(OnLoadingSubResourceError $event) const {
91
+ dispatchEvent("loadingSubResourceError", [$event=std::move($event)](jsi::Runtime &runtime) {
92
+ auto $payload = jsi::Object(runtime);
93
+ $payload.setProperty(runtime, "url", $event.url);
94
+ $payload.setProperty(runtime, "loading", $event.loading);
95
+ $payload.setProperty(runtime, "title", $event.title);
96
+ $payload.setProperty(runtime, "canGoBack", $event.canGoBack);
97
+ $payload.setProperty(runtime, "canGoForward", $event.canGoForward);
98
+ $payload.setProperty(runtime, "lockIdentifier", $event.lockIdentifier);
99
+ $payload.setProperty(runtime, "domain", $event.domain);
100
+ $payload.setProperty(runtime, "code", $event.code);
101
+ $payload.setProperty(runtime, "description", $event.description);
102
+ return $payload;
103
+ });
104
+ }
105
+
106
+
90
107
  void RNCWebViewEventEmitter::onLoadingFinish(OnLoadingFinish $event) const {
91
108
  dispatchEvent("loadingFinish", [$event=std::move($event)](jsi::Runtime &runtime) {
92
109
  auto $payload = jsi::Object(runtime);
@@ -61,6 +61,18 @@ class RNCWebViewEventEmitter : public ViewEventEmitter {
61
61
  std::string description;
62
62
  };
63
63
 
64
+ struct OnLoadingSubResourceError {
65
+ std::string url;
66
+ bool loading;
67
+ std::string title;
68
+ bool canGoBack;
69
+ bool canGoForward;
70
+ double lockIdentifier;
71
+ std::string domain;
72
+ int code;
73
+ std::string description;
74
+ };
75
+
64
76
  enum class OnLoadingFinishNavigationType {
65
77
  Click,
66
78
  Formsubmit,
@@ -244,6 +256,8 @@ class RNCWebViewEventEmitter : public ViewEventEmitter {
244
256
 
245
257
  void onLoadingError(OnLoadingError value) const;
246
258
 
259
+ void onLoadingSubResourceError(OnLoadingSubResourceError value) const;
260
+
247
261
  void onLoadingFinish(OnLoadingFinish value) const;
248
262
 
249
263
  void onLoadingProgress(OnLoadingProgress value) const;
@@ -39,7 +39,7 @@ export const WEB_VIEW = "RNCWebView"
39
39
  @Sendable
40
40
  class WorkerRunnable implements WorkerTaskRunnable<ShouldStartParams> {
41
41
  run(rnInstance: AnyThreadRNInstance, params: ShouldStartParams): void {
42
- params.lockState = ShouldOverrideCallbackState.UNDECIDED
42
+ params.lockState = ShouldOverrideCallbackState.UNDECIDED
43
43
  rnInstance.getTurboModule<WebViewTurboModule>(TM.RNCWebViewModule.NAME).setShouldStartParams(params)
44
44
  }
45
45
  }
@@ -95,6 +95,9 @@ export struct RNCWebView {
95
95
  private shouldInterceptLoad: boolean = true
96
96
  private callLoadTimer: number = -1
97
97
  static readonly SHOULD_OVERRIDE_URL_LOADING_TIMEOUT: number = 250
98
+ private debounceTimer: number = -1
99
+ static readonly DEBOUNCE_TIME: number = 100
100
+ private isFirstDebounce: boolean = true
98
101
 
99
102
  aboutToAppear() {
100
103
  try {
@@ -398,6 +401,10 @@ export struct RNCWebView {
398
401
  return false
399
402
  }
400
403
 
404
+ onSslErrorEventCallback(event: SslErrorEvent){
405
+ this.webViewBaseOperate?.emitOnSslErrorEventCallback(event);
406
+ }
407
+
401
408
  build() {
402
409
  Stack() {
403
410
  if ( deviceInfo.sdkApiVersion >= 20) {
@@ -472,6 +479,7 @@ export struct RNCWebView {
472
479
  .onRenderExited((event: OnRenderExitedEvent) => this.webViewBaseOperate?.onRenderExited(event))
473
480
  .onLoadIntercept((event: OnLoadInterceptEvent) => this.onLoadIntercept(event))
474
481
  .onTitleReceive((event: OnTitleReceiveEvent) => this.webViewBaseOperate?.onTitleReceive(event))
482
+ .onSslErrorEvent((event: SslErrorEvent) => this.onSslErrorEventCallback(event))
475
483
  } else {
476
484
  Web({ src: "", controller: this.controller, renderMode: this.renderMode })
477
485
  .mixedMode(this.mode)
@@ -544,7 +552,7 @@ export struct RNCWebView {
544
552
  .onRenderExited((event: OnRenderExitedEvent) => this.webViewBaseOperate?.onRenderExited(event))
545
553
  .onLoadIntercept((event: OnLoadInterceptEvent) => this.onLoadIntercept(event))
546
554
  .onTitleReceive((event: OnTitleReceiveEvent) => this.webViewBaseOperate?.onTitleReceive(event))
547
-
555
+ .onSslErrorEvent((event: SslErrorEvent) => this.onSslErrorEventCallback(event))
548
556
  }
549
557
  }
550
558
  .width(this.webviewWidth)
@@ -613,8 +621,24 @@ export struct RNCWebView {
613
621
  })
614
622
  }
615
623
  // this.html = this.source.html
616
- this.webviewWidth = this.descriptorWrapper.layoutMetrics.frame.size.width
617
- this.webviewHeight = this.descriptorWrapper.layoutMetrics.frame.size.height
624
+ const newWidth = this.descriptorWrapper.layoutMetrics.frame.size.width
625
+ const newHeight = this.descriptorWrapper.layoutMetrics.frame.size.height
626
+
627
+ if (this.debounceTimer !== -1) {
628
+ clearTimeout(this.debounceTimer)
629
+ this.debounceTimer = -1
630
+ }
631
+
632
+ if (this.isFirstDebounce) {
633
+ this.webviewWidth = newWidth
634
+ this.webviewHeight = newHeight
635
+ this.isFirstDebounce = false
636
+ } else {
637
+ this.debounceTimer = setTimeout(() => {
638
+ this.webviewWidth = newWidth
639
+ this.webviewHeight = newHeight
640
+ }, RNCWebView.DEBOUNCE_TIME)
641
+ }
618
642
  this.scrollEnabled = this.descriptorWrapper.rawProps.scrollEnabled;
619
643
  // 当禁止滚动时,使用父组件滚动
620
644
  this.nestedScroll = this.scrollEnabled ? NestedScrollMode.SELF_FIRST : NestedScrollMode.PARENT_FIRST;
@@ -135,6 +135,50 @@ export class BaseOperate {
135
135
  }
136
136
  }
137
137
 
138
+ emitOnSslErrorEventCallback(event: SslErrorEvent) {
139
+ try {
140
+ const referrerUrl = event.referrer;
141
+ const url = event.url;
142
+ event.handler.handleCancel(true);
143
+ if (referrerUrl.toLowerCase() != url.toLowerCase()) {
144
+ Logger.debug(TAG, "[RNOH] Resource blocked from loading due to SSL error. Blocked URL: " + url);
145
+ let description = "";
146
+ const descriptionPrefix = "SSL error: ";
147
+ switch (event.error) {
148
+ case SslError.DateInvalid:
149
+ description = "The date of the certificate is invalid";
150
+ break;
151
+ case SslError.HostMismatch:
152
+ description = "Hostname mismatch";
153
+ break;
154
+ case SslError.Invalid:
155
+ description = "A generic error occurred";
156
+ break;
157
+ case SslError.Untrusted:
158
+ description = "The certificate authority is not trusted";
159
+ break;
160
+ default:
161
+ description = "Unknown SSL Error";
162
+ break;
163
+ }
164
+ description = descriptionPrefix + description;
165
+ this.eventEmitter!.emit('loadingSubResourceError', {
166
+ url: event.url,
167
+ loading: false,
168
+ title: this.controller.getTitle(),
169
+ canGoBack: this.controller.accessBackward(),
170
+ canGoForward: this.controller.accessForward(),
171
+ lockIdentifier: this.lockIdentifier,
172
+ domain: "",
173
+ code: event.error,
174
+ description: description
175
+ })
176
+ }
177
+ } catch (error) {
178
+ Logger.error(TAG, `[RNOH] emitLoadingError Errorcode: ${error.code}`);
179
+ }
180
+ }
181
+
138
182
  emitHttpError(event: OnHttpErrorReceiveEvent) {
139
183
  try {
140
184
  this.eventEmitter!.emit('httpError', {
@@ -453,6 +453,7 @@ export namespace RNCWebView {
453
453
  "customMenuSelection": {label: string, key: string, selectedText: string}
454
454
  "fileDownload": {downloadUrl: string}
455
455
  "loadingError": {url: string, loading: boolean, title: string, canGoBack: boolean, canGoForward: boolean, lockIdentifier: number, domain?: string, code: number, description: string}
456
+ "loadingSubResourceError": {url: string, loading: boolean, title: string, canGoBack: boolean, canGoForward: boolean, lockIdentifier: number, domain?: string, code: number, description: string}
456
457
  "loadingFinish": {url: string, loading: boolean, title: string, canGoBack: boolean, canGoForward: boolean, lockIdentifier: number, navigationType: 'click' | 'formsubmit' | 'backforward' | 'reload' | 'formresubmit' | 'other', mainDocumentURL?: string}
457
458
  "loadingProgress": {url: string, loading: boolean, title: string, canGoBack: boolean, canGoForward: boolean, lockIdentifier: number, progress: number}
458
459
  "loadingStart": {url: string, loading: boolean, title: string, canGoBack: boolean, canGoForward: boolean, lockIdentifier: number, navigationType: 'click' | 'formsubmit' | 'backforward' | 'reload' | 'formresubmit' | 'other', mainDocumentURL?: string}
Binary file
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "Thibault Malbranche <malbranche.thibault@gmail.com>"
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "13.15.1",
12
+ "version": "13.16.1-rc.1",
13
13
  "homepage": "https://gitcode.com/openharmony-sig/rntpc_react-native-webview/tree/br_rnoh0.77#readme",
14
14
  "scripts": {
15
15
  "macos": "react-native run-macos --scheme WebviewExample --project-path example/macos",
@@ -37,7 +37,7 @@
37
37
  "dependencies": {
38
38
  "escape-string-regexp": "^4.0.0",
39
39
  "invariant": "2.2.4",
40
- "react-native-webview": "13.15.0"
40
+ "react-native-webview": "13.16.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@babel/cli": "^7.20.0",
@@ -48,7 +48,7 @@
48
48
  "@react-native/eslint-config": "0.73.2",
49
49
  "@react-native/metro-config": "0.73.5",
50
50
  "@react-native/typescript-config": "0.73.1",
51
- "@react-native-oh/react-native-harmony-cli": "file:./packages/react-native-oh-react-native-harmony-cli-0.77.18.tgz",
51
+ "@react-native-oh/react-native-harmony-cli": "file:./packages/rnoh-react-native-harmony-cli-0.82.1.tgz",
52
52
  "@rnx-kit/metro-config": "1.3.15",
53
53
  "@semantic-release/git": "7.0.16",
54
54
  "@types/invariant": "^2.2.30",
@@ -279,6 +279,7 @@ export interface NativeProps extends ViewProps {
279
279
  messagingEnabled: boolean;
280
280
  shouldStartLoadWithRequestEnabled: boolean;
281
281
  onLoadingError: DirectEventHandler<WebViewErrorEvent>;
282
+ onLoadingSubResourceError: DirectEventHandler<WebViewErrorEvent>;
282
283
  onLoadingFinish: DirectEventHandler<WebViewNavigationEvent>;
283
284
  onLoadingProgress: DirectEventHandler<WebViewNativeProgressEvent>;
284
285
  onLoadingStart: DirectEventHandler<WebViewNavigationEvent>;
@@ -52,7 +52,7 @@ const useWarnIfChanges = <T extends unknown>(value: T, name: string) => {
52
52
  }
53
53
  };
54
54
 
55
- const WebViewComponent = forwardRef<{}, IOSWebViewProps & { scalesPageToFit: boolean, minimumFontSize: number, thirdPartyCookiesEnabled: boolean, geolocationEnabled: boolean }>(
55
+ const WebViewComponent = forwardRef<{}, IOSWebViewProps & {onLoadSubResourceError:()=>void, scalesPageToFit: boolean, minimumFontSize: number, thirdPartyCookiesEnabled: boolean, geolocationEnabled: boolean }>(
56
56
  (
57
57
  {
58
58
  fraudulentWebsiteWarningEnabled = true,
@@ -75,6 +75,7 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps & { scalesPageToFit: boo
75
75
  webviewDebuggingEnabled = false,
76
76
  paymentRequestEnabled = false,
77
77
  startInLoadingState,
78
+ onLoadSubResourceError,
78
79
  onNavigationStateChange,
79
80
  onLoadStart,
80
81
  onCustomMenuSelection,
@@ -134,6 +135,7 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps & { scalesPageToFit: boo
134
135
  lastErrorEvent,
135
136
  onHttpError,
136
137
  onLoadingError,
138
+ onLoadingSubResourceError,
137
139
  onLoadingFinish,
138
140
  onLoadingProgress,
139
141
  onOpenWindow,
@@ -142,6 +144,7 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps & { scalesPageToFit: boo
142
144
  onNavigationStateChange,
143
145
  onLoad,
144
146
  onError,
147
+ onLoadSubResourceError,
145
148
  onHttpErrorProp,
146
149
  onLoadEnd,
147
150
  onLoadProgress,
@@ -275,6 +278,7 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps & { scalesPageToFit: boo
275
278
  messagingEnabled={typeof onMessageProp === 'function'}
276
279
  messagingModuleName="" // android ONLY
277
280
  onLoadingError={onLoadingError}
281
+ onLoadingSubResourceError = {onLoadingSubResourceError}
278
282
  onLoadingFinish={onLoadingFinish}
279
283
  onLoadingProgress={onLoadingProgress}
280
284
  onScroll={onScroll}