Changeset 56107 in webkit


Ignore:
Timestamp:
Mar 17, 2010 6:51:45 AM (14 years ago)
Author:
apavlov@chromium.org
Message:

2010-03-17 Alexander Pavlov <apavlov@chromium.org>

Reviewed by Pavel Feldman.

Web Inspector: Reimplement style-related audits using native API
https://bugs.webkit.org/show_bug.cgi?id=36172

  • inspector/InspectorBackend.cpp: (WebCore::InspectorBackend::getAllStyles):
  • inspector/InspectorBackend.h:
  • inspector/InspectorBackend.idl:
  • inspector/InspectorDOMAgent.cpp: (WebCore::InspectorDOMAgent::getAllStyles): (WebCore::InspectorDOMAgent::getMatchedCSSRules): (WebCore::InspectorDOMAgent::buildObjectForStyleSheet): (WebCore::InspectorDOMAgent::buildObjectForRule):
  • inspector/InspectorDOMAgent.h:
  • inspector/InspectorFrontend.cpp: (WebCore::InspectorFrontend::didGetAllStyles):
  • inspector/InspectorFrontend.h:
  • inspector/front-end/AuditRules.js: (WebInspector.AuditRules.evaluateInTargetWindow): (WebInspector.AuditRules.UnusedCssRule.prototype.doRun.evalCallback.selectorsCallback): (WebInspector.AuditRules.UnusedCssRule.prototype.doRun.evalCallback.routine): (WebInspector.AuditRules.UnusedCssRule.prototype.doRun.evalCallback): (WebInspector.AuditRules.UnusedCssRule.prototype.doRun.routine): (WebInspector.AuditRules.UnusedCssRule.prototype.doRun): (WebInspector.AuditRules.ImageDimensionsRule.prototype.doRun): (WebInspector.AuditRules.CssInHeadRule.prototype.doRun): (WebInspector.AuditRules.StylesScriptsOrderRule.prototype.doRun):
  • inspector/front-end/DOMAgent.js:
  • inspector/front-end/InjectedScript.js: (injectedScriptConstructor):
