Saturday, February 2, 2008

Javascript alert / confirm trap

Yesterday I hit a web page that contained an infinite javascript loop. That's usually not too bad, because the browser will recognize that and say something like, "A script on this page is taking too long -- stop it?"

The problem this time was that this javascript infinite loop had calls to both the alert and confirm functions. Those functions pop up modal dialog boxes. So instead of a loop that was chewing up cpu time, this one was popping up OK and Yes/No dialog boxes as fast as one could close them. The nasty bit is that these are both modal dialog boxes, so one cannot do anything else in the browser while they are displayed.

In the old days, I would have just killed the browser and restarted it. But these days, with tabbed browsing, I wasn't just killing that page, but all my other tabs, too. Fortunately for me, at the time I had no unsaved state in any tabs. If I did I would have lost it. There's no way to even copy/paste before killing the browser, because of the modal state.

Why can't a modern browser detect this situation and offer a clean escape? For example, if a page has popped up five modal dialogs within five seconds, then offer the user something like, "This page is opening dialog boxes quickly -- stop loading?"

Sample page demonstrating this trap:



<html>
<head>
<title>Modal Hell</title>
<script language="JavaScript">
<!--
function infinite_loop(txt) {
while (1) {
alert(txt);
txt=txt+'.';
}
return;
}
-->
</script>
</head>

<body>
Can your browser break out of this?
<p>
<a name="foo"
onclick="infinite_loop('Now stuck')">
<u>Click me to start an infinite
modal dialog loop</u></a>

</p>
</body>
</html>

2 comments:

Anonymous said...

Yeah, it's pretty annoying. It's a difficult problem for browsers because the script pauses during the confirmation process, which makes it hard to determine that you're stuck in a loop - particularly for prompt() where loops are frequently legitimately used to ensure valid responses. Chrome has a crude response, which is to allow you to suppress all dialogue boxes from the given site from the dialogue prompt itself. However, I often don't want to kill all future prompts from a site, just the offending loop. It would seem that an easy hack that browsers could employ would be to look for rapid dismissal of dialogue boxes... i.e. if 5 prompts are dismissed within 2 seconds, the browser could know to break out of the script. Basically, whenever a dialogue box is called, a timer and dialogue-iterator is started... several seconds without a dialogue box would clear this check.

Anonymous said...

Opera dialogs offer the possibility to stop executing the script.