@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,299 @@
1
+ import React, {
2
+ forwardRef,
3
+ useCallback,
4
+ useImperativeHandle,
5
+ useRef,
6
+ } from 'react';
7
+ import { Image, View, ImageSourcePropType, HostComponent } from 'react-native';
8
+ import invariant from 'invariant';
9
+
10
+ import RNCWebView, { Commands, NativeProps } from './RNCWebViewNativeComponent';
11
+ import RNCWebViewModule from './NativeRNCWebViewModule';
12
+
13
+ import {
14
+ defaultOriginWhitelist,
15
+ defaultRenderError,
16
+ defaultRenderLoading,
17
+ useWebViewLogic,
18
+ } from './WebViewShared';
19
+ import {
20
+ IOSWebViewProps,
21
+ DecelerationRateConstant,
22
+ WebViewSourceUri,
23
+ } from './WebViewTypes';
24
+
25
+ import styles from './WebView.styles';
26
+
27
+ const { resolveAssetSource } = Image;
28
+ const processDecelerationRate = (
29
+ decelerationRate: DecelerationRateConstant | number | undefined
30
+ ) => {
31
+ let newDecelerationRate = decelerationRate;
32
+ if (newDecelerationRate === 'normal') {
33
+ newDecelerationRate = 0.998;
34
+ } else if (newDecelerationRate === 'fast') {
35
+ newDecelerationRate = 0.99;
36
+ }
37
+ return newDecelerationRate;
38
+ };
39
+
40
+ const useWarnIfChanges = <T extends unknown>(value: T, name: string) => {
41
+ const ref = useRef(value);
42
+ if (ref.current !== value) {
43
+ console.warn(
44
+ `Changes to property ${name} do nothing after the initial render.`
45
+ );
46
+ ref.current = value;
47
+ }
48
+ };
49
+
50
+ const WebViewComponent = forwardRef<{}, IOSWebViewProps>(
51
+ (
52
+ {
53
+ fraudulentWebsiteWarningEnabled = true,
54
+ javaScriptEnabled = true,
55
+ cacheEnabled = true,
56
+ originWhitelist = defaultOriginWhitelist,
57
+ useSharedProcessPool = true,
58
+ textInteractionEnabled = true,
59
+ injectedJavaScript,
60
+ injectedJavaScriptBeforeContentLoaded,
61
+ injectedJavaScriptForMainFrameOnly = true,
62
+ injectedJavaScriptBeforeContentLoadedForMainFrameOnly = true,
63
+ injectedJavaScriptObject,
64
+ startInLoadingState,
65
+ onNavigationStateChange,
66
+ onLoadStart,
67
+ onError,
68
+ onLoad,
69
+ onLoadEnd,
70
+ onLoadProgress,
71
+ onContentProcessDidTerminate: onContentProcessDidTerminateProp,
72
+ onFileDownload,
73
+ onHttpError: onHttpErrorProp,
74
+ onMessage: onMessageProp,
75
+ onOpenWindow: onOpenWindowProp,
76
+ renderLoading,
77
+ renderError,
78
+ style,
79
+ containerStyle,
80
+ source,
81
+ nativeConfig,
82
+ allowsInlineMediaPlayback,
83
+ allowsPictureInPictureMediaPlayback = true,
84
+ allowsAirPlayForMediaPlayback,
85
+ mediaPlaybackRequiresUserAction,
86
+ dataDetectorTypes,
87
+ incognito,
88
+ decelerationRate: decelerationRateProp,
89
+ onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp,
90
+ ...otherProps
91
+ },
92
+ ref
93
+ ) => {
94
+ const webViewRef = useRef<React.ComponentRef<
95
+ HostComponent<NativeProps>
96
+ > | null>(null);
97
+
98
+ const onShouldStartLoadWithRequestCallback = useCallback(
99
+ (shouldStart: boolean, _url: string, lockIdentifier = 0) => {
100
+ RNCWebViewModule.shouldStartLoadWithLockIdentifier(
101
+ shouldStart,
102
+ lockIdentifier
103
+ );
104
+ },
105
+ []
106
+ );
107
+
108
+ const {
109
+ onLoadingStart,
110
+ onShouldStartLoadWithRequest,
111
+ onMessage,
112
+ viewState,
113
+ setViewState,
114
+ lastErrorEvent,
115
+ onHttpError,
116
+ onLoadingError,
117
+ onLoadingFinish,
118
+ onLoadingProgress,
119
+ onOpenWindow,
120
+ onContentProcessDidTerminate,
121
+ } = useWebViewLogic({
122
+ onNavigationStateChange,
123
+ onLoad,
124
+ onError,
125
+ onHttpErrorProp,
126
+ onLoadEnd,
127
+ onLoadProgress,
128
+ onLoadStart,
129
+ onMessageProp,
130
+ onOpenWindowProp,
131
+ startInLoadingState,
132
+ originWhitelist,
133
+ onShouldStartLoadWithRequestProp,
134
+ onShouldStartLoadWithRequestCallback,
135
+ onContentProcessDidTerminateProp,
136
+ });
137
+
138
+ useImperativeHandle(
139
+ ref,
140
+ () => ({
141
+ goForward: () =>
142
+ webViewRef.current && Commands.goForward(webViewRef.current),
143
+ goBack: () => webViewRef.current && Commands.goBack(webViewRef.current),
144
+ reload: () => {
145
+ setViewState('LOADING');
146
+ if (webViewRef.current) {
147
+ Commands.reload(webViewRef.current);
148
+ }
149
+ },
150
+ stopLoading: () =>
151
+ webViewRef.current && Commands.stopLoading(webViewRef.current),
152
+ postMessage: (data: string) =>
153
+ webViewRef.current && Commands.postMessage(webViewRef.current, data),
154
+ injectJavaScript: (data: string) =>
155
+ webViewRef.current &&
156
+ Commands.injectJavaScript(webViewRef.current, data),
157
+ requestFocus: () =>
158
+ webViewRef.current && Commands.requestFocus(webViewRef.current),
159
+ clearCache: (includeDiskFiles: boolean) =>
160
+ webViewRef.current &&
161
+ Commands.clearCache(webViewRef.current, includeDiskFiles),
162
+ }),
163
+ [setViewState, webViewRef]
164
+ );
165
+
166
+ useWarnIfChanges(allowsInlineMediaPlayback, 'allowsInlineMediaPlayback');
167
+ useWarnIfChanges(
168
+ allowsPictureInPictureMediaPlayback,
169
+ 'allowsPictureInPictureMediaPlayback'
170
+ );
171
+ useWarnIfChanges(
172
+ allowsAirPlayForMediaPlayback,
173
+ 'allowsAirPlayForMediaPlayback'
174
+ );
175
+ useWarnIfChanges(incognito, 'incognito');
176
+ useWarnIfChanges(
177
+ mediaPlaybackRequiresUserAction,
178
+ 'mediaPlaybackRequiresUserAction'
179
+ );
180
+ useWarnIfChanges(dataDetectorTypes, 'dataDetectorTypes');
181
+
182
+ let otherView = null;
183
+ if (viewState === 'LOADING') {
184
+ otherView = (renderLoading || defaultRenderLoading)();
185
+ } else if (viewState === 'ERROR') {
186
+ invariant(
187
+ lastErrorEvent != null,
188
+ 'lastErrorEvent expected to be non-null'
189
+ );
190
+ otherView = (renderError || defaultRenderError)(
191
+ lastErrorEvent?.domain,
192
+ lastErrorEvent?.code ?? 0,
193
+ lastErrorEvent?.description ?? ''
194
+ );
195
+ } else if (viewState !== 'IDLE') {
196
+ console.error(`RNCWebView invalid state encountered: ${viewState}`);
197
+ }
198
+
199
+ const webViewStyles = [styles.container, styles.webView, style];
200
+ const webViewContainerStyle = [styles.container, containerStyle];
201
+
202
+ const decelerationRate = processDecelerationRate(decelerationRateProp);
203
+
204
+ const NativeWebView =
205
+ (nativeConfig?.component as typeof RNCWebView | undefined) || RNCWebView;
206
+
207
+ const sourceResolved = resolveAssetSource(source as ImageSourcePropType);
208
+ const newSource =
209
+ typeof sourceResolved === 'object'
210
+ ? Object.entries(sourceResolved as WebViewSourceUri).reduce(
211
+ (prev, [currKey, currValue]) => {
212
+ return {
213
+ ...prev,
214
+ [currKey]:
215
+ currKey === 'headers' &&
216
+ currValue &&
217
+ typeof currValue === 'object'
218
+ ? Object.entries(currValue).map(([key, value]) => {
219
+ return {
220
+ name: key,
221
+ value,
222
+ };
223
+ })
224
+ : currValue,
225
+ };
226
+ },
227
+ {}
228
+ )
229
+ : sourceResolved;
230
+
231
+ const webView = (
232
+ <NativeWebView
233
+ key="webViewKey"
234
+ {...otherProps}
235
+ fraudulentWebsiteWarningEnabled={fraudulentWebsiteWarningEnabled}
236
+ javaScriptEnabled={javaScriptEnabled}
237
+ cacheEnabled={cacheEnabled}
238
+ useSharedProcessPool={useSharedProcessPool}
239
+ textInteractionEnabled={textInteractionEnabled}
240
+ decelerationRate={decelerationRate}
241
+ messagingEnabled={typeof onMessageProp === 'function'}
242
+ messagingModuleName="" // android ONLY
243
+ onLoadingError={onLoadingError}
244
+ onLoadingFinish={onLoadingFinish}
245
+ onLoadingProgress={onLoadingProgress}
246
+ onFileDownload={onFileDownload}
247
+ onLoadingStart={onLoadingStart}
248
+ onHttpError={onHttpError}
249
+ onMessage={onMessage}
250
+ onOpenWindow={onOpenWindowProp && onOpenWindow}
251
+ hasOnOpenWindowEvent={onOpenWindowProp !== undefined}
252
+ onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
253
+ onContentProcessDidTerminate={onContentProcessDidTerminate}
254
+ injectedJavaScript={injectedJavaScript}
255
+ injectedJavaScriptBeforeContentLoaded={
256
+ injectedJavaScriptBeforeContentLoaded
257
+ }
258
+ injectedJavaScriptForMainFrameOnly={injectedJavaScriptForMainFrameOnly}
259
+ injectedJavaScriptBeforeContentLoadedForMainFrameOnly={
260
+ injectedJavaScriptBeforeContentLoadedForMainFrameOnly
261
+ }
262
+ injectedJavaScriptObject={JSON.stringify(injectedJavaScriptObject)}
263
+ dataDetectorTypes={
264
+ !dataDetectorTypes || Array.isArray(dataDetectorTypes)
265
+ ? dataDetectorTypes
266
+ : [dataDetectorTypes]
267
+ }
268
+ allowsAirPlayForMediaPlayback={allowsAirPlayForMediaPlayback}
269
+ allowsInlineMediaPlayback={allowsInlineMediaPlayback}
270
+ allowsPictureInPictureMediaPlayback={
271
+ allowsPictureInPictureMediaPlayback
272
+ }
273
+ incognito={incognito}
274
+ mediaPlaybackRequiresUserAction={mediaPlaybackRequiresUserAction}
275
+ newSource={newSource}
276
+ style={webViewStyles}
277
+ hasOnFileDownload={!!onFileDownload}
278
+ ref={webViewRef}
279
+ // @ts-expect-error old arch only
280
+ source={sourceResolved}
281
+ {...nativeConfig?.props}
282
+ />
283
+ );
284
+
285
+ return (
286
+ <View style={webViewContainerStyle}>
287
+ {webView}
288
+ {otherView}
289
+ </View>
290
+ );
291
+ }
292
+ );
293
+
294
+ // no native implementation for iOS, depends only on permissions
295
+ const isFileUploadSupported: () => Promise<boolean> = async () => true;
296
+
297
+ const WebView = Object.assign(WebViewComponent, { isFileUploadSupported });
298
+
299
+ export default WebView;
@@ -0,0 +1,245 @@
1
+ import React, {
2
+ forwardRef,
3
+ useCallback,
4
+ useImperativeHandle,
5
+ useRef,
6
+ } from 'react';
7
+ import { Image, View, ImageSourcePropType, HostComponent } from 'react-native';
8
+ import invariant from 'invariant';
9
+ import RNCWebView, { Commands, NativeProps } from './RNCWebViewNativeComponent';
10
+ import RNCWebViewModule from './NativeRNCWebViewModule';
11
+ import {
12
+ defaultOriginWhitelist,
13
+ defaultRenderError,
14
+ defaultRenderLoading,
15
+ useWebViewLogic,
16
+ } from './WebViewShared';
17
+ import { MacOSWebViewProps, WebViewSourceUri } from './WebViewTypes';
18
+
19
+ import styles from './WebView.styles';
20
+
21
+ const { resolveAssetSource } = Image;
22
+
23
+ const useWarnIfChanges = <T extends unknown>(value: T, name: string) => {
24
+ const ref = useRef(value);
25
+ if (ref.current !== value) {
26
+ console.warn(
27
+ `Changes to property ${name} do nothing after the initial render.`
28
+ );
29
+ ref.current = value;
30
+ }
31
+ };
32
+
33
+ const WebViewComponent = forwardRef<{}, MacOSWebViewProps>(
34
+ (
35
+ {
36
+ javaScriptEnabled = true,
37
+ cacheEnabled = true,
38
+ originWhitelist = defaultOriginWhitelist,
39
+ useSharedProcessPool = true,
40
+ injectedJavaScript,
41
+ injectedJavaScriptBeforeContentLoaded,
42
+ startInLoadingState,
43
+ onNavigationStateChange,
44
+ onLoadStart,
45
+ onError,
46
+ onLoad,
47
+ onLoadEnd,
48
+ onLoadProgress,
49
+ onHttpError: onHttpErrorProp,
50
+ onMessage: onMessageProp,
51
+ renderLoading,
52
+ renderError,
53
+ style,
54
+ containerStyle,
55
+ source,
56
+ nativeConfig,
57
+ allowsInlineMediaPlayback,
58
+ allowsPictureInPictureMediaPlayback = true,
59
+ allowsAirPlayForMediaPlayback,
60
+ mediaPlaybackRequiresUserAction,
61
+ incognito,
62
+ onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp,
63
+ ...otherProps
64
+ },
65
+ ref
66
+ ) => {
67
+ const webViewRef = useRef<React.ComponentRef<
68
+ HostComponent<NativeProps>
69
+ > | null>(null);
70
+
71
+ const onShouldStartLoadWithRequestCallback = useCallback(
72
+ (shouldStart: boolean, _url: string, lockIdentifier = 0) => {
73
+ RNCWebViewModule.shouldStartLoadWithLockIdentifier(
74
+ !!shouldStart,
75
+ lockIdentifier
76
+ );
77
+ },
78
+ []
79
+ );
80
+
81
+ const {
82
+ onLoadingStart,
83
+ onShouldStartLoadWithRequest,
84
+ onMessage,
85
+ viewState,
86
+ setViewState,
87
+ lastErrorEvent,
88
+ onHttpError,
89
+ onLoadingError,
90
+ onLoadingFinish,
91
+ onLoadingProgress,
92
+ onContentProcessDidTerminate,
93
+ } = useWebViewLogic({
94
+ onNavigationStateChange,
95
+ onLoad,
96
+ onError,
97
+ onHttpErrorProp,
98
+ onLoadEnd,
99
+ onLoadProgress,
100
+ onLoadStart,
101
+ onMessageProp,
102
+ startInLoadingState,
103
+ originWhitelist,
104
+ onShouldStartLoadWithRequestProp,
105
+ onShouldStartLoadWithRequestCallback,
106
+ });
107
+
108
+ useImperativeHandle(
109
+ ref,
110
+ () => ({
111
+ goForward: () =>
112
+ webViewRef.current && Commands.goForward(webViewRef.current),
113
+ goBack: () => webViewRef.current && Commands.goBack(webViewRef.current),
114
+ reload: () => {
115
+ setViewState('LOADING');
116
+ if (webViewRef.current) {
117
+ Commands.reload(webViewRef.current);
118
+ }
119
+ },
120
+ stopLoading: () =>
121
+ webViewRef.current && Commands.stopLoading(webViewRef.current),
122
+ postMessage: (data: string) =>
123
+ webViewRef.current && Commands.postMessage(webViewRef.current, data),
124
+ injectJavaScript: (data: string) =>
125
+ webViewRef.current &&
126
+ Commands.injectJavaScript(webViewRef.current, data),
127
+ requestFocus: () =>
128
+ webViewRef.current && Commands.requestFocus(webViewRef.current),
129
+ }),
130
+ [setViewState, webViewRef]
131
+ );
132
+
133
+ useWarnIfChanges(allowsInlineMediaPlayback, 'allowsInlineMediaPlayback');
134
+ useWarnIfChanges(
135
+ allowsPictureInPictureMediaPlayback,
136
+ 'allowsPictureInPictureMediaPlayback'
137
+ );
138
+ useWarnIfChanges(
139
+ allowsAirPlayForMediaPlayback,
140
+ 'allowsAirPlayForMediaPlayback'
141
+ );
142
+ useWarnIfChanges(incognito, 'incognito');
143
+ useWarnIfChanges(
144
+ mediaPlaybackRequiresUserAction,
145
+ 'mediaPlaybackRequiresUserAction'
146
+ );
147
+
148
+ let otherView = null;
149
+ if (viewState === 'LOADING') {
150
+ otherView = (renderLoading || defaultRenderLoading)();
151
+ } else if (viewState === 'ERROR') {
152
+ invariant(
153
+ lastErrorEvent != null,
154
+ 'lastErrorEvent expected to be non-null'
155
+ );
156
+ otherView = (renderError || defaultRenderError)(
157
+ lastErrorEvent?.domain,
158
+ lastErrorEvent?.code || 0,
159
+ lastErrorEvent?.description ?? ''
160
+ );
161
+ } else if (viewState !== 'IDLE') {
162
+ console.error(`RNCWebView invalid state encountered: ${viewState}`);
163
+ }
164
+
165
+ const webViewStyles = [styles.container, styles.webView, style];
166
+ const webViewContainerStyle = [styles.container, containerStyle];
167
+
168
+ const NativeWebView =
169
+ (nativeConfig?.component as typeof RNCWebView | undefined) || RNCWebView;
170
+
171
+ const sourceResolved = resolveAssetSource(source as ImageSourcePropType);
172
+ const newSource =
173
+ typeof sourceResolved === 'object'
174
+ ? Object.entries(sourceResolved as WebViewSourceUri).reduce(
175
+ (prev, [currKey, currValue]) => {
176
+ return {
177
+ ...prev,
178
+ [currKey]:
179
+ currKey === 'headers' &&
180
+ currValue &&
181
+ typeof currValue === 'object'
182
+ ? Object.entries(currValue).map(([key, value]) => {
183
+ return {
184
+ name: key,
185
+ value,
186
+ };
187
+ })
188
+ : currValue,
189
+ };
190
+ },
191
+ {}
192
+ )
193
+ : sourceResolved;
194
+
195
+ const webView = (
196
+ <NativeWebView
197
+ key="webViewKey"
198
+ {...otherProps}
199
+ javaScriptEnabled={javaScriptEnabled}
200
+ cacheEnabled={cacheEnabled}
201
+ useSharedProcessPool={useSharedProcessPool}
202
+ messagingEnabled={typeof onMessageProp === 'function'}
203
+ newSource={newSource}
204
+ onLoadingError={onLoadingError}
205
+ onLoadingFinish={onLoadingFinish}
206
+ onLoadingProgress={onLoadingProgress}
207
+ onLoadingStart={onLoadingStart}
208
+ onHttpError={onHttpError}
209
+ onMessage={onMessage}
210
+ onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
211
+ onContentProcessDidTerminate={onContentProcessDidTerminate}
212
+ injectedJavaScript={injectedJavaScript}
213
+ injectedJavaScriptBeforeContentLoaded={
214
+ injectedJavaScriptBeforeContentLoaded
215
+ }
216
+ allowsAirPlayForMediaPlayback={allowsAirPlayForMediaPlayback}
217
+ allowsInlineMediaPlayback={allowsInlineMediaPlayback}
218
+ allowsPictureInPictureMediaPlayback={
219
+ allowsPictureInPictureMediaPlayback
220
+ }
221
+ incognito={incognito}
222
+ mediaPlaybackRequiresUserAction={mediaPlaybackRequiresUserAction}
223
+ ref={webViewRef}
224
+ // @ts-expect-error old arch only
225
+ source={sourceResolved}
226
+ style={webViewStyles}
227
+ {...nativeConfig?.props}
228
+ />
229
+ );
230
+
231
+ return (
232
+ <View style={webViewContainerStyle}>
233
+ {webView}
234
+ {otherView}
235
+ </View>
236
+ );
237
+ }
238
+ );
239
+
240
+ // no native implementation for macOS, depends only on permissions
241
+ const isFileUploadSupported: () => Promise<boolean> = async () => true;
242
+
243
+ const WebView = Object.assign(WebViewComponent, { isFileUploadSupported });
244
+
245
+ export default WebView;
@@ -0,0 +1,41 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ const styles = StyleSheet.create({
4
+ container: {
5
+ flex: 1,
6
+ overflow: 'hidden',
7
+ },
8
+ loadingOrErrorView: {
9
+ position: 'absolute',
10
+ flex: 1,
11
+ justifyContent: 'center',
12
+ alignItems: 'center',
13
+ height: '100%',
14
+ width: '100%',
15
+ backgroundColor: 'white',
16
+ },
17
+ loadingProgressBar: {
18
+ height: 20,
19
+ },
20
+ errorText: {
21
+ fontSize: 14,
22
+ textAlign: 'center',
23
+ marginBottom: 2,
24
+ },
25
+ errorTextTitle: {
26
+ fontSize: 15,
27
+ fontWeight: '500',
28
+ marginBottom: 10,
29
+ },
30
+ webView: {
31
+ backgroundColor: '#ffffff',
32
+ },
33
+ flexStart: {
34
+ alignSelf: 'flex-start',
35
+ },
36
+ colorRed: {
37
+ color: 'red',
38
+ },
39
+ });
40
+
41
+ export default styles;
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { Text, View } from 'react-native';
3
+ import {
4
+ IOSWebViewProps,
5
+ AndroidWebViewProps,
6
+ WindowsWebViewProps,
7
+ } from './WebViewTypes';
8
+ import styles from './WebView.styles';
9
+
10
+ export type WebViewProps = IOSWebViewProps &
11
+ AndroidWebViewProps &
12
+ WindowsWebViewProps;
13
+
14
+ // This "dummy" WebView is to render something for unsupported platforms,
15
+ // like for example Expo SDK "web" platform.
16
+ const WebView: React.FunctionComponent<WebViewProps> = () => (
17
+ <View style={styles.flexStart}>
18
+ <Text style={styles.colorRed}>
19
+ React Native WebView does not support this platform.
20
+ </Text>
21
+ </View>
22
+ );
23
+
24
+ export { WebView };
25
+ export default WebView;