Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: alerts could freeze the application #1437

Merged
merged 1 commit into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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