Skip to content

Commit 0fd43ae

Browse files
dpa99cjanpio
authored andcommitted
Fixes loadAfterBeforeload on iOS. Resolves #349. (#350)
For both UIWebView and WKWebView implementations on iOS. <!-- Please make sure the checklist boxes are all checked before submitting the PR. The checklist is intended as a quick reference, for complete details please see our Contributor Guidelines: http://cordova.apache.org/contribute/contribute_guidelines.html Thanks! --> ### Platforms affected iOS ### What does this PR do? Fixes `beforeload` event (introduced by #276) for iOS ### What testing has been done on this change? Tested both allow & deny loading of URL with both iOS implementations in [test container app](https://github.com/dpa99c/cordova-plugin-inappbrowser-wkwebview-test) (ignore its README). - To test with UIWebView use options: `beforeload=yes,usewkwebview=no` - To test with WKWebView use options: `beforeload=yes,usewkwebview=yes` ### Checklist - [x] [Reported an issue](http://cordova.apache.org/contribute/issues.html) in the JIRA database - [x] Commit message follows the format: "CB-3232: (android) Fix bug with resolving file paths", where CB-xxxx is the JIRA ID & "android" is the platform affected. - [x] Added automated test coverage as appropriate for this change. closes #349
1 parent 3b82c16 commit 0fd43ae

File tree

4 files changed

+68
-10
lines changed

4 files changed

+68
-10
lines changed

src/ios/CDVInAppBrowser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
- (void)injectScriptCode:(CDVInvokedUrlCommand*)command;
3131
- (void)show:(CDVInvokedUrlCommand*)command;
3232
- (void)hide:(CDVInvokedUrlCommand*)command;
33+
- (void)loadAfterBeforeload:(CDVInvokedUrlCommand*)command;
3334

3435
@end
3536

src/ios/CDVInAppBrowser.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,14 @@ - (void)injectStyleFile:(CDVInvokedUrlCommand*)command
121121
}
122122
}
123123

124+
- (void)loadAfterBeforeload:(CDVInvokedUrlCommand*)command
125+
{
126+
if(self.usewkwebview){
127+
[[CDVWKInAppBrowser getInstance] loadAfterBeforeload:command];
128+
}else{
129+
[[CDVUIInAppBrowser getInstance] loadAfterBeforeload:command];
130+
}
131+
}
132+
124133

125134
@end

src/ios/CDVWKInAppBrowser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
@class CDVWKInAppBrowserViewController;
2828

2929
@interface CDVWKInAppBrowser : CDVPlugin {
30+
@private
31+
BOOL _useBeforeload;
32+
BOOL _waitForBeforeload;
3033
}
3134

3235
@property (nonatomic, retain) CDVWKInAppBrowser* instance;
@@ -40,6 +43,7 @@
4043
- (void)injectScriptCode:(CDVInvokedUrlCommand*)command;
4144
- (void)show:(CDVInvokedUrlCommand*)command;
4245
- (void)hide:(CDVInvokedUrlCommand*)command;
46+
- (void)loadAfterBeforeload:(CDVInvokedUrlCommand*)command;
4347

4448
@end
4549

src/ios/CDVWKInAppBrowser.m

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ - (void)pluginInitialize
6060
instance = self;
6161
_previousStatusBarStyle = -1;
6262
_callbackIdPattern = nil;
63+
_useBeforeload = NO;
64+
_waitForBeforeload = NO;
6365
}
6466

6567
- (id)settingForKey:(NSString*)key
@@ -263,6 +265,9 @@ - (void)openInInAppBrowser:(NSURL*)url withOptions:(NSString*)options
263265
}
264266
}
265267

268+
// use of beforeload event
269+
_useBeforeload = browserOptions.beforeload;
270+
_waitForBeforeload = browserOptions.beforeload;
266271

267272
[self.inAppBrowserViewController navigateTo:url];
268273
[self show:nil withNoAnimate:browserOptions.hidden];
@@ -370,6 +375,27 @@ - (void)openInSystem:(NSURL*)url
370375
[[UIApplication sharedApplication] openURL:url];
371376
}
372377

