- Revision
- 208267
- Author
- [email protected]
- Date
- 2016-11-01 17:59:52 -0700 (Tue, 01 Nov 2016)
Log Message
[CSS Parser] Support the shadow DOM
https://bugs.webkit.org/show_bug.cgi?id=164240
Reviewed by Dean Jackson.
* css/CSSSelector.cpp:
(WebCore::CSSSelector::selectorText):
Remove ShadowDeep, ShadowSlot and ShadowPseudo in favor of our
ShadowDescendant combinator.
* css/CSSSelector.h:
* css/SelectorChecker.cpp:
(WebCore::SelectorChecker::matchRecursively):
Remove ShadowDeep, ShadowSlot and ShadowPseudo in favor of our
ShadowDescendant combinator.
* css/SelectorFilter.cpp:
(WebCore::SelectorFilter::collectIdentifierHashes):
Remove ShadowDeep, ShadowSlot and ShadowPseudo in favor of our
ShadowDescendant combinator.
* css/SelectorPseudoElementTypeMap.in:
Add support for slotted.
* css/parser/CSSParserValues.cpp:
(WebCore::CSSParserSelector::appendTagHistory):
* css/parser/CSSParserValues.h:
(WebCore::CSSParserSelector::needsImplicitShadowCombinatorForMatching):
Remove ShadowDeep, ShadowSlot and ShadowPseudo in favor of our
ShadowDescendant combinator. Take :slotted out of
needsImplicitShadowCombinatorForMatching(), since our code doesn't do
this for :slotted.
* css/parser/CSSSelectorParser.cpp:
(WebCore::isPseudoClassFunction):
:host can be both an id and a function, so don't restrict it.
(WebCore::CSSSelectorParser::consumePseudo):
Put in a hack for :host (inside the hack we already plan on removing
once we turn on).
(WebCore::CSSSelectorParser::consumeCombinator):
Remove deep shadow combinator support, as we don't support matching
on it.
(WebCore::CSSSelectorParser::prependTypeSelectorIfNeeded):
(WebCore::CSSSelectorParser::splitCompoundAtImplicitShadowCrossingCombinator):
Make the split use our combinator, ShadowDescendant, and no longer do anything
special with :slotted.
* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::fragmentRelationForSelectorRelation):
Remove ShadowDeep, ShadowSlot and ShadowPseudo in favor of our
ShadowDescendant combinator.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (208266 => 208267)
--- trunk/Source/WebCore/ChangeLog 2016-11-02 00:52:41 UTC (rev 208266)
+++ trunk/Source/WebCore/ChangeLog 2016-11-02 00:59:52 UTC (rev 208267)
@@ -1,3 +1,60 @@
+2016-11-01 Dave Hyatt <[email protected]>
+
+ [CSS Parser] Support the shadow DOM
+ https://bugs.webkit.org/show_bug.cgi?id=164240
+
+ Reviewed by Dean Jackson.
+
+ * css/CSSSelector.cpp:
+ (WebCore::CSSSelector::selectorText):
+ Remove ShadowDeep, ShadowSlot and ShadowPseudo in favor of our
+ ShadowDescendant combinator.
+
+ * css/CSSSelector.h:
+ * css/SelectorChecker.cpp:
+ (WebCore::SelectorChecker::matchRecursively):
+ Remove ShadowDeep, ShadowSlot and ShadowPseudo in favor of our
+ ShadowDescendant combinator.
+
+ * css/SelectorFilter.cpp:
+ (WebCore::SelectorFilter::collectIdentifierHashes):
+ Remove ShadowDeep, ShadowSlot and ShadowPseudo in favor of our
+ ShadowDescendant combinator.
+
+ * css/SelectorPseudoElementTypeMap.in:
+ Add support for slotted.
+
+ * css/parser/CSSParserValues.cpp:
+ (WebCore::CSSParserSelector::appendTagHistory):
+ * css/parser/CSSParserValues.h:
+ (WebCore::CSSParserSelector::needsImplicitShadowCombinatorForMatching):
+ Remove ShadowDeep, ShadowSlot and ShadowPseudo in favor of our
+ ShadowDescendant combinator. Take :slotted out of
+ needsImplicitShadowCombinatorForMatching(), since our code doesn't do
+ this for :slotted.
+
+ * css/parser/CSSSelectorParser.cpp:
+ (WebCore::isPseudoClassFunction):
+ :host can be both an id and a function, so don't restrict it.
+
+ (WebCore::CSSSelectorParser::consumePseudo):
+ Put in a hack for :host (inside the hack we already plan on removing
+ once we turn on).
+
+ (WebCore::CSSSelectorParser::consumeCombinator):
+ Remove deep shadow combinator support, as we don't support matching
+ on it.
+
+ (WebCore::CSSSelectorParser::prependTypeSelectorIfNeeded):
+ (WebCore::CSSSelectorParser::splitCompoundAtImplicitShadowCrossingCombinator):
+ Make the split use our combinator, ShadowDescendant, and no longer do anything
+ special with :slotted.
+
+ * cssjit/SelectorCompiler.cpp:
+ (WebCore::SelectorCompiler::fragmentRelationForSelectorRelation):
+ Remove ShadowDeep, ShadowSlot and ShadowPseudo in favor of our
+ ShadowDescendant combinator.
+
2016-11-01 Wenson Hsieh <[email protected]>
Turn the Input Events runtime flag on by default
Modified: trunk/Source/WebCore/css/CSSSelector.cpp (208266 => 208267)
--- trunk/Source/WebCore/css/CSSSelector.cpp 2016-11-02 00:52:41 UTC (rev 208266)
+++ trunk/Source/WebCore/css/CSSSelector.cpp 2016-11-02 00:59:52 UTC (rev 208267)
@@ -727,8 +727,6 @@
return tagHistory->selectorText(" " + str.toString() + rightSide);
case CSSSelector::Child:
return tagHistory->selectorText(" > " + str.toString() + rightSide);
- case CSSSelector::ShadowDeep:
- return tagHistory->selectorText(" /deep/ " + str.toString() + rightSide);
case CSSSelector::DirectAdjacent:
return tagHistory->selectorText(" + " + str.toString() + rightSide);
case CSSSelector::IndirectAdjacent:
@@ -743,8 +741,6 @@
FALLTHROUGH;
#endif
case CSSSelector::ShadowDescendant:
- case CSSSelector::ShadowPseudo:
- case CSSSelector::ShadowSlot:
return tagHistory->selectorText(str.toString() + rightSide);
}
}
Modified: trunk/Source/WebCore/css/CSSSelector.h (208266 => 208267)
--- trunk/Source/WebCore/css/CSSSelector.h 2016-11-02 00:52:41 UTC (rev 208266)
+++ trunk/Source/WebCore/css/CSSSelector.h 2016-11-02 00:59:52 UTC (rev 208267)
@@ -90,10 +90,7 @@
#if ENABLE(CSS_SELECTORS_LEVEL4)
DescendantDoubleChild,
#endif
- ShadowDescendant, // FIXME-NEWPARSER: Remove this in favor of the new shadow values below.
- ShadowPseudo, // Special case of shadow DOM pseudo elements / shadow pseudo element
- ShadowDeep, // /deep/ combinator
- ShadowSlot // slotted to <slot> e
+ ShadowDescendant
};
enum PseudoClassType {
Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (208266 => 208267)
--- trunk/Source/WebCore/css/SelectorChecker.cpp 2016-11-02 00:52:41 UTC (rev 208266)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp 2016-11-02 00:59:52 UTC (rev 208267)
@@ -448,13 +448,6 @@
return MatchResult::updateWithMatchType(result, matchType);
}
-
- case CSSSelector::ShadowPseudo:
- case CSSSelector::ShadowDeep:
- case CSSSelector::ShadowSlot:
- // FIXME-NEWPARSER: Have to implement these.
- // ASSERT_NOT_REACHED();
- return MatchResult::fails(Match::SelectorFailsCompletely);
}
Modified: trunk/Source/WebCore/css/SelectorFilter.cpp (208266 => 208267)
--- trunk/Source/WebCore/css/SelectorFilter.cpp 2016-11-02 00:52:41 UTC (rev 208266)
+++ trunk/Source/WebCore/css/SelectorFilter.cpp 2016-11-02 00:59:52 UTC (rev 208267)
@@ -138,17 +138,11 @@
case CSSSelector::ShadowDescendant:
skipOverSubselectors = true;
break;
- case CSSSelector::ShadowSlot:
- // Disable fastRejectSelector.
- *identifierHashes = 0;
- return;
case CSSSelector::DescendantSpace:
#if ENABLE_CSS_SELECTORS_LEVEL4
case CSSSelector::DescendantDoubleChild:
#endif
case CSSSelector::Child:
- case CSSSelector::ShadowPseudo:
- case CSSSelector::ShadowDeep:
skipOverSubselectors = false;
collectDescendantSelectorIdentifierHashes(selector, hash);
break;
Modified: trunk/Source/WebCore/css/parser/CSSParserValues.cpp (208266 => 208267)
--- trunk/Source/WebCore/css/parser/CSSParserValues.cpp 2016-11-02 00:52:41 UTC (rev 208266)
+++ trunk/Source/WebCore/css/parser/CSSParserValues.cpp 2016-11-02 00:59:52 UTC (rev 208267)
@@ -242,9 +242,16 @@
AtomicString name = pseudoTypeString.toAtomicString();
CSSSelector::PseudoElementType pseudoType = CSSSelector::parsePseudoElementType(name);
- if (pseudoType == CSSSelector::PseudoElementUnknown)
- return nullptr;
-
+ if (pseudoType == CSSSelector::PseudoElementUnknown) {
+ // FIXME-NEWPARSER: We can't add "slotted" to the map without breaking the old
+ // parser, so this hack ensures the new parser still recognizes it. When the new
+ // parser turns on, we can add "slotted" to the map and remove this code.
+ if (pseudoTypeString.startsWithIgnoringASCIICase("slotted"))
+ pseudoType = CSSSelector::PseudoElementSlotted;
+ else
+ return nullptr;
+ }
+
auto selector = std::make_unique<CSSParserSelector>();
selector->m_selector->setMatch(CSSSelector::PseudoElement);
selector->m_selector->setPseudoElementType(pseudoType);
@@ -494,15 +501,6 @@
case CSSParserSelectorCombinator::IndirectAdjacent:
selectorRelation = CSSSelector::IndirectAdjacent;
break;
- case CSSParserSelectorCombinator::ShadowDeep:
- selectorRelation = CSSSelector::ShadowDeep;
- break;
- case CSSParserSelectorCombinator::ShadowPseudo:
- selectorRelation = CSSSelector::ShadowPseudo;
- break;
- case CSSParserSelectorCombinator::ShadowSlot:
- selectorRelation = CSSSelector::ShadowSlot;
- break;
}
end->setRelation(selectorRelation);
end->setTagHistory(WTFMove(selector));
Modified: trunk/Source/WebCore/css/parser/CSSParserValues.h (208266 => 208267)
--- trunk/Source/WebCore/css/parser/CSSParserValues.h 2016-11-02 00:52:41 UTC (rev 208266)
+++ trunk/Source/WebCore/css/parser/CSSParserValues.h 2016-11-02 00:59:52 UTC (rev 208267)
@@ -194,10 +194,7 @@
DescendantDoubleChild,
#endif
DirectAdjacent,
- IndirectAdjacent,
- ShadowPseudo, // Special case of shadow DOM pseudo elements / shadow pseudo element
- ShadowDeep, // /deep/ combinator
- ShadowSlot // slotted to <slot> e
+ IndirectAdjacent
};
class CSSParserSelector {
@@ -262,8 +259,11 @@
bool isHostPseudoSelector() const;
- // FIXME-NEWPARSER: Missing "shadow"
- bool needsImplicitShadowCombinatorForMatching() const { return match() == CSSSelector::PseudoElement && (pseudoElementType() == CSSSelector::PseudoElementWebKitCustom || pseudoElementType() == CSSSelector::PseudoElementUserAgentCustom || pseudoElementType() == CSSSelector::PseudoElementWebKitCustomLegacyPrefixed || pseudoElementType() == CSSSelector::PseudoElementCue || pseudoElementType() == CSSSelector::PseudoElementSlotted); }
+ // FIXME-NEWPARSER: "slotted" was removed here for now, since it leads to a combinator
+ // connection of ShadowDescendant, and the current shadow DOM code doesn't expect this. When
+ // we do fix this issue, make sure to patch the namespace prependTag code to remove the slotted
+ // special case, since it will be covered by this function once again.
+ bool needsImplicitShadowCombinatorForMatching() const { return match() == CSSSelector::PseudoElement && (pseudoElementType() == CSSSelector::PseudoElementWebKitCustom || pseudoElementType() == CSSSelector::PseudoElementUserAgentCustom || pseudoElementType() == CSSSelector::PseudoElementWebKitCustomLegacyPrefixed || pseudoElementType() == CSSSelector::PseudoElementCue); }
CSSParserSelector* tagHistory() const { return m_tagHistory.get(); }
void setTagHistory(std::unique_ptr<CSSParserSelector> selector) { m_tagHistory = WTFMove(selector); }
Modified: trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp (208266 => 208267)
--- trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp 2016-11-02 00:52:41 UTC (rev 208266)
+++ trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp 2016-11-02 00:59:52 UTC (rev 208267)
@@ -472,7 +472,6 @@
case CSSSelector::PseudoClassNthLastOfType:
case CSSSelector::PseudoClassLang:
case CSSSelector::PseudoClassAny:
- case CSSSelector::PseudoClassHost:
#if ENABLE_CSS_SELECTORS_LEVEL4
case CSSSelector::PseudoClassDir:
case CSSSelector::PseudoClassRole:
@@ -518,9 +517,12 @@
// uses without breaking it; this hack allows function selectors to work. When the new
// parser turns on, we can patch the map and remove this code.
String newValue;
- if (token.type() == FunctionToken) {
- newValue = value.toString() + "(";
- value = newValue;
+ if (token.type() == FunctionToken && colons == 1) {
+ String tokenString = value.toString();
+ if (!tokenString.startsWithIgnoringASCIICase("host")) {
+ newValue = value.toString() + "(";
+ value = newValue;
+ }
}
if (colons == 1)
@@ -527,7 +529,7 @@
selector = std::unique_ptr<CSSParserSelector>(CSSParserSelector::parsePseudoClassSelectorFromStringView(value));
else
selector = std::unique_ptr<CSSParserSelector>(CSSParserSelector::parsePseudoElementSelectorFromStringView(value));
-
+
if (!selector || (selector->match() == CSSSelector::PseudoElement && m_disallowPseudoElements))
return nullptr;
@@ -604,7 +606,6 @@
selector->setSelectorList(WTFMove(selectorList));
return selector;
}
- // FIXME-NEWPARSER: Support :host-context
case CSSSelector::PseudoClassAny:
case CSSSelector::PseudoClassHost: {
DisallowPseudoElementsScope scope(this);
@@ -699,17 +700,7 @@
return CSSSelector::Child;
}
- // Match /deep/
- if (delimiter != '/')
- return fallbackResult;
- range.consume();
- const CSSParserToken& ident = range.consume();
- if (ident.type() != IdentToken || !equalIgnoringASCIICase(ident.value(), "deep"))
- m_failedParsing = true;
- const CSSParserToken& slash = range.consumeIncludingWhitespace();
- if (slash.type() != DelimiterToken || slash.delimiter() != '/')
- m_failedParsing = true;
- return CSSSelector::ShadowDeep;
+ return fallbackResult;
}
CSSSelector::Match CSSSelectorParser::consumeAttributeMatch(CSSParserTokenRange& range)
@@ -847,7 +838,9 @@
void CSSSelectorParser::prependTypeSelectorIfNeeded(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* compoundSelector)
{
- if (elementName.isNull() && defaultNamespace() == starAtom && !compoundSelector->needsImplicitShadowCombinatorForMatching())
+ bool isShadowDOM = compoundSelector->needsImplicitShadowCombinatorForMatching();
+
+ if (elementName.isNull() && defaultNamespace() == starAtom && !isShadowDOM)
return;
AtomicString determinedElementName = elementName.isNull() ? starAtom : elementName;
@@ -861,16 +854,16 @@
determinedPrefix = nullAtom;
QualifiedName tag = QualifiedName(determinedPrefix, determinedElementName, namespaceURI);
- // *:host/*:host-context never matches, so we can't discard the *,
+ // *:host never matches, so we can't discard the *,
// otherwise we can't tell the difference between *:host and just :host.
//
// Also, selectors where we use a ShadowPseudo combinator between the
// element and the pseudo element for matching (custom pseudo elements,
- // ::cue, ::shadow), we need a universal selector to set the combinator
+ // ::cue), we need a universal selector to set the combinator
// (relation) on in the cases where there are no simple selectors preceding
// the pseudo element.
bool explicitForHost = compoundSelector->isHostPseudoSelector() && !elementName.isNull();
- if (tag != anyQName() || explicitForHost || compoundSelector->needsImplicitShadowCombinatorForMatching())
+ if (tag != anyQName() || explicitForHost || isShadowDOM)
compoundSelector->prependTagSelector(tag, determinedPrefix == nullAtom && determinedElementName == starAtom && !explicitForHost);
}
@@ -908,7 +901,7 @@
return compoundSelector;
std::unique_ptr<CSSParserSelector> secondCompound = splitAfter->releaseTagHistory();
- secondCompound->appendTagHistory(secondCompound->pseudoElementType() == CSSSelector::PseudoElementSlotted ? CSSSelector::ShadowSlot : CSSSelector::ShadowPseudo, WTFMove(compoundSelector));
+ secondCompound->appendTagHistory(CSSSelector::ShadowDescendant, WTFMove(compoundSelector));
return secondCompound;
}
Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (208266 => 208267)
--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2016-11-02 00:52:41 UTC (rev 208266)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2016-11-02 00:59:52 UTC (rev 208267)
@@ -414,9 +414,6 @@
return FragmentRelation::IndirectAdjacent;
case CSSSelector::Subselector:
case CSSSelector::ShadowDescendant:
- case CSSSelector::ShadowPseudo:
- case CSSSelector::ShadowDeep:
- case CSSSelector::ShadowSlot:
ASSERT_NOT_REACHED();
}
ASSERT_NOT_REACHED();