Example #1
0
PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeCompoundSelector(CSSParserTokenRange& range)
{
    OwnPtr<CSSParserSelector> selector;

    AtomicString namespacePrefix;
    AtomicString elementName;
    bool hasNamespace;
    if (!consumeName(range, elementName, namespacePrefix, hasNamespace)) {
        selector = consumeSimpleSelector(range);
        if (!selector)
            return nullptr;
    }
    if (m_context.isHTMLDocument())
        elementName = elementName.lower();

    while (OwnPtr<CSSParserSelector> nextSelector = consumeSimpleSelector(range)) {
        if (selector)
            selector = rewriteSpecifiers(selector.release(), nextSelector.release());
        else
            selector = nextSelector.release();
    }

    if (!selector) {
        if (hasNamespace)
            return CSSParserSelector::create(determineNameInNamespace(namespacePrefix, elementName));
        return CSSParserSelector::create(QualifiedName(nullAtom, elementName, m_defaultNamespace));
    }
    if (elementName.isNull())
        rewriteSpecifiersWithNamespaceIfNeeded(selector.get());
    else
        rewriteSpecifiersWithElementName(namespacePrefix, elementName, selector.get());
    return selector.release();
}
Example #2
0
std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumeCompoundSelector(
    CSSParserTokenRange& range) {
  std::unique_ptr<CSSParserSelector> compoundSelector;

  AtomicString namespacePrefix;
  AtomicString elementName;
  CSSSelector::PseudoType compoundPseudoElement = CSSSelector::PseudoUnknown;
  if (!consumeName(range, elementName, namespacePrefix)) {
    compoundSelector = consumeSimpleSelector(range);
    if (!compoundSelector)
      return nullptr;
    if (compoundSelector->match() == CSSSelector::PseudoElement)
      compoundPseudoElement = compoundSelector->pseudoType();
  }
  if (m_context.isHTMLDocument())
    elementName = elementName.lower();

  while (std::unique_ptr<CSSParserSelector> simpleSelector =
             consumeSimpleSelector(range)) {
    // TODO([email protected]): crbug.com/578131
    // The UASheetMode check is a work-around to allow this selector in
    // mediaControls(New).css:
    // video::-webkit-media-text-track-region-container.scrolling
    if (m_context.mode() != UASheetMode &&
        !isSimpleSelectorValidAfterPseudoElement(*simpleSelector.get(),
                                                 compoundPseudoElement)) {
      m_failedParsing = true;
      return nullptr;
    }
    if (simpleSelector->match() == CSSSelector::PseudoElement)
      compoundPseudoElement = simpleSelector->pseudoType();

    if (compoundSelector)
      compoundSelector = addSimpleSelectorToCompound(
          std::move(compoundSelector), std::move(simpleSelector));
    else
      compoundSelector = std::move(simpleSelector);
  }

  if (!compoundSelector) {
    AtomicString namespaceURI = determineNamespace(namespacePrefix);
    if (namespaceURI.isNull()) {
      m_failedParsing = true;
      return nullptr;
    }
    if (namespaceURI == defaultNamespace())
      namespacePrefix = nullAtom;
    return CSSParserSelector::create(
        QualifiedName(namespacePrefix, elementName, namespaceURI));
  }
  prependTypeSelectorIfNeeded(namespacePrefix, elementName,
                              compoundSelector.get());
  return splitCompoundAtImplicitShadowCrossingCombinator(
      std::move(compoundSelector));
}