@exodus/react-native-webview 13.16.0-exodus.2 → 13.16.0-exodus.4
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.
- package/android/build.gradle +11 -7
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java +15 -18
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java +0 -21
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt +5 -50
- package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java +0 -58
- package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewManager.java +0 -40
- package/apple/RNCWebView.mm +0 -8
- package/apple/RNCWebViewDecisionManager.m +17 -0
- package/apple/RNCWebViewImpl.h +0 -10
- package/apple/RNCWebViewImpl.m +24 -72
- package/apple/RNCWebViewManager.mm +0 -8
- package/lib/RNCWebViewNativeComponent.d.ts +0 -26
- package/lib/RNCWebViewNativeComponent.js +1 -1
- package/lib/WebView.android.js +1 -1
- package/lib/WebView.d.ts +2 -2
- package/lib/WebView.ios.js +1 -1
- package/lib/WebViewShared.d.ts +5 -5
- package/lib/WebViewShared.js +1 -1
- package/lib/WebViewTypes.d.ts +5 -358
- package/lib/WebViewTypes.js +1 -1
- package/package.json +4 -11
- package/react-native-webview.podspec +1 -1
- package/src/RNCWebViewNativeComponent.ts +0 -37
- package/src/WebView.android.tsx +293 -284
- package/src/WebView.ios.tsx +223 -256
- package/src/WebView.tsx +2 -8
- package/src/WebViewShared.tsx +2 -11
- package/src/WebViewTypes.ts +2 -396
- package/src/__tests__/WebViewShared-test.js +40 -62
- package/src/__tests__/__snapshots__/WebViewShared-test.js.snap +0 -1
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopHttpErrorEvent.kt +0 -25
- package/lib/WebView.windows.d.ts +0 -17
- package/lib/WebView.windows.js +0 -1
- package/lib/WebViewNativeComponent.windows.d.ts +0 -3
- package/lib/WebViewNativeComponent.windows.js +0 -1
- package/src/WebView.macos.tsx +0 -252
- package/src/WebView.windows.tsx +0 -217
- package/src/WebViewNativeComponent.macos.ts +0 -7
- package/src/WebViewNativeComponent.windows.ts +0 -8
package/src/WebView.android.tsx
CHANGED
|
@@ -4,6 +4,7 @@ import React, {
|
|
|
4
4
|
useCallback,
|
|
5
5
|
useEffect,
|
|
6
6
|
useImperativeHandle,
|
|
7
|
+
useMemo,
|
|
7
8
|
useRef,
|
|
8
9
|
useState,
|
|
9
10
|
} from 'react';
|
|
@@ -31,6 +32,8 @@ import {
|
|
|
31
32
|
defaultRenderLoading,
|
|
32
33
|
useWebViewLogic,
|
|
33
34
|
versionPasses,
|
|
35
|
+
passesWhitelist,
|
|
36
|
+
compileWhitelist,
|
|
34
37
|
} from './WebViewShared';
|
|
35
38
|
import {
|
|
36
39
|
AndroidWebViewProps,
|
|
@@ -39,6 +42,7 @@ import {
|
|
|
39
42
|
type ShouldStartLoadRequestEvent,
|
|
40
43
|
} from './WebViewTypes';
|
|
41
44
|
|
|
45
|
+
import validateProps from './validation';
|
|
42
46
|
import styles from './WebView.styles';
|
|
43
47
|
|
|
44
48
|
const { resolveAssetSource } = Image;
|
|
@@ -92,315 +96,320 @@ const securityMixedContentMode = 'never' as const;
|
|
|
92
96
|
*/
|
|
93
97
|
let uniqueRef = 0;
|
|
94
98
|
|
|
95
|
-
const WebViewComponent = forwardRef<{}, AndroidWebViewProps>(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
99
|
+
const WebViewComponent = forwardRef<{}, AndroidWebViewProps>((props, ref) => {
|
|
100
|
+
// Exodus: Validate props at runtime
|
|
101
|
+
validateProps(props);
|
|
102
|
+
|
|
103
|
+
const {
|
|
104
|
+
overScrollMode = 'always',
|
|
105
|
+
javaScriptEnabled = true,
|
|
106
|
+
thirdPartyCookiesEnabled = true,
|
|
107
|
+
scalesPageToFit = true,
|
|
108
|
+
allowsFullscreenVideo = false,
|
|
109
|
+
saveFormDataDisabled = false,
|
|
110
|
+
cacheEnabled = true,
|
|
111
|
+
androidLayerType = 'none',
|
|
112
|
+
originWhitelist = defaultOriginWhitelist,
|
|
113
|
+
deeplinkWhitelist = defaultDeeplinkWhitelist,
|
|
114
|
+
setBuiltInZoomControls = true,
|
|
115
|
+
setDisplayZoomControls = false,
|
|
116
|
+
nestedScrollEnabled = false,
|
|
117
|
+
startInLoadingState,
|
|
118
|
+
onNavigationStateChange,
|
|
119
|
+
onLoadStart,
|
|
120
|
+
onError,
|
|
121
|
+
onLoad,
|
|
122
|
+
onLoadEnd,
|
|
123
|
+
onLoadSubResourceError,
|
|
124
|
+
onLoadProgress,
|
|
125
|
+
onRenderProcessGone: onRenderProcessGoneProp,
|
|
126
|
+
onMessage: onMessageProp,
|
|
127
|
+
onOpenWindow: onOpenWindowProp,
|
|
128
|
+
renderLoading,
|
|
129
|
+
renderError,
|
|
130
|
+
style,
|
|
131
|
+
containerStyle,
|
|
132
|
+
source,
|
|
133
|
+
onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp,
|
|
134
|
+
injectedJavaScriptObject,
|
|
135
|
+
validateMeta,
|
|
136
|
+
validateData,
|
|
137
|
+
minimumChromeVersion,
|
|
138
|
+
unsupportedVersionComponent: UnsupportedVersionComponent,
|
|
139
|
+
...otherProps
|
|
140
|
+
} = props;
|
|
141
|
+
|
|
142
|
+
const messagingModuleName = useRef<string>(
|
|
143
|
+
`WebViewMessageHandler${(uniqueRef += 1)}`
|
|
144
|
+
).current;
|
|
145
|
+
const webViewRef = useRef<React.ComponentRef<
|
|
146
|
+
HostComponent<NativeProps>
|
|
147
|
+
> | null>(null);
|
|
148
|
+
|
|
149
|
+
const [userAgent, setUserAgent] = useState<string>();
|
|
150
|
+
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
getUserAgent().then(setUserAgent);
|
|
153
|
+
}, []);
|
|
154
|
+
|
|
155
|
+
const onShouldStartLoadWithRequestCallback = useCallback(
|
|
156
|
+
(shouldStart: boolean, url: string, lockIdentifier?: number) => {
|
|
157
|
+
if (lockIdentifier) {
|
|
158
|
+
RNCWebViewModule.shouldStartLoadWithLockIdentifier(
|
|
159
|
+
shouldStart,
|
|
160
|
+
lockIdentifier
|
|
161
|
+
);
|
|
162
|
+
} else if (shouldStart && webViewRef.current) {
|
|
163
|
+
Commands.loadUrl(webViewRef.current, url);
|
|
164
|
+
}
|
|
137
165
|
},
|
|
138
|
-
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
166
|
+
[]
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
const {
|
|
170
|
+
onLoadingStart,
|
|
171
|
+
onShouldStartLoadWithRequest,
|
|
172
|
+
onMessage,
|
|
173
|
+
viewState,
|
|
174
|
+
setViewState,
|
|
175
|
+
lastErrorEvent,
|
|
176
|
+
onLoadingError,
|
|
177
|
+
onLoadingSubResourceError,
|
|
178
|
+
onLoadingFinish,
|
|
179
|
+
onLoadingProgress,
|
|
180
|
+
onOpenWindow,
|
|
181
|
+
onRenderProcessGone,
|
|
182
|
+
} = useWebViewLogic({
|
|
183
|
+
onNavigationStateChange,
|
|
184
|
+
onLoad,
|
|
185
|
+
onError,
|
|
186
|
+
onLoadSubResourceError,
|
|
187
|
+
onLoadEnd,
|
|
188
|
+
onLoadProgress,
|
|
189
|
+
onLoadStart,
|
|
190
|
+
onRenderProcessGoneProp,
|
|
191
|
+
onMessageProp,
|
|
192
|
+
onOpenWindowProp,
|
|
193
|
+
startInLoadingState,
|
|
194
|
+
originWhitelist,
|
|
195
|
+
deeplinkWhitelist,
|
|
196
|
+
onShouldStartLoadWithRequestProp,
|
|
197
|
+
onShouldStartLoadWithRequestCallback,
|
|
198
|
+
validateMeta,
|
|
199
|
+
validateData,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
useImperativeHandle(
|
|
203
|
+
ref,
|
|
204
|
+
() => ({
|
|
205
|
+
goForward: () =>
|
|
206
|
+
webViewRef.current && Commands.goForward(webViewRef.current),
|
|
207
|
+
goBack: () => webViewRef.current && Commands.goBack(webViewRef.current),
|
|
208
|
+
reload: () => {
|
|
209
|
+
setViewState('LOADING');
|
|
210
|
+
if (webViewRef.current) {
|
|
211
|
+
Commands.reload(webViewRef.current);
|
|
162
212
|
}
|
|
163
213
|
},
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
onLoadProgress,
|
|
189
|
-
onLoadStart,
|
|
190
|
-
onRenderProcessGoneProp,
|
|
191
|
-
onMessageProp,
|
|
192
|
-
onOpenWindowProp,
|
|
193
|
-
startInLoadingState,
|
|
194
|
-
originWhitelist,
|
|
195
|
-
deeplinkWhitelist,
|
|
196
|
-
onShouldStartLoadWithRequestProp,
|
|
197
|
-
onShouldStartLoadWithRequestCallback,
|
|
198
|
-
validateMeta,
|
|
199
|
-
validateData,
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
useImperativeHandle(
|
|
203
|
-
ref,
|
|
204
|
-
() => ({
|
|
205
|
-
goForward: () =>
|
|
206
|
-
webViewRef.current && Commands.goForward(webViewRef.current),
|
|
207
|
-
goBack: () => webViewRef.current && Commands.goBack(webViewRef.current),
|
|
208
|
-
reload: () => {
|
|
209
|
-
setViewState('LOADING');
|
|
210
|
-
if (webViewRef.current) {
|
|
211
|
-
Commands.reload(webViewRef.current);
|
|
214
|
+
stopLoading: () =>
|
|
215
|
+
webViewRef.current && Commands.stopLoading(webViewRef.current),
|
|
216
|
+
postMessage: (data: string) =>
|
|
217
|
+
webViewRef.current && Commands.postMessage(webViewRef.current, data),
|
|
218
|
+
requestFocus: () =>
|
|
219
|
+
webViewRef.current && Commands.requestFocus(webViewRef.current),
|
|
220
|
+
clearFormData: () =>
|
|
221
|
+
webViewRef.current && Commands.clearFormData(webViewRef.current),
|
|
222
|
+
clearCache: (includeDiskFiles: boolean) =>
|
|
223
|
+
webViewRef.current &&
|
|
224
|
+
Commands.clearCache(webViewRef.current, includeDiskFiles),
|
|
225
|
+
clearHistory: () =>
|
|
226
|
+
webViewRef.current && Commands.clearHistory(webViewRef.current),
|
|
227
|
+
}),
|
|
228
|
+
[setViewState, webViewRef]
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
useEffect(() => {
|
|
232
|
+
const onShouldStartLoadWithRequestSubscription =
|
|
233
|
+
directEventEmitter.addListener(
|
|
234
|
+
'onShouldStartLoadWithRequest',
|
|
235
|
+
(
|
|
236
|
+
event: ShouldStartLoadRequestEvent & {
|
|
237
|
+
messagingModuleName?: string;
|
|
212
238
|
}
|
|
213
|
-
|
|
214
|
-
stopLoading: () =>
|
|
215
|
-
webViewRef.current && Commands.stopLoading(webViewRef.current),
|
|
216
|
-
postMessage: (data: string) =>
|
|
217
|
-
webViewRef.current && Commands.postMessage(webViewRef.current, data),
|
|
218
|
-
injectJavaScript: (data: string) =>
|
|
219
|
-
webViewRef.current &&
|
|
220
|
-
Commands.injectJavaScript(webViewRef.current, data),
|
|
221
|
-
requestFocus: () =>
|
|
222
|
-
webViewRef.current && Commands.requestFocus(webViewRef.current),
|
|
223
|
-
clearFormData: () =>
|
|
224
|
-
webViewRef.current && Commands.clearFormData(webViewRef.current),
|
|
225
|
-
clearCache: (includeDiskFiles: boolean) =>
|
|
226
|
-
webViewRef.current &&
|
|
227
|
-
Commands.clearCache(webViewRef.current, includeDiskFiles),
|
|
228
|
-
clearHistory: () =>
|
|
229
|
-
webViewRef.current && Commands.clearHistory(webViewRef.current),
|
|
230
|
-
}),
|
|
231
|
-
[setViewState, webViewRef]
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
useEffect(() => {
|
|
235
|
-
const onShouldStartLoadWithRequestSubscription =
|
|
236
|
-
directEventEmitter.addListener(
|
|
237
|
-
'onShouldStartLoadWithRequest',
|
|
238
|
-
(
|
|
239
|
-
event: ShouldStartLoadRequestEvent & {
|
|
240
|
-
messagingModuleName?: string;
|
|
241
|
-
}
|
|
242
|
-
) => {
|
|
243
|
-
if (event.messagingModuleName === messagingModuleName) {
|
|
244
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
245
|
-
const { messagingModuleName: _, ...rest } = event;
|
|
246
|
-
onShouldStartLoadWithRequest(rest);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
);
|
|
250
|
-
|
|
251
|
-
const onMessageSubscription = directEventEmitter.addListener(
|
|
252
|
-
'onMessage',
|
|
253
|
-
(event: WebViewMessageEvent & { messagingModuleName?: string }) => {
|
|
239
|
+
) => {
|
|
254
240
|
if (event.messagingModuleName === messagingModuleName) {
|
|
255
241
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
256
242
|
const { messagingModuleName: _, ...rest } = event;
|
|
257
|
-
|
|
243
|
+
onShouldStartLoadWithRequest(rest);
|
|
258
244
|
}
|
|
259
245
|
}
|
|
260
246
|
);
|
|
261
247
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
248
|
+
const onMessageSubscription = directEventEmitter.addListener(
|
|
249
|
+
'onMessage',
|
|
250
|
+
(event: WebViewMessageEvent & { messagingModuleName?: string }) => {
|
|
251
|
+
if (event.messagingModuleName === messagingModuleName) {
|
|
252
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
253
|
+
const { messagingModuleName: _, ...rest } = event;
|
|
254
|
+
onMessage(rest);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
);
|
|
267
258
|
|
|
268
|
-
|
|
269
|
-
|
|
259
|
+
return () => {
|
|
260
|
+
onShouldStartLoadWithRequestSubscription.remove();
|
|
261
|
+
onMessageSubscription.remove();
|
|
262
|
+
};
|
|
263
|
+
}, [messagingModuleName, onMessage, onShouldStartLoadWithRequest]);
|
|
270
264
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
)
|
|
265
|
+
// Exodus: Compile origin whitelist for initial-load guard
|
|
266
|
+
const compiledWhitelist = useMemo(
|
|
267
|
+
() => compileWhitelist(originWhitelist),
|
|
268
|
+
[originWhitelist]
|
|
269
|
+
);
|
|
274
270
|
|
|
271
|
+
// Exodus: Guard initial source against origin whitelist (H-02)
|
|
272
|
+
const safeSource = useMemo(() => {
|
|
275
273
|
if (
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
274
|
+
source &&
|
|
275
|
+
typeof source === 'object' &&
|
|
276
|
+
'uri' in source &&
|
|
277
|
+
typeof source.uri === 'string'
|
|
280
278
|
) {
|
|
281
|
-
if (
|
|
282
|
-
|
|
279
|
+
if (!passesWhitelist(compiledWhitelist, source.uri)) {
|
|
280
|
+
console.warn(
|
|
281
|
+
`WebView: source.uri "${source.uri}" does not pass the origin whitelist. Loading about:blank instead.`
|
|
282
|
+
);
|
|
283
|
+
return { uri: 'about:blank' };
|
|
283
284
|
}
|
|
284
|
-
return (
|
|
285
|
-
<View style={{ alignSelf: 'flex-start' }}>
|
|
286
|
-
<Text style={{ color: 'red' }}>
|
|
287
|
-
Chrome version is outdated and insecure. Update it to continue.
|
|
288
|
-
</Text>
|
|
289
|
-
</View>
|
|
290
|
-
);
|
|
291
285
|
}
|
|
286
|
+
return source;
|
|
287
|
+
}, [source, compiledWhitelist]);
|
|
288
|
+
|
|
289
|
+
// Stop the rendering until userAgent is known
|
|
290
|
+
if (!userAgent) return null;
|
|
291
|
+
|
|
292
|
+
const chromeVersion = userAgent.match(/chrome\/((?:[0-9]+\.)+[0-9]+)/i)?.[1];
|
|
293
|
+
|
|
294
|
+
if (
|
|
295
|
+
!(
|
|
296
|
+
versionPasses(chromeVersion, minimumChromeVersion) &&
|
|
297
|
+
versionPasses(chromeVersion, hardMinimumChromeVersion)
|
|
298
|
+
)
|
|
299
|
+
) {
|
|
300
|
+
if (UnsupportedVersionComponent) {
|
|
301
|
+
return <UnsupportedVersionComponent />;
|
|
302
|
+
}
|
|
303
|
+
return (
|
|
304
|
+
<View style={{ alignSelf: 'flex-start' }}>
|
|
305
|
+
<Text style={{ color: 'red' }}>
|
|
306
|
+
Chrome version is outdated and insecure. Update it to continue.
|
|
307
|
+
</Text>
|
|
308
|
+
</View>
|
|
309
|
+
);
|
|
310
|
+
}
|
|
292
311
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
312
|
+
let otherView: ReactElement | undefined;
|
|
313
|
+
if (viewState === 'LOADING') {
|
|
314
|
+
otherView = (renderLoading || defaultRenderLoading)();
|
|
315
|
+
} else if (viewState === 'ERROR') {
|
|
316
|
+
invariant(lastErrorEvent != null, 'lastErrorEvent expected to be non-null');
|
|
317
|
+
if (lastErrorEvent) {
|
|
318
|
+
otherView = (renderError || defaultRenderError)(
|
|
319
|
+
lastErrorEvent.domain,
|
|
320
|
+
lastErrorEvent.code,
|
|
321
|
+
lastErrorEvent.description
|
|
300
322
|
);
|
|
301
|
-
if (lastErrorEvent) {
|
|
302
|
-
otherView = (renderError || defaultRenderError)(
|
|
303
|
-
lastErrorEvent.domain,
|
|
304
|
-
lastErrorEvent.code,
|
|
305
|
-
lastErrorEvent.description
|
|
306
|
-
);
|
|
307
|
-
}
|
|
308
|
-
} else if (viewState !== 'IDLE') {
|
|
309
|
-
console.error(`RNCWebView invalid state encountered: ${viewState}`);
|
|
310
323
|
}
|
|
324
|
+
} else if (viewState !== 'IDLE') {
|
|
325
|
+
console.error(`RNCWebView invalid state encountered: ${viewState}`);
|
|
326
|
+
}
|
|
311
327
|
|
|
312
|
-
|
|
313
|
-
|
|
328
|
+
const webViewStyles = [styles.container, styles.webView, style];
|
|
329
|
+
const webViewContainerStyle = [styles.container, containerStyle];
|
|
314
330
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
331
|
+
if (typeof safeSource !== 'number' && safeSource && 'method' in safeSource) {
|
|
332
|
+
if (safeSource.method === 'POST' && safeSource.headers) {
|
|
333
|
+
console.warn(
|
|
334
|
+
'WebView: `source.headers` is not supported when using POST.'
|
|
335
|
+
);
|
|
336
|
+
} else if (safeSource.method === 'GET' && safeSource.body) {
|
|
337
|
+
console.warn('WebView: `source.body` is not supported when using GET.');
|
|
323
338
|
}
|
|
324
|
-
|
|
325
|
-
const NativeWebView =
|
|
326
|
-
(nativeConfig?.component as typeof RNCWebView | undefined) || RNCWebView;
|
|
327
|
-
|
|
328
|
-
const sourceResolved = resolveAssetSource(source as ImageSourcePropType);
|
|
329
|
-
const newSource =
|
|
330
|
-
typeof sourceResolved === 'object'
|
|
331
|
-
? Object.entries(sourceResolved as WebViewSourceUri).reduce(
|
|
332
|
-
(prev, [currKey, currValue]) => {
|
|
333
|
-
return {
|
|
334
|
-
...prev,
|
|
335
|
-
[currKey]:
|
|
336
|
-
currKey === 'headers' &&
|
|
337
|
-
currValue &&
|
|
338
|
-
typeof currValue === 'object'
|
|
339
|
-
? Object.entries(currValue).map(([key, value]) => {
|
|
340
|
-
return {
|
|
341
|
-
name: key,
|
|
342
|
-
value,
|
|
343
|
-
};
|
|
344
|
-
})
|
|
345
|
-
: currValue,
|
|
346
|
-
};
|
|
347
|
-
},
|
|
348
|
-
{}
|
|
349
|
-
)
|
|
350
|
-
: sourceResolved;
|
|
351
|
-
|
|
352
|
-
const webView = (
|
|
353
|
-
<NativeWebView
|
|
354
|
-
key="webViewKey"
|
|
355
|
-
{...otherProps}
|
|
356
|
-
messagingEnabled={typeof onMessageProp === 'function'}
|
|
357
|
-
messagingModuleName={messagingModuleName}
|
|
358
|
-
hasOnScroll={!!otherProps.onScroll}
|
|
359
|
-
onLoadingError={onLoadingError}
|
|
360
|
-
onLoadingSubResourceError={onLoadingSubResourceError}
|
|
361
|
-
onLoadingFinish={onLoadingFinish}
|
|
362
|
-
onLoadingProgress={onLoadingProgress}
|
|
363
|
-
onLoadingStart={onLoadingStart}
|
|
364
|
-
onHttpError={onHttpError}
|
|
365
|
-
onRenderProcessGone={onRenderProcessGone}
|
|
366
|
-
onMessage={onMessage}
|
|
367
|
-
onOpenWindow={onOpenWindow}
|
|
368
|
-
hasOnOpenWindowEvent={onOpenWindowProp !== undefined}
|
|
369
|
-
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
|
370
|
-
ref={webViewRef}
|
|
371
|
-
// TODO: find a better way to type this.
|
|
372
|
-
// @ts-expect-error source is old arch
|
|
373
|
-
source={sourceResolved}
|
|
374
|
-
newSource={newSource}
|
|
375
|
-
style={webViewStyles}
|
|
376
|
-
overScrollMode={overScrollMode}
|
|
377
|
-
javaScriptEnabled={javaScriptEnabled}
|
|
378
|
-
thirdPartyCookiesEnabled={thirdPartyCookiesEnabled}
|
|
379
|
-
scalesPageToFit={scalesPageToFit}
|
|
380
|
-
allowsFullscreenVideo={allowsFullscreenVideo}
|
|
381
|
-
allowFileAccess={allowFileAccess}
|
|
382
|
-
saveFormDataDisabled={saveFormDataDisabled}
|
|
383
|
-
cacheEnabled={cacheEnabled}
|
|
384
|
-
androidLayerType={androidLayerType}
|
|
385
|
-
setSupportMultipleWindows={securitySupportMultipleWindows}
|
|
386
|
-
setBuiltInZoomControls={setBuiltInZoomControls}
|
|
387
|
-
setDisplayZoomControls={setDisplayZoomControls}
|
|
388
|
-
nestedScrollEnabled={nestedScrollEnabled}
|
|
389
|
-
mixedContentMode={securityMixedContentMode}
|
|
390
|
-
mediaPlaybackRequiresUserAction={mediaPlaybackRequiresUserAction}
|
|
391
|
-
injectedJavaScriptObject={JSON.stringify(injectedJavaScriptObject)}
|
|
392
|
-
{...nativeConfig?.props}
|
|
393
|
-
/>
|
|
394
|
-
);
|
|
395
|
-
|
|
396
|
-
return (
|
|
397
|
-
<View style={webViewContainerStyle}>
|
|
398
|
-
{webView}
|
|
399
|
-
{otherView}
|
|
400
|
-
</View>
|
|
401
|
-
);
|
|
402
339
|
}
|
|
403
|
-
|
|
340
|
+
|
|
341
|
+
const sourceResolved = resolveAssetSource(safeSource as ImageSourcePropType);
|
|
342
|
+
const newSource =
|
|
343
|
+
typeof sourceResolved === 'object'
|
|
344
|
+
? Object.entries(sourceResolved as WebViewSourceUri).reduce(
|
|
345
|
+
(prev, [currKey, currValue]) => {
|
|
346
|
+
return {
|
|
347
|
+
...prev,
|
|
348
|
+
[currKey]:
|
|
349
|
+
currKey === 'headers' &&
|
|
350
|
+
currValue &&
|
|
351
|
+
typeof currValue === 'object'
|
|
352
|
+
? Object.entries(currValue).map(([key, value]) => {
|
|
353
|
+
return {
|
|
354
|
+
name: key,
|
|
355
|
+
value,
|
|
356
|
+
};
|
|
357
|
+
})
|
|
358
|
+
: currValue,
|
|
359
|
+
};
|
|
360
|
+
},
|
|
361
|
+
{}
|
|
362
|
+
)
|
|
363
|
+
: sourceResolved;
|
|
364
|
+
|
|
365
|
+
const webView = (
|
|
366
|
+
<RNCWebView
|
|
367
|
+
key="webViewKey"
|
|
368
|
+
{...otherProps}
|
|
369
|
+
messagingEnabled={typeof onMessageProp === 'function'}
|
|
370
|
+
messagingModuleName={messagingModuleName}
|
|
371
|
+
hasOnScroll={!!otherProps.onScroll}
|
|
372
|
+
onLoadingError={onLoadingError}
|
|
373
|
+
onLoadingSubResourceError={onLoadingSubResourceError}
|
|
374
|
+
onLoadingFinish={onLoadingFinish}
|
|
375
|
+
onLoadingProgress={onLoadingProgress}
|
|
376
|
+
onLoadingStart={onLoadingStart}
|
|
377
|
+
onRenderProcessGone={onRenderProcessGone}
|
|
378
|
+
onMessage={onMessage}
|
|
379
|
+
onOpenWindow={onOpenWindow}
|
|
380
|
+
hasOnOpenWindowEvent={onOpenWindowProp !== undefined}
|
|
381
|
+
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
|
382
|
+
ref={webViewRef}
|
|
383
|
+
// TODO: find a better way to type this.
|
|
384
|
+
// @ts-expect-error source is old arch
|
|
385
|
+
source={sourceResolved}
|
|
386
|
+
newSource={newSource}
|
|
387
|
+
style={webViewStyles}
|
|
388
|
+
overScrollMode={overScrollMode}
|
|
389
|
+
javaScriptEnabled={javaScriptEnabled}
|
|
390
|
+
thirdPartyCookiesEnabled={thirdPartyCookiesEnabled}
|
|
391
|
+
scalesPageToFit={scalesPageToFit}
|
|
392
|
+
allowsFullscreenVideo={allowsFullscreenVideo}
|
|
393
|
+
saveFormDataDisabled={saveFormDataDisabled}
|
|
394
|
+
cacheEnabled={cacheEnabled}
|
|
395
|
+
androidLayerType={androidLayerType}
|
|
396
|
+
setSupportMultipleWindows={securitySupportMultipleWindows}
|
|
397
|
+
setBuiltInZoomControls={setBuiltInZoomControls}
|
|
398
|
+
setDisplayZoomControls={setDisplayZoomControls}
|
|
399
|
+
nestedScrollEnabled={nestedScrollEnabled}
|
|
400
|
+
mixedContentMode={securityMixedContentMode}
|
|
401
|
+
mediaPlaybackRequiresUserAction={mediaPlaybackRequiresUserAction}
|
|
402
|
+
injectedJavaScriptObject={JSON.stringify(injectedJavaScriptObject)}
|
|
403
|
+
/>
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
return (
|
|
407
|
+
<View style={webViewContainerStyle}>
|
|
408
|
+
{webView}
|
|
409
|
+
{otherView}
|
|
410
|
+
</View>
|
|
411
|
+
);
|
|
412
|
+
});
|
|
404
413
|
|
|
405
414
|
// native implementation should return "true" only for Android 5+
|
|
406
415
|
const { isFileUploadSupported } = RNCWebViewModule;
|