Skip to content

Commit

Permalink
fix: alerts could freeze the application (#1437)
Browse files Browse the repository at this point in the history
Closes GH-1120.
Closes GH-1121.
Closes GH-1429.
  • Loading branch information
dpogue authored Aug 28, 2024
1 parent c3d5949 commit 5dede30
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ - (void)pluginInitialize
self.CDV_ASSETS_URL = [NSString stringWithFormat:@"%@://%@", scheme, hostname];
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,24 @@

#import <WebKit/WebKit.h>

#ifdef NS_SWIFT_UI_ACTOR
#define CDV_SWIFT_UI_ACTOR NS_SWIFT_UI_ACTOR
#else
#define CDV_SWIFT_UI_ACTOR
#endif

@class CDVViewController;

NS_ASSUME_NONNULL_BEGIN

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

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

- (instancetype)initWithTitle:(NSString*)title;
- (instancetype)initWithViewController:(CDVViewController*)vc;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,32 @@ Licensed to the Apache Software Foundation (ASF) under one
*/

#import "CDVWebViewUIDelegate.h"
#import <Cordova/CDVViewController.h>

@interface CDVWebViewUIDelegate ()

@property (nonatomic, weak) CDVViewController *viewController;

@end

@implementation CDVWebViewUIDelegate
{
NSMutableArray<UIViewController *> *windows;
}

- (instancetype)initWithTitle:(NSString*)title
- (instancetype)initWithViewController:(CDVViewController *)vc
{
self = [super init];

if (self) {
self.title = title;
self.viewController = vc;
self.title = vc.title;
windows = [[NSMutableArray alloc] init];
}

return self;
}

- (void) webView:(WKWebView*)webView runJavaScriptAlertPanelWithMessage:(NSString*)message
initiatedByFrame:(WKFrameInfo*)frame completionHandler:(void (^)(void))completionHandler
- (void)webView:(WKWebView*)webView runJavaScriptAlertPanelWithMessage:(NSString*)message initiatedByFrame:(WKFrameInfo*)frame completionHandler:(CDV_SWIFT_UI_ACTOR void (^)(void))completionHandler
{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title
message:message
Expand All @@ -49,13 +59,10 @@ - (void) webView:(WKWebView*)webView runJavaScriptAlertPanelWithMessage:(NSS

[alert addAction:ok];

UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController;

[rootController presentViewController:alert animated:YES completion:nil];
[[self topViewController] presentViewController:alert animated:YES completion:nil];
}

- (void) webView:(WKWebView*)webView runJavaScriptConfirmPanelWithMessage:(NSString*)message
initiatedByFrame:(WKFrameInfo*)frame completionHandler:(void (^)(BOOL result))completionHandler
- (void)webView:(WKWebView*)webView runJavaScriptConfirmPanelWithMessage:(NSString*)message initiatedByFrame:(WKFrameInfo*)frame completionHandler:(CDV_SWIFT_UI_ACTOR void (^)(BOOL result))completionHandler
{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title
message:message
Expand All @@ -80,14 +87,10 @@ - (void) webView:(WKWebView*)webView runJavaScriptConfirmPanelWithMessage:(N
}];
[alert addAction:cancel];

UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController;

[rootController presentViewController:alert animated:YES completion:nil];
[[self topViewController] presentViewController:alert animated:YES completion:nil];
}

- (void) webView:(WKWebView*)webView runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt
defaultText:(NSString*)defaultText initiatedByFrame:(WKFrameInfo*)frame
completionHandler:(void (^)(NSString* result))completionHandler
- (void)webView:(WKWebView*)webView runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt defaultText:(NSString*)defaultText initiatedByFrame:(WKFrameInfo*)frame completionHandler:(CDV_SWIFT_UI_ACTOR void (^)(NSString* result))completionHandler
{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title
message:prompt
Expand Down Expand Up @@ -116,12 +119,10 @@ - (void) webView:(WKWebView*)webView runJavaScriptTextInputPanelWithPrompt:
textField.text = defaultText;
}];

UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController;

[rootController presentViewController:alert animated:YES completion:nil];
[[self topViewController] presentViewController:alert animated:YES completion:nil];
}

- (WKWebView*) webView:(WKWebView*)webView createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration forNavigationAction:(WKNavigationAction*)navigationAction windowFeatures:(WKWindowFeatures*)windowFeatures
- (nullable WKWebView*)webView:(WKWebView*)webView createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration forNavigationAction:(WKNavigationAction*)navigationAction windowFeatures:(WKWindowFeatures*)windowFeatures
{
if (!navigationAction.targetFrame.isMainFrame) {
if (self.allowNewWindows) {
Expand All @@ -135,8 +136,7 @@ - (WKWebView*) webView:(WKWebView*)webView createWebViewWithConfiguration:(WKWeb

[windows addObject:vc];

UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController;
[rootController presentViewController:vc animated:YES completion:nil];
[[self topViewController] presentViewController:vc animated:YES completion:nil];
return v;
} else {
[webView loadRequest:navigationAction.request];
Expand All @@ -159,5 +159,17 @@ - (void)webViewDidClose:(WKWebView*)webView
// We do not allow closing the primary WebView
}

#pragma mark - Utility Methods

- (nullable UIViewController *)topViewController
{
UIViewController *vc = self.viewController;

while (vc.presentedViewController != nil && ![vc.presentedViewController isBeingDismissed]) {
vc = vc.presentedViewController;
}

return vc;
}

@end

0 comments on commit 5dede30

Please sign in to comment.