378+
- (void)loadAfterBeforeload:(CDVInvokedUrlCommand*)command
379+
{
380+
NSString* urlStr = [command argumentAtIndex:0];
381+
382+
if (!_useBeforeload) {
383+
NSLog(@"unexpected loadAfterBeforeload called without feature beforeload=yes");
384+
}
385+
if (self.inAppBrowserViewController == nil) {
386+
NSLog(@"Tried to invoke loadAfterBeforeload on IAB after it was closed.");
387+
return;
388+
}
389+
if (urlStr == nil) {
390+
NSLog(@"loadAfterBeforeload called with nil argument, ignoring.");
391+
return;
392+
}
393+
394+
NSURL* url = [NSURL URLWithString:urlStr];
395+
_waitForBeforeload = NO;
396+
[self.inAppBrowserViewController navigateTo:url];
397+
}
398+
373399
// This is a helper method for the inject{Script|Style}{Code|File} API calls, which
374400
// provides a consistent method for injecting JavaScript code into the document.
375401
//
@@ -480,16 +506,29 @@ - (BOOL)isValidCallbackId:(NSString *)callbackId
480506
* to the InAppBrowser plugin. Care has been taken that other callbacks cannot be triggered, and that no
481507
* other code execution is possible.
482508
*/
483-
- (BOOL)webView:(WKWebView*)theWebView decidePolicyForNavigationAction:(NSURLRequest*)request
484-
{
485-
NSURL* url = request.URL;
486-
BOOL isTopLevelNavigation = [request.URL isEqual:[request mainDocumentURL]];
509+
- (void)webView:(WKWebView *)theWebView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
510+
511+
NSURL* url = navigationAction.request.URL;
512+
NSURL* mainDocumentURL = navigationAction.request.mainDocumentURL;
513+
BOOL isTopLevelNavigation = [url isEqual:mainDocumentURL];
514+
BOOL shouldStart = YES;
515+
516+
// When beforeload=yes, on first URL change, initiate JS callback. Only after the beforeload event, continue.
517+
if (_waitForBeforeload && isTopLevelNavigation) {
518+
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
519+
messageAsDictionary:@{@"type":@"beforeload", @"url":[url absoluteString]}];
520+
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
521+
522+
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
523+
decisionHandler(WKNavigationActionPolicyCancel);
524+
return;
525+
}
487526

488527
//if is an app store link, let the system handle it, otherwise it fails to load it
489528
if ([[ url scheme] isEqualToString:@"itms-appss"] || [[ url scheme] isEqualToString:@"itms-apps"]) {
490529
[theWebView stopLoading];
491530
[self openInSystem:url];
492-
return NO;
531+
shouldStart = NO;
493532
}
494533
else if ((self.callbackId != nil) && isTopLevelNavigation) {
495534
// Send a loadstart event for each top-level navigation (includes redirects).
@@ -499,8 +538,16 @@ - (BOOL)webView:(WKWebView*)theWebView decidePolicyForNavigationAction:(NSURLReq
499538

500539
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
501540
}
541+
542+
if (_useBeforeload && isTopLevelNavigation) {
543+
_waitForBeforeload = YES;
544+
}
502545

503-
return YES;
546+
if(shouldStart){
547+
decisionHandler(WKNavigationActionPolicyAllow);
548+
}else{
549+
decisionHandler(WKNavigationActionPolicyCancel);
550+
}
504551
}
505552

506553
#pragma mark WKScriptMessageHandler delegate
@@ -1072,10 +1119,7 @@ - (void)webView:(WKWebView *)theWebView decidePolicyForNavigationAction:(WKNavig
10721119
self.currentURL = url;
10731120
}
10741121

1075-
[self.navigationDelegate webView:theWebView decidePolicyForNavigationAction:navigationAction.request];
1076-
1077-
decisionHandler(WKNavigationActionPolicyAllow);
1078-
1122+
[self.navigationDelegate webView:theWebView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
10791123
}
10801124

10811125
- (void)webView:(WKWebView *)theWebView didFinishNavigation:(WKNavigation *)navigation

0 commit comments

Comments
 (0)