Skip to content

Commit

Permalink
Don't silently ignore creation of new windows
Browse files Browse the repository at this point in the history
Currently, attempts to create new windows (via links with
`target="_blank"` or JS `window.open`) for pages within the application
have no effect and are silently ignored.
(Links to pages outside the application trigger the allow-intent
functionality and open in Safari.)

With this PR, the default behaviour will be to open those links in the
**same** Web View (without creating a new window).

This also introduces a preference (`AllowNewWindows`) that allows the
creation of a new UIViewController to present the new page in a new Web
View frame on top of the existing Web View.
**Note:** This new window provides no controls, so it can only be closed
with `window.close()` in JS.
  • Loading branch information
dpogue committed Jun 17, 2020
1 parent c90fad4 commit 35e017c
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ - (void)pluginInitialize
self.CDV_ASSETS_URL = [NSString stringWithFormat:@"%@://%@", scheme, hostname];
}

self.uiDelegate = [[CDVWebViewUIDelegate alloc] initWithTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]];
CDVWebViewUIDelegate* uiDelegate = [[CDVWebViewUIDelegate alloc] initWithTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]];
uiDelegate.allowNewWindows = [settings cordovaBoolSettingForKey:@"AllowNewWindows" defaultValue:NO];
self.uiDelegate = uiDelegate;

CDVWebViewWeakScriptMessageHandler *weakScriptMessageHandler = [[CDVWebViewWeakScriptMessageHandler alloc] initWithScriptMessageHandler:self];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@
#import <WebKit/WebKit.h>

@interface CDVWebViewUIDelegate : NSObject <WKUIDelegate>
{
NSMutableArray<UIViewController*>* windows;
}

@property (nonatomic, copy) NSString* title;
@property (nonatomic, assign) BOOL allowNewWindows;

- (instancetype)initWithTitle:(NSString*)title;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ - (instancetype)initWithTitle:(NSString*)title
self = [super init];
if (self) {
self.title = title;
windows = [[NSMutableArray alloc] init];
}

return self;
Expand Down Expand Up @@ -120,4 +121,43 @@ - (void) webView:(WKWebView*)webView runJavaScriptTextInputPanelWithPrompt:
[rootController presentViewController:alert animated:YES completion:nil];
}

- (WKWebView*) webView:(WKWebView*)webView createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration forNavigationAction:(WKNavigationAction*)navigationAction windowFeatures:(WKWindowFeatures*)windowFeatures
{
if (!navigationAction.targetFrame.isMainFrame) {
if (self.allowNewWindows) {
WKWebView* v = [[WKWebView alloc] initWithFrame:webView.frame configuration:configuration];
v.UIDelegate = webView.UIDelegate;
v.navigationDelegate = webView.navigationDelegate;

UIViewController* vc = [[UIViewController alloc] init];
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
vc.view = v;

[windows addObject:vc];

UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController;
[rootController presentViewController:vc animated:YES completion:nil];
return v;
} else {
[webView loadRequest:navigationAction.request];
}
}

return nil;
}

- (void)webViewDidClose:(WKWebView*)webView
{
for (UIViewController* vc in windows) {
if (vc.view == webView) {
[vc dismissViewControllerAnimated:YES completion:nil];
[windows removeObject:vc];
break;
}
}

// We do not allow closing the primary WebView
}


@end

0 comments on commit 35e017c

Please sign in to comment.