Title: [176436] trunk/Source/WebCore
Revision
176436
Author
[email protected]
Date
2014-11-20 20:31:06 -0800 (Thu, 20 Nov 2014)

Log Message

Web Inspector: do not show invalid specificity for dynamic cases of :matches()
https://bugs.webkit.org/show_bug.cgi?id=138911

Reviewed by Joseph Pecoraro.

* css/CSSSelector.cpp:
(WebCore::simpleSelectorFunctionalPseudoClassStaticSpecificity):
(WebCore::functionalPseudoClassStaticSpecificity):
(WebCore::staticSpecificityInternal):
(WebCore::CSSSelector::staticSpecificity):
(WebCore::CSSSelector::specificity): Deleted.
* css/CSSSelector.h:
Add an additional computation path for the inspector.

The regular path ignores everything inside function pseudo classes.
This new path takes the static specificity of the regular path, then evaluate
recursively all the selector lists inside any level of :matches().

If two complex selector of selector list do not have the same specificity,
we bail out and refuse to compute a static specificity representing the selector.

* inspector/InspectorStyleSheet.cpp:
(WebCore::buildObjectForSelectorHelper):
(WebCore::selectorsFromSource):
(WebCore::InspectorStyleSheet::buildObjectForSelector):
Do not add the complexity to the inspector's CSSSelector structure whenever
it is dynamic.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (176435 => 176436)


--- trunk/Source/WebCore/ChangeLog	2014-11-21 04:30:38 UTC (rev 176435)
+++ trunk/Source/WebCore/ChangeLog	2014-11-21 04:31:06 UTC (rev 176436)
@@ -1,3 +1,33 @@
+2014-11-20  Benjamin Poulain  <[email protected]>
+
+        Web Inspector: do not show invalid specificity for dynamic cases of :matches()
+        https://bugs.webkit.org/show_bug.cgi?id=138911
+
+        Reviewed by Joseph Pecoraro.
+
+        * css/CSSSelector.cpp:
+        (WebCore::simpleSelectorFunctionalPseudoClassStaticSpecificity):
+        (WebCore::functionalPseudoClassStaticSpecificity):
+        (WebCore::staticSpecificityInternal):
+        (WebCore::CSSSelector::staticSpecificity):
+        (WebCore::CSSSelector::specificity): Deleted.
+        * css/CSSSelector.h:
+        Add an additional computation path for the inspector.
+
+        The regular path ignores everything inside function pseudo classes.
+        This new path takes the static specificity of the regular path, then evaluate
+        recursively all the selector lists inside any level of :matches().
+
+        If two complex selector of selector list do not have the same specificity,
+        we bail out and refuse to compute a static specificity representing the selector.
+
+        * inspector/InspectorStyleSheet.cpp:
+        (WebCore::buildObjectForSelectorHelper):
+        (WebCore::selectorsFromSource):
+        (WebCore::InspectorStyleSheet::buildObjectForSelector):
+        Do not add the complexity to the inspector's CSSSelector structure whenever
+        it is dynamic.
+
 2014-11-20  Benjamin Poulain  <[email protected]>
 
         Remove InspectorCSSAgent::buildArrayForRuleList()

Modified: trunk/Source/WebCore/css/CSSSelector.cpp (176435 => 176436)


--- trunk/Source/WebCore/css/CSSSelector.cpp	2014-11-21 04:30:38 UTC (rev 176435)
+++ trunk/Source/WebCore/css/CSSSelector.cpp	2014-11-21 04:31:06 UTC (rev 176436)
@@ -78,14 +78,6 @@
     return maxSpecificity;
 }
 
-unsigned CSSSelector::specificity() const
-{
-    if (isForPage())
-        return specificityForPage() & maxValueMask;
-
-    return selectorSpecificity(*this, false);
-}
-
 static unsigned simpleSelectorSpecificityInternal(const CSSSelector& simpleSelector, bool isComputingMaximumSpecificity)
 {
     ASSERT_WITH_MESSAGE(!simpleSelector.isForPage(), "At the time of this writing, page selectors are not treated as real selectors that are matched. The value computed here only account for real selectors.");
@@ -140,6 +132,58 @@
     return simpleSelectorSpecificityInternal(*this, false);
 }
 
