Wednesday, May 26, 2010

Safari focus() and popup alerts

Generally, browsers allow Javascript code to force a particular text field (or various other things) to be in focus. For a text field, that means that the cursor will appear in the text field and blink (or do whatever it does), and keys typed will cause text to appear there. In Safari, a text field glows blue when it's in focus, which I think is a security measure, and a fairly irksome one for designers at that. (What if my page is green? Ugh.)

Well on top of that, while I'm bitching about Safari, there's another limitation with forcing focus. In general, Safari refuses to allow itself to grab focus overall; that is, to grab focus on a desktop application basis. That's done by calling the window.focus()method. IE is generally delighted to push itself in front of other desktop windows. Firefox will do it if the user's configured it to do so. The WebKit browsers, however, are uncooperative. That in and of itself doesn't really bother me; there are few cases where I really feel that's justified, and windows that raise themselves more often than not annoy me to the point of a killin' rage.

However, this reluctance to impose itself causes a weird effect with Safari with respect to Javascript alert() pop-ups. I think that because the window generated by an alert() steals "application focus" from the browser itself, then after that point attempts to force focus on a form field fail. This situation is not really a contrived one: consider a form submission event handler that wants to point out that a particular text field must be filled out. The handler launches a pop-up alert()to convey the message, and then when the dialog is dismissed it tries to set focus. Well, that works in other browsers, but not Safari. Safari seems convinced that its application window has lost desktop focus, and therefore it ignores attempts to give focus to form fields in the page.

This sample illustrates the problem. (It's not very interesting in browsers other than Safari, of course.) If you visit that page and click the "Click me" button, you'll get a pop-up. Dismiss it and then do nothing. Nothing will happen when the page posts a log message indicating that it has tried to force focus. Now, click the "Click me" button again, and again dismiss the pop-up. This time, right after the pop-up goes away, click anywhere in the page (not the input field of course). That click should bring Safari to the foreground, so to speak, and then after a couple seconds the attempt to force focus will work, and the input field will get that irritating fuzzy blue border.