*/
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;
},
/**
// 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 ) {}
// 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