+static unsigned staticSpecificityInternal(const CSSSelector& firstSimpleSelector, bool& ok);
+
+static unsigned simpleSelectorFunctionalPseudoClassStaticSpecificity(const CSSSelector& simpleSelector, bool& ok)
+{
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+    if (simpleSelector.match() == CSSSelector::PseudoClass) {
+        if (simpleSelector.pseudoClassType() == CSSSelector::PseudoClassMatches) {
+            const CSSSelectorList& selectorList = *simpleSelector.selectorList();
+            const CSSSelector& firstSubselector = *selectorList.first();
+
+            unsigned initialSpecificity = staticSpecificityInternal(firstSubselector, ok);
+            if (!ok)
+                return 0;
+
+            const CSSSelector* subselector = &firstSubselector;
+            while ((subselector = CSSSelectorList::next(subselector))) {
+                unsigned subSelectorSpecificity = staticSpecificityInternal(*subselector, ok);
+                if (initialSpecificity != subSelectorSpecificity)
+                    ok = false;
+                if (!ok)
+                    return 0;
+            }
+            return initialSpecificity;
+        }
+    }
+#endif
+    return 0;
+}
+
+static unsigned functionalPseudoClassStaticSpecificity(const CSSSelector& firstSimpleSelector, bool& ok)
+{
+    unsigned total = 0;
+    for (const CSSSelector* selector = &firstSimpleSelector; selector; selector = selector->tagHistory()) {
+        total = CSSSelector::addSpecificities(total, simpleSelectorFunctionalPseudoClassStaticSpecificity(*selector, ok));
+        if (!ok)
+            return 0;
+    }
+    return total;
+}
+
+static unsigned staticSpecificityInternal(const CSSSelector& firstSimpleSelector, bool& ok)
+{
+    unsigned staticSpecificity = selectorSpecificity(firstSimpleSelector, false);
+    return CSSSelector::addSpecificities(staticSpecificity, functionalPseudoClassStaticSpecificity(firstSimpleSelector, ok));
+}
+
+unsigned CSSSelector::staticSpecificity(bool &ok) const
+{
+    ok = true;
+    return staticSpecificityInternal(*this, ok);
+}
+
 unsigned CSSSelector::addSpecificities(unsigned a, unsigned b)
 {
     unsigned total = a;

Modified: trunk/Source/WebCore/css/CSSSelector.h (176435 => 176436)


--- trunk/Source/WebCore/css/CSSSelector.h	2014-11-21 04:30:38 UTC (rev 176435)
+++ trunk/Source/WebCore/css/CSSSelector.h	2014-11-21 04:31:06 UTC (rev 176436)
@@ -58,7 +58,7 @@
         static const unsigned classMask = 0xff00;
         static const unsigned elementMask = 0xff;
 
-        unsigned specificity() const;
+        unsigned staticSpecificity(bool& ok) const;
         unsigned specificityForPage() const;
         unsigned simpleSelectorSpecificity() const;
         static unsigned addSpecificities(unsigned, unsigned);

Modified: trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp (176435 => 176436)


--- trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp	2014-11-21 04:30:38 UTC (rev 176435)
+++ trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp	2014-11-21 04:31:06 UTC (rev 176436)
@@ -991,18 +991,23 @@
         .release();
 }
 
-static PassRefPtr<Inspector::Protocol::CSS::CSSSelector> buildObjectForSelectorHelper(const String& selectorText, unsigned specificity)
+static PassRefPtr<Inspector::Protocol::CSS::CSSSelector> buildObjectForSelectorHelper(const String& selectorText, const CSSSelector& selector)
 {
-    RefPtr<Inspector::Protocol::CSS::CSSSelector> selector = Inspector::Protocol::CSS::CSSSelector::create()
+    RefPtr<Inspector::Protocol::CSS::CSSSelector> inspectorSelector = Inspector::Protocol::CSS::CSSSelector::create()
         .setText(selectorText);
 
-    RefPtr<Inspector::Protocol::Array<int>> tuple = Inspector::Protocol::Array<int>::create();
-    tuple->addItem(static_cast<int>((specificity & CSSSelector::idMask) >> 16));
-    tuple->addItem(static_cast<int>((specificity & CSSSelector::classMask) >> 8));
-    tuple->addItem(static_cast<int>(specificity & CSSSelector::elementMask));
-    selector->setSpecificity(tuple.release());
+    bool ok;
+    unsigned specificity = selector.staticSpecificity(ok);
 
-    return selector.release();
+    if (ok) {
+        RefPtr<Inspector::Protocol::Array<int>> tuple = Inspector::Protocol::Array<int>::create();
+        tuple->addItem(static_cast<int>((specificity & CSSSelector::idMask) >> 16));
+        tuple->addItem(static_cast<int>((specificity & CSSSelector::classMask) >> 8));
+        tuple->addItem(static_cast<int>(specificity & CSSSelector::elementMask));
+        inspectorSelector->setSpecificity(tuple.release());
+    }
+
+    return inspectorSelector.release();
 }
 
 static PassRefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSSelector>> selectorsFromSource(const CSSRuleSourceData* sourceData, const String& sheetText, const CSSSelectorList& selectorList)
@@ -1018,7 +1023,7 @@
 
         // We don't want to see any comments in the selector components, only the meaningful parts.
         replace(selectorText, comment, String());
-        result->addItem(buildObjectForSelectorHelper(selectorText.stripWhiteSpace(), selector->specificity()));
+        result->addItem(buildObjectForSelectorHelper(selectorText.stripWhiteSpace(), *selector));
 
         selector = CSSSelectorList::next(selector);
     }
@@ -1027,7 +1032,7 @@
 
 PassRefPtr<Inspector::Protocol::CSS::CSSSelector> InspectorStyleSheet::buildObjectForSelector(const CSSSelector* selector)
 {
-    return buildObjectForSelectorHelper(selector->selectorText(), selector->specificity());
+    return buildObjectForSelectorHelper(selector->selectorText(), *selector);
 }
 
 PassRefPtr<Inspector::Protocol::CSS::SelectorList> InspectorStyleSheet::buildObjectForSelectorList(CSSStyleRule* rule)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to