jenkins-bot has submitted this change and it was merged.

Change subject: mediawiki.inspect: add CSS report
......................................................................


mediawiki.inspect: add CSS report

This patch extends mediawiki#inspect to add a notion of 'reports'. Instead of
there being one single view for all ResourceLoader module debug data, you can
now request that a specific report be run. Each report highlights a set of
metrics that are unified by some common theme.

The previous, unqualified report is now branded the 'size' report. In addition
to it, this patch also adds a CSS report, which prints the count of selectors
and the count of selectors that match against the current time

Change-Id: I0e7a47b5a93a66ecb103fe30a3de8a2ca8a4eb84
(cherry picked from commit 678d976f0b646c98ca679f0dbb47602da72a947c)
---
M maintenance/jsduck/categories.json
M resources/mediawiki/mediawiki.inspect.js
M resources/mediawiki/mediawiki.js
3 files changed, 114 insertions(+), 22 deletions(-)

Approvals:
  Ori.livneh: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/maintenance/jsduck/categories.json 
b/maintenance/jsduck/categories.json
index e98e9c0..f96902d 100644
--- a/maintenance/jsduck/categories.json
+++ b/maintenance/jsduck/categories.json
@@ -21,6 +21,7 @@
                                "classes": [
                                        "mw.Title",
                                        "mw.inspect",
+                                       "mw.inspect.reports",
                                        "mw.notification",
                                        "mw.user",
                                        "mw.util",
diff --git a/resources/mediawiki/mediawiki.inspect.js 
b/resources/mediawiki/mediawiki.inspect.js
index 5cecc16..8268f12 100644
--- a/resources/mediawiki/mediawiki.inspect.js
+++ b/resources/mediawiki/mediawiki.inspect.js
@@ -4,7 +4,15 @@
  * @author Ori Livneh
  * @since 1.22
  */
+/*jshint devel:true */
 ( function ( mw, $ ) {
+
+       function sortByProperty( array, prop, descending ) {
+               var order = descending ? -1 : 1;
+               return array.sort( function ( a, b ) {
+                       return a[prop] > b[prop] ? order : a[prop] < b[prop] ? 
-order : 0;
+               } );
+       }
 
        /**
         * @class mw.inspect
@@ -46,6 +54,32 @@
                },
 
                /**
+                * Given CSS source, count both the total number of selectors it
+                * contains and the number which match some element in the 
current
+                * document.
+                *
+                * @param {string} css CSS source
+                * @return Selector counts
+                * @return {number} return.selectors Total number of selectors
+                * @return {number} return.matched Number of matched selectors
+                */
+               auditSelectors: function ( css ) {
+                       var selectors = { total: 0, matched: 0 },
+                               style = document.createElement( 'style' );
+
+                       style.textContent = css;
+                       document.body.appendChild( style );
+                       $.each( style.sheet.cssRules, function ( index, rule ) {
+                               selectors.total++;
+                               if ( document.querySelector( rule.selectorText 
) !== null ) {
+                                       selectors.matched++;
+                               }
+                       } );
+                       document.body.removeChild( style );
+                       return selectors;
+               },
+
+               /**
                 * Get a list of all loaded ResourceLoader modules.
                 *
                 * @return {Array} List of module names
@@ -57,13 +91,53 @@
                },
 
                /**
-                * Print a breakdown of all loaded modules and their size in 
kilobytes
-                * to the debug console. Modules are ordered from largest to 
smallest.
+                * Print tabular data to the console, using console.table, 
console.log,
+                * or mw.log (in declining order of preference).
+                *
+                * @param {Array} data Tabular data represented as an array of 
objects
+                *  with common properties.
                 */
-               inspectModules: function () {
-                       var console = window.console;
+               dumpTable: function ( data ) {
+                       try {
+                               // Bartosz made me put this here.
+                               if ( window.opera ) { throw window.opera; }
+                               console.table( data );
+                               return;
+                       } catch (e) {}
+                       try {
+                               console.log( JSON.stringify( data, null, 2 ) );
+                               return;
+                       } catch (e) {}
+                       mw.log( data );
+               },
 
-                       $( function () {
+               /**
+                * Generate and print one more reports. When invoked with no 
arguments,
+                * print all reports.
+                *
+                * @param {string...} [reports] Report names to run, or unset 
to print
+                *  all available reports.
+                */
+               runReports: function () {
+                       var reports = arguments.length > 0 ?
+                               Array.prototype.slice.call( arguments ) :
+                               $.map( inspect.reports, function ( v, k ) { 
return k; } );
+
+                       $.each( reports, function ( index, name ) {
+                               inspect.dumpTable( inspect.reports[name]() );
+                       } );
+               },
+
+               /**
+                * @class mw.inspect.reports
+                * @singleton
+                */
+               reports: {
+                       /**
+                        * Generate a breakdown of all loaded modules and their 
size in
+                        * kilobytes. Modules are ordered from largest to 
smallest.
+                        */
+                       size: function () {
                                // Map each module to a descriptor object.
                                var modules = $.map( 
inspect.getLoadedModules(), function ( module ) {
                                        return {
@@ -73,9 +147,7 @@
                                } );
 
                                // Sort module descriptors by size, largest 
first.
-                               modules.sort( function ( a, b ) {
-                                       return b.size - a.size;
-                               } );
+                               sortByProperty( modules, 'size', true );
 
                                // Convert size to human-readable string.
                                $.each( modules, function ( i, module ) {
@@ -84,22 +156,40 @@
                                                ( module.size !== null ? 
module.size + ' B' : null );
                                } );
 
-                               if ( console ) {
-                                       if ( console.table ) {
-                                               console.table( modules );
-                                       } else {
-                                               $.each( modules, function ( i, 
module ) {
-                                                       console.log( [ 
module.name, module.size ].join( '\t' ) );
-                                               } );
-                                       }
-                               }
-                       } );
+                               return modules;
+                       },
+
+                       /**
+                        * For each module with styles, count the number of 
selectors, and
+                        * count how many match against some element currently 
in the DOM.
+                        */
+                       css: function () {
+                               var modules = [];
+
+                               $.each( inspect.getLoadedModules(), function ( 
index, name ) {
+                                       var css, stats, module = 
mw.loader.moduleRegistry[name];
+
+                                       try {
+                                               css = module.style.css.join();
+                                       } catch (e) { return; } // skip
+
+                                       stats = inspect.auditSelectors( css );
+                                       modules.push( {
+                                               module: name,
+                                               allSelectors: stats.total,
+                                               matchedSelectors: stats.matched,
+                                               percentMatched: stats.total !== 
0 ?
+                                                       ( stats.matched / 
stats.total * 100 ).toFixed( 2 )  + '%' : null
+                                       } );
+                               } );
+                               sortByProperty( modules, 'allSelectors', true );
+                               return modules;
+                       },
                }
        };
 
        if ( mw.config.get( 'debug' ) ) {
-               inspect.getModuleSize = function () { return null; };
-               mw.log( 'mw.inspect: Module sizes are not available in debug 
mode.' );
+               mw.log( 'mw.inspect: reports are not available in debug mode.' 
);
        }
 
        mw.inspect = inspect;
diff --git a/resources/mediawiki/mediawiki.js b/resources/mediawiki/mediawiki.js
index 4138ac8..cc996e5 100644
--- a/resources/mediawiki/mediawiki.js
+++ b/resources/mediawiki/mediawiki.js
@@ -1702,12 +1702,13 @@
                                },
 
                                /**
-                                * @inheritdoc mw.inspect#inspectModules
+                                * @inheritdoc mw.inspect#runReports
                                 * @method
                                 */
                                inspect: function () {
+                                       var args = slice.call( arguments );
                                        mw.loader.using( 'mediawiki.inspect', 
function () {
-                                               mw.inspect.inspectModules();
+                                               mw.inspect.runReports.apply( 
mw.inspect, args );
                                        } );
                                }
 

-- 
To view, visit https://gerrit.wikimedia.org/r/91301
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I0e7a47b5a93a66ecb103fe30a3de8a2ca8a4eb84
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: wmf/1.22wmf21
Gerrit-Owner: Ori.livneh <[email protected]>
Gerrit-Reviewer: Ori.livneh <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to