* @param {Function} callback
*/
trackUnsubscribe: function ( callback ) {
- trackHandlers = $.grep( trackHandlers, function ( fns ) {
+ trackHandlers = trackHandlers.filter( function ( fns ) {
if ( fns[ 1 ] === callback ) {
trackCallbacks.remove( fns[ 0 ] );
// Ensure the tuple is removed to avoid holding on to closures
// Cache
marker = document.querySelector( 'meta[name="ResourceLoaderDynamicStyles"]' );
if ( !marker ) {
- mw.log( 'Create <meta name="ResourceLoaderDynamicStyles"> dynamically' );
- marker = $( '<meta>' ).attr( 'name', 'ResourceLoaderDynamicStyles' ).appendTo( 'head' )[ 0 ];
+ mw.log( 'Created ResourceLoaderDynamicStyles marker dynamically' );
+ marker = document.createElement( 'meta' );
+ marker.name = 'ResourceLoaderDynamicStyles';
+ document.head.appendChild( marker );
}
}
return marker;
if ( nextNode && nextNode.parentNode ) {
nextNode.parentNode.insertBefore( s, nextNode );
} else {
- document.getElementsByTagName( 'head' )[ 0 ].appendChild( s );
+ document.head.appendChild( s );
}
return s;
registry[ module ].dependencies = [ registry[ module ].dependencies ];
}
}
- if ( $.inArray( module, resolved ) !== -1 ) {
+ if ( resolved.indexOf( module ) !== -1 ) {
// Module already resolved; nothing to do
return;
}
// Tracks down dependencies
deps = registry[ module ].dependencies;
for ( i = 0; i < deps.length; i++ ) {
- if ( $.inArray( deps[ i ], resolved ) === -1 ) {
+ if ( resolved.indexOf( deps[ i ] ) === -1 ) {
if ( unresolved.has( deps[ i ] ) ) {
throw new Error( mw.format(
'Circular reference detected: $1 -> $2',
registry[ module ].state = 'executing';
runScript = function () {
- var script, markModuleReady, nestedAddScript, implicitDependencies, implicitWait;
+ var script, markModuleReady, nestedAddScript;
script = registry[ module ].script;
markModuleReady = function () {
} );
};
- implicitDependencies = [];
-
- if ( module === 'user' ) {
- // Implicit dependency on the site module. Not real dependency because
- // it should run after 'site' regardless of whether it succeeds or fails.
- implicitDependencies.push( 'site' );
- }
-
- implicitWait = implicitDependencies.length ?
- mw.loader.using( implicitDependencies ) :
- $.Deferred().resolve();
-
- implicitWait.always( function () {
- try {
- if ( Array.isArray( script ) ) {
- nestedAddScript( script, markModuleReady, 0 );
- } else if ( typeof script === 'function' ) {
- // Pass jQuery twice so that the signature of the closure which wraps
- // the script can bind both '$' and 'jQuery'.
- script( $, $, mw.loader.require, registry[ module ].module );
- markModuleReady();
-
- } else if ( typeof script === 'string' ) {
- // Site and user modules are legacy scripts that run in the global scope.
- // This is transported as a string instead of a function to avoid needing
- // to use string manipulation to undo the function wrapper.
- $.globalEval( script );
- markModuleReady();
+ try {
+ if ( Array.isArray( script ) ) {
+ nestedAddScript( script, markModuleReady, 0 );
+ } else if ( typeof script === 'function' ) {
+ // Pass jQuery twice so that the signature of the closure which wraps
+ // the script can bind both '$' and 'jQuery'.
+ script( $, $, mw.loader.require, registry[ module ].module );
+ markModuleReady();
+
+ } else if ( typeof script === 'string' ) {
+ // Site and user modules are legacy scripts that run in the global scope.
+ // This is transported as a string instead of a function to avoid needing
+ // to use string manipulation to undo the function wrapper.
+ $.globalEval( script );
+ markModuleReady();
- } else {
- // Module without script
- markModuleReady();
- }
- } catch ( e ) {
- // Use mw.track instead of mw.log because these errors are common in production mode
- // (e.g. undefined variable), and mw.log is only enabled in debug mode.
- registry[ module ].state = 'error';
- mw.track( 'resourceloader.exception', { exception: e, module: module, source: 'module-execute' } );
- handlePending( module );
+ } else {
+ // Module without script
+ markModuleReady();
}
- } );
+ } catch ( e ) {
+ // Use mw.track instead of mw.log because these errors are common in production mode
+ // (e.g. undefined variable), and mw.log is only enabled in debug mode.
+ registry[ module ].state = 'error';
+ mw.track( 'resourceloader.exception', { exception: e, module: module, source: 'module-execute' } );
+ handlePending( module );
+ }
};
// Add localizations to message system
// cssHandlesRegistered ensures we don't take off too soon, e.g. when
// one of the cssHandles is fired while we're still creating more handles.
if ( cssHandlesRegistered && pending === 0 && runScript ) {
- runScript();
+ if ( module === 'user' ) {
+ // Implicit dependency on the site module. Not real dependency because
+ // it should run after 'site' regardless of whether it succeeds or fails.
+ mw.loader.using( [ 'site' ] ).always( runScript );
+ } else {
+ runScript();
+ }
runScript = undefined; // Revoke
}
};
if ( ready !== undefined || error !== undefined ) {
jobs.push( {
// Narrow down the list to modules that are worth waiting for
- dependencies: $.grep( dependencies, function ( module ) {
+ dependencies: dependencies.filter( function ( module ) {
var state = mw.loader.getState( module );
return state === 'registered' || state === 'loaded' || state === 'loading' || state === 'executing';
} ),
} );
}
- $.each( dependencies, function ( idx, module ) {
+ dependencies.forEach( function ( module ) {
var state = mw.loader.getState( module );
// Only queue modules that are still in the initial 'registered' state
// (not ones already loading, ready or error).
- if ( state === 'registered' && $.inArray( module, queue ) === -1 ) {
+ if ( state === 'registered' && queue.indexOf( module ) === -1 ) {
// Private modules must be embedded in the page. Don't bother queuing
// these as the server will deny them anyway (T101806).
if ( registry[ module ].group === 'private' ) {
a = [];
for ( key in o ) {
- if ( hasOwn.call( o, key ) ) {
- a.push( key );
- }
+ a.push( key );
}
a.sort();
for ( key = 0; key < a.length; key++ ) {
* @param {string} sourceLoadScript URL of load.php
*/
function doRequest( moduleMap, currReqBase, sourceLoadScript ) {
- var query = $.extend(
- { modules: buildModulesString( moduleMap ) },
- currReqBase
- );
+ // Optimisation: Inherit (Object.create), not copy ($.extend)
+ var query = Object.create( currReqBase );
+ query.modules = buildModulesString( moduleMap );
query = sortQuery( query );
addScript( sourceLoadScript + '?' + $.param( query ) );
}
// modules for this group from this source.
modules = splits[ source ][ group ];
- currReqBase = $.extend( {
- version: getCombinedVersion( modules )
- }, reqBase );
+ // Optimisation: Inherit (Object.create), not copy ($.extend)
+ currReqBase = Object.create( reqBase );
+ currReqBase.version = getCombinedVersion( modules );
+
// For user modules append a user name to the query string.
if ( group === 'user' && mw.config.get( 'wgUserName' ) !== null ) {
currReqBase.user = mw.config.get( 'wgUserName' );
function splitModuleKey( key ) {
var index = key.indexOf( '@' );
if ( index === -1 ) {
- return { name: key };
+ return {
+ name: key,
+ version: ''
+ };
}
return {
name: key.slice( 0, index ),
// Only load modules which are registered
if ( hasOwn.call( registry, queue[ q ] ) && registry[ queue[ q ] ].state === 'registered' ) {
// Prevent duplicate entries
- if ( $.inArray( queue[ q ], batch ) === -1 ) {
+ if ( batch.indexOf( queue[ q ] ) === -1 ) {
batch.push( queue[ q ] );
// Mark registered modules as loading
registry[ queue[ q ] ].state = 'loading';
if ( mw.loader.store.enabled ) {
implementations = [];
sourceModules = [];
- batch = $.grep( batch, function ( module ) {
+ batch = batch.filter( function ( module ) {
var implementation = mw.loader.store.get( module );
if ( implementation ) {
implementations.push( implementation );
mw.track( 'resourceloader.exception', { exception: err, source: 'store-eval' } );
// Re-add the failed ones that are still pending back to the batch
- failed = $.grep( sourceModules, function ( module ) {
+ failed = sourceModules.filter( function ( module ) {
return registry[ module ].state === 'loading';
} );
batchRequest( failed );
registry[ name ].messages = messages || null;
registry[ name ].templates = templates || null;
// The module may already have been marked as erroneous
- if ( $.inArray( registry[ name ].state, [ 'error', 'missing' ] ) === -1 ) {
+ if ( registry[ name ].state !== 'error' && registry[ name ].state !== 'missing' ) {
registry[ name ].state = 'loaded';
if ( allReady( registry[ name ].dependencies ) ) {
execute( name );
l = document.createElement( 'link' );
l.rel = 'stylesheet';
l.href = modules;
- $( 'head' ).append( l );
+ document.head.appendChild( l );
return;
}
if ( type === 'text/javascript' || type === undefined ) {
}
// Filter out top-level modules that are unknown or failed to load before.
- filtered = $.grep( modules, function ( module ) {
+ filtered = modules.filter( function ( module ) {
var state = mw.loader.getState( module );
return state !== 'error' && state !== 'missing';
} );
mw.loader.register( module );
}
registry[ module ].state = state;
- if ( $.inArray( state, [ 'ready', 'error', 'missing' ] ) !== -1 ) {
+ if ( state === 'ready' || state === 'error' || state === 'missing' ) {
// Make sure pending modules depending on this one get executed if their
// dependencies are now fulfilled!
handlePending( module );
* in the registry.
*/
getVersion: function ( module ) {
- if ( !hasOwn.call( registry, module ) || registry[ module ].version === undefined ) {
- return null;
- }
- return registry[ module ].version;
+ return hasOwn.call( registry, module ) ? registry[ module ].version : null;
},
/**
* in the registry.
*/
getState: function ( module ) {
- if ( !hasOwn.call( registry, module ) || registry[ module ].state === undefined ) {
- return null;
- }
- return registry[ module ].state;
+ return hasOwn.call( registry, module ) ? registry[ module ].state : null;
},
/**
// Module failed to load
descriptor.state !== 'ready' ||
// Unversioned, private, or site-/user-specific
- ( !descriptor.version || $.inArray( descriptor.group, [ 'private', 'user' ] ) !== -1 ) ||
+ !descriptor.version ||
+ descriptor.group === 'private' ||
+ descriptor.group === 'user' ||
// Partial descriptor
// (e.g. skipped module, or style module with state=ready)
- $.inArray( undefined, [ descriptor.script, descriptor.style,
- descriptor.messages, descriptor.templates ] ) !== -1
+ [ descriptor.script, descriptor.style, descriptor.messages,
+ descriptor.templates ].indexOf( undefined ) !== -1
) {
// Decline to store
return false;
// If we have an exception object, log it to the warning channel to trigger
// proper stacktraces in browsers that support it.
if ( e && console.warn ) {
- console.warn( String( e ), e );
+ console.warn( e );
}
}
/* eslint-enable no-console */
$( function () {
var loading, modules;
- modules = $.grep( mw.loader.getModuleNames(), function ( module ) {
+ modules = mw.loader.getModuleNames().filter( function ( module ) {
return mw.loader.getState( module ) === 'loading';
} );
// We only need a callback, not any actual module. First try a single using()