@react-native-ohos/react-native-webview 13.16.2-beta.2 → 13.16.2

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/LICENSE +20 -20
  3. package/README.OpenSource +10 -10
  4. package/README.md +469 -13
  5. package/harmony/rn_webview/.gitignore +6 -0
  6. package/harmony/rn_webview/BuildProfile.ets +17 -0
  7. package/harmony/rn_webview/OAT.xml +44 -44
  8. package/harmony/rn_webview/build-profile.json5 +28 -28
  9. package/harmony/rn_webview/index.ets +12 -12
  10. package/harmony/rn_webview/oh-package-lock.json5 +29 -0
  11. package/harmony/rn_webview/oh-package.json5 +13 -13
  12. package/harmony/rn_webview/src/main/cpp/CMakeLists.txt +9 -9
  13. package/harmony/rn_webview/src/main/cpp/WebViewPackage.h +16 -16
  14. package/harmony/rn_webview/src/main/cpp/generated/RNOH/generated/BaseReactNativeWebviewPackage.h +96 -96
  15. package/harmony/rn_webview/src/main/cpp/generated/RNOH/generated/components/RNCWebViewJSIBinder.h +121 -120
  16. package/harmony/rn_webview/src/main/cpp/generated/RNOH/generated/turbo_modules/RNCWebView.cpp +18 -18
  17. package/harmony/rn_webview/src/main/cpp/generated/RNOH/generated/turbo_modules/RNCWebView.h +16 -16
  18. package/harmony/rn_webview/src/main/cpp/generated/RNOH/generated/turbo_modules/RNCWebViewModule.cpp +17 -17
  19. package/harmony/rn_webview/src/main/cpp/generated/RNOH/generated/turbo_modules/RNCWebViewModule.h +16 -16
  20. package/harmony/rn_webview/src/main/cpp/generated/react/renderer/components/react_native_webview/ComponentDescriptors.h +24 -24
  21. package/harmony/rn_webview/src/main/cpp/generated/react/renderer/components/react_native_webview/EventEmitters.cpp +258 -258
  22. package/harmony/rn_webview/src/main/cpp/generated/react/renderer/components/react_native_webview/EventEmitters.h +277 -277
  23. package/harmony/rn_webview/src/main/cpp/generated/react/renderer/components/react_native_webview/Props.cpp +104 -103
  24. package/harmony/rn_webview/src/main/cpp/generated/react/renderer/components/react_native_webview/Props.h +510 -509
  25. package/harmony/rn_webview/src/main/cpp/generated/react/renderer/components/react_native_webview/ShadowNodes.cpp +17 -17
  26. package/harmony/rn_webview/src/main/cpp/generated/react/renderer/components/react_native_webview/ShadowNodes.h +32 -32
  27. package/harmony/rn_webview/src/main/cpp/generated/react/renderer/components/react_native_webview/States.cpp +16 -16
  28. package/harmony/rn_webview/src/main/cpp/generated/react/renderer/components/react_native_webview/States.h +28 -28
  29. package/harmony/rn_webview/src/main/ets/Logger.ts +43 -43
  30. package/harmony/rn_webview/src/main/ets/Magic.ets +201 -198
  31. package/harmony/rn_webview/src/main/ets/RNCWebView.ets +1019 -818
  32. package/harmony/rn_webview/src/main/ets/RNCWebViewPackage.ets +37 -37
  33. package/harmony/rn_webview/src/main/ets/WebViewBaseOperate.ets +528 -514
  34. package/harmony/rn_webview/src/main/ets/WebViewTurboModule.ets +67 -63
  35. package/harmony/rn_webview/src/main/ets/generated/components/RNCWebView.ts +529 -525
  36. package/harmony/rn_webview/src/main/ets/generated/components/ts.ts +5 -5
  37. package/harmony/rn_webview/src/main/ets/generated/index.ets +5 -5
  38. package/harmony/rn_webview/src/main/ets/generated/ts.ts +6 -6
  39. package/harmony/rn_webview/src/main/ets/generated/turboModules/RNCWebView.ts +18 -18
  40. package/harmony/rn_webview/src/main/ets/generated/turboModules/RNCWebViewModule.ts +16 -16
  41. package/harmony/rn_webview/src/main/ets/generated/turboModules/ts.ts +6 -6
  42. package/harmony/rn_webview/src/main/module.json5 +10 -10
  43. package/harmony/rn_webview/src/main/resources/base/element/string.json +39 -39
  44. package/harmony/rn_webview/src/main/resources/en_US/element/string.json +39 -39
  45. package/harmony/rn_webview/src/main/resources/zh_CN/element/string.json +39 -39
  46. package/harmony/rn_webview/src/test/List.test.ets +4 -4
  47. package/harmony/rn_webview/src/test/LocalUnit.test.ets +32 -32
  48. package/harmony/rn_webview/ts.ets +8 -8
  49. package/harmony/rn_webview.har +0 -0
  50. package/lib/NativeRNCWebView.d.ts +10 -0
  51. package/lib/NativeRNCWebView.d.ts.map +1 -0
  52. package/lib/NativeRNCWebView.js +1 -0
  53. package/lib/NativeRNCWebViewModule.d.ts +9 -0
  54. package/lib/NativeRNCWebViewModule.d.ts.map +1 -0
  55. package/lib/NativeRNCWebViewModule.js +1 -0
  56. package/lib/RNCWebViewNativeComponent.d.ts +250 -0
  57. package/lib/RNCWebViewNativeComponent.d.ts.map +1 -0
  58. package/lib/RNCWebViewNativeComponent.js +1 -0
  59. package/lib/WebView.d.ts +4 -0
  60. package/lib/WebView.d.ts.map +1 -0
  61. package/lib/WebView.harmony.d.ts +16 -0
  62. package/lib/WebView.harmony.d.ts.map +1 -0
  63. package/lib/WebView.harmony.js +1 -0
  64. package/lib/WebView.js +1 -0
  65. package/lib/codegenUtils.d.ts +3 -0
  66. package/lib/codegenUtils.d.ts.map +1 -0
  67. package/lib/codegenUtils.js +0 -0
  68. package/lib/index.d.ts +4 -0
  69. package/lib/index.d.ts.map +1 -0
  70. package/lib/index.js +1 -0
  71. package/package.json +101 -101
  72. package/src/NativeRNCWebView.ts +21 -21
  73. package/src/NativeRNCWebViewModule.ts +19 -19
  74. package/src/RNCWebViewNativeComponent.ts +356 -355
  75. package/src/WebView.harmony.tsx +348 -346
  76. package/src/WebView.tsx +10 -10
  77. package/src/codegenUtils.ts +10 -10
  78. package/src/index.ts +10 -10
  79. package/harmony/rn_webview/src/main/ets/CutomReference.ts +0 -30
  80. package/harmony/rn_webview/src/main/ets/ShouldRequestUrl.ts +0 -48
