Esempio n. 1
0
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));
}
Esempio n. 3
0
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();
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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;
}