Call jQuery.ready() before </body>
authorTimo Tijhof <krinklemail@gmail.com>
Thu, 25 Apr 2013 08:12:07 +0000 (10:12 +0200)
committerTimo Tijhof <krinklemail@gmail.com>
Mon, 29 Apr 2013 19:47:24 +0000 (21:47 +0200)
mw.loader defaults to async=false. Overridden when $.isReady=true
or a mw.loader call sets async=true.

The problem is in calls to mw.loader.load that are not in
the HTML output but occur *before* the DOMContentReady event.

In those cases we want to use async (creating a script tag)
instead of synchronous (document.write) because in Firefox
DOMContentReady is emitted some time after it is no longer safe
to use document.write (bug 47457).

This also optimises the dom ready event cross-browser.

Bug: 34542
Bug: 47457
Change-Id: Ic3d0c937268d0943d2f770f3ca18bcf4e1eed346

includes/OutputPage.php

index 65800dd..2f1f62e 100644 (file)
@@ -2954,11 +2954,18 @@ $templates
         */
        function getBottomScripts() {
                global $wgResourceLoaderExperimentalAsyncLoading;
+
+               // Optimise jQuery ready event cross-browser.
+               // This also enforces $.isReady to be true at </body> which fixes the
+               // mw.loader bug in Firefox with using document.write between </body>
+               // and the DOMContentReady event (bug 47457).
+               $html = Html::inlineScript( 'jQuery.ready();' );
+
                if ( !$wgResourceLoaderExperimentalAsyncLoading ) {
-                       return $this->getScriptsForBottomQueue( false );
-               } else {
-                       return '';
+                       $html .= $this->getScriptsForBottomQueue( false );
                }
+
+               return $html;
        }
 
        /**