Matmarex has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/73177


Change subject: mw.loader: Rip out broken code path from addScript()
......................................................................

mw.loader: Rip out broken code path from addScript()

ResouceLoader's addScript() function (called by mw.loader.load and
friends) only used the standard method of loading scripts (create a
<script> element, append it to <head>, wait for it to load
asynchronously) if fired after document-ready (or if the caller
specifically asked for it, which wasn't even documented).

Otherwise it used 1995-style document.write() with a big fat comment
about our not actually knowing whether it's even synchronous or
asynchronous and whether the callback logic for it actually works.

I'm not sure what was the reasoning for it - possibly better loading
performance in some old browsers (the code comes from the massive
"Merging resourceloader branch into trunk" commit, r72349, making
tracing its origins hard), but document.write() just loves to cause
issues (for example bug 34542, bug 47457, bug 50746).

Anything remotely recent supports the normal method (it doesn't
block) and IE5 or whatever that code was written for should continue
working with degraded performance (blocking instead of async).

Change-Id: I897ff585155c14e2dc27adf2712b4872b5418b23
---
M resources/mediawiki/mediawiki.js
1 file changed, 47 insertions(+), 59 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/77/73177/1

diff --git a/resources/mediawiki/mediawiki.js b/resources/mediawiki/mediawiki.js
index e36d9d0..42ef5bc 100644
--- a/resources/mediawiki/mediawiki.js
+++ b/resources/mediawiki/mediawiki.js
@@ -858,79 +858,67 @@
                        }
 
                        /**
-                        * Adds a script tag to the DOM, either using 
document.write or low-level DOM manipulation,
-                        * depending on whether document-ready has occurred yet 
and whether we are in async mode.
+                        * Adds a script tag to the DOM. The script will be 
loaded asynchronously, firing the callback
+                        * after it is loaded and executed.
                         *
                         * @private
                         * @param {string} src URL to script, will be used as 
the src attribute in the script tag
                         * @param {Function} [callback] Callback which will be 
run when the script is done
                         */
-                       function addScript( src, callback, async ) {
-                               /*jshint evil:true */
+                       function addScript( src, callback ) {
                                var script, head, done;
 
-                               // Using isReady directly instead of storing it 
locally from
-                               // a $.fn.ready callback (bug 31895).
-                               if ( $.isReady || async ) {
-                                       // Can't use jQuery.getScript because 
that only uses <script> for cross-domain,
-                                       // it uses XHR and eval for same-domain 
scripts, which we don't want because it
-                                       // messes up line numbers.
-                                       // The below is based on jQuery 
([jquery@1.8.2]/src/ajax/script.js)
+                               // Can't use jQuery.getScript because that only 
uses <script> for cross-domain,
+                               // it uses XHR and eval for same-domain 
scripts, which we don't want because it
+                               // messes up line numbers.
+                               // The below is based on jQuery 
([jquery@1.8.2]/src/ajax/script.js)
 
-                                       // IE-safe way of getting the <head>. 
document.head isn't supported
-                                       // in old IE, and doesn't work when in 
the <head>.
-                                       done = false;
-                                       head = document.getElementsByTagName( 
'head' )[0] || document.body;
+                               // IE-safe way of getting the <head>. 
document.head isn't supported
+                               // in old IE, and doesn't work when in the 
<head>.
+                               done = false;
+                               head = document.getElementsByTagName( 'head' 
)[0] || document.body;
 
-                                       script = document.createElement( 
'script' );
-                                       script.async = true;
-                                       script.src = src;
-                                       if ( $.isFunction( callback ) ) {
-                                               script.onload = 
script.onreadystatechange = function () {
-                                                       if (
-                                                               !done
-                                                               && (
-                                                                       
!script.readyState
-                                                                       || 
/loaded|complete/.test( script.readyState )
-                                                               )
-                                                       ) {
-                                                               done = true;
+                               script = document.createElement( 'script' );
+                               script.async = true;
+                               script.src = src;
+                               if ( $.isFunction( callback ) ) {
+                                       script.onload = 
script.onreadystatechange = function () {
+                                               if (
+                                                       !done
+                                                       && (
+                                                               
!script.readyState
+                                                               || 
/loaded|complete/.test( script.readyState )
+                                                       )
+                                               ) {
+                                                       done = true;
 
-                                                               // Handle 
memory leak in IE
-                                                               script.onload = 
script.onreadystatechange = null;
+                                                       // Handle memory leak 
in IE
+                                                       script.onload = 
script.onreadystatechange = null;
 
-                                                               // Detach the 
element from the document
-                                                               if ( 
script.parentNode ) {
-                                                                       
script.parentNode.removeChild( script );
-                                                               }
-
-                                                               // Dereference 
the element from javascript
-                                                               script = 
undefined;
-
-                                                               callback();
+                                                       // Detach the element 
from the document
+                                                       if ( script.parentNode 
) {
+                                                               
script.parentNode.removeChild( script );
                                                        }
-                                               };
-                                       }
 
-                                       if ( window.opera ) {
-                                               // Appending to the <head> 
blocks rendering completely in Opera,
-                                               // so append to the <body> 
after document ready. This means the
-                                               // scripts only start loading 
after the document has been rendered,
-                                               // but so be it. Opera users 
don't deserve faster web pages if their
-                                               // browser makes it impossible.
-                                               $( function () {
-                                                       
document.body.appendChild( script );
-                                               } );
-                                       } else {
-                                               head.appendChild( script );
-                                       }
+                                                       // Dereference the 
element from javascript
+                                                       script = undefined;
+
+                                                       callback();
+                                               }
+                                       };
+                               }
+
+                               if ( window.opera ) {
+                                       // Appending to the <head> blocks 
rendering completely in Opera,
+                                       // so append to the <body> after 
document ready. This means the
+                                       // scripts only start loading after the 
document has been rendered,
+                                       // but so be it. Opera users don't 
deserve faster web pages if their
+                                       // browser makes it impossible.
+                                       $( function () {
+                                               document.body.appendChild( 
script );
+                                       } );
                                } else {
-                                       document.write( mw.html.element( 
'script', { 'src': src }, '' ) );
-                                       if ( $.isFunction( callback ) ) {
-                                               // Document.write is 
synchronous, so this is called when it's done
-                                               // FIXME: that's a lie. 
doc.write isn't actually synchronous
-                                               callback();
-                                       }
+                                       head.appendChild( script );
                                }
                        }
 

-- 
To view, visit https://gerrit.wikimedia.org/r/73177
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I897ff585155c14e2dc27adf2712b4872b5418b23
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Matmarex <matma....@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to