var modules = inspect.getLoadedModules(),
graph = {};
- $.each( modules, function ( moduleIndex, moduleName ) {
+ modules.forEach( function ( moduleName ) {
var dependencies = mw.loader.moduleRegistry[ moduleName ].dependencies || [];
if ( !hasOwn.call( graph, moduleName ) ) {
*/
getModuleSize: function ( moduleName ) {
var module = mw.loader.moduleRegistry[ moduleName ],
- payload = 0;
+ args, i, size;
- if ( mw.loader.getState( moduleName ) !== 'ready' ) {
+ if ( module.state !== 'ready' ) {
return null;
}
if ( !module.style && !module.script ) {
- return null;
+ return 0;
}
- // Tally CSS
- if ( module.style && $.isArray( module.style.css ) ) {
- $.each( module.style.css, function ( i, stylesheet ) {
- payload += $.byteLength( stylesheet );
- } );
+ function getFunctionBody( func ) {
+ return String( func )
+ // To ensure a deterministic result, replace the start of the function
+ // declaration with a fixed string. For example, in Chrome 55, it seems
+ // V8 seemingly-at-random decides to sometimes put a line break between
+ // the opening brace and first statement of the function body. T159751.
+ .replace( /^\s*function\s*\([^)]*\)\s*{\s*/, 'function(){' )
+ .replace( /\s*}\s*$/, '}' );
+ }
+
+ // Based on the load.php response for this module.
+ // For example: `mw.loader.implement("example", function(){}, {"css":[".x{color:red}"]});`
+ // @see mw.loader.store.set().
+ args = [
+ moduleName,
+ module.script,
+ module.style,
+ module.messages,
+ module.templates
+ ];
+ // Trim trailing null or empty object, as load.php would have done.
+ // @see ResourceLoader::makeLoaderImplementScript and ResourceLoader::trimArray.
+ i = args.length;
+ while ( i-- ) {
+ if ( args[ i ] === null || ( $.isPlainObject( args[ i ] ) && $.isEmptyObject( args[ i ] ) ) ) {
+ args.splice( i, 1 );
+ } else {
+ break;
+ }
}
- // Tally JavaScript
- if ( $.isFunction( module.script ) ) {
- payload += $.byteLength( module.script.toString() );
+ size = 0;
+ for ( i = 0; i < args.length; i++ ) {
+ if ( typeof args[ i ] === 'function' ) {
+ size += $.byteLength( getFunctionBody( args[ i ] ) );
+ } else {
+ size += $.byteLength( JSON.stringify( args[ i ] ) );
+ }
}
- return payload;
+ return size;
},
/**
* @return {Array} List of module names
*/
getLoadedModules: function () {
- return $.grep( mw.loader.getModuleNames(), function ( module ) {
+ return mw.loader.getModuleNames().filter( function ( module ) {
return mw.loader.getState( module ) === 'ready';
} );
},
// Use Function.prototype#call to force an exception on Firefox,
// which doesn't define console#table but doesn't complain if you
// try to invoke it.
+ // eslint-disable-next-line no-useless-call
console.table.call( console, data );
return;
} catch ( e ) {}
Array.prototype.slice.call( arguments ) :
$.map( inspect.reports, function ( v, k ) { return k; } );
- $.each( reports, function ( index, name ) {
+ reports.forEach( function ( name ) {
inspect.dumpTable( inspect.reports[ name ]() );
} );
},
*/
size: function () {
// Map each module to a descriptor object.
- var modules = $.map( inspect.getLoadedModules(), function ( module ) {
+ var modules = inspect.getLoadedModules().map( function ( module ) {
return {
name: module,
size: inspect.getModuleSize( module )
sortByProperty( modules, 'size', true );
// Convert size to human-readable string.
- $.each( modules, function ( i, module ) {
+ modules.forEach( function ( module ) {
module.sizeInBytes = module.size;
module.size = humanSize( module.size );
} );
css: function () {
var modules = [];
- $.each( inspect.getLoadedModules(), function ( index, name ) {
+ inspect.getLoadedModules().forEach( function ( name ) {
var css, stats, module = mw.loader.moduleRegistry[ name ];
try {
pattern = new RegExp( mw.RegExp.escape( pattern ), 'g' );
}
- return $.grep( inspect.getLoadedModules(), function ( moduleName ) {
+ return inspect.getLoadedModules().filter( function ( moduleName ) {
var module = mw.loader.moduleRegistry[ moduleName ];
// Grep module's JavaScript
// Grep module's CSS
if (
- $.isPlainObject( module.style ) && $.isArray( module.style.css ) &&
+ $.isPlainObject( module.style ) && Array.isArray( module.style.css ) &&
pattern.test( module.style.css.join( '' ) )
) {
// Module's CSS source matches