- 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)