| Index: Source/core/css/CSSParser-in.cpp
|
| diff --git a/Source/core/css/CSSParser-in.cpp b/Source/core/css/CSSParser-in.cpp
|
| index b38112bb1936a811e1cdac454ea90779720f5505..e16ad3539876c8e73c9c05cc6298700b07ee0769 100644
|
| --- a/Source/core/css/CSSParser-in.cpp
|
| +++ b/Source/core/css/CSSParser-in.cpp
|
| @@ -11208,14 +11208,21 @@ CSSParserSelector* CSSParser::rewriteSpecifiersWithElementName(const AtomicStrin
|
| return rewriteSpecifiersForShadowDistributed(specifiers, distributedPseudoElementSelector);
|
| }
|
|
|
| - if (!specifiers->needsCrossingTreeScopeBoundary()) {
|
| - if (tag == anyQName())
|
| - return specifiers;
|
| - specifiers->prependTagSelector(tag, tagIsForNamespaceRule);
|
| + if (specifiers->needsCrossingTreeScopeBoundary())
|
| + 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;
|
| +}
|
|
|
| - // We should treat ::cue in the same way as custom pseudo element.
|
| +CSSParserSelector* CSSParser::rewriteSpecifiersWithElementNameForCustomPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule)
|
| +{
|
| CSSParserSelector* lastShadowPseudo = specifiers;
|
| CSSParserSelector* history = specifiers;
|
| while (history->tagHistory()) {
|
| @@ -11238,6 +11245,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->relationIsAffectedByPseudoContent())
|
| + 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();
|
| @@ -11257,7 +11288,7 @@ CSSParserSelector* CSSParser::rewriteSpecifiersForShadowDistributed(CSSParserSel
|
| case CSSSelector::Child:
|
| case CSSSelector::Descendant:
|
| end->setTagHistory(sinkFloatingSelector(specifiers));
|
| - end->setRelationIsForShadowDistributed();
|
| + end->setRelationIsAffectedByPseudoContent();
|
| return argumentSelector;
|
| default:
|
| return 0;
|
| @@ -11271,11 +11302,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->needsCrossingTreeScopeBoundary()) {
|
| // 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;
|
| }
|
|
|