Skip to content

Commit 5dede30

Browse files
authored
fix: alerts could freeze the application (#1437)
Closes GH-1120. Closes GH-1121. Closes GH-1429.
1 parent c3d5949 commit 5dede30

File tree

3 files changed

+51
-28
lines changed

3 files changed

+51
-28
lines changed

CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,8 @@ - (void)pluginInitialize
192192
self.CDV_ASSETS_URL = [NSString stringWithFormat:@"%@://%@", scheme, hostname];
193193
}
194194

195-
CDVWebViewUIDelegate* uiDelegate = [[CDVWebViewUIDelegate alloc] initWithTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]];
195+
CDVWebViewUIDelegate* uiDelegate = [[CDVWebViewUIDelegate alloc] initWithViewController:vc];
196+
uiDelegate.title = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
196197
uiDelegate.allowNewWindows = [settings cordovaBoolSettingForKey:@"AllowNewWindows" defaultValue:NO];
197198
self.uiDelegate = uiDelegate;
198199

CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewUIDelegate.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,24 @@
1919

2020
#import <WebKit/WebKit.h>
2121

22+
#ifdef NS_SWIFT_UI_ACTOR
23+
#define CDV_SWIFT_UI_ACTOR NS_SWIFT_UI_ACTOR
24+
#else
25+
#define CDV_SWIFT_UI_ACTOR
26+
#endif
27+
28+
@class CDVViewController;
29+
30+
NS_ASSUME_NONNULL_BEGIN
31+
32+
CDV_SWIFT_UI_ACTOR
2233
@interface CDVWebViewUIDelegate : NSObject <WKUIDelegate>
23-
{
24-
NSMutableArray<UIViewController*>* windows;
25-
}
2634

27-
@property (nonatomic, copy) NSString* title;
35+
@property (nonatomic, nullable, copy) NSString* title;
2836
@property (nonatomic, assign) BOOL allowNewWindows;
2937

30-
- (instancetype)initWithTitle:(NSString*)title;
38+
- (instancetype)initWithViewController:(CDVViewController*)vc;
3139

3240
@end
41+
42+
NS_ASSUME_NONNULL_END

CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewUIDelegate.m

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,32 @@ Licensed to the Apache Software Foundation (ASF) under one
1818
*/
1919

2020
#import "CDVWebViewUIDelegate.h"
21+
#import <Cordova/CDVViewController.h>
22+
23+
@interface CDVWebViewUIDelegate ()
24+
25+
@property (nonatomic, weak) CDVViewController *viewController;
26+
27+
@end
2128

2229
@implementation CDVWebViewUIDelegate
30+
{
31+
NSMutableArray<UIViewController *> *windows;
32+
}
2333

24-
- (instancetype)initWithTitle:(NSString*)title
34+
- (instancetype)initWithViewController:(CDVViewController *)vc
2535
{
2636
self = [super init];
37+
2738
if (self) {
28-
self.title = title;
39+
self.viewController = vc;
40+
self.title = vc.title;
2941
windows = [[NSMutableArray alloc] init];
3042
}
31-
3243
return self;
3344
}
3445

35-
- (void) webView:(WKWebView*)webView runJavaScriptAlertPanelWithMessage:(NSString*)message
36-
initiatedByFrame:(WKFrameInfo*)frame completionHandler:(void (^)(void))completionHandler
46+
- (void)webView:(WKWebView*)webView runJavaScriptAlertPanelWithMessage:(NSString*)message initiatedByFrame:(WKFrameInfo*)frame completionHandler:(CDV_SWIFT_UI_ACTOR void (^)(void))completionHandler
3747
{
3848
UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title
3949
message:message
@@ -49,13 +59,10 @@ - (void) webView:(WKWebView*)webView runJavaScriptAlertPanelWithMessage:(NSS
4959

5060
[alert addAction:ok];
5161

52-
UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController;
53-
54-
[rootController presentViewController:alert animated:YES completion:nil];
62+
[[self topViewController] presentViewController:alert animated:YES completion:nil];
5563
}
5664

57-
- (void) webView:(WKWebView*)webView runJavaScriptConfirmPanelWithMessage:(NSString*)message
58-
initiatedByFrame:(WKFrameInfo*)frame completionHandler:(void (^)(BOOL result))completionHandler
65+
- (void)webView:(WKWebView*)webView runJavaScriptConfirmPanelWithMessage:(NSString*)message initiatedByFrame:(WKFrameInfo*)frame completionHandler:(CDV_SWIFT_UI_ACTOR void (^)(BOOL result))completionHandler
5966
{
6067
UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title
6168
message:message
@@ -80,14 +87,10 @@ - (void) webView:(WKWebView*)webView runJavaScriptConfirmPanelWithMessage:(N
8087
}];
8188
[alert addAction:cancel];
8289

83-
UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController;
84-
85-
[rootController presentViewController:alert animated:YES completion:nil];
90+
[[self topViewController] presentViewController:alert animated:YES completion:nil];
8691
}
8792

88-
- (void) webView:(WKWebView*)webView runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt
89-
defaultText:(NSString*)defaultText initiatedByFrame:(WKFrameInfo*)frame
90-
completionHandler:(void (^)(NSString* result))completionHandler
93+
- (void)webView:(WKWebView*)webView runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt defaultText:(NSString*)defaultText initiatedByFrame:(WKFrameInfo*)frame completionHandler:(CDV_SWIFT_UI_ACTOR void (^)(NSString* result))completionHandler
9194
{
9295
UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title
9396
message:prompt
@@ -116,12 +119,10 @@ - (void) webView:(WKWebView*)webView runJavaScriptTextInputPanelWithPrompt:
116119
textField.text = defaultText;
117120
}];
118121

119-
UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController;
120-
121-
[rootController presentViewController:alert animated:YES completion:nil];
122+
[[self topViewController] presentViewController:alert animated:YES completion:nil];
122123
}
123124

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

136137
[windows addObject:vc];
137138

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

162+
#pragma mark - Utility Methods
163+
164+
- (nullable UIViewController *)topViewController
165+
{
166+
UIViewController *vc = self.viewController;
167+
168+
while (vc.presentedViewController != nil && ![vc.presentedViewController isBeingDismissed]) {
169+
vc = vc.presentedViewController;
170+
}
171+
172+
return vc;
173+
}
162174

163175
@end

0 commit comments

Comments
 (0)