Changeset 178767 in webkit


Ignore:
Timestamp:
Jan 20, 2015 4:30:36 PM (9 years ago)
Author:
commit-queue@webkit.org
Message:

Web Inspector: Should show dynamic specificity values
https://bugs.webkit.org/show_bug.cgi?id=140647

Patch by Joseph Pecoraro <Joseph Pecoraro> on 2015-01-20
Reviewed by Benjamin Poulain.

Source/JavaScriptCore:

  • inspector/protocol/CSS.json:

Clarify CSSSelector optional values and add "dynamic" property indicating
if the selector can be dynamic based on the element it is matched against.

Source/WebCore:

Test: inspector/css/selector-dynamic-specificity.html

  • inspector/InspectorCSSAgent.h:
  • inspector/InspectorCSSAgent.cpp:

(WebCore::InspectorCSSAgent::setRuleSelector):
(WebCore::InspectorCSSAgent::addRule):
(WebCore::InspectorCSSAgent::buildObjectForRule):
(WebCore::InspectorCSSAgent::buildArrayForMatchedRuleList):
When building a response for a particular element, pass the element along.

  • inspector/InspectorStyleSheet.h:
  • inspector/InspectorStyleSheet.cpp:

(WebCore::hasDynamicSpecificity):
(WebCore::buildObjectForSelectorHelper):
(WebCore::selectorsFromSource):
(WebCore::InspectorStyleSheet::buildObjectForSelector):
(WebCore::InspectorStyleSheet::buildObjectForSelectorList):
(WebCore::InspectorStyleSheet::buildObjectForRule):
(WebCore::InspectorStyleSheet::buildArrayForRuleList):
(WebCore::InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle):
When building a response for a Selector, include the specificity if we know
the element in context.

Source/WebInspectorUI:

For dynamic selectors, provide text in the tooltip describing that the
specificity is dynamic and may change, and pointing out the element
the current value was calculated against.

  • Localizations/en.lproj/localizedStrings.js:
  • UserInterface/Models/CSSSelector.js:

(WebInspector.CSSSelector):
(WebInspector.CSSSelector.prototype.get specificity):
(WebInspector.CSSSelector.prototype.get dynamic):

  • UserInterface/Models/DOMNodeStyles.js:

(WebInspector.DOMNodeStyles.prototype._parseSelectorListPayload.return):
(WebInspector.DOMNodeStyles.prototype._parseSelectorListPayload):

  • UserInterface/Views/CSSStyleDeclarationSection.js:

(WebInspector.CSSStyleDeclarationSection.prototype.refresh.appendSelector):

LayoutTests:

  • inspector/css/selector-dynamic-specificity-expected.txt: Added.
  • inspector/css/selector-dynamic-specificity.html: Added.
