Index: Source/core/css/CSSParser-in.cpp |
diff --git a/Source/core/css/CSSParser-in.cpp b/Source/core/css/CSSParser-in.cpp |
index 75759b6d8ec1898f7d17c16a941f435eafcf04c8..a5bce83e5d0b3cefdcd7c2d07cc374a9c00f3c79 100644 |
--- a/Source/core/css/CSSParser-in.cpp |
+++ b/Source/core/css/CSSParser-in.cpp |
@@ -11209,14 +11209,21 @@ CSSParserSelector* CSSParser::rewriteSpecifiersWithElementName(const AtomicStrin |
return rewriteSpecifiersForShadowDistributed(specifiers, distributedPseudoElementSelector); |
} |
- if (!specifiers->isCustomPseudoElement()) { |
- if (tag == anyQName()) |
- return specifiers; |
- if (!(specifiers->pseudoType() == CSSSelector::PseudoCue)) |
- specifiers->prependTagSelector(tag, tagIsForNamespaceRule); |
+ if (specifiers->isCustomPseudoElement()) |
+ return rewriteSpecifiersWithElementNameForCustomPseudoElement(tag, elementName, specifiers, tagIsForNamespaceRule); |
+ |
+ if (specifiers->isContentPseudoElement()) |
+ return rewriteSpecifiersWithElementNameForContentPseudoElement(tag, elementName, specifiers, tagIsForNamespaceRule); |
+ |
+ if (tag == anyQName()) |
return specifiers; |
- } |
+ if (!(specifiers->pseudoType() == CSSSelector::PseudoCue)) |
+ specifiers->prependTagSelector(tag, tagIsForNamespaceRule); |
+ return specifiers; |
+} |
+CSSParserSelector* CSSParser::rewriteSpecifiersWithElementNameForCustomPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule) |
+{ |
CSSParserSelector* lastShadowPseudo = specifiers; |
CSSParserSelector* history = specifiers; |
while (history->tagHistory()) { |
@@ -11239,6 +11246,30 @@ CSSParserSelector* CSSParser::rewriteSpecifiersWithElementName(const AtomicStrin |
return specifiers; |
} |
+CSSParserSelector* CSSParser::rewriteSpecifiersWithElementNameForContentPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule) |
+{ |
+ CSSParserSelector* last = specifiers; |
+ CSSParserSelector* history = specifiers; |
+ while (history->tagHistory()) { |
+ history = history->tagHistory(); |
+ if (history->isContentPseudoElement() || history->relationIsForShadowDistributed()) |
+ last = history; |
+ } |
+ |
+ if (last->tagHistory()) { |
+ if (tag != anyQName()) |
+ last->tagHistory()->prependTagSelector(tag, tagIsForNamespaceRule); |
+ return specifiers; |
+ } |
+ |
+ // For shadow-ID pseudo-elements to be correctly matched, the ShadowPseudo combinator has to be used. |
+ // We therefore create a new Selector with that combinator here in any case, even if matching any (host) element in any namespace (i.e. '*'). |
+ OwnPtr<CSSParserSelector> elementNameSelector = adoptPtr(new CSSParserSelector(tag)); |
+ last->setTagHistory(elementNameSelector.release()); |
+ last->setRelation(CSSSelector::SubSelector); |
+ return specifiers; |
+} |
+ |
CSSParserSelector* CSSParser::rewriteSpecifiersForShadowDistributed(CSSParserSelector* specifiers, CSSParserSelector* distributedPseudoElementSelector) |
{ |
CSSParserSelector* argumentSelector = distributedPseudoElementSelector->functionArgumentSelector(); |
@@ -11272,11 +11303,19 @@ CSSParserSelector* CSSParser::rewriteSpecifiers(CSSParserSelector* specifiers, C |
newSpecifier->appendTagHistory(CSSSelector::ShadowPseudo, sinkFloatingSelector(specifiers)); |
return newSpecifier; |
} |
+ if (newSpecifier->isContentPseudoElement()) { |
+ newSpecifier->appendTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(specifiers)); |
+ return newSpecifier; |
+ } |
if (specifiers->isCustomPseudoElement()) { |
// Specifiers for unknown pseudo element go right behind it in the chain. |
specifiers->insertTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier), CSSSelector::ShadowPseudo); |
return specifiers; |
} |
+ if (specifiers->isContentPseudoElement()) { |
+ specifiers->insertTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier), CSSSelector::SubSelector); |
+ return specifiers; |
+ } |
specifiers->appendTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier)); |
return specifiers; |
} |