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.
Files changed (101) hide show
  1. package/README.md +53 -69
  2. package/android/build.gradle +1 -11
  3. package/android/gradle.properties +0 -42
  4. package/android/src/main/AndroidManifest.xml +3 -1
  5. package/android/src/main/AndroidManifestNew.xml +97 -0
  6. package/android/src/main/java/kr/co/bootpay/webview/BPCWebChromeClient.java +54 -10
  7. package/android/src/main/java/kr/co/bootpay/webview/BPCWebView.java +101 -68
  8. package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewClient.java +68 -60
  9. package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewManagerImpl.kt +119 -65
  10. package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewMessagingModule.kt +9 -0
  11. package/android/src/main/java/kr/co/bootpay/webview/BPCWebViewModuleImpl.java +1 -1
  12. package/android/src/main/java/kr/co/bootpay/webview/BootpayUrlHelper.java +4 -12
  13. package/android/src/newarch/{com/reactnativecommunity → kr/co/bootpay}/webview/BPCWebViewManager.java +118 -109
  14. package/android/src/newarch/{com/reactnativecommunity → kr/co/bootpay}/webview/BPCWebViewModule.java +1 -1
  15. package/android/src/{main/java → oldarch}/kr/co/bootpay/webview/BPCWebViewManager.java +63 -58
  16. package/android/src/{main/java → oldarch}/kr/co/bootpay/webview/BPCWebViewModule.java +1 -1
  17. package/apple/BPCWebView.mm +39 -30
  18. package/apple/BPCWebViewImpl.h +10 -0
  19. package/apple/BPCWebViewImpl.m +267 -205
  20. package/apple/BPCWebViewManager.mm +5 -24
  21. package/apple/BPCWebViewModule.h +23 -0
  22. package/apple/BPCWebViewModule.mm +34 -0
  23. package/apple/RCTConvert+WKDataDetectorTypes.h +11 -0
  24. package/apple/RCTConvert+WKDataDetectorTypes.m +27 -0
  25. package/index.d.ts +54 -48
  26. package/ios/RNCWebView.xcodeproj/project.pbxproj +24 -24
  27. package/ios/RNCWebView.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  28. package/ios/RNCWebView.xcodeproj/project.xcworkspace/xcuserdata/taesupyoon.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  29. package/ios/RNCWebView.xcodeproj/xcuserdata/taesupyoon.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  30. package/lib/BPCWebViewNativeComponent.d.ts +24 -25
  31. package/lib/BPCWebViewNativeComponent.js +1 -1
  32. package/lib/{NativeBPCWebView.d.ts → NativeBPCWebViewModule.d.ts} +2 -5
  33. package/lib/{NativeBPCWebView.js → NativeBPCWebViewModule.js} +1 -1
  34. package/lib/WebView.android.d.ts +0 -1
  35. package/lib/WebView.android.js +1 -1
  36. package/lib/WebView.d.ts +0 -1
  37. package/lib/WebView.ios.d.ts +0 -1
  38. package/lib/WebView.ios.js +1 -1
  39. package/lib/WebView.js +1 -1
  40. package/lib/WebView.macos.d.ts +0 -1
  41. package/lib/WebView.macos.js +1 -1
  42. package/lib/WebView.styles.d.ts +37 -11
  43. package/lib/WebView.styles.js +1 -1
  44. package/lib/WebView.windows.d.ts +0 -1
  45. package/lib/WebView.windows.js +1 -1
  46. package/lib/WebViewNativeComponent.macos.d.ts +1 -2
  47. package/lib/WebViewNativeComponent.windows.d.ts +1 -2
  48. package/lib/WebViewShared.d.ts +0 -1
  49. package/lib/WebViewShared.js +1 -1
  50. package/lib/WebViewTypes.d.ts +51 -3
  51. package/lib/WebViewTypes.js +1 -1
  52. package/lib/index.d.ts +0 -1
  53. package/macos/RNCWebView.xcodeproj/project.pbxproj +36 -36
  54. package/package.json +12 -11
  55. package/react-native-webview-bootpay.podspec +2 -2
  56. package/react-native.config.js +1 -5
  57. package/src/BPCWebViewNativeComponent.ts +143 -79
  58. package/src/NativeBPCWebViewModule.ts +13 -0
  59. package/src/WebView.android.tsx +295 -190
  60. package/src/WebView.ios.tsx +253 -186
  61. package/src/WebView.macos.tsx +220 -152
  62. package/src/WebView.styles.ts +9 -12
  63. package/src/WebView.tsx +14 -7
  64. package/src/WebView.windows.tsx +180 -126
  65. package/src/WebViewNativeComponent.macos.ts +4 -5
  66. package/src/WebViewNativeComponent.windows.ts +6 -8
  67. package/src/WebViewShared.tsx +139 -91
  68. package/src/WebViewTypes.ts +80 -35
  69. package/src/__tests__/WebViewShared-test.js +170 -55
  70. package/windows/ReactNativeWebView/ReactNativeWebView.vcxproj +8 -17
  71. package/windows/ReactNativeWebView/ReactPackageProvider.cpp +5 -1
  72. package/windows/ReactNativeWebView/ReactWebView.cpp +73 -6
  73. package/windows/ReactNativeWebView/ReactWebView.h +11 -1
  74. package/windows/ReactNativeWebView/ReactWebView.idl +12 -3
  75. package/windows/ReactNativeWebView/ReactWebView2.cpp +294 -129
  76. package/windows/ReactNativeWebView/ReactWebView2.h +42 -5
  77. package/windows/ReactNativeWebView/ReactWebView2Manager.cpp +60 -34
  78. package/windows/ReactNativeWebView/ReactWebView2Manager.h +4 -4
  79. package/windows/ReactNativeWebView/ReactWebViewHelpers.cpp +70 -0
  80. package/windows/ReactNativeWebView/ReactWebViewHelpers.h +16 -0
  81. package/windows/ReactNativeWebView/ReactWebViewManager.cpp +22 -3
  82. package/windows/ReactNativeWebView/ReactWebViewManager.h +6 -1
  83. package/windows/ReactNativeWebView/pch.h +11 -7
  84. package/windows/ReactNativeWebView.sln +14 -14
  85. package/ios/main.jsbundle +0 -457
  86. package/lib/BPCWebViewNativeComponent.d.ts.map +0 -1
  87. package/lib/NativeBPCWebView.d.ts.map +0 -1
  88. package/lib/WebView.android.d.ts.map +0 -1
  89. package/lib/WebView.d.ts.map +0 -1
  90. package/lib/WebView.ios.d.ts.map +0 -1
  91. package/lib/WebView.macos.d.ts.map +0 -1
  92. package/lib/WebView.styles.d.ts.map +0 -1
  93. package/lib/WebView.windows.d.ts.map +0 -1
  94. package/lib/WebViewNativeComponent.macos.d.ts.map +0 -1
  95. package/lib/WebViewNativeComponent.windows.d.ts.map +0 -1
  96. package/lib/WebViewShared.d.ts.map +0 -1
  97. package/lib/WebViewTypes.d.ts.map +0 -1
  98. package/lib/index.d.ts.map +0 -1
  99. package/src/NativeBPCWebView.ts +0 -14
  100. package/windows/ReactNativeWebView/packages.config +0 -5
  101. /package/android/src/main/java/kr/co/bootpay/webview/{BPCWebviewWrapper.kt → BPCWebViewWrapper.kt} +0 -0
