(In reply to comment #0)
> @Brad Jorsch: It seems that the Firefox bug with document.write being
> disabled before DOMContentReady is worse than we thought. It is disabled even
> before the end of the </body> has been reached. We found through
> trial-and-error that placing it after the main content but before the bottom
> queue worked.

But it works from synchronously-processed scripts, even just before </body>.

I've done some more testing on this Firefox situation. More specifically, it seems that *any* document.write called from a setTimeout callback will replace the document, even if it fires during <head>. And this even avoids the check (since Gecko 2.0 (Firefox 4.0)) that is supposed to disable document.write when called from async-loaded scripts.[1]

 [1]: https://developer.mozilla.org/en-US/docs/HTML/Element/script#attr-async

The following browsers seem to be affected by this issue: Firefox 20, IE8, IE10, Chrome 24, Chrome 26, Opera 12.14.

The following browsers seem to *not* be affected by this issue: Safari 5.1 (Windows)

So runScript() should probably be forcing async when it calls addScript(), since it is called from a setTimeout in addEmbeddedCss(), as another layer of fix for bug 47457.


> As Brad pointed out, $.ready being triggered earlier makes no difference for
> the bottom queue because they are loaded asynchronously, they always execute
> without blocking the parser or the DOM ready event.

In fact, this should make the behavior for the bottom queue *more* predictable. Previously, depending on whether the async-loaded scripts for the bottom queue loaded extremely quickly (e.g. from cache) and whether the browser then decided to process them before firing DOMContentLoaded, they might sometimes be fired before $.ready and sometimes after. Now they'll always be after, no matter what the browser does.

> However note that the user scripts (like the site scripts) are *not* loaded
> through mw.loader because we still support legacy global scope for them. They
> are loaded by a hardcoded script tag in the DOM. Which means they are
> blocking and used to block dom-ready

I suppose that's where these complaints about mwCustomEditButtons and other such are coming from, if someone coded something assuming pre-ready directly in a user script or site script. OTOH, scripts loaded from the site or user scripts loaded via mw.loader.load() already had the issue (thanks to the fix for bug 34542 defaulting that sort of thing to async), so it only half-worked at best before bug 47457 anyway.