@@ -1,347 +1,349 @@
1
- /*
2
- * Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
3
- * Use of this source code is governed by a MIT license that can be
4
- * found in the LICENSE file.
5
- */
6
-
7
- import React, {
8
- forwardRef,
9
- useCallback,
10
- useImperativeHandle,
11
- useRef
12
- } from 'react';
13
- import { Image, View, ImageSourcePropType, HostComponent } from 'react-native';
14
- import invariant from 'invariant';
15
-
16
- import RNCWebView, { Commands, NativeProps } from './RNCWebViewNativeComponent';
17
- import RNCWebViewModule from './NativeRNCWebViewModule';
18
-
19
- import {
20
- defaultOriginWhitelist,
21
- defaultRenderError,
22
- defaultRenderLoading,
23
- useWebViewLogic,
24
- } from 'react-native-webview/src/WebViewShared';
25
- import {
26
- IOSWebViewProps,
27
- DecelerationRateConstant,
28
- WebViewSourceUri,
29
- } from 'react-native-webview/src/WebViewTypes';
30
-
31
- import styles from 'react-native-webview/src/WebView.styles';
32
- const { resolveAssetSource } = Image;
33
- const processDecelerationRate = (
34
- decelerationRate: DecelerationRateConstant | number | undefined
35
- ) => {
36
- let newDecelerationRate = decelerationRate;
37
- if (newDecelerationRate === 'normal') {
38
- newDecelerationRate = 0.998;
39
- } else if (newDecelerationRate === 'fast') {
40
- newDecelerationRate = 0.99;
41
- }
42
- return newDecelerationRate;
43
- };
44
-
45
- const useWarnIfChanges = <T extends unknown>(value: T, name: string) => {
46
- const ref = useRef(value);
47
- if (ref.current !== value) {
48
- console.warn(
49
- `Changes to property ${name} do nothing after the initial render.`
50
- );
51
- ref.current = value;
52
- }
53
- };
54
-
55
- const WebViewComponent = forwardRef<{}, IOSWebViewProps & {onLoadSubResourceError:()=>void, scalesPageToFit: boolean, minimumFontSize: number, thirdPartyCookiesEnabled: boolean, geolocationEnabled: boolean }>(
56
- (
57
- {
58
- fraudulentWebsiteWarningEnabled = true,
59
- javaScriptEnabled = true,
60
- cacheEnabled = true,
61
- originWhitelist = defaultOriginWhitelist,
62
- applicationNameForUserAgent,
63
- ignoreSilentHardwareSwitch,
64
- minimumFontSize,
65
- useSharedProcessPool = true,
66
- textInteractionEnabled = true,
67
- injectedJavaScript,
68
- injectedJavaScriptBeforeContentLoaded,
69
- injectedJavaScriptObject,
70
- menuItems,
71
- injectedJavaScriptForMainFrameOnly = true,
72
- injectedJavaScriptBeforeContentLoadedForMainFrameOnly = true,
73
- thirdPartyCookiesEnabled = false,
74
- geolocationEnabled = false,
75
- webviewDebuggingEnabled = false,
76
- paymentRequestEnabled = false,
77
- startInLoadingState,
78
- onLoadSubResourceError,
79
- onNavigationStateChange,
80
- onLoadStart,
81
- onCustomMenuSelection,
82
- onError,
83
- onLoad,
84
- onLoadEnd,
85
- onLoadProgress,
86
- onScroll,
87
- onContentProcessDidTerminate: onContentProcessDidTerminateProp,
88
- onFileDownload,
89
- onHttpError: onHttpErrorProp,
90
- onMessage: onMessageProp,
91
- onOpenWindow: onOpenWindowProp,
92
- renderLoading,
93
- renderError,
94
- style,
95
- containerStyle,
96
- source,
97
- nativeConfig,
98
- allowsInlineMediaPlayback,
99
- allowsPictureInPictureMediaPlayback,
100
- allowsAirPlayForMediaPlayback,
101
- mediaPlaybackRequiresUserAction=true,
102
- dataDetectorTypes,
103
- incognito,
104
- decelerationRate: decelerationRateProp,
105
- onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp,
106
- onStartShouldSetResponder,
107
- onMoveShouldSetResponderCapture,
108
- pullToRefreshEnabled=false,
109
- refreshControlLightMode=false,
110
- onResponderMove,
111
- ...otherProps
112
- },
113
- ref
114
- ) => {
115
- const webViewRef = useRef<React.ComponentRef<
116
- HostComponent<NativeProps>
117
- > | null>(null);
118
-
119
- const onShouldStartLoadWithRequestCallback = useCallback(
120
- (shouldStart: boolean, _url: string, lockIdentifier = 0) => {
121
- RNCWebViewModule.shouldStartLoadWithLockIdentifier(
122
- shouldStart,
123
- lockIdentifier
124
- );
125
- },
126
- []
127
- );
128
-
129
- const {
130
- onLoadingStart,
131
- onShouldStartLoadWithRequest,
132
- onMessage,
133
- viewState,
134
- setViewState,
135
- lastErrorEvent,
136
- onHttpError,
137
- onLoadingError,
138
- onLoadingSubResourceError,
139
- onLoadingFinish,
140
- onLoadingProgress,
141
- onOpenWindow,
142
- onContentProcessDidTerminate,
143
- } = useWebViewLogic({
144
- onNavigationStateChange,
145
- onLoad,
146
- onError,
147
- onLoadSubResourceError,
148
- onHttpErrorProp,
149
- onLoadEnd,
150
- onLoadProgress,
151
- // @ts-expect-error old arch only
152
- onScroll,
153
- onLoadStart,
154
- onMessageProp,
155
- onOpenWindowProp,
156
- startInLoadingState,
157
- originWhitelist,
158
- ignoreSilentHardwareSwitch,
159
- allowsPictureInPictureMediaPlayback,
160
- minimumFontSize,
161
- onShouldStartLoadWithRequestProp,
162
- onShouldStartLoadWithRequestCallback,
163
- onContentProcessDidTerminateProp,
164
- });
165
-
166
- useImperativeHandle(
167
- ref,
168
- () => ({
169
- goForward: () =>
170
- webViewRef.current && Commands.goForward(webViewRef.current),
171
- goBack: () => webViewRef.current && Commands.goBack(webViewRef.current),
172
- reload: () => {
173
- setViewState('LOADING');
174
- if (webViewRef.current) {
175
- Commands.reload(webViewRef.current);
176
- }
177
- },
178
- stopLoading: () =>
179
- webViewRef.current && Commands.stopLoading(webViewRef.current),
180
- postMessage: (data: string) =>
181
- webViewRef.current && Commands.postMessage(webViewRef.current, data),
182
- injectJavaScript: (data: string) =>
183
- webViewRef.current &&
184
- Commands.injectJavaScript(webViewRef.current, data),
185
- requestFocus: () =>
186
- webViewRef.current && Commands.requestFocus(webViewRef.current),
187
- clearCache: (includeDiskFiles: boolean) =>
188
- webViewRef.current &&
189
- Commands.clearCache(webViewRef.current, includeDiskFiles),
190
- clearHistory: () => webViewRef.current && Commands.clearHistory(webViewRef.current),
191
- loadUrl: (data: string) => webViewRef.current && Commands.loadUrl(webViewRef.current, data),
192
- }),
193
- [setViewState, webViewRef]
194
- );
195
-
196
- useWarnIfChanges(allowsInlineMediaPlayback, 'allowsInlineMediaPlayback');
197
- useWarnIfChanges(
198
- allowsPictureInPictureMediaPlayback,
199
- 'allowsPictureInPictureMediaPlayback'
200
- );
201
- useWarnIfChanges(
202
- allowsAirPlayForMediaPlayback,
203
- 'allowsAirPlayForMediaPlayback'
204
- );
205
- useWarnIfChanges(incognito, 'incognito');
206
- useWarnIfChanges(
207
- mediaPlaybackRequiresUserAction,
208
- 'mediaPlaybackRequiresUserAction'
209
- );
210
- useWarnIfChanges(dataDetectorTypes, 'dataDetectorTypes');
211
-
212
- let otherView = null;
213
- if (viewState === 'LOADING') {
214
- otherView = (renderLoading || defaultRenderLoading)();
215
- } else if (viewState === 'ERROR') {
216
- invariant(
217
- lastErrorEvent != null,
218
- 'lastErrorEvent expected to be non-null'
219
- );
220
- otherView = (renderError || defaultRenderError)(
221
- lastErrorEvent?.domain,
222
- lastErrorEvent?.code ?? 0,
223
- lastErrorEvent?.description ?? ''
224
- );
225
- } else if (viewState !== 'IDLE') {
226
- console.error(`RNCWebView invalid state encountered: ${viewState}`);
227
- }
228
-
229
- const webViewStyles = [styles.container, styles.webView, style];
230
- const webViewContainerStyle = [styles.container, containerStyle];
231
-
232
- const decelerationRate = processDecelerationRate(decelerationRateProp);
233
-
234
- const NativeWebView =
235
- (nativeConfig?.component as typeof RNCWebView | undefined) || RNCWebView;
236
-
237
- const sourceResolved = resolveAssetSource(source as ImageSourcePropType);
238
- const newSource =
239
- typeof sourceResolved === 'object'
240
- ? Object.entries(sourceResolved as WebViewSourceUri).reduce(
241
- (prev, [currKey, currValue]) => {
242
- return {
243
- ...prev,
244
- [currKey]:
245
- currKey === 'headers' &&
246
- currValue &&
247
- typeof currValue === 'object'
248
- ? Object.entries(currValue).map(([key, value]) => {
249
- return {
250
- name: key,
251
- value,
252
- };
253
- })
254
- : currValue,
255
- };
256
- },
257
- {}
258
- )
259
- : sourceResolved;
260
-
261
- const webView = (
262
- <NativeWebView
263
- key="webViewKey"
264
- {...otherProps}
265
- scrollEnabled={otherProps.scrollEnabled ?? true}
266
- ignoreSilentHardwareSwitch={ignoreSilentHardwareSwitch}
267
- minimumFontSize={minimumFontSize}
268
- scalesPageToFit={otherProps.scalesPageToFit ?? true}
269
- fraudulentWebsiteWarningEnabled={fraudulentWebsiteWarningEnabled}
270
- javaScriptEnabled={javaScriptEnabled}
271
- onCustomMenuSelection={onCustomMenuSelection}
272
- applicationNameForUserAgent={applicationNameForUserAgent}
273
- cacheEnabled={cacheEnabled}
274
- useSharedProcessPool={useSharedProcessPool}
275
- textInteractionEnabled={textInteractionEnabled}
276
- geolocationEnabled={geolocationEnabled}
277
- decelerationRate={decelerationRate}
278
- messagingEnabled={typeof onMessageProp === 'function'}
279
- messagingModuleName="" // android ONLY
280
- onLoadingError={onLoadingError}
281
- onLoadingSubResourceError = {onLoadingSubResourceError}
282
- onLoadingFinish={onLoadingFinish}
283
- onLoadingProgress={onLoadingProgress}
284
- onScroll={onScroll}
285
- onFileDownload={onFileDownload}
286
- onLoadingStart={onLoadingStart}
287
- onHttpError={onHttpError}
288
- onMessage={onMessage}
289
- onOpenWindow={onOpenWindowProp && onOpenWindow}
290
- hasOnOpenWindowEvent={onOpenWindowProp !== undefined}
291
- onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
292
- onContentProcessDidTerminate={onContentProcessDidTerminate}
293
- thirdPartyCookiesEnabled={thirdPartyCookiesEnabled}
294
- pullToRefreshEnabled={pullToRefreshEnabled}
295
- refreshControlLightMode={refreshControlLightMode}
296
- injectedJavaScript={injectedJavaScript}
297
- injectedJavaScriptBeforeContentLoaded={
298
- injectedJavaScriptBeforeContentLoaded
299
- }
300
- injectedJavaScriptForMainFrameOnly={injectedJavaScriptForMainFrameOnly}
301
- injectedJavaScriptBeforeContentLoadedForMainFrameOnly={
302
- injectedJavaScriptBeforeContentLoadedForMainFrameOnly
303
- }
304
- injectedJavaScriptObject={JSON.stringify(injectedJavaScriptObject)}
305
- dataDetectorTypes={
306
- !dataDetectorTypes || Array.isArray(dataDetectorTypes)
307
- ? dataDetectorTypes
308
- : [dataDetectorTypes]
309
- }
310
- allowsAirPlayForMediaPlayback={allowsAirPlayForMediaPlayback}
311
- allowsPictureInPictureMediaPlayback={allowsPictureInPictureMediaPlayback}
312
- allowsInlineMediaPlayback={allowsInlineMediaPlayback}
313
- incognito={incognito}
314
- mediaPlaybackRequiresUserAction={mediaPlaybackRequiresUserAction}
315
- menuItems={menuItems}
316
- newSource={newSource}
317
- style={webViewStyles}
318
- webviewDebuggingEnabled={webviewDebuggingEnabled}
319
- paymentRequestEnabled={paymentRequestEnabled}
320
- hasOnFileDownload={!!onFileDownload}
321
- ref={webViewRef}
322
- // @ts-expect-error old arch only
323
- source={sourceResolved}
324
- {...nativeConfig?.props}
325
- />
326
- );
327
-
328
- return (
329
- <View
330
- style={webViewContainerStyle}
331
- onStartShouldSetResponder={(e) => onStartShouldSetResponder ? onStartShouldSetResponder(e) : false}
332
- onMoveShouldSetResponderCapture={(e) => onMoveShouldSetResponderCapture ? onMoveShouldSetResponderCapture(e) : false}
333
- onResponderMove={(e) => onResponderMove ? onResponderMove(e) : null}
334
- >
335
- {webView}
336
- {otherView}
337
- </View>
338
- );
339
- }
340
- );
341
-
342
- // no native implementation for iOS, depends only on permissions
343
- const isFileUploadSupported: () => Promise<boolean> = async () => true;
344
-
345
- const WebView = Object.assign(WebViewComponent, { isFileUploadSupported });
346
-
1
+ /*
2
+ * Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
3
+ * Use of this source code is governed by a MIT license that can be
4
+ * found in the LICENSE file.
5
+ */
6
+
7
+ import React, {
8
+ forwardRef,
9
+ useCallback,
10
+ useImperativeHandle,
11
+ useRef
12
+ } from 'react';
13
+ import { Image, View, ImageSourcePropType, HostComponent } from 'react-native';
14
+ import invariant from 'invariant';
15
+
16
+ import RNCWebView, { Commands, NativeProps } from './RNCWebViewNativeComponent';
17
+ import RNCWebViewModule from './NativeRNCWebViewModule';
18
+
19
+ import {
20
+ defaultOriginWhitelist,
21
+ defaultRenderError,
22
+ defaultRenderLoading,
23
+ useWebViewLogic,
24
+ } from 'react-native-webview/src/WebViewShared';
25
+ import {
26
+ IOSWebViewProps,
27
+ DecelerationRateConstant,
28
+ WebViewSourceUri,
29
+ } from 'react-native-webview/src/WebViewTypes';
30
+
31
+ import styles from 'react-native-webview/src/WebView.styles';
32
+ const { resolveAssetSource } = Image;
33
+ const processDecelerationRate = (
34
+ decelerationRate: DecelerationRateConstant | number | undefined
35
+ ) => {
36
+ let newDecelerationRate = decelerationRate;
37
+ if (newDecelerationRate === 'normal') {
38
+ newDecelerationRate = 0.998;
39
+ } else if (newDecelerationRate === 'fast') {
40
+ newDecelerationRate = 0.99;
41
+ }
42
+ return newDecelerationRate;
43
+ };
44
+
45
+ const useWarnIfChanges = <T extends unknown>(value: T, name: string) => {
46
+ const ref = useRef(value);
47
+ if (ref.current !== value) {
48
+ console.warn(
49
+ `Changes to property ${name} do nothing after the initial render.`
50
+ );
51
+ ref.current = value;
52
+ }
53
+ };
54
+
55
+ const WebViewComponent = forwardRef<{}, IOSWebViewProps & {onLoadSubResourceError:()=>void, scalesPageToFit: boolean, minimumFontSize: number, thirdPartyCookiesEnabled: boolean, geolocationEnabled: boolean, paymentRequestEnabled?: boolean, allowsPictureInPictureMediaPlayback?: boolean, refreshControlLightMode?: boolean }>(
56
+ (
57
+ {
58
+ fraudulentWebsiteWarningEnabled = true,
59
+ javaScriptEnabled = true,
60
+ cacheEnabled = true,
61
+ originWhitelist = defaultOriginWhitelist,
62
+ applicationNameForUserAgent,
63
+ ignoreSilentHardwareSwitch,
64
+ minimumFontSize,
65
+ useSharedProcessPool = true,
66
+ textInteractionEnabled = true,
67
+ injectedJavaScript,
68
+ injectedJavaScriptBeforeContentLoaded,
69
+ injectedJavaScriptObject,
70
+ menuItems,
71
+ injectedJavaScriptForMainFrameOnly = true,
72
+ injectedJavaScriptBeforeContentLoadedForMainFrameOnly = true,
73
+ thirdPartyCookiesEnabled = false,
74
+ geolocationEnabled = false,
75
+ webviewDebuggingEnabled = false,
76
+ paymentRequestEnabled = false,
77
+ startInLoadingState,
78
+ onLoadSubResourceError,
79
+ onNavigationStateChange,
80
+ onLoadStart,
81
+ onCustomMenuSelection,
82
+ onError,
83
+ onLoad,
84
+ onLoadEnd,
85
+ onLoadProgress,
86
+ onScroll,
87
+ onContentProcessDidTerminate: onContentProcessDidTerminateProp,
88
+ onFileDownload,
89
+ onHttpError: onHttpErrorProp,
90
+ onMessage: onMessageProp,
91
+ onOpenWindow: onOpenWindowProp,
92
+ renderLoading,
93
+ renderError,
94
+ style,
95
+ containerStyle,
96
+ source,
97
+ nativeConfig,
98
+ allowsInlineMediaPlayback,
99
+ allowsPictureInPictureMediaPlayback,
100
+ allowsAirPlayForMediaPlayback,
101
+ mediaPlaybackRequiresUserAction=true,
102
+ dataDetectorTypes,
103
+ incognito,
104
+ decelerationRate: decelerationRateProp,
105
+ onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp,
106
+ onStartShouldSetResponder,
107
+ onMoveShouldSetResponderCapture,
108
+ pullToRefreshEnabled=false,
109
+ refreshControlLightMode=false,
110
+ onResponderMove,
111
+ ...otherProps
112
+ },
113
+ ref
114
+ ) => {
115
+ const webViewRef = useRef<React.ComponentRef<
116
+ HostComponent<NativeProps>
117
+ > | null>(null);
118
+
119
+ const onShouldStartLoadWithRequestCallback = useCallback(
120
+ (shouldStart: boolean, _url: string, lockIdentifier = 0) => {
121
+ RNCWebViewModule.shouldStartLoadWithLockIdentifier(
122
+ shouldStart,
123
+ lockIdentifier
124
+ );
125
+ },
126
+ []
127
+ );
128
+
129
+ const {
130
+ onLoadingStart,
131
+ onShouldStartLoadWithRequest,
132
+ onMessage,
133
+ viewState,
134
+ setViewState,
135
+ lastErrorEvent,
136
+ onHttpError,
137
+ onLoadingError,
138
+ // @ts-ignore
139
+ onLoadingSubResourceError,
140
+ onLoadingFinish,
141
+ onLoadingProgress,
142
+ onOpenWindow,
143
+ onContentProcessDidTerminate,
144
+ } = useWebViewLogic({
145
+ onNavigationStateChange,
146
+ onLoad,
147
+ onError,
148
+ // @ts-ignore
149
+ onLoadSubResourceError,
150
+ onHttpErrorProp,
151
+ onLoadEnd,
152
+ onLoadProgress,
153
+ // @ts-ignore
154
+ onScroll,
155
+ onLoadStart,
156
+ onMessageProp,
157
+ onOpenWindowProp,
158
+ startInLoadingState,
159
+ originWhitelist,
160
+ ignoreSilentHardwareSwitch,
161
+ allowsPictureInPictureMediaPlayback,
162
+ minimumFontSize,
163
+ onShouldStartLoadWithRequestProp,
164
+ onShouldStartLoadWithRequestCallback,
165
+ onContentProcessDidTerminateProp,
166
+ });
167
+
168
+ useImperativeHandle(
169
+ ref,
170
+ () => ({
171
+ goForward: () =>
172
+ webViewRef.current && Commands.goForward(webViewRef.current),
173
+ goBack: () => webViewRef.current && Commands.goBack(webViewRef.current),
174
+ reload: () => {
175
+ setViewState('LOADING');
176
+ if (webViewRef.current) {
177
+ Commands.reload(webViewRef.current);
178
+ }
179
+ },
180
+ stopLoading: () =>
181
+ webViewRef.current && Commands.stopLoading(webViewRef.current),
182
+ postMessage: (data: string) =>
183
+ webViewRef.current && Commands.postMessage(webViewRef.current, data),
184
+ injectJavaScript: (data: string) =>
185
+ webViewRef.current &&
186
+ Commands.injectJavaScript(webViewRef.current, data),
187
+ requestFocus: () =>
188
+ webViewRef.current && Commands.requestFocus(webViewRef.current),
189
+ clearCache: (includeDiskFiles: boolean) =>
190
+ webViewRef.current &&
191
+ Commands.clearCache(webViewRef.current, includeDiskFiles),
192
+ clearHistory: () => webViewRef.current && Commands.clearHistory(webViewRef.current),
193
+ loadUrl: (data: string) => webViewRef.current && Commands.loadUrl(webViewRef.current, data),
194
+ }),
195
+ [setViewState, webViewRef]
196
+ );
197
+
198
+ useWarnIfChanges(allowsInlineMediaPlayback, 'allowsInlineMediaPlayback');
199
+ useWarnIfChanges(
200
+ allowsPictureInPictureMediaPlayback,
201
+ 'allowsPictureInPictureMediaPlayback'
202
+ );
203
+ useWarnIfChanges(
204
+ allowsAirPlayForMediaPlayback,
205
+ 'allowsAirPlayForMediaPlayback'
206
+ );
207
+ useWarnIfChanges(incognito, 'incognito');
208
+ useWarnIfChanges(
209
+ mediaPlaybackRequiresUserAction,
210
+ 'mediaPlaybackRequiresUserAction'
211
+ );
212
+ useWarnIfChanges(dataDetectorTypes, 'dataDetectorTypes');
213
+
214
+ let otherView = null;
215
+ if (viewState === 'LOADING') {
216
+ otherView = (renderLoading || defaultRenderLoading)();
217
+ } else if (viewState === 'ERROR') {
218
+ invariant(
219
+ lastErrorEvent != null,
220
+ 'lastErrorEvent expected to be non-null'
221
+ );
222
+ otherView = (renderError || defaultRenderError)(
223
+ lastErrorEvent?.domain,
224
+ lastErrorEvent?.code ?? 0,
225
+ lastErrorEvent?.description ?? ''
226
+ );
227
+ } else if (viewState !== 'IDLE') {
228
+ console.error(`RNCWebView invalid state encountered: ${viewState}`);
229
+ }
230
+
231
+ const webViewStyles = [styles.container, styles.webView, style];
232
+ const webViewContainerStyle = [styles.container, containerStyle];
233
+
234
+ const decelerationRate = processDecelerationRate(decelerationRateProp);
235
+
236
+ const NativeWebView =
237
+ (nativeConfig?.component as typeof RNCWebView | undefined) || RNCWebView;
238
+
239
+ const sourceResolved = resolveAssetSource(source as ImageSourcePropType);
240
+ const newSource =
241
+ typeof sourceResolved === 'object'
242
+ ? Object.entries(sourceResolved as WebViewSourceUri).reduce(
243
+ (prev, [currKey, currValue]) => {
244
+ return {
245
+ ...prev,
246
+ [currKey]:
247
+ currKey === 'headers' &&
248
+ currValue &&
249
+ typeof currValue === 'object'
250
+ ? Object.entries(currValue).map(([key, value]) => {
251
+ return {
252
+ name: key,
253
+ value,
254
+ };
255
+ })
256
+ : currValue,
257
+ };
258
+ },
259
+ {}
260
+ )
261
+ : sourceResolved;
262
+
263
+ const webView = (
264
+ <NativeWebView
265
+ key="webViewKey"
266
+ {...otherProps}
267
+ scrollEnabled={otherProps.scrollEnabled ?? true}
268
+ ignoreSilentHardwareSwitch={ignoreSilentHardwareSwitch}
269
+ minimumFontSize={minimumFontSize}
270
+ scalesPageToFit={otherProps.scalesPageToFit ?? true}
271
+ fraudulentWebsiteWarningEnabled={fraudulentWebsiteWarningEnabled}
272
+ javaScriptEnabled={javaScriptEnabled}
273
+ onCustomMenuSelection={onCustomMenuSelection}
274
+ applicationNameForUserAgent={applicationNameForUserAgent}
275
+ cacheEnabled={cacheEnabled}
276
+ useSharedProcessPool={useSharedProcessPool}
277
+ textInteractionEnabled={textInteractionEnabled}
278
+ geolocationEnabled={geolocationEnabled}
279
+ decelerationRate={decelerationRate}
280
+ messagingEnabled={typeof onMessageProp === 'function'}
281
+ messagingModuleName="" // android ONLY
282
+ onLoadingError={onLoadingError}
283
+ onLoadingSubResourceError = {onLoadingSubResourceError}
284
+ onLoadingFinish={onLoadingFinish}
285
+ onLoadingProgress={onLoadingProgress}
286
+ onScroll={onScroll}
287
+ onFileDownload={onFileDownload}
288
+ onLoadingStart={onLoadingStart}
289
+ onHttpError={onHttpError}
290
+ onMessage={onMessage}
291
+ onOpenWindow={onOpenWindowProp && onOpenWindow}
292
+ hasOnOpenWindowEvent={onOpenWindowProp !== undefined}
293
+ onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
294
+ onContentProcessDidTerminate={onContentProcessDidTerminate}
295
+ thirdPartyCookiesEnabled={thirdPartyCookiesEnabled}
296
+ pullToRefreshEnabled={pullToRefreshEnabled}
297
+ refreshControlLightMode={refreshControlLightMode}
298
+ injectedJavaScript={injectedJavaScript}
299
+ injectedJavaScriptBeforeContentLoaded={
300
+ injectedJavaScriptBeforeContentLoaded
301
+ }
302
+ injectedJavaScriptForMainFrameOnly={injectedJavaScriptForMainFrameOnly}
303
+ injectedJavaScriptBeforeContentLoadedForMainFrameOnly={
304
+ injectedJavaScriptBeforeContentLoadedForMainFrameOnly
305
+ }
306
+ injectedJavaScriptObject={JSON.stringify(injectedJavaScriptObject)}
307
+ dataDetectorTypes={
308
+ !dataDetectorTypes || Array.isArray(dataDetectorTypes)
309
+ ? dataDetectorTypes
310
+ : [dataDetectorTypes]
311
+ }
312
+ allowsAirPlayForMediaPlayback={allowsAirPlayForMediaPlayback}
313
+ allowsPictureInPictureMediaPlayback={allowsPictureInPictureMediaPlayback}
314
+ allowsInlineMediaPlayback={allowsInlineMediaPlayback}
315
+ incognito={incognito}
316
+ mediaPlaybackRequiresUserAction={mediaPlaybackRequiresUserAction}
317
+ menuItems={menuItems}
318
+ newSource={newSource}
319
+ style={webViewStyles}
320
+ webviewDebuggingEnabled={webviewDebuggingEnabled}
321
+ paymentRequestEnabled={paymentRequestEnabled}
322
+ hasOnFileDownload={!!onFileDownload}
323
+ ref={webViewRef}
324
+ // @ts-expect-error old arch only
325
+ source={sourceResolved}
326
+ {...nativeConfig?.props}
327
+ />
328
+ );
329
+
330
+ return (
331
+ <View
332
+ style={webViewContainerStyle}
333
+ onStartShouldSetResponder={(e) => onStartShouldSetResponder ? onStartShouldSetResponder(e) : false}
334
+ onMoveShouldSetResponderCapture={(e) => onMoveShouldSetResponderCapture ? onMoveShouldSetResponderCapture(e) : false}
335
+ onResponderMove={(e) => onResponderMove ? onResponderMove(e) : null}
336
+ >
337
+ {webView}
338
+ {otherView}
339
+ </View>
340
+ );
341
+ }
342
+ );
343
+
344
+ // no native implementation for iOS, depends only on permissions
345
+ const isFileUploadSupported: () => Promise<boolean> = async () => true;
346
+
347
+ const WebView = Object.assign(WebViewComponent, { isFileUploadSupported });
348
+
347
349
  export default WebView;