Location:
trunk
Files:
2 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r178766 r178767  
     12015-01-20  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Should show dynamic specificity values
     4        https://bugs.webkit.org/show_bug.cgi?id=140647
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        * inspector/css/selector-dynamic-specificity-expected.txt: Added.
     9        * inspector/css/selector-dynamic-specificity.html: Added.
     10
    1112015-01-20  Alexey Proskuryakov  <ap@apple.com>
    212
  • trunk/Source/JavaScriptCore/ChangeLog

    r178756 r178767  
     12015-01-20  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Should show dynamic specificity values
     4        https://bugs.webkit.org/show_bug.cgi?id=140647
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        * inspector/protocol/CSS.json:
     9        Clarify CSSSelector optional values and add "dynamic" property indicating
     10        if the selector can be dynamic based on the element it is matched against.
     11
    1122015-01-20  Commit Queue  <commit-queue@webkit.org>
    213
  • trunk/Source/JavaScriptCore/inspector/protocol/CSS.json

    r175483 r178767  
    6464            "properties": [
    6565                { "name": "text", "type": "string", "description": "Canonicalized selector text." },
    66                 { "name": "specificity", "optional": true, "type": "array", "items": { "type": "integer" }, "description": "Specificity (a, b, c) tuple. If missing the specificity is not known statically and may be dynamic." }
     66                { "name": "specificity", "optional": true, "type": "array", "items": { "type": "integer" }, "description": "Specificity (a, b, c) tuple. Included if the selector is sent in response to CSS.getMatchedStylesForNode which provides a context element." },
     67                { "name": "dynamic", "optional": true, "type": "boolean", "description": "Whether or not the specificity can be dynamic. Included if the selector is sent in response to CSS.getMatchedStylesForNode which provides a context element." }
    6768            ],
    6869            "description": "CSS selector."
  • trunk/Source/WebCore/ChangeLog

    r178762 r178767  
     12015-01-20  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Should show dynamic specificity values
     4        https://bugs.webkit.org/show_bug.cgi?id=140647
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        Test: inspector/css/selector-dynamic-specificity.html
     9
     10        * inspector/InspectorCSSAgent.h:
     11        * inspector/InspectorCSSAgent.cpp:
     12        (WebCore::InspectorCSSAgent::setRuleSelector):
     13        (WebCore::InspectorCSSAgent::addRule):
     14        (WebCore::InspectorCSSAgent::buildObjectForRule):
     15        (WebCore::InspectorCSSAgent::buildArrayForMatchedRuleList):
     16        When building a response for a particular element, pass the element along.
     17
     18        * inspector/InspectorStyleSheet.h:
     19        * inspector/InspectorStyleSheet.cpp:
     20        (WebCore::hasDynamicSpecificity):
     21        (WebCore::buildObjectForSelectorHelper):
     22        (WebCore::selectorsFromSource):
     23        (WebCore::InspectorStyleSheet::buildObjectForSelector):
     24        (WebCore::InspectorStyleSheet::buildObjectForSelectorList):
     25        (WebCore::InspectorStyleSheet::buildObjectForRule):
     26        (WebCore::InspectorStyleSheet::buildArrayForRuleList):
     27        (WebCore::InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle):
     28        When building a response for a Selector, include the specificity if we know
     29        the element in context.
     30
    1312015-01-20  Brent Fulgham  <bfulgham@apple.com>
    232
  • trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp

    r178060 r178767  
    782782
    783783    if (success)
    784         result = inspectorStyleSheet->buildObjectForRule(inspectorStyleSheet->ruleForId(compoundId));
     784        result = inspectorStyleSheet->buildObjectForRule(inspectorStyleSheet->ruleForId(compoundId), nullptr);
    785785    errorString = InspectorDOMAgent::toErrorString(ec);
    786786}
     
    809809    InspectorCSSId ruleId = rawAction->newRuleId();
    810810    CSSStyleRule* rule = inspectorStyleSheet->ruleForId(ruleId);
    811     result = inspectorStyleSheet->buildObjectForRule(rule);
     811    result = inspectorStyleSheet->buildObjectForRule(rule, nullptr);
    812812}
    813813
     
    10171017}
    10181018
    1019 RefPtr<Inspector::Protocol::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(StyleRule* styleRule, StyleResolver& styleResolver)
     1019RefPtr<Inspector::Protocol::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(StyleRule* styleRule, StyleResolver& styleResolver, Element* element)
    10201020{
    10211021    if (!styleRule)
     
    10281028        return nullptr;
    10291029    InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(cssomWrapper->parentStyleSheet());
    1030     return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(cssomWrapper) : nullptr;
     1030    return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(cssomWrapper, element) : nullptr;
    10311031}
    10321032
     
    10381038    ASSERT(rule->parentStyleSheet());
    10391039    InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(rule->parentStyleSheet());
    1040     return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(rule) : nullptr;
     1040    return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(rule, nullptr) : nullptr;
    10411041}
    10421042
     
    10491049
    10501050    for (auto& matchedRule : matchedRules) {
    1051         RefPtr<Inspector::Protocol::CSS::CSSRule> ruleObject = buildObjectForRule(matchedRule.get(), styleResolver);
     1051        RefPtr<Inspector::Protocol::CSS::CSSRule> ruleObject = buildObjectForRule(matchedRule.get(), styleResolver, element);
    10521052        if (!ruleObject)
    10531053            continue;
  • trunk/Source/WebCore/inspector/InspectorCSSAgent.h

    r178060 r178767  
    153153    Inspector::Protocol::CSS::StyleSheetOrigin detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument);
    154154
    155     RefPtr<Inspector::Protocol::CSS::CSSRule> buildObjectForRule(StyleRule*, StyleResolver&);
     155    RefPtr<Inspector::Protocol::CSS::CSSRule> buildObjectForRule(StyleRule*, StyleResolver&, Element*);
    156156    RefPtr<Inspector::Protocol::CSS::CSSRule> buildObjectForRule(CSSStyleRule*);
    157157    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::RuleMatch>> buildArrayForMatchedRuleList(const Vector<RefPtr<StyleRule>>&, StyleResolver&, Element*);
  • trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp

    r178060 r178767  
    997997}
    998998
    999 static Ref<Inspector::Protocol::CSS::CSSSelector> buildObjectForSelectorHelper(const String& selectorText, const CSSSelector& selector)
     999static bool hasDynamicSpecificity(const CSSSelector& simpleSelector)
     1000{
     1001    // It is possible that these can have a static specificity if each selector in the list has
     1002    // equal specificity, but lets always report that they can be dynamic.
     1003    for (const CSSSelector* selector = &simpleSelector; selector; selector = selector->tagHistory()) {
     1004        if (selector->match() == CSSSelector::PseudoClass) {
     1005            CSSSelector::PseudoClassType pseudoClassType = selector->pseudoClassType();
     1006            if (pseudoClassType == CSSSelector::PseudoClassMatches)
     1007                return true;
     1008            if (pseudoClassType == CSSSelector::PseudoClassNthChild || pseudoClassType == CSSSelector::PseudoClassNthLastChild) {
     1009                if (selector->selectorList())
     1010                    return true;
     1011                return false;
     1012            }
     1013        }
     1014    }
     1015
     1016    return false;
     1017}
     1018
     1019static Ref<Inspector::Protocol::CSS::CSSSelector> buildObjectForSelectorHelper(const String& selectorText, const CSSSelector& selector, Element* element)
    10001020{
    10011021    auto inspectorSelector = Inspector::Protocol::CSS::CSSSelector::create()
     
    10031023        .release();
    10041024
    1005     bool ok;
    1006     unsigned specificity = selector.staticSpecificity(ok);
    1007 
    1008     if (ok) {
    1009         auto tuple = Inspector::Protocol::Array<int>::create();
    1010         tuple->addItem(static_cast<int>((specificity & CSSSelector::idMask) >> 16));
    1011         tuple->addItem(static_cast<int>((specificity & CSSSelector::classMask) >> 8));
    1012         tuple->addItem(static_cast<int>(specificity & CSSSelector::elementMask));
    1013         inspectorSelector->setSpecificity(WTF::move(tuple));
     1025    if (element) {
     1026        bool dynamic = hasDynamicSpecificity(selector);
     1027        if (dynamic)
     1028            inspectorSelector->setDynamic(true);
     1029
     1030        SelectorChecker::CheckingContext context(SelectorChecker::Mode::CollectingRules);
     1031        SelectorChecker selectorChecker(element->document());
     1032
     1033        unsigned specificity;
     1034        bool okay = selectorChecker.match(&selector, element, context, specificity);
     1035        if (!okay)
     1036            specificity = selector.staticSpecificity(okay);
     1037
     1038        if (okay) {
     1039            auto tuple = Inspector::Protocol::Array<int>::create();
     1040            tuple->addItem(static_cast<int>((specificity & CSSSelector::idMask) >> 16));
     1041            tuple->addItem(static_cast<int>((specificity & CSSSelector::classMask) >> 8));
     1042            tuple->addItem(static_cast<int>(specificity & CSSSelector::elementMask));
     1043            inspectorSelector->setSpecificity(WTF::move(tuple));
     1044        }
    10141045    }
    10151046
     
    10171048}
    10181049
    1019 static Ref<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSSelector>> selectorsFromSource(const CSSRuleSourceData* sourceData, const String& sheetText, const CSSSelectorList& selectorList)
     1050static Ref<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSSelector>> selectorsFromSource(const CSSRuleSourceData* sourceData, const String& sheetText, const CSSSelectorList& selectorList, Element* element)
    10201051{
    10211052    DEPRECATED_DEFINE_STATIC_LOCAL(JSC::Yarr::RegularExpression, comment, ("/\\*[^]*?\\*/", TextCaseSensitive, JSC::Yarr::MultilineEnabled));
     
    10301061        // We don't want to see any comments in the selector components, only the meaningful parts.
    10311062        replace(selectorText, comment, String());
    1032         result->addItem(buildObjectForSelectorHelper(selectorText.stripWhiteSpace(), *selector));
     1063        result->addItem(buildObjectForSelectorHelper(selectorText.stripWhiteSpace(), *selector, element));
    10331064
    10341065        selector = CSSSelectorList::next(selector);
     
    10371068}
    10381069
    1039 Ref<Inspector::Protocol::CSS::CSSSelector> InspectorStyleSheet::buildObjectForSelector(const CSSSelector* selector)
    1040 {
    1041     return buildObjectForSelectorHelper(selector->selectorText(), *selector);
    1042 }
    1043 
    1044 Ref<Inspector::Protocol::CSS::SelectorList> InspectorStyleSheet::buildObjectForSelectorList(CSSStyleRule* rule)
     1070Ref<Inspector::Protocol::CSS::CSSSelector> InspectorStyleSheet::buildObjectForSelector(const CSSSelector* selector, Element* element)
     1071{
     1072    return buildObjectForSelectorHelper(selector->selectorText(), *selector, element);
     1073}
     1074
     1075Ref<Inspector::Protocol::CSS::SelectorList> InspectorStyleSheet::buildObjectForSelectorList(CSSStyleRule* rule, Element* element)
    10451076{
    10461077    RefPtr<CSSRuleSourceData> sourceData;
     
    10531084
    10541085    if (sourceData)
    1055         selectors = selectorsFromSource(sourceData.get(), m_parsedStyleSheet->text(), rule->styleRule().selectorList());
     1086        selectors = selectorsFromSource(sourceData.get(), m_parsedStyleSheet->text(), rule->styleRule().selectorList(), element);
    10561087    else {
    10571088        selectors = Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSSelector>::create();
    10581089        const CSSSelectorList& selectorList = rule->styleRule().selectorList();
    10591090        for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
    1060             selectors->addItem(buildObjectForSelector(selector));
     1091            selectors->addItem(buildObjectForSelector(selector, element));
    10611092    }
    10621093    auto result = Inspector::Protocol::CSS::SelectorList::create()
     
    10691100}
    10701101
    1071 RefPtr<Inspector::Protocol::CSS::CSSRule> InspectorStyleSheet::buildObjectForRule(CSSStyleRule* rule)
     1102RefPtr<Inspector::Protocol::CSS::CSSRule> InspectorStyleSheet::buildObjectForRule(CSSStyleRule* rule, Element* element)
    10721103{
    10731104    CSSStyleSheet* styleSheet = pageStyleSheet();
     
    10761107
    10771108    auto result = Inspector::Protocol::CSS::CSSRule::create()
    1078         .setSelectorList(buildObjectForSelectorList(rule))
     1109        .setSelectorList(buildObjectForSelectorList(rule, element))
    10791110        .setSourceLine(rule->styleRule().sourceLine())
    10801111        .setOrigin(m_origin)
     
    14361467
    14371468    for (unsigned i = 0, size = rules.size(); i < size; ++i)
    1438         result->addItem(buildObjectForRule(rules.at(i).get()));
     1469        result->addItem(buildObjectForRule(rules.at(i).get(), nullptr));
    14391470
    14401471    return WTF::move(result);
     
    14651496
    14661497InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(InspectorPageAgent* pageAgent, const String& id, RefPtr<Element>&& element, Inspector::Protocol::CSS::StyleSheetOrigin origin, Listener* listener)
    1467     : InspectorStyleSheet(pageAgent, id, nullptr, origin, "", listener)
     1498    : InspectorStyleSheet(pageAgent, id, nullptr, origin, String(), listener)
    14681499    , m_element(WTF::move(element))
    14691500    , m_ruleSourceData(nullptr)
  • trunk/Source/WebCore/inspector/InspectorStyleSheet.h

    r178105 r178767  
    5151class InspectorPageAgent;
    5252class InspectorStyleSheet;
    53 class Node;
    5453
    5554#if ENABLE(INSPECTOR)
     
    195194    RefPtr<Inspector::Protocol::CSS::CSSStyleSheetBody> buildObjectForStyleSheet();
    196195    RefPtr<Inspector::Protocol::CSS::CSSStyleSheetHeader> buildObjectForStyleSheetInfo();
    197     RefPtr<Inspector::Protocol::CSS::CSSRule> buildObjectForRule(CSSStyleRule*);
     196    RefPtr<Inspector::Protocol::CSS::CSSRule> buildObjectForRule(CSSStyleRule*, Element*);
    198197    RefPtr<Inspector::Protocol::CSS::CSSStyle> buildObjectForStyle(CSSStyleDeclaration*);
    199198    bool setStyleText(const InspectorCSSId&, const String& text, String* oldText, ExceptionCode&);
     
    240239    bool inlineStyleSheetText(String* result) const;
    241240    Ref<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSRule>> buildArrayForRuleList(CSSRuleList*);
    242     Ref<Inspector::Protocol::CSS::CSSSelector> buildObjectForSelector(const CSSSelector*);
    243     Ref<Inspector::Protocol::CSS::SelectorList> buildObjectForSelectorList(CSSStyleRule*);
     241    Ref<Inspector::Protocol::CSS::CSSSelector> buildObjectForSelector(const CSSSelector*, Element*);
     242    Ref<Inspector::Protocol::CSS::SelectorList> buildObjectForSelectorList(CSSStyleRule*, Element*);
    244243
    245244    InspectorPageAgent* m_pageAgent;
  • trunk/Source/WebInspectorUI/ChangeLog

    r178695 r178767  
     12015-01-20  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Should show dynamic specificity values
     4        https://bugs.webkit.org/show_bug.cgi?id=140647
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        For dynamic selectors, provide text in the tooltip describing that the
     9        specificity is dynamic and may change, and pointing out the element
     10        the current value was calculated against.
     11
     12        * Localizations/en.lproj/localizedStrings.js:
     13        * UserInterface/Models/CSSSelector.js:
     14        (WebInspector.CSSSelector):
     15        (WebInspector.CSSSelector.prototype.get specificity):
     16        (WebInspector.CSSSelector.prototype.get dynamic):
     17        * UserInterface/Models/DOMNodeStyles.js:
     18        (WebInspector.DOMNodeStyles.prototype._parseSelectorListPayload.return):
     19        (WebInspector.DOMNodeStyles.prototype._parseSelectorListPayload):
     20        * UserInterface/Views/CSSStyleDeclarationSection.js:
     21        (WebInspector.CSSStyleDeclarationSection.prototype.refresh.appendSelector):
     22
    1232015-01-19  Saam Barati  <saambarati1@gmail.com>
    224
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r178137 r178767  
    149149localizedStrings["Download Web Archive"] = "Download Web Archive";
    150150localizedStrings["Duration"] = "Duration";
     151localizedStrings["Dynamically calculated for the parent element"] = "Dynamically calculated for the parent element";
     152localizedStrings["Dynamically calculated for the selected element"] = "Dynamically calculated for the selected element";
     153localizedStrings["Dynamically calculated for the selected element and did not match"] = "Dynamically calculated for the selected element and did not match";
    151154localizedStrings["Edit Attribute"] = "Edit Attribute";
    152155localizedStrings["Edit Breakpoint…"] = "Edit Breakpoint…";
     
    412415localizedStrings["Source Code"] = "Source Code";
    413416localizedStrings["Specificity: (%d, %d, %d) ≈ %d"] = "Specificity: (%d, %d, %d) ≈ %d";
     417localizedStrings["Specificity: No value for selected element"] = "Specificity: No value for selected element";
    414418localizedStrings["Spelling"] = "Spelling";
    415419localizedStrings["Start Playback"] = "Start Playback";
  • trunk/Source/WebInspectorUI/UserInterface/Models/CSSSelector.js

    r175483 r178767  
    2424 */
    2525
    26 WebInspector.CSSSelector = function(text, specificity)
     26WebInspector.CSSSelector = function(text, specificity, dynamic)
    2727{
    2828    WebInspector.Object.call(this);
     
    3232    this._text = text;
    3333    this._specificity = specificity || null;
     34    this._dynamic = dynamic || false;
    3435};
    3536
     
    4849    {
    4950        return this._specificity;
     51    },
     52
     53    get dynamic()
     54    {
     55        return this._dynamic;
    5056    }
    5157};
  • trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js

    r178110 r178767  
    771771
    772772        return selectors.map(function(selectorPayload) {
    773             return new WebInspector.CSSSelector(selectorPayload.text, selectorPayload.specificity);
     773            return new WebInspector.CSSSelector(selectorPayload.text, selectorPayload.specificity, selectorPayload.dynamic);
    774774        });
    775775    },
  • trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.js

    r175642 r178767  
    182182            if (specificity) {
    183183                var approximatedSpecificity = (specificity[0] * 100) + (specificity[1] * 10) + specificity[2];
    184                 selectorElement.title = WebInspector.UIString("Specificity: (%d, %d, %d) ≈ %d").format(specificity[0], specificity[1], specificity[2], approximatedSpecificity);
     184                var tooltip = WebInspector.UIString("Specificity: (%d, %d, %d) ≈ %d").format(specificity[0], specificity[1], specificity[2], approximatedSpecificity);
     185                if (selector.dynamic) {
     186                    tooltip += "\n";
     187                    if (this._style.inherited)
     188                        tooltip += WebInspector.UIString("Dynamically calculated for the parent element");
     189                    else
     190                        tooltip += WebInspector.UIString("Dynamically calculated for the selected element");
     191                }
     192                selectorElement.title = tooltip;
     193            } else if (selector.dynamic) {
     194                var tooltip = WebInspector.UIString("Specificity: No value for selected element");
     195                tooltip += "\n";
     196                tooltip += WebInspector.UIString("Dynamically calculated for the selected element and did not match");
     197                selectorElement.title = tooltip;
    185198            }
    186199
Note: See TracChangeset for help on using the changeset viewer.