From 40ed8e0f8e4ac1cde023a0ba2bac13755cd40406 Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Tue, 13 Sep 2011 13:55:43 +0000 Subject: [PATCH] Address one of the fixmes on r88053: because addScript() is asynchronous, calling it repeatedly can lead to scripts loading out of order. The specific bug was that if you had a module with two script files, A and B (in that order; scripts are always loaded in the order in which they are specified for multi-file modules) and A is 40M while B is 1K, then B would be executed before A if the module is loaded after document ready (through e.g. mw.loader.using) and the files are not in the browser cache. So instead of calling addScript() repeatedly in a loop, this commit calls addScript() recursively from its own callback, using a helper function called nestedAddScript(). This also means the if block that checks if the scripts array is empty can be removed, because nestedAddScript() handles empty arrays correctly. --- resources/mediawiki/mediawiki.js | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/resources/mediawiki/mediawiki.js b/resources/mediawiki/mediawiki.js index 7b704490fa..9bf91963be 100644 --- a/resources/mediawiki/mediawiki.js +++ b/resources/mediawiki/mediawiki.js @@ -546,22 +546,24 @@ window.mw = window.mediaWiki = new ( function( $ ) { if ( $.isFunction( callback ) ) { callback(); } + }, + nestedAddScript = function( arr, callback, i ) { + // Recursively call addScript() in its own callback + // for each element of arr. + if ( i >= arr.length ) { + // We're at the end of the array + callback(); + return; + } + + addScript( arr[i], function() { + nestedAddScript( arr, callback, i + 1 ); + } ); }; if ( $.isArray( script ) ) { - var done = 0; - if ( script.length === 0 ) { - // No scripts in this module? Let's dive out early. - markModuleReady(); - } - for ( var i = 0; i < script.length; i++ ) { - registry[module].state = 'loading'; - addScript( script[i], function() { - if ( ++done === script.length ) { - markModuleReady(); - } - } ); - } + registry[module].state = 'loading'; + nestedAddScript( script, markModuleReady, 0 ); } else if ( $.isFunction( script ) ) { script( $ ); markModuleReady(); @@ -703,7 +705,7 @@ window.mw = window.mediaWiki = new ( function( $ ) { function addScript( src, callback ) { var done = false, script; if ( ready ) { - // jQuery's getScript method is NOT better than doing this the old-fassioned way + // jQuery's getScript method is NOT better than doing this the old-fashioned way // because jQuery will eval the script's code, and errors will not have sane // line numbers. script = document.createElement( 'script' ); -- 2.20.1