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