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

app hang while showing alert when select dropdown box is actively showing #1047

Open
samyc1201 opened this issue Dec 28, 2020 · 7 comments · May be fixed by #1121
Open

app hang while showing alert when select dropdown box is actively showing #1047

samyc1201 opened this issue Dec 28, 2020 · 7 comments · May be fixed by #1121

Comments

@samyc1201
Copy link

Bug Report

app hang while showing alert when select dropdown box is actively showing

Problem

cordova app went hang when calling javascript executing alert() when user has clicked the select box and the select box dropdown box is showing on screen

What is expected to happen?

alert box should show on top of the page, the app shouldn't hang

What does actually happen?

Information

Please refer to the code below, there are one select box and one button, first, please click the button, the alert box will show after 2 seconds. After the button is clicked, do click the "select" box immediately, after that, wait for 2 seconds. Dismiss the dropdown box, the app will go hang and nothing is responding anymore.

Command or Code

Code snippet:

<!DOCTYPE html>

<html>
    <head>
        <meta charset="utf-8">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover">
        <meta name="color-scheme" content="light dark">
        <link rel="stylesheet" href="css/index.css">
        <title>Hello World</title>
        <script>
            function test() {
                setTimeout(function(){ alert("Hello"); }, 2000);
            }
        </script>
    </head>
    <body>
        <div class="app">
            <h1>Apache Cordova</h1>
            <div id="deviceready" class="blink">
                <p class="event listening">Connecting to Device</p>
                <p class="event received">Device is Ready</p>
            </div>
            <select><option>sdfsdf</option>
                <option>sdfsdf</option>
                <option>sdfsdf</option>
            </select>
            <button type="button" onclick="test()">Click Me!</button>
        </div>
        <script src="cordova.js"></script>
        <script src="js/index.js"></script>
    </body>
</html>

Environment, Platform, Device

iOS device (iphone or ipad), tested in iOS 13 and 14

Version information

What are relevant versions you are using?
For example:
Cordova CLI 10.0.0
Cordova iOS: 6.1.0

Checklist

  • [x ] I searched for existing GitHub issues
  • [ x] I updated all Cordova tooling to most recent version
  • [x ] I included all the necessary information above
@breautek
Copy link
Contributor

alert box should show on top of the page, the app shouldn't hang

So if I understand correctly, if the native browser select box is opened, and alert is called, the alert dialog opens (which is thread blocking until it is dismissed) but it isn't visible because it's displayed under the select modal?

Since you're dealing with native browser UI, this smells like a browser bug. I would try your test case with pure safari using https://jsfiddle.net/ or something.

Potential workaround is to not rely on the browser alert dialog and use the dialogs plugin instead, which is non-blocking asynchronous.

@samyc1201
Copy link
Author

it isn't visible because it's displayed under the select modal?

Yes it is not visible but it doesn't show under select modal too. It is just not showing and the whole page is not responding, any click to the button or input element are not receivable.

Since you're dealing with native browser UI, this smells like a browser bug.

I have tried just now, it doesn't happen in Safari in my ipad.

What my guess is, Cordova using WebView implementation and also implement its own alert modal, which is not the same as the native browser. The alert modal (guess it is UIAlertController) doesn't work well while there is select modal (not sure this, might be other UIViewController) showing.

I will try to look into "dialogs plugin", although that is not convenient, because the usage of "alert()" is everywhere in my project.

@breautek
Copy link
Contributor

breautek commented Dec 29, 2020

What my guess is, Cordova using WebView implementation and also implement its own alert modal, which is not the same as the native browser.

Yah, you might be right here. I'm not too familiar with objective-c or the ios code base for that matter but Cordova has a `CDVWebViewUIDelegate class that looks like it handles how to display the alert box among other native modals like confirm and prompt.

- (void) webView:(WKWebView*)webView runJavaScriptAlertPanelWithMessage:(NSString*)message
initiatedByFrame:(WKFrameInfo*)frame completionHandler:(void (^)(void))completionHandler
{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction* action)
{
completionHandler();
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:ok];
UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController;
[rootController presentViewController:alert animated:YES completion:nil];
}

This is where my expertise kinda ends. I'm not sure if there is a way to ensure that the alert modal is always displayed on top or if there is any other potential solutions but I think this method is the method of interest.

@samyc1201
Copy link
Author

Yes, I guess something need to change there. I used to see people encounter crashing when multiple alert() being called at the same time, I guess this issue already fixed by Apple because I didn't encounter it anymore in Cordova. For example, this.

For the case reported above, it might be similar root cause, selectbox dropdown UIPopoverPresentationController somehow conflict with the UIAlertController. So in the method you share, I guess it need to dismiss/check UIPopoverPresentationController first before showing new alert box.

@JeffBerman
Copy link

I don't know if this is directly related, but I'm currently investigating an issue in our app where an alert is sent while a date picker is open. What happens is the alert appears and instantly disappears by itself, the picker also disappears by itself, and then the date element becomes unresponsive and also persists on the screen through successive Cordova screens. The only way to clear it is to force-quit the app and relaunch. This only happens in iOS 14. My app is built using Cordova 10.0.0 and iOS platform 6.1.1.

@samyc1201
Copy link
Author

@JeffBerman yes, sound like quite related, very similar to what I have encountered. Hope the developer can investigate this as soon as possible.

@JeffBerman
Copy link

JeffBerman commented Jan 27, 2021

So if I understand correctly, if the native browser select box is opened, and alert is called, the alert dialog opens (which is thread blocking until it is dismissed) but it isn't visible because it's displayed under the select modal?

I don't think this is what is happening. In our app, the first time we send an alert it works, but the second time the alert never shows and the app hangs and must be force-quit (however, if the keyboard is visible at the time then the app hangs on the first try). I am not an expert with this stuff, but I debugged our Cordova app while the alert dialog was displayed and could graphically see the alert view in Xcode in the view hierarchy. When an alert is sent the second time (which causes the app to hang), the alert view doesn't appear in the list of views. Further, I placed breakpoints at all relevant lines in CDVWebViewUIDelegate.m, and they don't break when window.alert is called in the JavaScript code.

Update: It turns out that our app calls navigator.notification.alert to send the alert message. However, it also hangs when window.alert is called.

@dpogue dpogue linked a pull request Apr 16, 2023 that will close this issue
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants