void CSSParserSelector::appendTagHistory(CSSSelector::Relation relation, PassOwnPtr<CSSParserSelector> selector) { CSSParserSelector* end = this; while (end->tagHistory()) end = end->tagHistory(); end->setRelation(relation); end->setTagHistory(selector); }
void CSSParserSelector::appendTagHistory(CSSSelector::Relation relation, std::unique_ptr<CSSParserSelector> selector) { CSSParserSelector* end = this; while (end->tagHistory()) end = end->tagHistory(); end->setRelation(relation); end->setTagHistory(WTF::move(selector)); }
PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeComplexSelector(CSSParserTokenRange& range) { OwnPtr<CSSParserSelector> selector = consumeCompoundSelector(range); if (!selector) return nullptr; while (CSSSelector::Relation combinator = consumeCombinator(range)) { OwnPtr<CSSParserSelector> nextSelector = consumeCompoundSelector(range); if (!nextSelector) return combinator == CSSSelector::Descendant ? selector.release() : nullptr; CSSParserSelector* end = nextSelector.get(); while (end->tagHistory()) end = end->tagHistory(); end->setRelation(combinator); if (selector->isContentPseudoElement()) end->setRelationIsAffectedByPseudoContent(); end->setTagHistory(selector.release()); selector = nextSelector.release(); } return selector.release(); }
void CSSSelectorParser::rewriteSpecifiersWithElementNameForCustomPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule) { CSSParserSelector* lastShadowPseudo = specifiers; CSSParserSelector* history = specifiers; while (history->tagHistory()) { history = history->tagHistory(); if (history->crossesTreeScopes() || history->hasShadowPseudo()) lastShadowPseudo = history; } if (lastShadowPseudo->tagHistory()) { if (tag != anyQName()) lastShadowPseudo->tagHistory()->prependTagSelector(tag, tagIsForNamespaceRule); return; } // 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)); lastShadowPseudo->setTagHistory(elementNameSelector.release()); lastShadowPseudo->setRelation(CSSSelector::ShadowPseudo); }
std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumeComplexSelector( CSSParserTokenRange& range) { std::unique_ptr<CSSParserSelector> selector = consumeCompoundSelector(range); if (!selector) return nullptr; unsigned previousCompoundFlags = 0; for (CSSParserSelector* simple = selector.get(); simple && !previousCompoundFlags; simple = simple->tagHistory()) previousCompoundFlags |= extractCompoundFlags(*simple, m_context.mode()); while (CSSSelector::RelationType combinator = consumeCombinator(range)) { std::unique_ptr<CSSParserSelector> nextSelector = consumeCompoundSelector(range); if (!nextSelector) return combinator == CSSSelector::Descendant ? std::move(selector) : nullptr; if (previousCompoundFlags & HasPseudoElementForRightmostCompound) return nullptr; CSSParserSelector* end = nextSelector.get(); unsigned compoundFlags = extractCompoundFlags(*end, m_context.mode()); while (end->tagHistory()) { end = end->tagHistory(); compoundFlags |= extractCompoundFlags(*end, m_context.mode()); } end->setRelation(combinator); if (previousCompoundFlags & HasContentPseudoElement) end->setRelationIsAffectedByPseudoContent(); previousCompoundFlags = compoundFlags; end->setTagHistory(std::move(selector)); selector = std::move(nextSelector); } return selector; }