react-native-webview-bootpay 13.8.42 → 13.13.4-6.alpha.1
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 +97 -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 +39 -30
- package/apple/BPCWebViewImpl.h +10 -0
- package/apple/BPCWebViewImpl.m +267 -205
- 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/index.d.ts +54 -48
- 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 +12 -11
- package/react-native-webview-bootpay.podspec +2 -2
- 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/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/apple/BPCWebViewImpl.m
CHANGED
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
#import "objc/runtime.h"
|
|
19
19
|
|
|
20
20
|
static NSTimer *keyboardTimer;
|
|
21
|
-
static NSString *const HistoryShimName = @"
|
|
21
|
+
static NSString *const HistoryShimName = @"BPReactNativeHistoryShim";
|
|
22
22
|
static NSString *const MessageHandlerName = @"BootpayRNWebView";
|
|
23
23
|
static NSURLCredential* clientAuthenticationCredential;
|
|
24
24
|
static NSDictionary* customCertificatesForHost;
|
|
25
25
|
|
|
26
26
|
NSString *const BPCUSTOM_SELECTOR = @"_BPCUSTOM_SELECTOR_";
|
|
27
27
|
|
|
28
|
-
#if
|
|
28
|
+
#if TARGET_OS_IOS
|
|
29
29
|
// runtime trick to remove WKWebView keyboard default toolbar
|
|
30
30
|
// see: http://stackoverflow.com/questions/19033292/ios-7-uiwebview-keyboard-issue/19042279#19042279
|
|
31
31
|
@interface _BPSwizzleHelperWK : UIView
|
|
@@ -46,7 +46,7 @@ NSString *const BPCUSTOM_SELECTOR = @"_BPCUSTOM_SELECTOR_";
|
|
|
46
46
|
return nil;
|
|
47
47
|
}
|
|
48
48
|
@end
|
|
49
|
-
#endif //
|
|
49
|
+
#endif // TARGET_OS_IOS
|
|
50
50
|
|
|
51
51
|
@interface BPCWKWebView : WKWebView
|
|
52
52
|
#if !TARGET_OS_OSX
|
|
@@ -103,9 +103,9 @@ NSString *const BPCUSTOM_SELECTOR = @"_BPCUSTOM_SELECTOR_";
|
|
|
103
103
|
}
|
|
104
104
|
#else // TARGET_OS_OSX
|
|
105
105
|
- (void)scrollWheel:(NSEvent *)theEvent {
|
|
106
|
-
BPCWebViewImpl *
|
|
107
|
-
RCTAssert([
|
|
108
|
-
if (![
|
|
106
|
+
BPCWebViewImpl *rncWebView = (BPCWebViewImpl *)[self superview];
|
|
107
|
+
RCTAssert([rncWebView isKindOfClass:[rncWebView class]], @"superview must be an BPCWebViewImpl");
|
|
108
|
+
if (![rncWebView scrollEnabled]) {
|
|
109
109
|
[[self nextResponder] scrollWheel:theEvent];
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
@@ -117,6 +117,7 @@ NSString *const BPCUSTOM_SELECTOR = @"_BPCUSTOM_SELECTOR_";
|
|
|
117
117
|
@interface BPCWebViewImpl () <WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler, WKHTTPCookieStoreObserver,
|
|
118
118
|
#if !TARGET_OS_OSX
|
|
119
119
|
UIScrollViewDelegate,
|
|
120
|
+
UIGestureRecognizerDelegate,
|
|
120
121
|
#endif // !TARGET_OS_OSX
|
|
121
122
|
RCTAutoInsetsProtocol>
|
|
122
123
|
|
|
@@ -138,7 +139,7 @@ RCTAutoInsetsProtocol>
|
|
|
138
139
|
BOOL _savedKeyboardDisplayRequiresUserAction;
|
|
139
140
|
|
|
140
141
|
// Workaround for StatusBar appearance bug for iOS 12
|
|
141
|
-
// https://github.com/react-native-webview
|
|
142
|
+
// https://github.com/react-native-webview/react-native-webview/issues/62
|
|
142
143
|
BOOL _isFullScreenVideoOpen;
|
|
143
144
|
#if !TARGET_OS_OSX
|
|
144
145
|
UIStatusBarStyle _savedStatusBarStyle;
|
|
@@ -164,34 +165,48 @@ RCTAutoInsetsProtocol>
|
|
|
164
165
|
_bounces = YES;
|
|
165
166
|
_scrollEnabled = YES;
|
|
166
167
|
_showsHorizontalScrollIndicator = YES;
|
|
168
|
+
_javaScriptEnabled = YES;
|
|
169
|
+
_allowsLinkPreview = YES;
|
|
167
170
|
_showsVerticalScrollIndicator = YES;
|
|
168
171
|
_directionalLockEnabled = YES;
|
|
172
|
+
_useSharedProcessPool = YES;
|
|
173
|
+
_cacheEnabled = YES;
|
|
174
|
+
_mediaPlaybackRequiresUserAction = YES;
|
|
169
175
|
_automaticallyAdjustContentInsets = YES;
|
|
170
176
|
_autoManageStatusBarEnabled = YES;
|
|
171
177
|
_contentInset = UIEdgeInsetsZero;
|
|
172
178
|
_savedKeyboardDisplayRequiresUserAction = YES;
|
|
173
|
-
#if !TARGET_OS_OSX
|
|
174
|
-
_savedStatusBarStyle = RCTSharedApplication().statusBarStyle;
|
|
175
|
-
_savedStatusBarHidden = RCTSharedApplication().statusBarHidden;
|
|
176
|
-
#endif // !TARGET_OS_OSX
|
|
177
179
|
_injectedJavaScript = nil;
|
|
178
180
|
_injectedJavaScriptForMainFrameOnly = YES;
|
|
179
181
|
_injectedJavaScriptBeforeContentLoaded = nil;
|
|
180
182
|
_injectedJavaScriptBeforeContentLoadedForMainFrameOnly = YES;
|
|
181
|
-
|
|
183
|
+
_enableApplePay = NO;
|
|
184
|
+
#if TARGET_OS_IOS
|
|
185
|
+
_savedStatusBarStyle = RCTSharedApplication().statusBarStyle;
|
|
186
|
+
_savedStatusBarHidden = RCTSharedApplication().statusBarHidden;
|
|
187
|
+
#endif // TARGET_OS_IOS
|
|
182
188
|
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
|
183
189
|
_savedContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
|
184
190
|
#endif
|
|
185
191
|
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */
|
|
186
192
|
_savedAutomaticallyAdjustsScrollIndicatorInsets = NO;
|
|
193
|
+
_fraudulentWebsiteWarningEnabled = YES;
|
|
194
|
+
#endif
|
|
195
|
+
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140500 /* __IPHONE_13_0 */
|
|
196
|
+
_textInteractionEnabled = YES;
|
|
187
197
|
#endif
|
|
188
|
-
_enableApplePay = NO;
|
|
189
198
|
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */
|
|
190
199
|
_mediaCapturePermissionGrantType = BPCWebViewPermissionGrantType_Prompt;
|
|
200
|
+
#endif
|
|
201
|
+
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 160000 /* iOS 15 */
|
|
202
|
+
if (@available(iOS 16.0, *)) {
|
|
203
|
+
_editMenuInteraction = [[UIEditMenuInteraction alloc] initWithDelegate:self];
|
|
204
|
+
[self addInteraction:_editMenuInteraction];
|
|
205
|
+
}
|
|
191
206
|
#endif
|
|
192
207
|
}
|
|
193
208
|
|
|
194
|
-
#if
|
|
209
|
+
#if TARGET_OS_IOS
|
|
195
210
|
[[NSNotificationCenter defaultCenter]addObserver:self
|
|
196
211
|
selector:@selector(appDidBecomeActive)
|
|
197
212
|
name:UIApplicationDidBecomeActiveNotification
|
|
@@ -214,7 +229,7 @@ RCTAutoInsetsProtocol>
|
|
|
214
229
|
name:UIKeyboardWillShowNotification object:nil];
|
|
215
230
|
|
|
216
231
|
// Workaround for StatusBar appearance bug for iOS 12
|
|
217
|
-
// https://github.com/react-native-webview
|
|
232
|
+
// https://github.com/react-native-webview/react-native-webview/issues/62
|
|
218
233
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
219
234
|
selector:@selector(showFullScreenVideoStatusBars)
|
|
220
235
|
name:UIWindowDidBecomeVisibleNotification
|
|
@@ -226,7 +241,7 @@ RCTAutoInsetsProtocol>
|
|
|
226
241
|
object:nil];
|
|
227
242
|
|
|
228
243
|
}
|
|
229
|
-
#endif //
|
|
244
|
+
#endif // TARGET_OS_IOS
|
|
230
245
|
return self;
|
|
231
246
|
}
|
|
232
247
|
|
|
@@ -246,29 +261,51 @@ RCTAutoInsetsProtocol>
|
|
|
246
261
|
if (pressSender.state != UIGestureRecognizerStateEnded || !self.menuItems) {
|
|
247
262
|
return;
|
|
248
263
|
}
|
|
249
|
-
|
|
250
|
-
|
|
264
|
+
if (@available(iOS 16.0, *)) {
|
|
265
|
+
CGPoint location = [pressSender locationInView:self];
|
|
266
|
+
UIEditMenuConfiguration *config = [UIEditMenuConfiguration configurationWithIdentifier:nil sourcePoint:location];
|
|
267
|
+
[_editMenuInteraction presentEditMenuWithConfiguration:config];
|
|
268
|
+
} else {
|
|
269
|
+
// When a long press ends, bring up our custom UIMenu if defined
|
|
270
|
+
if (self.menuItems.count == 0) {
|
|
251
271
|
UIMenuController *menuController = [UIMenuController sharedMenuController];
|
|
252
272
|
menuController.menuItems = nil;
|
|
253
|
-
[menuController
|
|
273
|
+
[menuController showMenuFromView:self rect:self.bounds];
|
|
254
274
|
return;
|
|
255
|
-
|
|
256
|
-
UIMenuController *menuController = [UIMenuController sharedMenuController];
|
|
257
|
-
NSMutableArray *menuControllerItems = [NSMutableArray arrayWithCapacity:self.menuItems.count];
|
|
258
|
-
|
|
259
|
-
for(NSDictionary *menuItem in self.menuItems) {
|
|
260
|
-
NSString *menuItemLabel = [RCTConvert NSString:menuItem[@"label"]];
|
|
261
|
-
NSString *menuItemKey = [RCTConvert NSString:menuItem[@"key"]];
|
|
262
|
-
NSString *sel = [NSString stringWithFormat:@"%@%@", BPCUSTOM_SELECTOR, menuItemKey];
|
|
263
|
-
UIMenuItem *item = [[UIMenuItem alloc] initWithTitle: menuItemLabel
|
|
264
|
-
action: NSSelectorFromString(sel)];
|
|
265
|
-
[menuControllerItems addObject: item];
|
|
266
|
-
}
|
|
275
|
+
}
|
|
267
276
|
|
|
268
|
-
|
|
269
|
-
|
|
277
|
+
UIMenuController *menuController = [UIMenuController sharedMenuController];
|
|
278
|
+
NSMutableArray *menuControllerItems = [NSMutableArray arrayWithCapacity:self.menuItems.count];
|
|
279
|
+
|
|
280
|
+
for(NSDictionary *menuItem in self.menuItems) {
|
|
281
|
+
NSString *menuItemLabel = [RCTConvert NSString:menuItem[@"label"]];
|
|
282
|
+
NSString *menuItemKey = [RCTConvert NSString:menuItem[@"key"]];
|
|
283
|
+
NSString *sel = [NSString stringWithFormat:@"%@%@", BPCUSTOM_SELECTOR, menuItemKey];
|
|
284
|
+
UIMenuItem *item = [[UIMenuItem alloc] initWithTitle: menuItemLabel
|
|
285
|
+
action: NSSelectorFromString(sel)];
|
|
286
|
+
[menuControllerItems addObject: item];
|
|
287
|
+
}
|
|
288
|
+
menuController.menuItems = menuControllerItems;
|
|
289
|
+
[menuController showMenuFromView:self rect:self.bounds];
|
|
290
|
+
}
|
|
270
291
|
}
|
|
271
292
|
|
|
293
|
+
- (UIMenu *)editMenuInteraction:(UIEditMenuInteraction *)interaction menuForConfiguration:(UIEditMenuConfiguration *)configuration suggestedActions:(NSArray<UIMenuElement *> *)suggestedActions API_AVAILABLE(ios(16.0))
|
|
294
|
+
{
|
|
295
|
+
NSMutableArray<UICommand *> *menuItems = [NSMutableArray new];
|
|
296
|
+
for(NSDictionary *menuItem in self.menuItems) {
|
|
297
|
+
NSString *menuItemLabel = [RCTConvert NSString:menuItem[@"label"]];
|
|
298
|
+
NSString *menuItemKey = [RCTConvert NSString:menuItem[@"key"]];
|
|
299
|
+
NSString *sel = [NSString stringWithFormat:@"%@%@", BPCUSTOM_SELECTOR, menuItemKey];
|
|
300
|
+
UICommand *command = [UICommand commandWithTitle:menuItemLabel
|
|
301
|
+
image:nil
|
|
302
|
+
action:NSSelectorFromString(sel)
|
|
303
|
+
propertyList:nil];
|
|
304
|
+
[menuItems addObject:command];
|
|
305
|
+
}
|
|
306
|
+
UIMenu *menu = [UIMenu menuWithChildren:menuItems];
|
|
307
|
+
return menu;
|
|
308
|
+
}
|
|
272
309
|
#endif // !TARGET_OS_OSX
|
|
273
310
|
|
|
274
311
|
- (void)dealloc
|
|
@@ -352,38 +389,40 @@ RCTAutoInsetsProtocol>
|
|
|
352
389
|
*/
|
|
353
390
|
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
|
|
354
391
|
{
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
// NSURL *url = navigationAction.request.URL;
|
|
359
|
-
|
|
360
|
-
if ([url containsString:@"bootpay.co.kr"]) {
|
|
392
|
+
if (!navigationAction.targetFrame.isMainFrame) {
|
|
393
|
+
NSString *url = navigationAction.request.URL.absoluteString;
|
|
394
|
+
if ([url containsString:@"bootpay.co.kr"]) {
|
|
361
395
|
// 팝업(새 창) 뜨는 경우 호출됨 (window.open 또는 target="_blank")
|
|
362
396
|
WKWebView *popupView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height) configuration:configuration];
|
|
363
|
-
|
|
364
397
|
[popupView autoresizingMask];
|
|
365
398
|
popupView.navigationDelegate = self;
|
|
366
399
|
popupView.UIDelegate = self;
|
|
367
|
-
|
|
368
400
|
[self addSubview:popupView];
|
|
369
|
-
|
|
370
401
|
return popupView;
|
|
371
|
-
} else {
|
|
372
|
-
if (_onOpenWindow) {
|
|
373
|
-
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
|
|
374
|
-
[event addEntriesFromDictionary: @{@"targetUrl": url}];
|
|
375
|
-
_onOpenWindow(event);
|
|
376
402
|
} else {
|
|
377
|
-
|
|
403
|
+
if (_onOpenWindow) {
|
|
404
|
+
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
|
|
405
|
+
[event addEntriesFromDictionary: @{@"targetUrl": url}];
|
|
406
|
+
_onOpenWindow(event);
|
|
407
|
+
} else {
|
|
408
|
+
[webView loadRequest:navigationAction.request];
|
|
409
|
+
}
|
|
378
410
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
411
|
+
}
|
|
412
|
+
// if (!navigationAction.targetFrame.isMainFrame) {
|
|
413
|
+
// NSURL *url = navigationAction.request.URL;
|
|
414
|
+
//
|
|
415
|
+
// if (_onOpenWindow) {
|
|
416
|
+
// NSMutableDictionary<NSString *, id> *event = [self baseEvent];
|
|
417
|
+
// [event addEntriesFromDictionary: @{@"targetUrl": url.absoluteString}];
|
|
418
|
+
// _onOpenWindow(event);
|
|
419
|
+
// } else {
|
|
420
|
+
// [webView loadRequest:navigationAction.request];
|
|
421
|
+
// }
|
|
422
|
+
// }
|
|
383
423
|
return nil;
|
|
384
424
|
}
|
|
385
425
|
|
|
386
|
-
|
|
387
426
|
- (void)webViewDidClose:(WKWebView *)webView {
|
|
388
427
|
[webView removeFromSuperview];
|
|
389
428
|
}
|
|
@@ -483,6 +522,7 @@ RCTAutoInsetsProtocol>
|
|
|
483
522
|
|
|
484
523
|
#if !TARGET_OS_OSX
|
|
485
524
|
wkWebViewConfig.allowsInlineMediaPlayback = _allowsInlineMediaPlayback;
|
|
525
|
+
wkWebViewConfig.allowsPictureInPictureMediaPlayback = _allowsPictureInPictureMediaPlayback;
|
|
486
526
|
wkWebViewConfig.mediaTypesRequiringUserActionForPlayback = _mediaPlaybackRequiresUserAction
|
|
487
527
|
? WKAudiovisualMediaTypeAll
|
|
488
528
|
: WKAudiovisualMediaTypeNone;
|
|
@@ -551,6 +591,7 @@ RCTAutoInsetsProtocol>
|
|
|
551
591
|
[self setKeyboardDisplayRequiresUserAction: _savedKeyboardDisplayRequiresUserAction];
|
|
552
592
|
[self visitSource];
|
|
553
593
|
}
|
|
594
|
+
|
|
554
595
|
#if !TARGET_OS_OSX
|
|
555
596
|
// Allow this object to recognize gestures
|
|
556
597
|
if (self.menuItems != nil) {
|
|
@@ -592,6 +633,11 @@ RCTAutoInsetsProtocol>
|
|
|
592
633
|
[_webView.configuration.userContentController removeScriptMessageHandlerForName:MessageHandlerName];
|
|
593
634
|
[_webView removeObserver:self forKeyPath:@"estimatedProgress"];
|
|
594
635
|
[_webView removeFromSuperview];
|
|
636
|
+
if (@available(iOS 15.0, macOS 12.0, *)) {
|
|
637
|
+
[_webView pauseAllMediaPlaybackWithCompletionHandler:nil];
|
|
638
|
+
} else if (@available(iOS 14.5, macOS 11.3, *)) {
|
|
639
|
+
[_webView suspendAllMediaPlayback:nil];
|
|
640
|
+
}
|
|
595
641
|
#if !TARGET_OS_OSX
|
|
596
642
|
_webView.scrollView.delegate = nil;
|
|
597
643
|
if (_menuItems) {
|
|
@@ -611,7 +657,7 @@ RCTAutoInsetsProtocol>
|
|
|
611
657
|
#endif
|
|
612
658
|
}
|
|
613
659
|
|
|
614
|
-
#if
|
|
660
|
+
#if TARGET_OS_IOS
|
|
615
661
|
-(void)showFullScreenVideoStatusBars
|
|
616
662
|
{
|
|
617
663
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
@@ -667,7 +713,7 @@ RCTAutoInsetsProtocol>
|
|
|
667
713
|
}];
|
|
668
714
|
}
|
|
669
715
|
}
|
|
670
|
-
#endif //
|
|
716
|
+
#endif // TARGET_OS_IOS
|
|
671
717
|
|
|
672
718
|
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
|
|
673
719
|
if ([keyPath isEqual:@"estimatedProgress"] && object == self.webView) {
|
|
@@ -754,6 +800,7 @@ RCTAutoInsetsProtocol>
|
|
|
754
800
|
if (_onMessage) {
|
|
755
801
|
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
|
|
756
802
|
[event addEntriesFromDictionary: @{@"data": message.body}];
|
|
803
|
+
[event addEntriesFromDictionary: @{@"url": message.frameInfo.request.URL.absoluteString}];
|
|
757
804
|
_onMessage(event);
|
|
758
805
|
}
|
|
759
806
|
}
|
|
@@ -781,22 +828,25 @@ RCTAutoInsetsProtocol>
|
|
|
781
828
|
}
|
|
782
829
|
}
|
|
783
830
|
|
|
784
|
-
#if !TARGET_OS_OSX
|
|
785
831
|
- (void)setContentInset:(UIEdgeInsets)contentInset
|
|
786
832
|
{
|
|
833
|
+
#if !TARGET_OS_OSX
|
|
787
834
|
_contentInset = contentInset;
|
|
788
835
|
[RCTView autoAdjustInsetsForView:self
|
|
789
836
|
withScrollView:_webView.scrollView
|
|
790
837
|
updateOffset:NO];
|
|
838
|
+
#endif // !TARGET_OS_OSX
|
|
791
839
|
}
|
|
792
840
|
|
|
793
841
|
- (void)refreshContentInset
|
|
794
842
|
{
|
|
843
|
+
#if !TARGET_OS_OSX
|
|
795
844
|
[RCTView autoAdjustInsetsForView:self
|
|
796
845
|
withScrollView:_webView.scrollView
|
|
797
846
|
updateOffset:YES];
|
|
798
|
-
}
|
|
799
847
|
#endif // !TARGET_OS_OSX
|
|
848
|
+
}
|
|
849
|
+
|
|
800
850
|
|
|
801
851
|
- (void)visitSource
|
|
802
852
|
{
|
|
@@ -824,6 +874,9 @@ RCTAutoInsetsProtocol>
|
|
|
824
874
|
NSString *allowingReadAccessToURL = _allowingReadAccessToURL;
|
|
825
875
|
|
|
826
876
|
[self syncCookiesToWebView:^{
|
|
877
|
+
// Add observer to sync cookies from webview to sharedHTTPCookieStorage
|
|
878
|
+
[webView.configuration.websiteDataStore.httpCookieStore addObserver:self];
|
|
879
|
+
|
|
827
880
|
// Because of the way React works, as pages redirect, we actually end up
|
|
828
881
|
// passing the redirect urls back here, so we ignore them if trying to load
|
|
829
882
|
// the same url. We'll expose a call to 'reload' to allow a user to load
|
|
@@ -857,8 +910,10 @@ RCTAutoInsetsProtocol>
|
|
|
857
910
|
_webView.suppressMenuItems = suppressMenuItems;
|
|
858
911
|
}
|
|
859
912
|
|
|
913
|
+
#if TARGET_OS_IOS
|
|
860
914
|
-(void)setKeyboardDisplayRequiresUserAction:(BOOL)keyboardDisplayRequiresUserAction
|
|
861
915
|
{
|
|
916
|
+
_keyboardDisplayRequiresUserAction = keyboardDisplayRequiresUserAction;
|
|
862
917
|
if (_webView == nil) {
|
|
863
918
|
_savedKeyboardDisplayRequiresUserAction = keyboardDisplayRequiresUserAction;
|
|
864
919
|
return;
|
|
@@ -891,7 +946,7 @@ RCTAutoInsetsProtocol>
|
|
|
891
946
|
SEL selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:");
|
|
892
947
|
method = class_getInstanceMethod(class, selector);
|
|
893
948
|
IMP original = method_getImplementation(method);
|
|
894
|
-
override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
|
|
949
|
+
override = imp_implementationWithBlock(^void(id me, void* arg0, __unused BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
|
|
895
950
|
((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4);
|
|
896
951
|
});
|
|
897
952
|
}
|
|
@@ -900,7 +955,7 @@ RCTAutoInsetsProtocol>
|
|
|
900
955
|
SEL selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:");
|
|
901
956
|
method = class_getInstanceMethod(class, selector);
|
|
902
957
|
IMP original = method_getImplementation(method);
|
|
903
|
-
override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
|
|
958
|
+
override = imp_implementationWithBlock(^void(id me, void* arg0, __unused BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
|
|
904
959
|
((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4);
|
|
905
960
|
});
|
|
906
961
|
}
|
|
@@ -909,7 +964,7 @@ RCTAutoInsetsProtocol>
|
|
|
909
964
|
SEL selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:");
|
|
910
965
|
method = class_getInstanceMethod(class, selector);
|
|
911
966
|
IMP original = method_getImplementation(method);
|
|
912
|
-
override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
|
|
967
|
+
override = imp_implementationWithBlock(^void(id me, void* arg0, __unused BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
|
|
913
968
|
((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4);
|
|
914
969
|
});
|
|
915
970
|
} else {
|
|
@@ -917,7 +972,7 @@ RCTAutoInsetsProtocol>
|
|
|
917
972
|
SEL selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:");
|
|
918
973
|
method = class_getInstanceMethod(class, selector);
|
|
919
974
|
IMP original = method_getImplementation(method);
|
|
920
|
-
override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, id arg3) {
|
|
975
|
+
override = imp_implementationWithBlock(^void(id me, void* arg0, __unused BOOL arg1, BOOL arg2, id arg3) {
|
|
921
976
|
((void (*)(id, SEL, void*, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3);
|
|
922
977
|
});
|
|
923
978
|
}
|
|
@@ -927,12 +982,15 @@ RCTAutoInsetsProtocol>
|
|
|
927
982
|
|
|
928
983
|
-(void)setHideKeyboardAccessoryView:(BOOL)hideKeyboardAccessoryView
|
|
929
984
|
{
|
|
985
|
+
_hideKeyboardAccessoryView = hideKeyboardAccessoryView;
|
|
986
|
+
_savedHideKeyboardAccessoryView = hideKeyboardAccessoryView;
|
|
987
|
+
|
|
930
988
|
if (_webView == nil) {
|
|
931
|
-
_savedHideKeyboardAccessoryView = hideKeyboardAccessoryView;
|
|
932
989
|
return;
|
|
933
990
|
}
|
|
934
991
|
|
|
935
992
|
if (_savedHideKeyboardAccessoryView == false) {
|
|
993
|
+
[self __addInputAccessoryView];
|
|
936
994
|
return;
|
|
937
995
|
}
|
|
938
996
|
|
|
@@ -961,6 +1019,22 @@ RCTAutoInsetsProtocol>
|
|
|
961
1019
|
|
|
962
1020
|
object_setClass(subview, newClass);
|
|
963
1021
|
}
|
|
1022
|
+
#endif // TARGET_OS_IOS
|
|
1023
|
+
|
|
1024
|
+
- (void)__addInputAccessoryView {
|
|
1025
|
+
UIView* subview;
|
|
1026
|
+
|
|
1027
|
+
for (UIView* view in _webView.scrollView.subviews) {
|
|
1028
|
+
if([[view.class description] hasSuffix:@"_BPSwizzleHelperWK"])
|
|
1029
|
+
subview = view;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
if(subview == nil) return;
|
|
1033
|
+
|
|
1034
|
+
Class newClass = subview.superclass;
|
|
1035
|
+
|
|
1036
|
+
object_setClass(subview, newClass);
|
|
1037
|
+
}
|
|
964
1038
|
|
|
965
1039
|
// UIScrollViewDelegate method
|
|
966
1040
|
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
|
|
@@ -1131,7 +1205,7 @@ RCTAutoInsetsProtocol>
|
|
|
1131
1205
|
{
|
|
1132
1206
|
#if !TARGET_OS_OSX
|
|
1133
1207
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
|
|
1134
|
-
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
|
1208
|
+
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(__unused UIAlertAction *action) {
|
|
1135
1209
|
completionHandler();
|
|
1136
1210
|
}]];
|
|
1137
1211
|
[[self topViewController] presentViewController:alert animated:YES completion:NULL];
|
|
@@ -1150,10 +1224,10 @@ RCTAutoInsetsProtocol>
|
|
|
1150
1224
|
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
|
|
1151
1225
|
#if !TARGET_OS_OSX
|
|
1152
1226
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
|
|
1153
|
-
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
|
1227
|
+
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(__unused UIAlertAction *action) {
|
|
1154
1228
|
completionHandler(YES);
|
|
1155
1229
|
}]];
|
|
1156
|
-
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
|
|
1230
|
+
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(__unused UIAlertAction *action) {
|
|
1157
1231
|
completionHandler(NO);
|
|
1158
1232
|
}]];
|
|
1159
1233
|
[[self topViewController] presentViewController:alert animated:YES completion:NULL];
|
|
@@ -1178,11 +1252,11 @@ RCTAutoInsetsProtocol>
|
|
|
1178
1252
|
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
|
1179
1253
|
textField.text = defaultText;
|
|
1180
1254
|
}];
|
|
1181
|
-
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
|
1255
|
+
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(__unused UIAlertAction *action) {
|
|
1182
1256
|
completionHandler([[alert.textFields lastObject] text]);
|
|
1183
1257
|
}];
|
|
1184
1258
|
[alert addAction:okAction];
|
|
1185
|
-
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
|
|
1259
|
+
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(__unused UIAlertAction *action) {
|
|
1186
1260
|
completionHandler(nil);
|
|
1187
1261
|
}];
|
|
1188
1262
|
[alert addAction:cancelAction];
|
|
@@ -1257,121 +1331,114 @@ RCTAutoInsetsProtocol>
|
|
|
1257
1331
|
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
|
|
1258
1332
|
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
|
|
1259
1333
|
{
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
if([self isItunesURL:url]) {
|
|
1267
|
-
[self startAppToApp:[NSURL URLWithString:url]];
|
|
1268
|
-
decisionHandler(WKNavigationActionPolicyCancel);
|
|
1269
|
-
} else if([url hasPrefix:@"about:blank"]) {
|
|
1334
|
+
NSString *url = navigationAction.request.URL.absoluteString;
|
|
1335
|
+
|
|
1336
|
+
if([self isItunesURL:url]) {
|
|
1337
|
+
[self startAppToApp:[NSURL URLWithString:url]];
|
|
1338
|
+
decisionHandler(WKNavigationActionPolicyCancel);
|
|
1339
|
+
} else if([url hasPrefix:@"about:blank"]) {
|
|
1270
1340
|
decisionHandler(WKNavigationActionPolicyAllow);
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1341
|
+
} else if(![url hasPrefix:@"http"]) {
|
|
1342
|
+
[self startAppToApp:[NSURL URLWithString:url]];
|
|
1343
|
+
decisionHandler(WKNavigationActionPolicyCancel);
|
|
1344
|
+
} else {
|
|
1275
1345
|
[self webViewRN:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
|
|
1276
|
-
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1346
|
+
}
|
|
1279
1347
|
}
|
|
1280
1348
|
|
|
1281
|
-
|
|
1282
|
-
- (void) webViewRN:(WKWebView *)webView
|
|
1349
|
+
- (void) webViewRN:(WKWebView *)webView
|
|
1283
1350
|
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
|
|
1284
1351
|
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
|
|
1285
1352
|
{
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
WKNavigationType navigationType = navigationAction.navigationType;
|
|
1301
|
-
NSURLRequest *request = navigationAction.request;
|
|
1302
|
-
BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL];
|
|
1303
|
-
BOOL hasTargetFrame = navigationAction.targetFrame != nil;
|
|
1304
|
-
|
|
1305
|
-
if (_onOpenWindow && !hasTargetFrame) {
|
|
1306
|
-
// When OnOpenWindow should be called, we want to prevent the navigation
|
|
1307
|
-
// If not prevented, the `decisionHandler` is called first and after that `createWebViewWithConfiguration` is called
|
|
1308
|
-
// In that order the WebView's ref would be updated with the target URL even if `createWebViewWithConfiguration` does not call `loadRequest`
|
|
1309
|
-
// So the WebView's document stays on the current URL, but the WebView's ref is replaced by the target URL
|
|
1310
|
-
// By preventing the navigation here, we also prevent the WebView's ref mutation
|
|
1311
|
-
// The counterpart is that we have to manually call `_onOpenWindow` here, because no navigation means no call to `createWebViewWithConfiguration`
|
|
1312
|
-
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
|
|
1313
|
-
[event addEntriesFromDictionary: @{@"targetUrl": request.URL.absoluteString}];
|
|
1314
|
-
decisionHandler(WKNavigationActionPolicyCancel);
|
|
1315
|
-
_onOpenWindow(event);
|
|
1316
|
-
return;
|
|
1317
|
-
}
|
|
1353
|
+
static NSDictionary<NSNumber *, NSString *> *navigationTypes;
|
|
1354
|
+
static dispatch_once_t onceToken;
|
|
1355
|
+
|
|
1356
|
+
dispatch_once(&onceToken, ^{
|
|
1357
|
+
navigationTypes = @{
|
|
1358
|
+
@(WKNavigationTypeLinkActivated): @"click",
|
|
1359
|
+
@(WKNavigationTypeFormSubmitted): @"formsubmit",
|
|
1360
|
+
@(WKNavigationTypeBackForward): @"backforward",
|
|
1361
|
+
@(WKNavigationTypeReload): @"reload",
|
|
1362
|
+
@(WKNavigationTypeFormResubmitted): @"formresubmit",
|
|
1363
|
+
@(WKNavigationTypeOther): @"other",
|
|
1364
|
+
};
|
|
1365
|
+
});
|
|
1318
1366
|
|
|
1319
|
-
|
|
1367
|
+
WKNavigationType navigationType = navigationAction.navigationType;
|
|
1368
|
+
NSURLRequest *request = navigationAction.request;
|
|
1369
|
+
BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL];
|
|
1370
|
+
BOOL hasTargetFrame = navigationAction.targetFrame != nil;
|
|
1371
|
+
|
|
1372
|
+
if (_onOpenWindow && !hasTargetFrame) {
|
|
1373
|
+
// When OnOpenWindow should be called, we want to prevent the navigation
|
|
1374
|
+
// If not prevented, the `decisionHandler` is called first and after that `createWebViewWithConfiguration` is called
|
|
1375
|
+
// In that order the WebView's ref would be updated with the target URL even if `createWebViewWithConfiguration` does not call `loadRequest`
|
|
1376
|
+
// So the WebView's document stays on the current URL, but the WebView's ref is replaced by the target URL
|
|
1377
|
+
// By preventing the navigation here, we also prevent the WebView's ref mutation
|
|
1378
|
+
// The counterpart is that we have to manually call `_onOpenWindow` here, because no navigation means no call to `createWebViewWithConfiguration`
|
|
1320
1379
|
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
decisionHandler(WKNavigationActionPolicyCancel);
|
|
1325
|
-
return;
|
|
1326
|
-
}
|
|
1327
|
-
if (self->_onLoadingStart) {
|
|
1328
|
-
// We have this check to filter out iframe requests and whatnot
|
|
1329
|
-
if (isTopFrame) {
|
|
1330
|
-
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
|
|
1331
|
-
[event addEntriesFromDictionary: @{
|
|
1332
|
-
@"url": (request.URL).absoluteString,
|
|
1333
|
-
@"navigationType": navigationTypes[@(navigationType)]
|
|
1334
|
-
}];
|
|
1335
|
-
self->_onLoadingStart(event);
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1339
|
-
// Allow all navigation by default
|
|
1340
|
-
decisionHandler(WKNavigationActionPolicyAllow);
|
|
1341
|
-
});
|
|
1342
|
-
|
|
1343
|
-
}];
|
|
1344
|
-
if (request.mainDocumentURL) {
|
|
1345
|
-
[event addEntriesFromDictionary: @{
|
|
1346
|
-
@"mainDocumentURL": (request.mainDocumentURL).absoluteString,
|
|
1347
|
-
}];
|
|
1348
|
-
}
|
|
1349
|
-
[event addEntriesFromDictionary: @{
|
|
1350
|
-
@"url": (request.URL).absoluteString,
|
|
1351
|
-
@"navigationType": navigationTypes[@(navigationType)],
|
|
1352
|
-
@"isTopFrame": @(isTopFrame),
|
|
1353
|
-
@"hasTargetFrame": @(hasTargetFrame),
|
|
1354
|
-
@"lockIdentifier": @(lockIdentifier)
|
|
1355
|
-
}];
|
|
1356
|
-
_onShouldStartLoadWithRequest(event);
|
|
1357
|
-
// decisionHandler(WKNavigationActionPolicyAllow);
|
|
1380
|
+
[event addEntriesFromDictionary: @{@"targetUrl": request.URL.absoluteString}];
|
|
1381
|
+
decisionHandler(WKNavigationActionPolicyCancel);
|
|
1382
|
+
_onOpenWindow(event);
|
|
1358
1383
|
return;
|
|
1359
|
-
|
|
1384
|
+
}
|
|
1360
1385
|
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1386
|
+
if (_onShouldStartLoadWithRequest) {
|
|
1387
|
+
int lockIdentifier = [[BPCWebViewDecisionManager getInstance] setDecisionHandler: ^(BOOL shouldStart){
|
|
1388
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
1389
|
+
if (!shouldStart) {
|
|
1390
|
+
decisionHandler(WKNavigationActionPolicyCancel);
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
if (self->_onLoadingStart) {
|
|
1394
|
+
// We have this check to filter out iframe requests and whatnot
|
|
1395
|
+
if (isTopFrame) {
|
|
1396
|
+
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
|
|
1397
|
+
[event addEntriesFromDictionary: @{
|
|
1398
|
+
@"url": (request.URL).absoluteString,
|
|
1399
|
+
@"navigationType": navigationTypes[@(navigationType)]
|
|
1400
|
+
}];
|
|
1401
|
+
self->_onLoadingStart(event);
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
// Allow all navigation by default
|
|
1406
|
+
decisionHandler(WKNavigationActionPolicyAllow);
|
|
1407
|
+
});
|
|
1408
|
+
|
|
1409
|
+
}];
|
|
1410
|
+
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
|
|
1411
|
+
if (request.mainDocumentURL) {
|
|
1365
1412
|
[event addEntriesFromDictionary: @{
|
|
1366
|
-
|
|
1367
|
-
@"navigationType": navigationTypes[@(navigationType)]
|
|
1413
|
+
@"mainDocumentURL": (request.mainDocumentURL).absoluteString,
|
|
1368
1414
|
}];
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1415
|
+
}
|
|
1416
|
+
[event addEntriesFromDictionary: @{
|
|
1417
|
+
@"url": (request.URL).absoluteString,
|
|
1418
|
+
@"navigationType": navigationTypes[@(navigationType)],
|
|
1419
|
+
@"isTopFrame": @(isTopFrame),
|
|
1420
|
+
@"hasTargetFrame": @(hasTargetFrame),
|
|
1421
|
+
@"lockIdentifier": @(lockIdentifier)
|
|
1422
|
+
}];
|
|
1423
|
+
_onShouldStartLoadWithRequest(event);
|
|
1424
|
+
// decisionHandler(WKNavigationActionPolicyAllow);
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1372
1427
|
|
|
1373
|
-
|
|
1374
|
-
|
|
1428
|
+
if (_onLoadingStart) {
|
|
1429
|
+
// We have this check to filter out iframe requests and whatnot
|
|
1430
|
+
if (isTopFrame) {
|
|
1431
|
+
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
|
|
1432
|
+
[event addEntriesFromDictionary: @{
|
|
1433
|
+
@"url": (request.URL).absoluteString,
|
|
1434
|
+
@"navigationType": navigationTypes[@(navigationType)]
|
|
1435
|
+
}];
|
|
1436
|
+
_onLoadingStart(event);
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
// Allow all navigation by default
|
|
1441
|
+
decisionHandler(WKNavigationActionPolicyAllow);
|
|
1375
1442
|
}
|
|
1376
1443
|
|
|
1377
1444
|
/**
|
|
@@ -1396,11 +1463,10 @@ RCTAutoInsetsProtocol>
|
|
|
1396
1463
|
decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
|
|
1397
1464
|
{
|
|
1398
1465
|
WKNavigationResponsePolicy policy = WKNavigationResponsePolicyAllow;
|
|
1399
|
-
if (
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1466
|
+
if ([navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) {
|
|
1467
|
+
NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
|
|
1468
|
+
NSInteger statusCode = response.statusCode;
|
|
1469
|
+
if (_onHttpError && navigationResponse.forMainFrame) {
|
|
1404
1470
|
if (statusCode >= 400) {
|
|
1405
1471
|
NSMutableDictionary<NSString *, id> *httpErrorEvent = [self baseEvent];
|
|
1406
1472
|
[httpErrorEvent addEntriesFromDictionary: @{
|
|
@@ -1410,22 +1476,21 @@ RCTAutoInsetsProtocol>
|
|
|
1410
1476
|
|
|
1411
1477
|
_onHttpError(httpErrorEvent);
|
|
1412
1478
|
}
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
}
|
|
1479
|
+
}
|
|
1480
|
+
NSString *disposition = nil;
|
|
1481
|
+
if (@available(iOS 13, macOS 10.15, *)) {
|
|
1482
|
+
disposition = [response valueForHTTPHeaderField:@"Content-Disposition"];
|
|
1483
|
+
}
|
|
1484
|
+
BOOL isAttachment = disposition != nil && [disposition hasPrefix:@"attachment"];
|
|
1485
|
+
if (isAttachment || !navigationResponse.canShowMIMEType) {
|
|
1486
|
+
if (_onFileDownload) {
|
|
1487
|
+
policy = WKNavigationResponsePolicyCancel;
|
|
1488
|
+
|
|
1489
|
+
NSMutableDictionary<NSString *, id> *downloadEvent = [self baseEvent];
|
|
1490
|
+
[downloadEvent addEntriesFromDictionary: @{
|
|
1491
|
+
@"downloadUrl": (response.URL).absoluteString,
|
|
1492
|
+
}];
|
|
1493
|
+
_onFileDownload(downloadEvent);
|
|
1429
1494
|
}
|
|
1430
1495
|
}
|
|
1431
1496
|
}
|
|
@@ -1582,6 +1647,9 @@ didFinishNavigation:(WKNavigation *)navigation
|
|
|
1582
1647
|
{
|
|
1583
1648
|
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
|
|
1584
1649
|
_refreshControl = refreshControl;
|
|
1650
|
+
if(_refreshControlLightMode) {
|
|
1651
|
+
[refreshControl setTintColor:[UIColor whiteColor]];
|
|
1652
|
+
}
|
|
1585
1653
|
[_webView.scrollView addSubview: refreshControl];
|
|
1586
1654
|
[refreshControl addTarget:self action:@selector(pullToRefresh:) forControlEvents: UIControlEventValueChanged];
|
|
1587
1655
|
}
|
|
@@ -1658,7 +1726,6 @@ didFinishNavigation:(WKNavigation *)navigation
|
|
|
1658
1726
|
_webView.scrollView.bounces = _pullToRefreshEnabled || bounces;
|
|
1659
1727
|
}
|
|
1660
1728
|
#endif // !TARGET_OS_OSX
|
|
1661
|
-
|
|
1662
1729
|
|
|
1663
1730
|
- (void)setInjectedJavaScript:(NSString *)source {
|
|
1664
1731
|
_injectedJavaScript = source;
|
|
@@ -1674,15 +1741,16 @@ didFinishNavigation:(WKNavigation *)navigation
|
|
|
1674
1741
|
|
|
1675
1742
|
- (void)setInjectedJavaScriptObject:(NSString *)source
|
|
1676
1743
|
{
|
|
1744
|
+
_injectedJavaScriptObject = source;
|
|
1677
1745
|
self.injectedObjectJsonScript = [
|
|
1678
1746
|
[WKUserScript alloc]
|
|
1679
1747
|
initWithSource: [
|
|
1680
1748
|
NSString
|
|
1681
1749
|
stringWithFormat:
|
|
1682
|
-
@"window.%@
|
|
1750
|
+
@"window.%@ = window.%@ || {};"
|
|
1683
1751
|
"window.%@.injectedObjectJson = function () {"
|
|
1684
1752
|
" return `%@`;"
|
|
1685
|
-
"};", MessageHandlerName, MessageHandlerName, source
|
|
1753
|
+
"};", MessageHandlerName, MessageHandlerName, MessageHandlerName, source
|
|
1686
1754
|
]
|
|
1687
1755
|
injectionTime:WKUserScriptInjectionTimeAtDocumentStart
|
|
1688
1756
|
/* TODO: For a separate (minor) PR: use logic like this (as react-native-wkwebview does) so that messaging can be used in all frames if desired.
|
|
@@ -1730,11 +1798,10 @@ didFinishNavigation:(WKNavigation *)navigation
|
|
|
1730
1798
|
initWithSource: [
|
|
1731
1799
|
NSString
|
|
1732
1800
|
stringWithFormat:
|
|
1733
|
-
|
|
1734
|
-
"
|
|
1735
|
-
"
|
|
1736
|
-
"
|
|
1737
|
-
"};", MessageHandlerName, MessageHandlerName
|
|
1801
|
+
@"window.%@ = window.%@ || {};"
|
|
1802
|
+
"window.%@.postMessage = function (data) {"
|
|
1803
|
+
" window.webkit.messageHandlers.%@.postMessage(String(data));"
|
|
1804
|
+
"};", MessageHandlerName, MessageHandlerName, MessageHandlerName, MessageHandlerName
|
|
1738
1805
|
]
|
|
1739
1806
|
injectionTime:WKUserScriptInjectionTimeAtDocumentStart
|
|
1740
1807
|
/* TODO: For a separate (minor) PR: use logic like this (as react-native-wkwebview does) so that messaging can be used in all frames if desired.
|
|
@@ -1813,8 +1880,8 @@ didFinishNavigation:(WKNavigation *)navigation
|
|
|
1813
1880
|
" })\n"
|
|
1814
1881
|
"})(window.history)\n", HistoryShimName
|
|
1815
1882
|
];
|
|
1816
|
-
WKUserScript *
|
|
1817
|
-
[wkWebViewConfig.userContentController addUserScript:
|
|
1883
|
+
WKUserScript *userScript = [[WKUserScript alloc] initWithSource:html5HistoryAPIShimSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
|
|
1884
|
+
[wkWebViewConfig.userContentController addUserScript:userScript];
|
|
1818
1885
|
|
|
1819
1886
|
if(_sharedCookiesEnabled) {
|
|
1820
1887
|
// More info to sending cookies with WKWebView
|
|
@@ -1826,9 +1893,7 @@ didFinishNavigation:(WKNavigation *)navigation
|
|
|
1826
1893
|
if(!_incognito && !_cacheEnabled) {
|
|
1827
1894
|
wkWebViewConfig.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
|
|
1828
1895
|
}
|
|
1829
|
-
[self syncCookiesToWebView:^{
|
|
1830
|
-
[wkWebViewConfig.websiteDataStore.httpCookieStore addObserver:self];
|
|
1831
|
-
}];
|
|
1896
|
+
[self syncCookiesToWebView:^{}];
|
|
1832
1897
|
} else {
|
|
1833
1898
|
NSMutableString *script = [NSMutableString string];
|
|
1834
1899
|
|
|
@@ -1917,7 +1982,6 @@ didFinishNavigation:(WKNavigation *)navigation
|
|
|
1917
1982
|
return request;
|
|
1918
1983
|
}
|
|
1919
1984
|
|
|
1920
|
-
|
|
1921
1985
|
#pragma mark - WebView Javascript
|
|
1922
1986
|
|
|
1923
1987
|
-(void) doJavascript:(NSString*) script {
|
|
@@ -2066,5 +2130,3 @@ didFinishNavigation:(WKNavigation *)navigation
|
|
|
2066
2130
|
}
|
|
2067
2131
|
|
|
2068
2132
|
@end
|
|
2069
|
-
|
|
2070
|
-
|