3

UPDATE BELOW

I think I've just found a really weird bug in Safari 5.1, on OS X Lion. I can't confirm for sure whether this bug existed on earlier versions of Safari, but I sort of suspect not (given the fact that the part of my site that references this issue used to work in pre-Lion Safari). I don't see the bug in Chrome, Firefox 6, IE7 or IE9. I've also been able to confirm that the bug does not happen in Safari 5.0.2 on Windows 7, which likely means this is new to Safari 5.1.

So here's the bug: it would appear that if the javascript confirm() function is inside of another function, then anything within that function called before confirm() is not executed until either the "OK" or "Cancel" button is clicked. That sure seems like a huge, and really weird, bug to me. Here's my sample code:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">

function myexit () {
    console.log(0);

    if ( confirm('Are you sure?') ) {
        window.close();
    }
}
</script>
</head>
<body>
<a href="#" onclick="myexit();">close window</a>
</body>
</html>

In all the other browsers I mention, the 0 appears in the console at the same time the modal confirm box appears. In Safari, the 0 appears only after clicking either "OK" or "Cancel".

Also, if I put the confirm() function in a sub-function, like this:

function confirmwrapper() {

    if ( confirm('Are you sure?') ) {
        console.log(1);
    }
}

function myexit () {
    console.log(0);
    confirmwrapper();
}

...it still breaks.

Am I missing something basic here? Respectfully, answers like "just use JQuery/Mootools/some other cool JS library" probably don't help me all that much, because this code is part of a legacy system that I can't completely rip apart right now, much as I want to.

UPDATE: I just tested a simple AJAX request (Mootools Request(), for those keeping score, though I don't think it really matters), and I was able to confirm that the Request is not executed until the confirm dialog is closed--either via "OK" or "Cancel". That's gotta be a bug. Nuts.

Thanks in advance

hairbo
  • 3,113
  • 2
  • 27
  • 34
  • Is the same true if you run a non-console statement? (i.e. could it be a threading issue where the console is written to, but the UI doesn't get a chance to update? To test, change your code to something like "var x = 0; if(confirm((x+2)+' Are you sure?")) { window.close(); }" -- does the "x+2" get evaluated? – groundh0g Sep 16 '11 at 16:28
  • Hmm...that is interesting. I tried your test, and Safari 5.1 correctly evaluated x+2. This is befuddling, because it was completely clear that the "real" code I had in place before the confirm statement was not getting evaluated, which is how I discovered the bug in the first place. I'll monkey around some more. – hairbo Sep 16 '11 at 16:41
  • just to be sure, set the "x+2" outside of the confirm. (so, it's "var x=0; x += 2; if(confirm(x+' Are you sure?')) { ... }". Should be same, but ... :) – groundh0g Sep 16 '11 at 16:45
  • I hear ya. It does appear to correctly do "x+2", and immediately display the result in the confirm box. Also, I added this prior to the confirm line: var res = document.getElementById('result'); res.innerHTML = 'hello there!'; ...and Safari 5.1 didn't display the result until after the confirm box was gone. Now I need to try an AJAX test, since that's what started this whole mess in the first place. Grr...maybe I should see if I can drop in a Mootools-based dialog. – hairbo Sep 16 '11 at 17:04
  • I just added an update on AJAX testing to the post body itself. – hairbo Sep 16 '11 at 18:32

1 Answers1

2

I'm sort of talking to myself at this point, but I've got "solution" (and when I say "solution" I really mean "hack that appears to work"), given that I can't use a modal dialogue from a JS library. If I put the confirm() call in another function, and invoke that with a setTimeout call, that appears to give Safari enough breathing room to allow the code before confirm() to execute. Here's the example:

function doconfirm() {
    if ( confirm('Are you sure you want to logout?') ) {
        window.top.close();
    }
}

function logout () {
    doCourseSave();
    window.setTimeout('doconfirm();', 500);
}

To be clear, "logout()" is the function which gets invoked on user action (button click).

hairbo
  • 3,113
  • 2
  • 27
  • 34