Location:
trunk/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r56105 r56107  
     12010-03-17  Alexander Pavlov  <apavlov@chromium.org>
     2
     3        Reviewed by Pavel Feldman.
     4
     5        Web Inspector: Reimplement style-related audits using native API
     6        https://bugs.webkit.org/show_bug.cgi?id=36172
     7
     8        * inspector/InspectorBackend.cpp:
     9        (WebCore::InspectorBackend::getAllStyles):
     10        * inspector/InspectorBackend.h:
     11        * inspector/InspectorBackend.idl:
     12        * inspector/InspectorDOMAgent.cpp:
     13        (WebCore::InspectorDOMAgent::getAllStyles):
     14        (WebCore::InspectorDOMAgent::getMatchedCSSRules):
     15        (WebCore::InspectorDOMAgent::buildObjectForStyleSheet):
     16        (WebCore::InspectorDOMAgent::buildObjectForRule):
     17        * inspector/InspectorDOMAgent.h:
     18        * inspector/InspectorFrontend.cpp:
     19        (WebCore::InspectorFrontend::didGetAllStyles):
     20        * inspector/InspectorFrontend.h:
     21        * inspector/front-end/AuditRules.js:
     22        (WebInspector.AuditRules.evaluateInTargetWindow):
     23        (WebInspector.AuditRules.UnusedCssRule.prototype.doRun.evalCallback.selectorsCallback):
     24        (WebInspector.AuditRules.UnusedCssRule.prototype.doRun.evalCallback.routine):
     25        (WebInspector.AuditRules.UnusedCssRule.prototype.doRun.evalCallback):
     26        (WebInspector.AuditRules.UnusedCssRule.prototype.doRun.routine):
     27        (WebInspector.AuditRules.UnusedCssRule.prototype.doRun):
     28        (WebInspector.AuditRules.ImageDimensionsRule.prototype.doRun):
     29        (WebInspector.AuditRules.CssInHeadRule.prototype.doRun):
     30        (WebInspector.AuditRules.StylesScriptsOrderRule.prototype.doRun):
     31        * inspector/front-end/DOMAgent.js:
     32        * inspector/front-end/InjectedScript.js:
     33        (injectedScriptConstructor):
     34
    1352010-03-17  Steve Block  <steveblock@google.com>
    236
  • trunk/WebCore/inspector/InspectorBackend.cpp

    r56049 r56107  
    363363}
    364364
     365void InspectorBackend::getAllStyles(long callId)
     366{
     367    if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
     368        domAgent->getAllStyles(callId);
     369}
     370
    365371void InspectorBackend::getInlineStyle(long callId, long nodeId)
    366372{
  • trunk/WebCore/inspector/InspectorBackend.h

    r56049 r56107  
    115115
    116116    void getStyles(long callId, long nodeId, bool authOnly);
     117    void getAllStyles(long callId);
    117118    void getInlineStyle(long callId, long nodeId);
    118119    void getComputedStyle(long callId, long nodeId);
  • trunk/WebCore/inspector/InspectorBackend.idl

    r56049 r56107  
    9292
    9393        void getStyles(in long callId, in long nodeId, in boolean authOnly);
     94        void getAllStyles(in long callId);
    9495        void getInlineStyle(in long callId, in long nodeId);
    9596        void getComputedStyle(in long callId, in long nodeId);
  • trunk/WebCore/inspector/InspectorDOMAgent.cpp

    r56059 r56107  
    705705}
    706706
     707void InspectorDOMAgent::getAllStyles(long callId)
     708{
     709    ScriptArray result = m_frontend->newScriptArray();
     710    unsigned counter = 0;
     711    for (ListHashSet<RefPtr<Document> >::iterator it = m_documents.begin(); it != m_documents.end(); ++it) {
     712        StyleSheetList* list = (*it)->styleSheets();
     713        for (unsigned i = 0; i < list->length(); ++i) {
     714            StyleSheet* styleSheet = list->item(i);
     715            if (styleSheet->isCSSStyleSheet())
     716                result.set(counter++, buildObjectForStyleSheet(static_cast<CSSStyleSheet*>(styleSheet)));
     717        }
     718    }
     719    m_frontend->didGetAllStyles(callId, result);
     720}
     721
    707722void InspectorDOMAgent::getInlineStyle(long callId, long nodeId)
    708723{
     
    735750    RefPtr<CSSRuleList> matchedRules = defaultView->getMatchedCSSRules(element, "", authorOnly);
    736751    ScriptArray matchedCSSRules = m_frontend->newScriptArray();
     752    unsigned counter = 0;
    737753    for (unsigned i = 0; matchedRules.get() && i < matchedRules->length(); ++i) {
    738754        CSSRule* rule = matchedRules->item(i);
    739755        if (rule->type() == CSSRule::STYLE_RULE)
    740             matchedCSSRules.set(i, buildObjectForRule(static_cast<CSSStyleRule*>(rule)));
     756            matchedCSSRules.set(counter++, buildObjectForRule(static_cast<CSSStyleRule*>(rule)));
    741757    }
    742758    return matchedCSSRules;
     
    10441060}
    10451061
     1062ScriptObject InspectorDOMAgent::buildObjectForStyleSheet(CSSStyleSheet* styleSheet)
     1063{
     1064    ScriptObject result = m_frontend->newScriptObject();
     1065    result.set("disabled", styleSheet->disabled());
     1066    result.set("href", styleSheet->href());
     1067    result.set("title", styleSheet->title());
     1068    result.set("documentElementId", m_documentNodeToIdMap.get(styleSheet->doc()));
     1069    ScriptArray cssRules = m_frontend->newScriptArray();
     1070    result.set("cssRules", cssRules);
     1071    PassRefPtr<CSSRuleList> cssRuleList = CSSRuleList::create(styleSheet, true);
     1072    if (!cssRuleList)
     1073        return result;
     1074    unsigned counter = 0;
     1075    for (unsigned i = 0; i < cssRuleList->length(); ++i) {
     1076        CSSRule* rule = cssRuleList->item(i);
     1077        if (rule->isStyleRule())
     1078            cssRules.set(counter++, buildObjectForRule(static_cast<CSSStyleRule*>(rule)));
     1079    }
     1080    return result;
     1081}
     1082
    10461083ScriptObject InspectorDOMAgent::buildObjectForRule(CSSStyleRule* rule)
    10471084{
     
    10501087    ScriptObject result = m_frontend->newScriptObject();
    10511088    result.set("selectorText", rule->selectorText());
     1089    result.set("cssText", rule->cssText());
    10521090    if (parentStyleSheet) {
    10531091        ScriptObject parentStyleSheetValue = m_frontend->newScriptObject();
  • trunk/WebCore/inspector/InspectorDOMAgent.h

    r56049 r56107  
    101101        // Methods called from the frontend for CSS styles inspection.
    102102        void getStyles(long callId, long nodeId, bool authorOnly);
     103        void getAllStyles(long callId);
    103104        void getInlineStyle(long callId, long nodeId);
    104105        void getComputedStyle(long callId, long nodeId);
     
    160161        void populateObjectWithStyleProperties(CSSStyleDeclaration*, ScriptObject& result);
    161162        ScriptObject buildObjectForRule(CSSStyleRule*);
     163        ScriptObject buildObjectForStyleSheet(CSSStyleSheet*);
    162164        Vector<String> uniqueStyleProperties(CSSStyleDeclaration*);
    163165        Vector<String> longhandProperties(CSSStyleDeclaration*, const String& shorthandProperty);
  • trunk/WebCore/inspector/InspectorFrontend.cpp

    r56051 r56107  
    507507}
    508508
     509void InspectorFrontend::didGetAllStyles(long callId, const ScriptArray& styles)
     510{
     511    ScriptFunctionCall function(m_webInspector, "dispatch");
     512    function.appendArgument("didGetAllStyles");
     513    function.appendArgument(callId);
     514    function.appendArgument(styles);
     515    function.call();
     516}
     517
    509518void InspectorFrontend::didGetComputedStyle(long callId, const ScriptValue& style)
    510519{
  • trunk/WebCore/inspector/InspectorFrontend.h

    r56051 r56107  
    136136
    137137        void didGetStyles(long callId, const ScriptValue& styles);
     138        void didGetAllStyles(long callId, const ScriptArray& styles);
    138139        void didGetInlineStyle(long callId, const ScriptValue& style);
    139140        void didGetComputedStyle(long callId, const ScriptValue& style);
  • trunk/WebCore/inspector/front-end/AuditRules.js

    r55727 r56107  
    6464}
    6565
    66 WebInspector.AuditRules.evaluateInTargetWindow = function(func, callback)
    67 {
    68     InjectedScriptAccess.getDefault().evaluateOnSelf(func.toString(), callback);
     66WebInspector.AuditRules.evaluateInTargetWindow = function(func, args, callback)
     67{
     68    InjectedScriptAccess.getDefault().evaluateOnSelf(func.toString(), args, callback);
    6969}
    7070
     
    279279    {
    280280        var self = this;
    281         function evalCallback(routineResult, isException) {
    282             if (isException || !routineResult || !routineResult.styleSheets.length)
     281        function evalCallback(styleSheets) {
     282            if (!styleSheets.length)
    283283                return callback(null);
    284284
    285             var totalUnusedPercent = Math.round(100 * routineResult.unusedSize / routineResult.totalSize);
    286             var summary = result.addChild(String.sprintf("%d%% of CSS (estimated) is not used by the current page.", totalUnusedPercent), true);
    287 
    288             for (var i = 0; i < routineResult.styleSheets.length; ++i) {
    289                 var stylesheet = routineResult.styleSheets[i];
    290 
    291                 var url = stylesheet.type === "href" ? WebInspector.linkifyURL(stylesheet.location) : String.sprintf("Inline block #%s", stylesheet.location);
    292                 var pctUnused = Math.round(100 * stylesheet.unusedSize / stylesheet.totalSize);
    293                 var entry = summary.addChild(String.sprintf("%s: %d%% (estimated) is not used by the current page.", url, pctUnused));
    294 
    295                 for (var j = 0; j < stylesheet.unusedRules.length; ++j)
    296                     entry.addSnippet(stylesheet.unusedRules[j]);
    297 
    298                 result.violationCount += stylesheet.unusedRules.length;
    299             }
    300 
    301             callback(result);
     285            var pseudoSelectorRegexp = /:hover|:link|:active|:visited|:focus|:before|:after/;
     286            var selectors = [];
     287            var testedSelectors = {};
     288            for (var i = 0; i < styleSheets.length; ++i) {
     289                var styleSheet = styleSheets[i];
     290                for (var curRule = 0; curRule < styleSheet.cssRules.length; ++curRule) {
     291                    var rule = styleSheet.cssRules[curRule];
     292                    if (rule.selectorText.match(pseudoSelectorRegexp))
     293                        continue;
     294                    selectors.push(rule.selectorText);
     295                    testedSelectors[rule.selectorText] = 1;
     296                }
     297            }
     298
     299            function selectorsCallback(callback, styleSheets, testedSelectors, foundSelectors)
     300            {
     301                var inlineBlockOrdinal = 0;
     302                var totalStylesheetSize = 0;
     303                var totalUnusedStylesheetSize = 0;
     304                var summary;
     305
     306                for (var i = 0; i < styleSheets.length; ++i) {
     307                    var styleSheet = styleSheets[i];
     308                    var stylesheetSize = 0;
     309                    var unusedStylesheetSize = 0;
     310                    var unusedRules = [];
     311                    for (var curRule = 0; curRule < styleSheet.cssRules.length; ++curRule) {
     312                        var rule = styleSheet.cssRules[curRule];
     313                        var textLength = rule.cssText ? rule.cssText.length : 0;
     314                        stylesheetSize += textLength;
     315                        if (!testedSelectors[rule.selectorText] || foundSelectors[rule.selectorText])
     316                            continue;
     317                        unusedStylesheetSize += textLength;
     318                        unusedRules.push(rule.selectorText);
     319                    }
     320                    totalStylesheetSize += stylesheetSize;
     321                    totalUnusedStylesheetSize += unusedStylesheetSize;
     322
     323                    if (!unusedRules.length)
     324                        continue;
     325
     326                    var url = styleSheet.href ? WebInspector.linkifyURL(styleSheet.href) : String.sprintf("Inline block #%d", ++inlineBlockOrdinal);
     327                    var pctUnused = Math.round(100 * unusedStylesheetSize / stylesheetSize);
     328                    if (!summary)
     329                        summary = result.addChild("", true);
     330                    var entry = summary.addChild(String.sprintf("%s: %d%% (estimated) is not used by the current page.", url, pctUnused));
     331
     332                    for (var j = 0; j < unusedRules.length; ++j)
     333                        entry.addSnippet(unusedRules[j]);
     334
     335                    result.violationCount += unusedRules.length;
     336                }
     337
     338                if (!totalUnusedStylesheetSize)
     339                    return callback(null);
     340
     341                var totalUnusedPercent = Math.round(100 * totalUnusedStylesheetSize / totalStylesheetSize);
     342                summary.value = String.sprintf("%d%% of CSS (estimated) is not used by the current page.", totalUnusedPercent);
     343
     344                callback(result);
     345            }
     346
     347            function routine(selectorArray)
     348            {
     349                var result = {};
     350                for (var i = 0; i < selectorArray.length; ++i) {
     351                    var nodes = document.querySelectorAll(selectorArray[i]);
     352                    if (nodes && nodes.length)
     353                        result[selectorArray[i]] = true;
     354                }
     355                return result;
     356            }
     357
     358            WebInspector.AuditRules.evaluateInTargetWindow(routine, [selectors], selectorsCallback.bind(null, callback, styleSheets, testedSelectors));
    302359        }
    303360
     
    307364            if (!styleSheets)
    308365                return false;
    309             var routineResult = { styleSheets: [] };
    310             var inlineBlockOrdinal = 0;
    311             var totalStylesheetSize = 0;
    312             var totalUnusedStylesheetSize = 0;
    313             var pseudoSelectorRegexp = /:hover|:link|:active|:visited|:focus/;
    314             for (var i = 0; i < styleSheets.length; ++i) {
    315                 var styleSheet = styleSheets[i];
    316                 if (!styleSheet.cssRules)
    317                     continue;
    318                 var stylesheetSize = 0;
    319                 var unusedStylesheetSize = 0;
    320                 var unusedRules = [];
    321                 for (var curRule = 0; curRule < styleSheet.cssRules.length; ++curRule) {
    322                     var rule = styleSheet.cssRules[curRule];
    323                     var textLength = rule.cssText ? rule.cssText.length : 0;
    324                     stylesheetSize += textLength;
    325                     if (rule.type !== 1 || rule.selectorText.match(pseudoSelectorRegexp))
    326                         continue;
    327                     var nodes = document.querySelectorAll(rule.selectorText);
    328                     if (nodes && nodes.length)
    329                         continue;
    330                     unusedStylesheetSize += textLength;
    331                     unusedRules.push(rule.selectorText);
    332                 }
    333                 totalStylesheetSize += stylesheetSize;
    334                 totalUnusedStylesheetSize += unusedStylesheetSize;
    335 
    336                 if (unusedRules.length) {
    337                     var entry = { type: styleSheet.href ? "href" : "inline",
    338                                   totalSize: stylesheetSize,
    339                                   unusedSize: unusedStylesheetSize,
    340                                   location: styleSheet.href ? styleSheet.href : ++inlineBlockOrdinal,
    341                                   unusedRules: unusedRules };
    342                     routineResult.styleSheets.push(entry);
    343                 }
    344             }
    345             routineResult.totalSize = totalStylesheetSize;
    346             routineResult.unusedSize = totalUnusedStylesheetSize;
     366
    347367            return routineResult;
    348368        }
    349369
    350         WebInspector.AuditRules.evaluateInTargetWindow(routine, evalCallback);
     370        InspectorBackend.getAllStyles(WebInspector.Callback.wrap(evalCallback));
    351371    }
    352372}
     
    670690        }
    671691
    672         WebInspector.AuditRules.evaluateInTargetWindow(routine, evalCallback.bind(this));
     692        WebInspector.AuditRules.evaluateInTargetWindow(routine, null, evalCallback.bind(this));
    673693    }
    674694}
     
    744764        }
    745765
    746         WebInspector.AuditRules.evaluateInTargetWindow(routine, evalCallback);
     766        WebInspector.AuditRules.evaluateInTargetWindow(routine, null, evalCallback);
    747767    }
    748768}
     
    791811        }
    792812
    793         WebInspector.AuditRules.evaluateInTargetWindow(routine, evalCallback.bind(this));
     813        WebInspector.AuditRules.evaluateInTargetWindow(routine, null, evalCallback.bind(this));
    794814    }
    795815}
  • trunk/WebCore/inspector/front-end/DOMAgent.js

    r56059 r56107  
    685685
    686686WebInspector.didGetStyles = WebInspector.Callback.processCallback;
     687WebInspector.didGetAllStyles = WebInspector.Callback.processCallback;
    687688WebInspector.didGetInlineStyle = WebInspector.Callback.processCallback;
    688689WebInspector.didGetComputedStyle = WebInspector.Callback.processCallback;
  • trunk/WebCore/inspector/front-end/InjectedScript.js

    r56049 r56107  
    787787}
    788788
    789 InjectedScript.evaluateOnSelf = function(funcBody)
    790 {
    791     return window.eval("(" + funcBody + ")();");
     789InjectedScript.evaluateOnSelf = function(funcBody, args)
     790{
     791    var func = window.eval("(" + funcBody + ")");
     792    return func.apply(this, args || []);
    792793}
    793794
Note: See TracChangeset for help on using the changeset viewer.