pendingRequests.push( function () {
if ( moduleName && hasOwn.call( registry, moduleName ) ) {
+ // Emulate runScript() part of execute()
window.require = mw.loader.require;
window.module = registry[ moduleName ].module;
}
addScript( src ).always( function () {
- // Clear environment
- delete window.require;
+ // 'module.exports' should not persist after the file is executed to
+ // avoid leakage to unrelated code. 'require' should be kept, however,
+ // as asynchronous access to 'require' is allowed and expected. (T144879)
delete window.module;
r.resolve();
} );
} );
- QUnit.test( 'require() in debug mode', 1, function ( assert ) {
+ QUnit.test( 'require() in debug mode', function ( assert ) {
var path = mw.config.get( 'wgScriptPath' );
mw.loader.register( [
[ 'test.require.define', '0' ],
mw.loader.implement( 'test.require.define', [ QUnit.fixurl( path + '/tests/qunit/data/defineCallMwLoaderTestCallback.js' ) ] );
return mw.loader.using( 'test.require.callback' ).then( function ( require ) {
- var exported = require( 'test.require.callback' );
- assert.strictEqual( exported, 'Require worked.Define worked.',
- 'module.exports worked in debug mode' );
+ var cb = require( 'test.require.callback' );
+ assert.strictEqual( cb.immediate, 'Defined.', 'module.exports and require work in debug mode' );
+ // Must use try-catch because cb.later() will throw if require is undefined,
+ // which doesn't work well inside Deferred.then() when using jQuery 1.x with QUnit
+ try {
+ assert.strictEqual( cb.later(), 'Defined.', 'require works asynchrously in debug mode' );
+ } catch ( e ) {
+ assert.equal( null, String( e ), 'require works asynchrously in debug mode' );
+ }
}, function () {
assert.ok( false, 'Error callback fired while loader.using "test.require.callback" module' );
} );