Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(405)

Unified Diff: Source/core/css/CSSParser-in.cpp

Issue 21151005: Implement ::content (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Patch for landing Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/css/CSSParser.h ('k') | Source/core/css/CSSParserValues.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
« no previous file with comments | « Source/core/css/CSSParser.h ('k') | Source/core/css/CSSParserValues.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698