From cb7e0ea507c55b49fd22f734fbfe048fe87d5557 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Fri, 26 Oct 2018 14:33:26 -0700 Subject: [PATCH] resoureloader: Restore support for plain callbacks in mediawiki.base's RLQ Follows-up dec800968e, which moved the processing of callbacks that require 'modules' from startup.js to mediawiki.base.js. In doing so, it made an incorrect assumption. It assumed that the simple signature of RLQ.push(Function) is not needed after 'mediawiki.base' loads. It is true that RLQ.push() is mostly an internal interface, and we only use it from within the HTML output, and that once the async pipeline has finished and startup.js has processed the simple callbacks, only calls with secondary signatures remain in the queue. But, while it is true that we don't use RLQ.push() outside the HTML, it is not true that the HTML will fully load and execute inline scripts before any of the async scripts execute. As such, the call to RLQ.push() in the HTML footer was sometimes being ignored because 'mediawiki.base' had already loaded by now. Bug: T208093 Change-Id: I25012a2c6f41968b1b4f85614a3bc0416512d530 --- resources/src/mediawiki.base/mediawiki.base.js | 12 +++++++++--- resources/src/startup/startup.js | 7 ++++--- .../resources/mediawiki/mediawiki.base.test.js | 11 ++++++++++- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/resources/src/mediawiki.base/mediawiki.base.js b/resources/src/mediawiki.base/mediawiki.base.js index 5820b83eb9..8a44dcc686 100644 --- a/resources/src/mediawiki.base/mediawiki.base.js +++ b/resources/src/mediawiki.base/mediawiki.base.js @@ -641,12 +641,18 @@ mw.log.deprecate( window, '$j', $, 'Use $ or jQuery instead.' ); // Process callbacks for Grade A that require modules. - // Plain ones were already processed by startup.js. queue = window.RLQ; - // Redefine publicly to capture any late arrivals + // Replace temporary RLQ implementation from startup.js with the + // final implementation that also processes callbacks that can + // require modules. It must also support late arrivals of + // plain callbacks. (T208093) window.RLQ = { push: function ( entry ) { - mw.loader.using( entry[ 0 ], entry[ 1 ] ); + if ( typeof entry === 'function' ) { + entry(); + } else { + mw.loader.using( entry[ 0 ], entry[ 1 ] ); + } } }; while ( queue[ 0 ] ) { diff --git a/resources/src/startup/startup.js b/resources/src/startup/startup.js index 5483ad23e8..bebf4dcf4a 100644 --- a/resources/src/startup/startup.js +++ b/resources/src/startup/startup.js @@ -118,9 +118,10 @@ if ( !isCompatible() ) { mw.config.set( $VARS.configuration ); // Process callbacks for Grade A - // Must be after registrations and mw.config.set, which mw.loader depends on. var queue = window.RLQ; - // Redefine push(), but keep type as array for storing callbacks that require modules. + // Replace RLQ placeholder from ResourceLoaderClientHtml with an implementation + // that executes simple callbacks, but continues to store callbacks that require + // modules. window.RLQ = []; /* global RLQ */ RLQ.push = function ( fn ) { @@ -132,7 +133,7 @@ if ( !isCompatible() ) { } }; while ( queue && queue[ 0 ] ) { - // Re-use our push() + // Re-use our new push() method RLQ.push( queue.shift() ); } diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.base.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.base.test.js index 33423d8071..b8f0d122cc 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.base.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.base.test.js @@ -126,12 +126,21 @@ QUnit.test( 'RLQ.push', function ( assert ) { /* global RLQ */ var loaded = 0, + called = 0, done = assert.async(); mw.loader.testCallback = function () { loaded++; delete mw.loader.testCallback; }; - mw.loader.implement( 'test.rlq-push', [ QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/mwLoaderTestCallback.js' ) ] ); + mw.loader.implement( 'test.rlq-push', [ + QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/mwLoaderTestCallback.js' ) + ] ); + + // Regression test for T208093 + RLQ.push( function () { + called++; + } ); + assert.strictEqual( called, 1, 'Invoke plain callbacks' ); RLQ.push( [ 'test.rlq-push', function () { assert.strictEqual( loaded, 1, 'Load the required module' ); -- 2.20.1