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(); }
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)); }