Update: If you are interested in how to make window.open work you might want to also read the follow-up: Safari and window.open – How to do it
Working on a project these days, I noticed that the only call to window.open in that app did not work in Safari. Looking into it, I found that it was Safari’s popup blocker that wouldn’t let that call succeed.
Usually, I don’t deal with window.open, so that behavior was new to me, and I asked Mr. Google what he knew on this. Not much, as it turned out out – I found only two interesting notes on it. One was pretty strange and I guess it was more about a Safari 3 beta not returning a window object. The other one proposed the the window.open call had to be within the same function body as the method handling the event. The comments on that post affirmed this suspicion, but I decided to look into it myself.
So I threw some buttons on a page and started connecting… Ah, that’s not entirely correct, I started with typing “window.open” into the console – to no avail, Safari didn’t do a thing.
Then I put the window.open call into an “onclick” attribute to make sure my Safari would open windows at all – yep, it did. Good. Ok, so I moved on, step by step to see when Safari drew the line.
Next were some basic connects using dojo.connect. All good. Then connections to anonymous functions calling window.open – all good. Connections to anonymous functions calling an object’s method that was calling another method that was calling window.open… still all good. So far for the theory the window.open call had to be in the same function body…
One step further: using dojo’s pub/sub system. So I connected a button to an anonymous function that published a topic, and subscribed to that topic, in different manners. Still Safari opened a new window every time, as ordered.
Finally, I tried callback functions. First, as an argument to dojo.xhrGet, then as an argument to setTimeout. And – bingo! Safari silently refused to open a new window. Phew. Ok. Well, at least I do know now.
The only tiny problem left, concerning the scenario present in that app I mentioned before: a callback is needed there. Some data is sent to the server and the new window can’t be opened until the app receives the response… And I don’t want to tell customers to turn off their popup blocker – especially since Safari doesn’t have site-specific settings for it’s popup blocker.
The file containing the tests can be found here.
Update: How to work around the popup blocker: Safari and window.open – How to do it