@javascriptcommon/react-native-webview 13.12.16

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 (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +82 -0
  3. package/android/build.gradle +110 -0
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/AndroidManifest.xml +15 -0
  6. package/android/src/main/AndroidManifestNew.xml +13 -0
  7. package/android/src/main/java/com/reactnativecommunity/webview/RNCBasicAuthCredential.java +11 -0
  8. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java +372 -0
  9. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebView.java +450 -0
  10. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java +328 -0
  11. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewConfig.java +11 -0
  12. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewFileProvider.java +14 -0
  13. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt +720 -0
  14. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewMessagingModule.kt +19 -0
  15. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModuleImpl.java +554 -0
  16. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java +56 -0
  17. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewWrapper.kt +39 -0
  18. package/android/src/main/java/com/reactnativecommunity/webview/URLUtil.java +179 -0
  19. package/android/src/main/java/com/reactnativecommunity/webview/events/TopCustomMenuSelectionEvent.kt +24 -0
  20. package/android/src/main/java/com/reactnativecommunity/webview/events/TopHttpErrorEvent.kt +25 -0
  21. package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingErrorEvent.kt +25 -0
  22. package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingFinishEvent.kt +24 -0
  23. package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingProgressEvent.kt +24 -0
  24. package/android/src/main/java/com/reactnativecommunity/webview/events/TopLoadingStartEvent.kt +25 -0
  25. package/android/src/main/java/com/reactnativecommunity/webview/events/TopMessageEvent.kt +24 -0
  26. package/android/src/main/java/com/reactnativecommunity/webview/events/TopNewWindowEvent.kt +25 -0
  27. package/android/src/main/java/com/reactnativecommunity/webview/events/TopRenderProcessGoneEvent.kt +26 -0
  28. package/android/src/main/java/com/reactnativecommunity/webview/events/TopShouldStartLoadWithRequestEvent.kt +29 -0
  29. package/android/src/main/res/xml/file_provider_paths.xml +6 -0
  30. package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java +553 -0
  31. package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewModule.java +63 -0
  32. package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewManager.java +328 -0
  33. package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewModule.java +59 -0
  34. package/apple/RCTConvert+WKDataDetectorTypes.h +11 -0
  35. package/apple/RCTConvert+WKDataDetectorTypes.m +27 -0
  36. package/apple/RNCWKProcessPoolManager.h +15 -0
  37. package/apple/RNCWKProcessPoolManager.m +36 -0
  38. package/apple/RNCWebView.h +35 -0
  39. package/apple/RNCWebView.mm +546 -0
  40. package/apple/RNCWebViewDecisionManager.h +20 -0
  41. package/apple/RNCWebViewDecisionManager.m +47 -0
  42. package/apple/RNCWebViewImpl.h +161 -0
  43. package/apple/RNCWebViewImpl.m +1979 -0
  44. package/apple/RNCWebViewManager.h +9 -0
  45. package/apple/RNCWebViewManager.mm +215 -0
  46. package/apple/RNCWebViewModule.h +23 -0
  47. package/apple/RNCWebViewModule.mm +34 -0
  48. package/index.d.ts +65 -0
  49. package/index.js +4 -0
  50. package/ios/RNCWebView.xcodeproj/project.pbxproj +273 -0
  51. package/lib/NativeRNCWebViewModule.d.ts +10 -0
  52. package/lib/NativeRNCWebViewModule.js +1 -0
  53. package/lib/RNCWebViewNativeComponent.d.ts +242 -0
  54. package/lib/RNCWebViewNativeComponent.js +1 -0
  55. package/lib/WebView.android.d.ts +6 -0
  56. package/lib/WebView.android.js +1 -0
  57. package/lib/WebView.d.ts +6 -0
  58. package/lib/WebView.ios.d.ts +6 -0
  59. package/lib/WebView.ios.js +1 -0
  60. package/lib/WebView.js +1 -0
  61. package/lib/WebView.macos.d.ts +6 -0
  62. package/lib/WebView.macos.js +1 -0
  63. package/lib/WebView.styles.d.ts +38 -0
  64. package/lib/WebView.styles.js +1 -0
  65. package/lib/WebView.windows.d.ts +17 -0
  66. package/lib/WebView.windows.js +1 -0
  67. package/lib/WebViewNativeComponent.macos.d.ts +3 -0
  68. package/lib/WebViewNativeComponent.macos.js +1 -0
  69. package/lib/WebViewNativeComponent.windows.d.ts +3 -0
  70. package/lib/WebViewNativeComponent.windows.js +1 -0
  71. package/lib/WebViewShared.d.ts +38 -0
  72. package/lib/WebViewShared.js +1 -0
  73. package/lib/WebViewTypes.d.ts +1093 -0
  74. package/lib/WebViewTypes.js +1 -0
  75. package/lib/index.d.ts +3 -0
  76. package/lib/index.js +1 -0
  77. package/macos/RNCWebView.xcodeproj/project.pbxproj +363 -0
  78. package/package.json +101 -0
  79. package/react-native-webview.podspec +46 -0
  80. package/react-native.config.js +44 -0
  81. package/src/NativeRNCWebViewModule.ts +15 -0
  82. package/src/RNCWebViewNativeComponent.ts +342 -0
  83. package/src/WebView.android.tsx +317 -0
  84. package/src/WebView.ios.tsx +299 -0
  85. package/src/WebView.macos.tsx +245 -0
  86. package/src/WebView.styles.ts +41 -0
  87. package/src/WebView.tsx +25 -0
  88. package/src/WebView.windows.tsx +210 -0
  89. package/src/WebViewNativeComponent.macos.ts +7 -0
  90. package/src/WebViewNativeComponent.windows.ts +8 -0
  91. package/src/WebViewShared.tsx +283 -0
  92. package/src/WebViewTypes.ts +1332 -0
  93. package/src/__tests__/WebViewShared-test.js +323 -0
  94. package/src/__tests__/__snapshots__/WebViewShared-test.js.snap +8 -0
  95. package/src/index.ts +4 -0
  96. package/windows/ExperimentalFeatures.props +11 -0
  97. package/windows/ReactNativeWebView/PropertySheet.props +16 -0
  98. package/windows/ReactNativeWebView/ReactNativeWebView.def +3 -0
  99. package/windows/ReactNativeWebView/ReactNativeWebView.filters +33 -0
  100. package/windows/ReactNativeWebView/ReactNativeWebView.vcxproj +189 -0
  101. package/windows/ReactNativeWebView/ReactPackageProvider.cpp +26 -0
  102. package/windows/ReactNativeWebView/ReactPackageProvider.h +20 -0
  103. package/windows/ReactNativeWebView/ReactPackageProvider.idl +7 -0
  104. package/windows/ReactNativeWebView/ReactWebView.cpp +242 -0
  105. package/windows/ReactNativeWebView/ReactWebView.h +56 -0
  106. package/windows/ReactNativeWebView/ReactWebView.idl +31 -0
  107. package/windows/ReactNativeWebView/ReactWebView2.cpp +473 -0
  108. package/windows/ReactNativeWebView/ReactWebView2.h +91 -0
  109. package/windows/ReactNativeWebView/ReactWebView2Manager.cpp +205 -0
  110. package/windows/ReactNativeWebView/ReactWebView2Manager.h +57 -0
  111. package/windows/ReactNativeWebView/ReactWebViewHelpers.cpp +70 -0
  112. package/windows/ReactNativeWebView/ReactWebViewHelpers.h +16 -0
  113. package/windows/ReactNativeWebView/ReactWebViewManager.cpp +224 -0
  114. package/windows/ReactNativeWebView/ReactWebViewManager.h +58 -0
  115. package/windows/ReactNativeWebView/WebBridge.cpp +19 -0
  116. package/windows/ReactNativeWebView/WebBridge.h +24 -0
  117. package/windows/ReactNativeWebView/WebBridge.idl +11 -0
  118. package/windows/ReactNativeWebView/pch.cpp +1 -0
  119. package/windows/ReactNativeWebView/pch.h +37 -0
  120. package/windows/ReactNativeWebView.sln +185 -0
@@ -0,0 +1,342 @@
1
+ import type { HostComponent, ViewProps } from 'react-native';
2
+ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
3
+ import {
4
+ DirectEventHandler,
5
+ Double,
6
+ Int32,
7
+ WithDefault,
8
+ } from 'react-native/Libraries/Types/CodegenTypes';
9
+ import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';
10
+
11
+ export type WebViewNativeEvent = Readonly<{
12
+ url: string;
13
+ loading: boolean;
14
+ title: string;
15
+ canGoBack: boolean;
16
+ canGoForward: boolean;
17
+ lockIdentifier: Double;
18
+ }>;
19
+ export type WebViewCustomMenuSelectionEvent = Readonly<{
20
+ label: string;
21
+ key: string;
22
+ selectedText: string;
23
+ }>;
24
+ export type WebViewMessageEvent = Readonly<{
25
+ url: string;
26
+ loading: boolean;
27
+ title: string;
28
+ canGoBack: boolean;
29
+ canGoForward: boolean;
30
+ lockIdentifier: Double;
31
+ data: string;
32
+ }>;
33
+ export type WebViewOpenWindowEvent = Readonly<{
34
+ targetUrl: string;
35
+ }>;
36
+ export type WebViewHttpErrorEvent = Readonly<{
37
+ url: string;
38
+ loading: boolean;
39
+ title: string;
40
+ canGoBack: boolean;
41
+ canGoForward: boolean;
42
+ lockIdentifier: Double;
43
+ description: string;
44
+ statusCode: Int32;
45
+ }>;
46
+
47
+ export type WebViewErrorEvent = Readonly<{
48
+ url: string;
49
+ loading: boolean;
50
+ title: string;
51
+ canGoBack: boolean;
52
+ canGoForward: boolean;
53
+ lockIdentifier: Double;
54
+ domain?: string;
55
+ code: Int32;
56
+ description: string;
57
+ }>;
58
+
59
+ export type WebViewNativeProgressEvent = Readonly<{
60
+ url: string;
61
+ loading: boolean;
62
+ title: string;
63
+ canGoBack: boolean;
64
+ canGoForward: boolean;
65
+ lockIdentifier: Double;
66
+ progress: Double;
67
+ }>;
68
+
69
+ export type WebViewNavigationEvent = Readonly<{
70
+ url: string;
71
+ loading: boolean;
72
+ title: string;
73
+ canGoBack: boolean;
74
+ canGoForward: boolean;
75
+ lockIdentifier: Double;
76
+ navigationType:
77
+ | 'click'
78
+ | 'formsubmit'
79
+ | 'backforward'
80
+ | 'reload'
81
+ | 'formresubmit'
82
+ | 'other';
83
+ mainDocumentURL?: string;
84
+ }>;
85
+
86
+ export type ShouldStartLoadRequestEvent = Readonly<{
87
+ url: string;
88
+ loading: boolean;
89
+ title: string;
90
+ canGoBack: boolean;
91
+ canGoForward: boolean;
92
+ lockIdentifier: Double;
93
+ navigationType:
94
+ | 'click'
95
+ | 'formsubmit'
96
+ | 'backforward'
97
+ | 'reload'
98
+ | 'formresubmit'
99
+ | 'other';
100
+ mainDocumentURL?: string;
101
+ isTopFrame: boolean;
102
+ }>;
103
+
104
+ type ScrollEvent = Readonly<{
105
+ contentInset: {
106
+ bottom: Double;
107
+ left: Double;
108
+ right: Double;
109
+ top: Double;
110
+ };
111
+ contentOffset: {
112
+ y: Double;
113
+ x: Double;
114
+ };
115
+ contentSize: {
116
+ height: Double;
117
+ width: Double;
118
+ };
119
+ layoutMeasurement: {
120
+ height: Double;
121
+ width: Double;
122
+ };
123
+ targetContentOffset?: {
124
+ y: Double;
125
+ x: Double;
126
+ };
127
+ velocity?: {
128
+ y: Double;
129
+ x: Double;
130
+ };
131
+ zoomScale?: Double;
132
+ responderIgnoreScroll?: boolean;
133
+ }>;
134
+
135
+ type WebViewRenderProcessGoneEvent = Readonly<{
136
+ didCrash: boolean;
137
+ }>;
138
+
139
+ type WebViewDownloadEvent = Readonly<{
140
+ downloadUrl: string;
141
+ }>;
142
+
143
+ // type MenuItem = Readonly<{label: string, key: string}>;
144
+
145
+ export interface NativeProps extends ViewProps {
146
+ // Android only
147
+ allowFileAccess?: boolean;
148
+ allowsProtectedMedia?: boolean;
149
+ allowsFullscreenVideo?: boolean;
150
+ androidLayerType?: WithDefault<'none' | 'software' | 'hardware', 'none'>;
151
+ cacheMode?: WithDefault<
152
+ | 'LOAD_DEFAULT'
153
+ | 'LOAD_CACHE_ELSE_NETWORK'
154
+ | 'LOAD_NO_CACHE'
155
+ | 'LOAD_CACHE_ONLY',
156
+ 'LOAD_DEFAULT'
157
+ >;
158
+ domStorageEnabled?: boolean;
159
+ downloadingMessage?: string;
160
+ forceDarkOn?: boolean;
161
+ geolocationEnabled?: boolean;
162
+ lackPermissionToDownloadMessage?: string;
163
+ messagingModuleName: string;
164
+ minimumFontSize?: Int32;
165
+ mixedContentMode?: WithDefault<'never' | 'always' | 'compatibility', 'never'>;
166
+ nestedScrollEnabled?: boolean;
167
+ onContentSizeChange?: DirectEventHandler<WebViewNativeEvent>;
168
+ onRenderProcessGone?: DirectEventHandler<WebViewRenderProcessGoneEvent>;
169
+ overScrollMode?: string;
170
+ saveFormDataDisabled?: boolean;
171
+ scalesPageToFit?: boolean;
172
+ setBuiltInZoomControls?: boolean;
173
+ setDisplayZoomControls?: boolean;
174
+ setSupportMultipleWindows?: boolean;
175
+ textZoom?: Int32;
176
+ thirdPartyCookiesEnabled?: boolean;
177
+ // Workaround to watch if listener if defined
178
+ hasOnScroll?: boolean;
179
+ // !Android only
180
+
181
+ // iOS only
182
+ allowingReadAccessToURL?: string;
183
+ allowsBackForwardNavigationGestures?: boolean;
184
+ allowsInlineMediaPlayback?: boolean;
185
+ allowsPictureInPictureMediaPlayback?: boolean;
186
+ allowsAirPlayForMediaPlayback?: boolean;
187
+ allowsLinkPreview?: boolean;
188
+ automaticallyAdjustContentInsets?: boolean;
189
+ autoManageStatusBarEnabled?: boolean;
190
+ bounces?: boolean;
191
+ contentInset?: Readonly<{
192
+ top?: Double;
193
+ left?: Double;
194
+ bottom?: Double;
195
+ right?: Double;
196
+ }>;
197
+ contentInsetAdjustmentBehavior?: WithDefault<
198
+ 'never' | 'automatic' | 'scrollableAxes' | 'always',
199
+ 'never'
200
+ >;
201
+ contentMode?: WithDefault<
202
+ 'recommended' | 'mobile' | 'desktop',
203
+ 'recommended'
204
+ >;
205
+ dataDetectorTypes?: WithDefault<
206
+ ReadonlyArray<
207
+ | 'address'
208
+ | 'link'
209
+ | 'calendarEvent'
210
+ | 'trackingNumber'
211
+ | 'flightNumber'
212
+ | 'lookupSuggestion'
213
+ | 'phoneNumber'
214
+ | 'all'
215
+ | 'none'
216
+ >,
217
+ 'phoneNumber'
218
+ >;
219
+ decelerationRate?: Double;
220
+ directionalLockEnabled?: boolean;
221
+ enableApplePay?: boolean;
222
+ hideKeyboardAccessoryView?: boolean;
223
+ keyboardDisplayRequiresUserAction?: boolean;
224
+ limitsNavigationsToAppBoundDomains?: boolean;
225
+ mediaCapturePermissionGrantType?: WithDefault<
226
+ | 'prompt'
227
+ | 'grant'
228
+ | 'deny'
229
+ | 'grantIfSameHostElsePrompt'
230
+ | 'grantIfSameHostElseDeny',
231
+ 'prompt'
232
+ >;
233
+ pagingEnabled?: boolean;
234
+ pullToRefreshEnabled?: boolean;
235
+ refreshControlLightMode?: boolean;
236
+ scrollEnabled?: boolean;
237
+ sharedCookiesEnabled?: boolean;
238
+ textInteractionEnabled?: boolean;
239
+ useSharedProcessPool?: boolean;
240
+ onContentProcessDidTerminate?: DirectEventHandler<WebViewNativeEvent>;
241
+ onCustomMenuSelection?: DirectEventHandler<WebViewCustomMenuSelectionEvent>;
242
+ onFileDownload?: DirectEventHandler<WebViewDownloadEvent>;
243
+
244
+ menuItems?: ReadonlyArray<Readonly<{ label: string; key: string }>>;
245
+ suppressMenuItems?: Readonly<string>[];
246
+ // Workaround to watch if listener if defined
247
+ hasOnFileDownload?: boolean;
248
+ fraudulentWebsiteWarningEnabled?: boolean;
249
+ // !iOS only
250
+
251
+ allowFileAccessFromFileURLs?: boolean;
252
+ allowUniversalAccessFromFileURLs?: boolean;
253
+ applicationNameForUserAgent?: string;
254
+ basicAuthCredential?: Readonly<{
255
+ username: string;
256
+ password: string;
257
+ }>;
258
+ cacheEnabled?: boolean;
259
+ incognito?: boolean;
260
+ injectedJavaScript?: string;
261
+ injectedJavaScriptBeforeContentLoaded?: string;
262
+ injectedJavaScriptForMainFrameOnly?: boolean;
263
+ injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean;
264
+ javaScriptCanOpenWindowsAutomatically?: boolean;
265
+ javaScriptEnabled?: boolean;
266
+ webviewDebuggingEnabled?: boolean;
267
+ mediaPlaybackRequiresUserAction?: boolean;
268
+ messagingEnabled: boolean;
269
+ onLoadingError: DirectEventHandler<WebViewErrorEvent>;
270
+ onLoadingFinish: DirectEventHandler<WebViewNavigationEvent>;
271
+ onLoadingProgress: DirectEventHandler<WebViewNativeProgressEvent>;
272
+ onLoadingStart: DirectEventHandler<WebViewNavigationEvent>;
273
+ onHttpError: DirectEventHandler<WebViewHttpErrorEvent>;
274
+ onMessage: DirectEventHandler<WebViewMessageEvent>;
275
+ onOpenWindow?: DirectEventHandler<WebViewOpenWindowEvent>;
276
+ hasOnOpenWindowEvent?: boolean;
277
+ onScroll?: DirectEventHandler<ScrollEvent>;
278
+ onShouldStartLoadWithRequest: DirectEventHandler<ShouldStartLoadRequestEvent>;
279
+ showsHorizontalScrollIndicator?: boolean;
280
+ showsVerticalScrollIndicator?: boolean;
281
+ newSource: Readonly<{
282
+ uri?: string;
283
+ method?: string;
284
+ body?: string;
285
+
286
+ headers?: ReadonlyArray<Readonly<{ name: string; value: string }>>;
287
+ html?: string;
288
+ baseUrl?: string;
289
+ }>;
290
+ userAgent?: string;
291
+ injectedJavaScriptObject?: string;
292
+ }
293
+
294
+ export interface NativeCommands {
295
+ goBack: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
296
+ goForward: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
297
+ reload: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
298
+ stopLoading: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
299
+ injectJavaScript: (
300
+ viewRef: React.ElementRef<HostComponent<NativeProps>>,
301
+ javascript: string
302
+ ) => void;
303
+ requestFocus: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
304
+ postMessage: (
305
+ viewRef: React.ElementRef<HostComponent<NativeProps>>,
306
+ data: string
307
+ ) => void;
308
+ // Android Only
309
+ loadUrl: (
310
+ viewRef: React.ElementRef<HostComponent<NativeProps>>,
311
+ url: string
312
+ ) => void;
313
+ clearFormData: (
314
+ viewRef: React.ElementRef<HostComponent<NativeProps>>
315
+ ) => void;
316
+ clearCache: (
317
+ viewRef: React.ElementRef<HostComponent<NativeProps>>,
318
+ includeDiskFiles: boolean
319
+ ) => void;
320
+ clearHistory: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
321
+ // !Android Only
322
+ }
323
+
324
+ export const Commands = codegenNativeCommands<NativeCommands>({
325
+ supportedCommands: [
326
+ 'goBack',
327
+ 'goForward',
328
+ 'reload',
329
+ 'stopLoading',
330
+ 'injectJavaScript',
331
+ 'requestFocus',
332
+ 'postMessage',
333
+ 'loadUrl',
334
+ 'clearFormData',
335
+ 'clearCache',
336
+ 'clearHistory',
337
+ ],
338
+ });
339
+
340
+ export default codegenNativeComponent<NativeProps>(
341
+ 'RNCWebView'
342
+ ) as HostComponent<NativeProps>;
@@ -0,0 +1,317 @@
1
+ import React, {
2
+ forwardRef,
3
+ ReactElement,
4
+ useCallback,
5
+ useEffect,
6
+ useImperativeHandle,
7
+ useRef,
8
+ } from 'react';
9
+
10
+ import {
11
+ Image,
12
+ View,
13
+ ImageSourcePropType,
14
+ HostComponent,
15
+ NativeEventEmitter,
16
+ } from 'react-native';
17
+
18
+ import invariant from 'invariant';
19
+
20
+ import RNCWebView, { Commands, NativeProps } from './RNCWebViewNativeComponent';
21
+ import RNCWebViewModule from './NativeRNCWebViewModule';
22
+ import {
23
+ defaultOriginWhitelist,
24
+ defaultRenderError,
25
+ defaultRenderLoading,
26
+ useWebViewLogic,
27
+ } from './WebViewShared';
28
+ import {
29
+ AndroidWebViewProps,
30
+ WebViewSourceUri,
31
+ type WebViewMessageEvent,
32
+ type ShouldStartLoadRequestEvent,
33
+ } from './WebViewTypes';
34
+
35
+ import styles from './WebView.styles';
36
+
37
+ const { resolveAssetSource } = Image;
38
+
39
+ const directEventEmitter = new NativeEventEmitter(RNCWebViewModule);
40
+
41
+ /**
42
+ * A simple counter to uniquely identify WebView instances. Do not use this for anything else.
43
+ */
44
+ let uniqueRef = 0;
45
+
46
+ const WebViewComponent = forwardRef<{}, AndroidWebViewProps>(
47
+ (
48
+ {
49
+ overScrollMode = 'always',
50
+ javaScriptEnabled = true,
51
+ thirdPartyCookiesEnabled = true,
52
+ scalesPageToFit = true,
53
+ allowsFullscreenVideo = false,
54
+ allowFileAccess = false,
55
+ saveFormDataDisabled = false,
56
+ cacheEnabled = true,
57
+ androidLayerType = 'none',
58
+ originWhitelist = defaultOriginWhitelist,
59
+ setSupportMultipleWindows = true,
60
+ setBuiltInZoomControls = true,
61
+ setDisplayZoomControls = false,
62
+ nestedScrollEnabled = false,
63
+ startInLoadingState,
64
+ onNavigationStateChange,
65
+ onLoadStart,
66
+ onError,
67
+ onLoad,
68
+ onLoadEnd,
69
+ onLoadProgress,
70
+ onHttpError: onHttpErrorProp,
71
+ onRenderProcessGone: onRenderProcessGoneProp,
72
+ onMessage: onMessageProp,
73
+ onOpenWindow: onOpenWindowProp,
74
+ renderLoading,
75
+ renderError,
76
+ style,
77
+ containerStyle,
78
+ source,
79
+ nativeConfig,
80
+ onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp,
81
+ injectedJavaScriptObject,
82
+ ...otherProps
83
+ },
84
+ ref
85
+ ) => {
86
+ const messagingModuleName = useRef<string>(
87
+ `WebViewMessageHandler${(uniqueRef += 1)}`
88
+ ).current;
89
+ const webViewRef = useRef<React.ComponentRef<
90
+ HostComponent<NativeProps>
91
+ > | null>(null);
92
+
93
+ const onShouldStartLoadWithRequestCallback = useCallback(
94
+ (shouldStart: boolean, url: string, lockIdentifier?: number) => {
95
+ if (lockIdentifier) {
96
+ RNCWebViewModule.shouldStartLoadWithLockIdentifier(
97
+ shouldStart,
98
+ lockIdentifier
99
+ );
100
+ } else if (shouldStart && webViewRef.current) {
101
+ Commands.loadUrl(webViewRef.current, url);
102
+ }
103
+ },
104
+ []
105
+ );
106
+
107
+ const {
108
+ onLoadingStart,
109
+ onShouldStartLoadWithRequest,
110
+ onMessage,
111
+ viewState,
112
+ setViewState,
113
+ lastErrorEvent,
114
+ onHttpError,
115
+ onLoadingError,
116
+ onLoadingFinish,
117
+ onLoadingProgress,
118
+ onOpenWindow,
119
+ onRenderProcessGone,
120
+ } = useWebViewLogic({
121
+ onNavigationStateChange,
122
+ onLoad,
123
+ onError,
124
+ onHttpErrorProp,
125
+ onLoadEnd,
126
+ onLoadProgress,
127
+ onLoadStart,
128
+ onRenderProcessGoneProp,
129
+ onMessageProp,
130
+ onOpenWindowProp,
131
+ startInLoadingState,
132
+ originWhitelist,
133
+ onShouldStartLoadWithRequestProp,
134
+ onShouldStartLoadWithRequestCallback,
135
+ });
136
+
137
+ useImperativeHandle(
138
+ ref,
139
+ () => ({
140
+ goForward: () =>
141
+ webViewRef.current && Commands.goForward(webViewRef.current),
142
+ goBack: () => webViewRef.current && Commands.goBack(webViewRef.current),
143
+ reload: () => {
144
+ setViewState('LOADING');
145
+ if (webViewRef.current) {
146
+ Commands.reload(webViewRef.current);
147
+ }
148
+ },
149
+ stopLoading: () =>
150
+ webViewRef.current && Commands.stopLoading(webViewRef.current),
151
+ postMessage: (data: string) =>
152
+ webViewRef.current && Commands.postMessage(webViewRef.current, data),
153
+ injectJavaScript: (data: string) =>
154
+ webViewRef.current &&
155
+ Commands.injectJavaScript(webViewRef.current, data),
156
+ requestFocus: () =>
157
+ webViewRef.current && Commands.requestFocus(webViewRef.current),
158
+ clearFormData: () =>
159
+ webViewRef.current && Commands.clearFormData(webViewRef.current),
160
+ clearCache: (includeDiskFiles: boolean) =>
161
+ webViewRef.current &&
162
+ Commands.clearCache(webViewRef.current, includeDiskFiles),
163
+ clearHistory: () =>
164
+ webViewRef.current && Commands.clearHistory(webViewRef.current),
165
+ }),
166
+ [setViewState, webViewRef]
167
+ );
168
+
169
+ useEffect(() => {
170
+ const onShouldStartLoadWithRequestSubscription =
171
+ directEventEmitter.addListener(
172
+ 'onShouldStartLoadWithRequest',
173
+ (
174
+ event: ShouldStartLoadRequestEvent & {
175
+ messagingModuleName?: string;
176
+ }
177
+ ) => {
178
+ if (event.messagingModuleName === messagingModuleName) {
179
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
180
+ const { messagingModuleName: _, ...rest } = event;
181
+ onShouldStartLoadWithRequest(rest);
182
+ }
183
+ }
184
+ );
185
+
186
+ const onMessageSubscription = directEventEmitter.addListener(
187
+ 'onMessage',
188
+ (event: WebViewMessageEvent & { messagingModuleName?: string }) => {
189
+ if (event.messagingModuleName === messagingModuleName) {
190
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
191
+ const { messagingModuleName: _, ...rest } = event;
192
+ onMessage(rest);
193
+ }
194
+ }
195
+ );
196
+
197
+ return () => {
198
+ onShouldStartLoadWithRequestSubscription.remove();
199
+ onMessageSubscription.remove();
200
+ };
201
+ }, [messagingModuleName, onMessage, onShouldStartLoadWithRequest]);
202
+
203
+ let otherView: ReactElement | undefined;
204
+ if (viewState === 'LOADING') {
205
+ otherView = (renderLoading || defaultRenderLoading)();
206
+ } else if (viewState === 'ERROR') {
207
+ invariant(
208
+ lastErrorEvent != null,
209
+ 'lastErrorEvent expected to be non-null'
210
+ );
211
+ if (lastErrorEvent) {
212
+ otherView = (renderError || defaultRenderError)(
213
+ lastErrorEvent.domain,
214
+ lastErrorEvent.code,
215
+ lastErrorEvent.description
216
+ );
217
+ }
218
+ } else if (viewState !== 'IDLE') {
219
+ console.error(`RNCWebView invalid state encountered: ${viewState}`);
220
+ }
221
+
222
+ const webViewStyles = [styles.container, styles.webView, style];
223
+ const webViewContainerStyle = [styles.container, containerStyle];
224
+
225
+ if (typeof source !== 'number' && source && 'method' in source) {
226
+ if (source.method === 'POST' && source.headers) {
227
+ console.warn(
228
+ 'WebView: `source.headers` is not supported when using POST.'
229
+ );
230
+ } else if (source.method === 'GET' && source.body) {
231
+ console.warn('WebView: `source.body` is not supported when using GET.');
232
+ }
233
+ }
234
+
235
+ const NativeWebView =
236
+ (nativeConfig?.component as typeof RNCWebView | undefined) || RNCWebView;
237
+
238
+ const sourceResolved = resolveAssetSource(source as ImageSourcePropType);
239
+ const newSource =
240
+ typeof sourceResolved === 'object'
241
+ ? Object.entries(sourceResolved as WebViewSourceUri).reduce(
242
+ (prev, [currKey, currValue]) => {
243
+ return {
244
+ ...prev,
245
+ [currKey]:
246
+ currKey === 'headers' &&
247
+ currValue &&
248
+ typeof currValue === 'object'
249
+ ? Object.entries(currValue).map(([key, value]) => {
250
+ return {
251
+ name: key,
252
+ value,
253
+ };
254
+ })
255
+ : currValue,
256
+ };
257
+ },
258
+ {}
259
+ )
260
+ : sourceResolved;
261
+
262
+ const webView = (
263
+ <NativeWebView
264
+ key="webViewKey"
265
+ {...otherProps}
266
+ messagingEnabled={typeof onMessageProp === 'function'}
267
+ messagingModuleName={messagingModuleName}
268
+ hasOnScroll={!!otherProps.onScroll}
269
+ onLoadingError={onLoadingError}
270
+ onLoadingFinish={onLoadingFinish}
271
+ onLoadingProgress={onLoadingProgress}
272
+ onLoadingStart={onLoadingStart}
273
+ onHttpError={onHttpError}
274
+ onRenderProcessGone={onRenderProcessGone}
275
+ onMessage={onMessage}
276
+ onOpenWindow={onOpenWindow}
277
+ hasOnOpenWindowEvent={onOpenWindowProp !== undefined}
278
+ onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
279
+ ref={webViewRef}
280
+ // TODO: find a better way to type this.
281
+ // @ts-expect-error source is old arch
282
+ source={sourceResolved}
283
+ newSource={newSource}
284
+ style={webViewStyles}
285
+ overScrollMode={overScrollMode}
286
+ javaScriptEnabled={javaScriptEnabled}
287
+ thirdPartyCookiesEnabled={thirdPartyCookiesEnabled}
288
+ scalesPageToFit={scalesPageToFit}
289
+ allowsFullscreenVideo={allowsFullscreenVideo}
290
+ allowFileAccess={allowFileAccess}
291
+ saveFormDataDisabled={saveFormDataDisabled}
292
+ cacheEnabled={cacheEnabled}
293
+ androidLayerType={androidLayerType}
294
+ setSupportMultipleWindows={setSupportMultipleWindows}
295
+ setBuiltInZoomControls={setBuiltInZoomControls}
296
+ setDisplayZoomControls={setDisplayZoomControls}
297
+ nestedScrollEnabled={nestedScrollEnabled}
298
+ injectedJavaScriptObject={JSON.stringify(injectedJavaScriptObject)}
299
+ {...nativeConfig?.props}
300
+ />
301
+ );
302
+
303
+ return (
304
+ <View style={webViewContainerStyle}>
305
+ {webView}
306
+ {otherView}
307
+ </View>
308
+ );
309
+ }
310
+ );
311
+
312
+ // native implementation should return "true" only for Android 5+
313
+ const { isFileUploadSupported } = RNCWebViewModule;
314
+
315
+ const WebView = Object.assign(WebViewComponent, { isFileUploadSupported });
316
+
317
+ export default WebView;