* Add more inline documentation.
* Use [0] instead of needless 'length'. (Optimisation)
* Don't lazy-create NORLQ as empty array only to dereference
it two statements later. (Optimisation)
* Add support for a secondary signature to RLQ.push.
The existing signature is a plain callback function that is
execute immediately after startup.
The new signature is an array of `[ string|Array, Function ]`
where the first value is required module(s), and
the second value is the callback function.
startup.js will leave the second form in the array, processing
them instead in 'mediawiki.base'.
This change is needed before I17cd13dffebd6a (T192623), which
will remove the undocumented behaviour of RLQ callbacks firing
only after base modules arrive, which means we need to provide
authors of inline scripts an alternate means of scheduling
callbacks for after 'jquery' and/or 'mediawiki.base' arrive.
Bug: T192623
Change-Id: Ica7bb9c3bdb77d96ca2e01530a76f7ca448acdb8
*
* - Beware: This file MUST parse without errors on even the most ancient of browsers!
*/
*
* - Beware: This file MUST parse without errors on even the most ancient of browsers!
*/
+/* eslint-disable vars-on-top, no-unmodified-loop-condition */
/* global mw, isCompatible, $VARS, $CODE */
/**
/* global mw, isCompatible, $VARS, $CODE */
/**
-// Conditional script injection
( function () {
var NORLQ, script;
( function () {
var NORLQ, script;
- // Undo class swapping in case of an unsupported browser.
- // See ResourceLoaderClientHtml::getDocumentAttributes().
+ // Undo speculative Grade A <html> class. See ResourceLoaderClientHtml::getDocumentAttributes().
document.documentElement.className = document.documentElement.className
.replace( /(^|\s)client-js(\s|$)/, '$1client-nojs$2' );
document.documentElement.className = document.documentElement.className
.replace( /(^|\s)client-js(\s|$)/, '$1client-nojs$2' );
- NORLQ = window.NORLQ || [];
- while ( NORLQ.length ) {
+ // Process any callbacks for Grade C
+ NORLQ = window.NORLQ;
+ while ( NORLQ && NORLQ[ 0 ] ) {
NORLQ.shift()();
}
window.NORLQ = {
NORLQ.shift()();
}
window.NORLQ = {
- // Clear and disable the other queue
+ // Clear and disable the Grade A queue
mw.config.set( $VARS.configuration );
mw.config.set( $VARS.configuration );
- // Must be after mw.config.set because these callbacks may use mw.loader which
- // needs to have values 'skin', 'debug' etc. from mw.config.
- // eslint-disable-next-line vars-on-top
- var RLQ = window.RLQ || [];
- while ( RLQ.length ) {
- RLQ.shift()();
- }
+ // Process callbacks for Grade A
+ // Must be after registrations and mw.config.set, which mw.loader depends on.
+ var queue = window.RLQ;
window.RLQ = {
push: function ( fn ) {
window.RLQ = {
push: function ( fn ) {
+ if ( typeof fn === 'function' ) {
+ fn();
+ } else {
+ // This callback has a requirement.
+ mw.loader.using( fn[ 0 ], fn[ 1 ] );
+ }
+ while ( queue && queue[ 0 ] ) {
+ // Re-use our push()
+ window.RLQ.push( queue.shift() );
+ }
- // Clear and disable the other queue
+ // Clear and disable the Grade C queue
push: function () {}
};
}
push: function () {}
};
}
+ QUnit.test( 'RLQ.push', function ( assert ) {
+ /* global RLQ */
+ var loaded = 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' ) ] );
+
+ RLQ.push( [ 'test.rlq-push', function () {
+ assert.strictEqual( loaded, 1, 'Load the required module' );
+ done();
+ } ] );
+ } );
+