react-native-webview-bootpay 13.8.42 → 13.13.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/README.md +53 -69
- package/android/build.gradle +1 -11
- package/android/gradle.properties +0 -42
- package/android/src/main/AndroidManifest.xml +3 -1
- package/android/src/main/AndroidManifestNew.xml +13 -0
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebChromeClient.java +54 -10
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebView.java +101 -68
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewClient.java +68 -60
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewManagerImpl.kt +119 -65
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewMessagingModule.kt +9 -0
- package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewModuleImpl.java +1 -1
- package/android/src/main/java/kr/co/bootpay/webview/BootpayUrlHelper.java +4 -12
- package/android/src/newarch/{com/reactnativecommunity → kr/co/bootpay}/webview/BPCWebViewManager.java +118 -109
- package/android/src/newarch/{com/reactnativecommunity → kr/co/bootpay}/webview/BPCWebViewModule.java +1 -1
- package/android/src/{main/java → oldarch}/kr/co/bootpay/webview/BPCWebViewManager.java +63 -58
- package/android/src/{main/java → oldarch}/kr/co/bootpay/webview/BPCWebViewModule.java +1 -1
- package/apple/BPCWebView.mm +21 -12
- package/apple/BPCWebViewImpl.h +11 -1
- package/apple/BPCWebViewImpl.m +278 -216
- package/apple/BPCWebViewManager.mm +5 -24
- package/apple/BPCWebViewModule.h +23 -0
- package/apple/BPCWebViewModule.mm +34 -0
- package/apple/RCTConvert+WKDataDetectorTypes.h +11 -0
- package/apple/RCTConvert+WKDataDetectorTypes.m +27 -0
- package/ios/RNCWebView.xcodeproj/project.pbxproj +24 -24
- package/ios/RNCWebView.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/RNCWebView.xcodeproj/project.xcworkspace/xcuserdata/taesupyoon.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/RNCWebView.xcodeproj/xcuserdata/taesupyoon.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/lib/BPCWebViewNativeComponent.d.ts +24 -25
- package/lib/BPCWebViewNativeComponent.js +1 -1
- package/lib/{NativeBPCWebView.d.ts → NativeBPCWebViewModule.d.ts} +2 -5
- package/lib/{NativeBPCWebView.js → NativeBPCWebViewModule.js} +1 -1
- package/lib/WebView.android.d.ts +0 -1
- package/lib/WebView.android.js +1 -1
- package/lib/WebView.d.ts +0 -1
- package/lib/WebView.ios.d.ts +0 -1
- package/lib/WebView.ios.js +1 -1
- package/lib/WebView.js +1 -1
- package/lib/WebView.macos.d.ts +0 -1
- package/lib/WebView.macos.js +1 -1
- package/lib/WebView.styles.d.ts +37 -11
- package/lib/WebView.styles.js +1 -1
- package/lib/WebView.windows.d.ts +0 -1
- package/lib/WebView.windows.js +1 -1
- package/lib/WebViewNativeComponent.macos.d.ts +1 -2
- package/lib/WebViewNativeComponent.windows.d.ts +1 -2
- package/lib/WebViewShared.d.ts +0 -1
- package/lib/WebViewShared.js +1 -1
- package/lib/WebViewTypes.d.ts +51 -3
- package/lib/WebViewTypes.js +1 -1
- package/lib/index.d.ts +0 -1
- package/macos/RNCWebView.xcodeproj/project.pbxproj +36 -36
- package/package.json +13 -12
- package/react-native.config.js +1 -5
- package/src/BPCWebViewNativeComponent.ts +143 -79
- package/src/NativeBPCWebViewModule.ts +13 -0
- package/src/WebView.android.tsx +295 -190
- package/src/WebView.ios.tsx +253 -186
- package/src/WebView.macos.tsx +220 -152
- package/src/WebView.styles.ts +9 -12
- package/src/WebView.tsx +14 -7
- package/src/WebView.windows.tsx +180 -126
- package/src/WebViewNativeComponent.macos.ts +4 -5
- package/src/WebViewNativeComponent.windows.ts +6 -8
- package/src/WebViewShared.tsx +139 -91
- package/src/WebViewTypes.ts +80 -35
- package/src/__tests__/WebViewShared-test.js +170 -55
- package/windows/ReactNativeWebView/ReactNativeWebView.vcxproj +8 -17
- package/windows/ReactNativeWebView/ReactPackageProvider.cpp +5 -1
- package/windows/ReactNativeWebView/ReactWebView.cpp +73 -6
- package/windows/ReactNativeWebView/ReactWebView.h +11 -1
- package/windows/ReactNativeWebView/ReactWebView.idl +12 -3
- package/windows/ReactNativeWebView/ReactWebView2.cpp +294 -129
- package/windows/ReactNativeWebView/ReactWebView2.h +42 -5
- package/windows/ReactNativeWebView/ReactWebView2Manager.cpp +60 -34
- package/windows/ReactNativeWebView/ReactWebView2Manager.h +4 -4
- package/windows/ReactNativeWebView/ReactWebViewHelpers.cpp +70 -0
- package/windows/ReactNativeWebView/ReactWebViewHelpers.h +16 -0
- package/windows/ReactNativeWebView/ReactWebViewManager.cpp +22 -3
- package/windows/ReactNativeWebView/ReactWebViewManager.h +6 -1
- package/windows/ReactNativeWebView/pch.h +11 -7
- package/windows/ReactNativeWebView.sln +14 -14
- package/ios/main.jsbundle +0 -457
- package/lib/BPCWebViewNativeComponent.d.ts.map +0 -1
- package/lib/NativeBPCWebView.d.ts.map +0 -1
- package/lib/WebView.android.d.ts.map +0 -1
- package/lib/WebView.d.ts.map +0 -1
- package/lib/WebView.ios.d.ts.map +0 -1
- package/lib/WebView.macos.d.ts.map +0 -1
- package/lib/WebView.styles.d.ts.map +0 -1
- package/lib/WebView.windows.d.ts.map +0 -1
- package/lib/WebViewNativeComponent.macos.d.ts.map +0 -1
- package/lib/WebViewNativeComponent.windows.d.ts.map +0 -1
- package/lib/WebViewShared.d.ts.map +0 -1
- package/lib/WebViewTypes.d.ts.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/react-native-webview-bootpay.podspec +0 -46
- package/src/NativeBPCWebView.ts +0 -14
- package/windows/ReactNativeWebView/packages.config +0 -5
- /package/android/src/main/java/kr/co/bootpay/webview/{BPCWebviewWrapper.kt → BPCWebViewWrapper.kt} +0 -0
package/src/WebView.windows.tsx
CHANGED
|
@@ -10,147 +10,201 @@
|
|
|
10
10
|
* Licensed under the MIT License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import React, {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} from 'react-native';
|
|
13
|
+
import React, {
|
|
14
|
+
forwardRef,
|
|
15
|
+
useCallback,
|
|
16
|
+
useImperativeHandle,
|
|
17
|
+
useRef,
|
|
18
|
+
} from 'react';
|
|
19
|
+
import { View, Image, ImageSourcePropType, NativeModules } from 'react-native';
|
|
20
20
|
import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';
|
|
21
21
|
import invariant from 'invariant';
|
|
22
|
-
import {RCTWebView, RCTWebView2} from
|
|
23
|
-
import { useWebViewLogic, defaultOriginWhitelist, defaultRenderError, defaultRenderLoading, } from './WebViewShared';
|
|
22
|
+
import { RCTWebView, RCTWebView2 } from './WebViewNativeComponent.windows';
|
|
24
23
|
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
useWebViewLogic,
|
|
25
|
+
defaultOriginWhitelist,
|
|
26
|
+
defaultRenderError,
|
|
27
|
+
defaultRenderLoading,
|
|
28
|
+
} from './WebViewShared';
|
|
29
|
+
import { NativeWebViewWindows, WindowsWebViewProps } from './WebViewTypes';
|
|
28
30
|
|
|
29
31
|
import styles from './WebView.styles';
|
|
30
32
|
|
|
31
33
|
const Commands = codegenNativeCommands({
|
|
32
|
-
supportedCommands: [
|
|
34
|
+
supportedCommands: [
|
|
35
|
+
'goBack',
|
|
36
|
+
'goForward',
|
|
37
|
+
'reload',
|
|
38
|
+
'stopLoading',
|
|
39
|
+
'injectJavaScript',
|
|
40
|
+
'requestFocus',
|
|
41
|
+
'clearCache',
|
|
42
|
+
'postMessage',
|
|
43
|
+
'loadUrl',
|
|
44
|
+
],
|
|
33
45
|
});
|
|
34
46
|
const { resolveAssetSource } = Image;
|
|
35
47
|
|
|
36
|
-
const WebViewComponent = forwardRef<{}, WindowsWebViewProps>(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const onShouldStartLoadWithRequestCallback = useCallback((shouldStart: boolean, url: string, lockIdentifier?: number) => {
|
|
63
|
-
if (lockIdentifier) {
|
|
64
|
-
if (RCTWebViewString === 'RCTWebView'){
|
|
65
|
-
NativeModules.RCTWebView.onShouldStartLoadWithRequestCallback(shouldStart, lockIdentifier);
|
|
66
|
-
}else{
|
|
67
|
-
NativeModules.RCTWebView2.onShouldStartLoadWithRequestCallback(shouldStart, lockIdentifier);
|
|
68
|
-
}
|
|
69
|
-
} else if (shouldStart) {
|
|
70
|
-
Commands.loadUrl(webViewRef, url);
|
|
71
|
-
}
|
|
72
|
-
}, [RCTWebViewString]);
|
|
73
|
-
|
|
74
|
-
const { onLoadingStart, onShouldStartLoadWithRequest, onMessage, viewState, setViewState, lastErrorEvent, onHttpError, onLoadingError, onLoadingFinish, onLoadingProgress } = useWebViewLogic({
|
|
75
|
-
onNavigationStateChange,
|
|
76
|
-
onLoad,
|
|
77
|
-
onError,
|
|
78
|
-
onHttpErrorProp,
|
|
79
|
-
onLoadEnd,
|
|
80
|
-
onLoadProgress,
|
|
81
|
-
onLoadStart,
|
|
82
|
-
onMessageProp,
|
|
83
|
-
startInLoadingState,
|
|
84
|
-
originWhitelist,
|
|
85
|
-
onShouldStartLoadWithRequestProp,
|
|
86
|
-
onShouldStartLoadWithRequestCallback,
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
useImperativeHandle(ref, () => ({
|
|
90
|
-
goForward: () => Commands.goForward(webViewRef.current),
|
|
91
|
-
goBack: () => Commands.goBack(webViewRef.current),
|
|
92
|
-
reload: () => {
|
|
93
|
-
setViewState(
|
|
94
|
-
'LOADING',
|
|
95
|
-
); Commands.reload(webViewRef.current)
|
|
48
|
+
const WebViewComponent = forwardRef<{}, WindowsWebViewProps>(
|
|
49
|
+
(
|
|
50
|
+
{
|
|
51
|
+
cacheEnabled = true,
|
|
52
|
+
originWhitelist = defaultOriginWhitelist,
|
|
53
|
+
startInLoadingState,
|
|
54
|
+
onNavigationStateChange,
|
|
55
|
+
onLoadStart,
|
|
56
|
+
onError,
|
|
57
|
+
onLoad,
|
|
58
|
+
onLoadEnd,
|
|
59
|
+
onLoadProgress,
|
|
60
|
+
onOpenWindow: onOpenWindowProp,
|
|
61
|
+
onSourceChanged,
|
|
62
|
+
onHttpError: onHttpErrorProp,
|
|
63
|
+
onMessage: onMessageProp,
|
|
64
|
+
renderLoading,
|
|
65
|
+
renderError,
|
|
66
|
+
style,
|
|
67
|
+
containerStyle,
|
|
68
|
+
source,
|
|
69
|
+
nativeConfig,
|
|
70
|
+
onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp,
|
|
71
|
+
useWebView2,
|
|
72
|
+
...otherProps
|
|
96
73
|
},
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
74
|
+
ref
|
|
75
|
+
) => {
|
|
76
|
+
const webViewRef = useRef<NativeWebViewWindows | null>(null);
|
|
77
|
+
|
|
78
|
+
const RCTWebViewString = useWebView2 ? 'RCTWebView2' : 'RCTWebView';
|
|
79
|
+
|
|
80
|
+
const onShouldStartLoadWithRequestCallback = useCallback(
|
|
81
|
+
(shouldStart: boolean, url: string, lockIdentifier?: number) => {
|
|
82
|
+
if (lockIdentifier) {
|
|
83
|
+
if (RCTWebViewString === 'RCTWebView') {
|
|
84
|
+
NativeModules.RCTWebView.onShouldStartLoadWithRequestCallback(
|
|
85
|
+
shouldStart,
|
|
86
|
+
lockIdentifier
|
|
87
|
+
);
|
|
88
|
+
} else {
|
|
89
|
+
NativeModules.RCTWebView2.onShouldStartLoadWithRequestCallback(
|
|
90
|
+
shouldStart,
|
|
91
|
+
lockIdentifier
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
} else if (shouldStart) {
|
|
95
|
+
Commands.loadUrl(webViewRef, url);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
[RCTWebViewString]
|
|
112
99
|
);
|
|
113
|
-
} else if (viewState !== 'IDLE') {
|
|
114
|
-
console.error(`BPCWebView invalid state encountered: ${viewState}`);
|
|
115
|
-
}
|
|
116
100
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
101
|
+
const {
|
|
102
|
+
onLoadingStart,
|
|
103
|
+
onShouldStartLoadWithRequest,
|
|
104
|
+
onMessage,
|
|
105
|
+
viewState,
|
|
106
|
+
setViewState,
|
|
107
|
+
lastErrorEvent,
|
|
108
|
+
onHttpError,
|
|
109
|
+
onLoadingError,
|
|
110
|
+
onLoadingFinish,
|
|
111
|
+
onLoadingProgress,
|
|
112
|
+
onOpenWindow,
|
|
113
|
+
} = useWebViewLogic({
|
|
114
|
+
onNavigationStateChange,
|
|
115
|
+
onLoad,
|
|
116
|
+
onError,
|
|
117
|
+
onHttpErrorProp,
|
|
118
|
+
onLoadEnd,
|
|
119
|
+
onLoadProgress,
|
|
120
|
+
onLoadStart,
|
|
121
|
+
onMessageProp,
|
|
122
|
+
startInLoadingState,
|
|
123
|
+
originWhitelist,
|
|
124
|
+
onShouldStartLoadWithRequestProp,
|
|
125
|
+
onShouldStartLoadWithRequestCallback,
|
|
126
|
+
onOpenWindowProp,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
useImperativeHandle(
|
|
130
|
+
ref,
|
|
131
|
+
() => ({
|
|
132
|
+
goForward: () => Commands.goForward(webViewRef.current),
|
|
133
|
+
goBack: () => Commands.goBack(webViewRef.current),
|
|
134
|
+
reload: () => {
|
|
135
|
+
setViewState('LOADING');
|
|
136
|
+
Commands.reload(webViewRef.current);
|
|
137
|
+
},
|
|
138
|
+
stopLoading: () => Commands.stopLoading(webViewRef.current),
|
|
139
|
+
postMessage: (data: string) =>
|
|
140
|
+
Commands.postMessage(webViewRef.current, data),
|
|
141
|
+
injectJavaScript: (data: string) =>
|
|
142
|
+
Commands.injectJavaScript(webViewRef.current, data),
|
|
143
|
+
requestFocus: () => Commands.requestFocus(webViewRef.current),
|
|
144
|
+
clearCache: () => Commands.clearCache(webViewRef.current),
|
|
145
|
+
loadUrl: (url: string) => Commands.loadUrl(webViewRef.current, url),
|
|
146
|
+
}),
|
|
147
|
+
[setViewState, webViewRef]
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
let otherView = null;
|
|
151
|
+
if (viewState === 'LOADING') {
|
|
152
|
+
otherView = (renderLoading || defaultRenderLoading)();
|
|
153
|
+
} else if (viewState === 'ERROR') {
|
|
154
|
+
invariant(
|
|
155
|
+
lastErrorEvent != null,
|
|
156
|
+
'lastErrorEvent expected to be non-null'
|
|
157
|
+
);
|
|
158
|
+
otherView = (renderError || defaultRenderError)(
|
|
159
|
+
lastErrorEvent.domain,
|
|
160
|
+
lastErrorEvent.code,
|
|
161
|
+
lastErrorEvent.description
|
|
162
|
+
);
|
|
163
|
+
} else if (viewState !== 'IDLE') {
|
|
164
|
+
console.error(`BPCWebView invalid state encountered: ${viewState}`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const webViewStyles = [styles.container, styles.webView, style];
|
|
168
|
+
const webViewContainerStyle = [styles.container, containerStyle];
|
|
169
|
+
|
|
170
|
+
const NativeWebView = useWebView2 ? RCTWebView2 : RCTWebView;
|
|
171
|
+
|
|
172
|
+
const webView = (
|
|
173
|
+
<NativeWebView
|
|
174
|
+
key="webViewKey"
|
|
175
|
+
{...otherProps}
|
|
176
|
+
messagingEnabled={typeof onMessageProp === 'function'}
|
|
177
|
+
linkHandlingEnabled={typeof onOpenWindowProp === 'function'}
|
|
178
|
+
onLoadingError={onLoadingError}
|
|
179
|
+
onLoadingFinish={onLoadingFinish}
|
|
180
|
+
onLoadingProgress={onLoadingProgress}
|
|
181
|
+
onLoadingStart={onLoadingStart}
|
|
182
|
+
onHttpError={onHttpError}
|
|
183
|
+
onMessage={onMessage}
|
|
184
|
+
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
|
185
|
+
onOpenWindow={onOpenWindow}
|
|
186
|
+
onSourceChanged={onSourceChanged}
|
|
187
|
+
ref={webViewRef}
|
|
188
|
+
// TODO: find a better way to type this.
|
|
189
|
+
source={resolveAssetSource(source as ImageSourcePropType)}
|
|
190
|
+
style={webViewStyles}
|
|
191
|
+
cacheEnabled={cacheEnabled}
|
|
192
|
+
{...nativeConfig?.props}
|
|
193
|
+
/>
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<View style={webViewContainerStyle}>
|
|
198
|
+
{webView}
|
|
199
|
+
{otherView}
|
|
200
|
+
</View>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
);
|
|
149
204
|
|
|
150
205
|
// native implementation should return "true" only for Android 5+
|
|
151
|
-
const isFileUploadSupported: () => Promise<boolean>
|
|
152
|
-
= async () => false;
|
|
206
|
+
const isFileUploadSupported: () => Promise<boolean> = async () => false;
|
|
153
207
|
|
|
154
|
-
const WebView = Object.assign(WebViewComponent, {isFileUploadSupported});
|
|
208
|
+
const WebView = Object.assign(WebViewComponent, { isFileUploadSupported });
|
|
155
209
|
|
|
156
210
|
export default WebView;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { requireNativeComponent } from
|
|
2
|
-
import type { NativeWebViewMacOS } from
|
|
1
|
+
import { requireNativeComponent } from 'react-native';
|
|
2
|
+
import type { NativeWebViewMacOS } from './WebViewTypes';
|
|
3
3
|
|
|
4
|
-
const BPCWebView: typeof NativeWebViewMacOS =
|
|
5
|
-
'BPCWebView'
|
|
6
|
-
);
|
|
4
|
+
const BPCWebView: typeof NativeWebViewMacOS =
|
|
5
|
+
requireNativeComponent('BPCWebView');
|
|
7
6
|
|
|
8
7
|
export default BPCWebView;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { requireNativeComponent } from
|
|
2
|
-
import type { NativeWebViewWindows } from
|
|
1
|
+
import { requireNativeComponent } from 'react-native';
|
|
2
|
+
import type { NativeWebViewWindows } from './WebViewTypes';
|
|
3
3
|
|
|
4
|
-
export const RCTWebView: typeof NativeWebViewWindows =
|
|
5
|
-
'RCTWebView'
|
|
6
|
-
);
|
|
4
|
+
export const RCTWebView: typeof NativeWebViewWindows =
|
|
5
|
+
requireNativeComponent('RCTWebView');
|
|
7
6
|
|
|
8
|
-
export const RCTWebView2: typeof NativeWebViewWindows =
|
|
9
|
-
'RCTWebView2'
|
|
10
|
-
);
|
|
7
|
+
export const RCTWebView2: typeof NativeWebViewWindows =
|
|
8
|
+
requireNativeComponent('RCTWebView2');
|
package/src/WebViewShared.tsx
CHANGED
|
@@ -27,16 +27,13 @@ const extractOrigin = (url: string): string => {
|
|
|
27
27
|
const originWhitelistToRegex = (originWhitelist: string): string =>
|
|
28
28
|
`^${escapeStringRegexp(originWhitelist).replace(/\\\*/g, '.*')}`;
|
|
29
29
|
|
|
30
|
-
const passesWhitelist = (
|
|
31
|
-
compiledWhitelist: readonly string[],
|
|
32
|
-
url: string,
|
|
33
|
-
) => {
|
|
30
|
+
const passesWhitelist = (compiledWhitelist: readonly string[], url: string) => {
|
|
34
31
|
const origin = extractOrigin(url);
|
|
35
|
-
return compiledWhitelist.some(x => new RegExp(x).test(origin));
|
|
32
|
+
return compiledWhitelist.some((x) => new RegExp(x).test(origin));
|
|
36
33
|
};
|
|
37
34
|
|
|
38
35
|
const compileWhitelist = (
|
|
39
|
-
originWhitelist: readonly string[]
|
|
36
|
+
originWhitelist: readonly string[]
|
|
40
37
|
): readonly string[] =>
|
|
41
38
|
['about:blank', ...(originWhitelist || [])].map(originWhitelistToRegex);
|
|
42
39
|
|
|
@@ -44,25 +41,27 @@ const createOnShouldStartLoadWithRequest = (
|
|
|
44
41
|
loadRequest: (
|
|
45
42
|
shouldStart: boolean,
|
|
46
43
|
url: string,
|
|
47
|
-
lockIdentifier: number
|
|
44
|
+
lockIdentifier: number
|
|
48
45
|
) => void,
|
|
49
46
|
originWhitelist: readonly string[],
|
|
50
|
-
onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest
|
|
47
|
+
onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest
|
|
51
48
|
) => {
|
|
52
49
|
return ({ nativeEvent }: ShouldStartLoadRequestEvent) => {
|
|
53
50
|
let shouldStart = true;
|
|
54
51
|
const { url, lockIdentifier } = nativeEvent;
|
|
55
52
|
|
|
56
53
|
if (!passesWhitelist(compileWhitelist(originWhitelist), url)) {
|
|
57
|
-
Linking.canOpenURL(url)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
Linking.canOpenURL(url)
|
|
55
|
+
.then((supported) => {
|
|
56
|
+
if (supported) {
|
|
57
|
+
return Linking.openURL(url);
|
|
58
|
+
}
|
|
59
|
+
console.warn(`Can't open url: ${url}`);
|
|
60
|
+
return undefined;
|
|
61
|
+
})
|
|
62
|
+
.catch((e) => {
|
|
63
|
+
console.warn('Error opening URL: ', e);
|
|
64
|
+
});
|
|
66
65
|
shouldStart = false;
|
|
67
66
|
} else if (onShouldStartLoadWithRequest) {
|
|
68
67
|
shouldStart = onShouldStartLoadWithRequest(nativeEvent);
|
|
@@ -80,7 +79,7 @@ const defaultRenderLoading = () => (
|
|
|
80
79
|
const defaultRenderError = (
|
|
81
80
|
errorDomain: string | undefined,
|
|
82
81
|
errorCode: number,
|
|
83
|
-
errorDesc: string
|
|
82
|
+
errorDesc: string
|
|
84
83
|
) => (
|
|
85
84
|
<View style={styles.loadingOrErrorView}>
|
|
86
85
|
<Text style={styles.errorTextTitle}>Error loading page</Text>
|
|
@@ -114,7 +113,7 @@ export const useWebViewLogic = ({
|
|
|
114
113
|
onShouldStartLoadWithRequestProp,
|
|
115
114
|
onShouldStartLoadWithRequestCallback,
|
|
116
115
|
}: {
|
|
117
|
-
startInLoadingState?: boolean
|
|
116
|
+
startInLoadingState?: boolean;
|
|
118
117
|
onNavigationStateChange?: (event: WebViewNavigation) => void;
|
|
119
118
|
onLoadStart?: (event: WebViewNavigationEvent) => void;
|
|
120
119
|
onLoad?: (event: WebViewNavigationEvent) => void;
|
|
@@ -128,94 +127,143 @@ export const useWebViewLogic = ({
|
|
|
128
127
|
onContentProcessDidTerminateProp?: (event: WebViewTerminatedEvent) => void;
|
|
129
128
|
originWhitelist: readonly string[];
|
|
130
129
|
onShouldStartLoadWithRequestProp?: OnShouldStartLoadWithRequest;
|
|
131
|
-
onShouldStartLoadWithRequestCallback: (
|
|
130
|
+
onShouldStartLoadWithRequestCallback: (
|
|
131
|
+
shouldStart: boolean,
|
|
132
|
+
url: string,
|
|
133
|
+
lockIdentifier?: number | undefined
|
|
134
|
+
) => void;
|
|
132
135
|
}) => {
|
|
136
|
+
const [viewState, setViewState] = useState<'IDLE' | 'LOADING' | 'ERROR'>(
|
|
137
|
+
startInLoadingState ? 'LOADING' : 'IDLE'
|
|
138
|
+
);
|
|
139
|
+
const [lastErrorEvent, setLastErrorEvent] = useState<WebViewError | null>(
|
|
140
|
+
null
|
|
141
|
+
);
|
|
142
|
+
const startUrl = useRef<string | null>(null);
|
|
133
143
|
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
144
|
+
const updateNavigationState = useCallback(
|
|
145
|
+
(event: WebViewNavigationEvent) => {
|
|
146
|
+
onNavigationStateChange?.(event.nativeEvent);
|
|
147
|
+
},
|
|
148
|
+
[onNavigationStateChange]
|
|
149
|
+
);
|
|
137
150
|
|
|
151
|
+
const onLoadingStart = useCallback(
|
|
152
|
+
(event: WebViewNavigationEvent) => {
|
|
153
|
+
// Needed for android
|
|
154
|
+
startUrl.current = event.nativeEvent.url;
|
|
155
|
+
// !Needed for android
|
|
138
156
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
157
|
+
onLoadStart?.(event);
|
|
158
|
+
updateNavigationState(event);
|
|
159
|
+
},
|
|
160
|
+
[onLoadStart, updateNavigationState]
|
|
161
|
+
);
|
|
142
162
|
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
163
|
+
const onLoadingError = useCallback(
|
|
164
|
+
(event: WebViewErrorEvent) => {
|
|
165
|
+
event.persist();
|
|
166
|
+
if (onError) {
|
|
167
|
+
onError(event);
|
|
168
|
+
} else {
|
|
169
|
+
console.warn('Encountered an error loading page', event.nativeEvent);
|
|
170
|
+
}
|
|
171
|
+
onLoadEnd?.(event);
|
|
172
|
+
if (event.isDefaultPrevented()) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
setViewState('ERROR');
|
|
176
|
+
setLastErrorEvent(event.nativeEvent);
|
|
177
|
+
},
|
|
178
|
+
[onError, onLoadEnd]
|
|
179
|
+
);
|
|
147
180
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (onError) {
|
|
155
|
-
onError(event);
|
|
156
|
-
} else {
|
|
157
|
-
console.warn('Encountered an error loading page', event.nativeEvent);
|
|
158
|
-
}
|
|
159
|
-
onLoadEnd?.(event);
|
|
160
|
-
if (event.isDefaultPrevented()) { return };
|
|
161
|
-
setViewState('ERROR');
|
|
162
|
-
setLastErrorEvent(event.nativeEvent);
|
|
163
|
-
}, [onError, onLoadEnd]);
|
|
164
|
-
|
|
165
|
-
const onHttpError = useCallback((event: WebViewHttpErrorEvent) => {
|
|
166
|
-
onHttpErrorProp?.(event);
|
|
167
|
-
}, [onHttpErrorProp]);
|
|
181
|
+
const onHttpError = useCallback(
|
|
182
|
+
(event: WebViewHttpErrorEvent) => {
|
|
183
|
+
onHttpErrorProp?.(event);
|
|
184
|
+
},
|
|
185
|
+
[onHttpErrorProp]
|
|
186
|
+
);
|
|
168
187
|
|
|
169
188
|
// Android Only
|
|
170
|
-
const onRenderProcessGone = useCallback(
|
|
171
|
-
|
|
172
|
-
|
|
189
|
+
const onRenderProcessGone = useCallback(
|
|
190
|
+
(event: WebViewRenderProcessGoneEvent) => {
|
|
191
|
+
onRenderProcessGoneProp?.(event);
|
|
192
|
+
},
|
|
193
|
+
[onRenderProcessGoneProp]
|
|
194
|
+
);
|
|
173
195
|
// !Android Only
|
|
174
196
|
|
|
175
197
|
// iOS Only
|
|
176
|
-
const onContentProcessDidTerminate = useCallback(
|
|
198
|
+
const onContentProcessDidTerminate = useCallback(
|
|
199
|
+
(event: WebViewTerminatedEvent) => {
|
|
177
200
|
onContentProcessDidTerminateProp?.(event);
|
|
178
|
-
|
|
201
|
+
},
|
|
202
|
+
[onContentProcessDidTerminateProp]
|
|
203
|
+
);
|
|
179
204
|
// !iOS Only
|
|
180
205
|
|
|
181
|
-
const onLoadingFinish = useCallback(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const onLoadingProgress = useCallback((event: WebViewProgressEvent) => {
|
|
198
|
-
const { nativeEvent: { progress } } = event;
|
|
199
|
-
// patch for Android only
|
|
200
|
-
if (Platform.OS === "android" && progress === 1) {
|
|
201
|
-
setViewState(prevViewState => prevViewState === 'LOADING' ? 'IDLE' : prevViewState);
|
|
202
|
-
}
|
|
203
|
-
// !patch for Android only
|
|
204
|
-
onLoadProgress?.(event);
|
|
205
|
-
}, [onLoadProgress]);
|
|
206
|
+
const onLoadingFinish = useCallback(
|
|
207
|
+
(event: WebViewNavigationEvent) => {
|
|
208
|
+
onLoad?.(event);
|
|
209
|
+
onLoadEnd?.(event);
|
|
210
|
+
const {
|
|
211
|
+
nativeEvent: { url },
|
|
212
|
+
} = event;
|
|
213
|
+
// on Android, only if url === startUrl
|
|
214
|
+
if (Platform.OS !== 'android' || url === startUrl.current) {
|
|
215
|
+
setViewState('IDLE');
|
|
216
|
+
}
|
|
217
|
+
// !on Android, only if url === startUrl
|
|
218
|
+
updateNavigationState(event);
|
|
219
|
+
},
|
|
220
|
+
[onLoad, onLoadEnd, updateNavigationState]
|
|
221
|
+
);
|
|
206
222
|
|
|
207
|
-
const
|
|
208
|
-
|
|
223
|
+
const onMessage = useCallback(
|
|
224
|
+
(event: WebViewMessageEvent) => {
|
|
225
|
+
onMessageProp?.(event);
|
|
226
|
+
},
|
|
227
|
+
[onMessageProp]
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const onLoadingProgress = useCallback(
|
|
231
|
+
(event: WebViewProgressEvent) => {
|
|
232
|
+
const {
|
|
233
|
+
nativeEvent: { progress },
|
|
234
|
+
} = event;
|
|
235
|
+
// patch for Android only
|
|
236
|
+
if (Platform.OS === 'android' && progress === 1) {
|
|
237
|
+
setViewState((prevViewState) =>
|
|
238
|
+
prevViewState === 'LOADING' ? 'IDLE' : prevViewState
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
// !patch for Android only
|
|
242
|
+
onLoadProgress?.(event);
|
|
243
|
+
},
|
|
244
|
+
[onLoadProgress]
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
const onShouldStartLoadWithRequest = useMemo(
|
|
248
|
+
() =>
|
|
249
|
+
createOnShouldStartLoadWithRequest(
|
|
250
|
+
onShouldStartLoadWithRequestCallback,
|
|
251
|
+
originWhitelist,
|
|
252
|
+
onShouldStartLoadWithRequestProp
|
|
253
|
+
),
|
|
254
|
+
[
|
|
209
255
|
originWhitelist,
|
|
210
256
|
onShouldStartLoadWithRequestProp,
|
|
211
|
-
|
|
212
|
-
|
|
257
|
+
onShouldStartLoadWithRequestCallback,
|
|
258
|
+
]
|
|
259
|
+
);
|
|
213
260
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
261
|
+
const onOpenWindow = useCallback(
|
|
262
|
+
(event: WebViewOpenWindowEvent) => {
|
|
263
|
+
onOpenWindowProp?.(event);
|
|
264
|
+
},
|
|
265
|
+
[onOpenWindowProp]
|
|
266
|
+
);
|
|
219
267
|
|
|
220
268
|
return {
|
|
221
269
|
onShouldStartLoadWithRequest,
|
|
@@ -231,5 +279,5 @@ export const useWebViewLogic = ({
|
|
|
231
279
|
viewState,
|
|
232
280
|
setViewState,
|
|
233
281
|
lastErrorEvent,
|
|
234
|
-
}
|
|
235
|
-
};
|
|
282
|
+
};
|
|
283
|
+
};
|