@@ -18,14 +18,14 @@
18
18
  #import "objc/runtime.h"
19
19
 
20
20
  static NSTimer *keyboardTimer;
21
- static NSString *const HistoryShimName = @"ReactNativeHistoryShim";
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 !TARGET_OS_OSX
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 // !TARGET_OS_OSX
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 *BPCWebView = (BPCWebViewImpl *)[self superview];
107
- RCTAssert([BPCWebView isKindOfClass:[BPCWebView class]], @"superview must be an BPCWebViewImpl");
108
- if (![BPCWebView scrollEnabled]) {
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-bootpay/react-native-webview-bootpay/issues/62
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 !TARGET_OS_OSX
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-bootpay/react-native-webview-bootpay/issues/62
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 // !TARGET_OS_OSX
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
- // When a long press ends, bring up our custom UIMenu if defined
250
- if (self.menuItems.count == 0) {
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 setMenuVisible:NO animated:YES];
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
- menuController.menuItems = menuControllerItems;
269
- [menuController setMenuVisible:YES animated:YES];
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
- if (!navigationAction.targetFrame.isMainFrame) {
356
-
357
- NSString *url = navigationAction.request.URL.absoluteString;
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
- [webView loadRequest:navigationAction.request];
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 !TARGET_OS_OSX
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 // !TARGET_OS_OSX
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
- NSString *url = navigationAction.request.URL.absoluteString;
1261
-
1262
- // _beforeUrl = url;
1263
-
1264
- // [self updateBlindViewIfNaverLogin:url];
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
- } else if(![url hasPrefix:@"http"]) {
1272
- [self startAppToApp:[NSURL URLWithString:url]];
1273
- decisionHandler(WKNavigationActionPolicyCancel);
1274
- } else {
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
- //decisionHandler(WKNavigationActionPolicyAllow);
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
- static NSDictionary<NSNumber *, NSString *> *navigationTypes;
1287
- static dispatch_once_t onceToken;
1288
-
1289
- dispatch_once(&onceToken, ^{
1290
- navigationTypes = @{
1291
- @(WKNavigationTypeLinkActivated): @"click",
1292
- @(WKNavigationTypeFormSubmitted): @"formsubmit",
1293
- @(WKNavigationTypeBackForward): @"backforward",
1294
- @(WKNavigationTypeReload): @"reload",
1295
- @(WKNavigationTypeFormResubmitted): @"formresubmit",
1296
- @(WKNavigationTypeOther): @"other",
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
- if (_onShouldStartLoadWithRequest) {
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
- int lockIdentifier = [[BPCWebViewDecisionManager getInstance] setDecisionHandler: ^(BOOL shouldStart){
1322
- dispatch_async(dispatch_get_main_queue(), ^{
1323
- if (!shouldStart) {
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
- if (_onLoadingStart) {
1362
- // We have this check to filter out iframe requests and whatnot
1363
- if (isTopFrame) {
1364
- NSMutableDictionary<NSString *, id> *event = [self baseEvent];
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
- @"url": (request.URL).absoluteString,
1367
- @"navigationType": navigationTypes[@(navigationType)]
1413
+ @"mainDocumentURL": (request.mainDocumentURL).absoluteString,
1368
1414
  }];
1369
- _onLoadingStart(event);
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
- // Allow all navigation by default
1374
- decisionHandler(WKNavigationActionPolicyAllow);
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 (_onHttpError && navigationResponse.forMainFrame) {
1400
- if ([navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) {
1401
- NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
1402
- NSInteger statusCode = response.statusCode;
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
- NSString *disposition = nil;
1415
- if (@available(iOS 13, macOS 10.15, *)) {
1416
- disposition = [response valueForHTTPHeaderField:@"Content-Disposition"];
1417
- }
1418
- BOOL isAttachment = disposition != nil && [disposition hasPrefix:@"attachment"];
1419
- if (isAttachment || !navigationResponse.canShowMIMEType) {
1420
- if (_onFileDownload) {
1421
- policy = WKNavigationResponsePolicyCancel;
1422
-
1423
- NSMutableDictionary<NSString *, id> *downloadEvent = [self baseEvent];
1424
- [downloadEvent addEntriesFromDictionary: @{
1425
- @"downloadUrl": (response.URL).absoluteString,
1426
- }];
1427
- _onFileDownload(downloadEvent);
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
- @"window.%@ = {"
1734
- " postMessage: function (data) {"
1735
- " window.webkit.messageHandlers.%@.postMessage(String(data));"
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 *script = [[WKUserScript alloc] initWithSource:html5HistoryAPIShimSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
1817
- [wkWebViewConfig.userContentController addUserScript:script];
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
-