ALWAYS_INLINE void SelectorDataList::executeSingleTagNameSelectorData(const Node* rootNode, const SelectorData& selectorData, typename SelectorQueryTrait::OutputType& output) const { ASSERT(m_selectors.size() == 1); ASSERT(isSingleTagNameSelector(selectorData.selector)); const QualifiedName& tagQualifiedName = selectorData.selector->tagQName(); const AtomicString& selectorLocalName = tagQualifiedName.localName(); const AtomicString& selectorNamespaceURI = tagQualifiedName.namespaceURI(); if (selectorNamespaceURI == starAtom) { if (selectorLocalName != starAtom) { // Common case: name defined, selectorNamespaceURI is a wildcard. elementsForLocalName<SelectorQueryTrait>(rootNode, selectorLocalName, output); } else { // Other fairly common case: both are wildcards. anyElement<SelectorQueryTrait>(rootNode, output); } } else { // Fallback: NamespaceURI is set, selectorLocalName may be starAtom. for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) { if (element->namespaceURI() == selectorNamespaceURI && (selectorLocalName == starAtom || element->tagQName().localName() == selectorLocalName)) { SelectorQueryTrait::appendOutputForElement(output, element); if (SelectorQueryTrait::shouldOnlyMatchFirstElement) return; } } } }
ALWAYS_INLINE void SelectorDataList::executeSingleTagNameSelectorData(const ContainerNode& rootNode, const SelectorData& selectorData, typename SelectorQueryTrait::OutputType& output) const { ASSERT(m_selectors.size() == 1); ASSERT(isSingleTagNameSelector(*selectorData.selector)); const QualifiedName& tagQualifiedName = selectorData.selector->tagQName(); const AtomicString& selectorLocalName = tagQualifiedName.localName(); const AtomicString& selectorLowercaseLocalName = selectorData.selector->tagLowercaseLocalName(); const AtomicString& selectorNamespaceURI = tagQualifiedName.namespaceURI(); if (selectorNamespaceURI == starAtom) { if (selectorLocalName != starAtom) { // Common case: name defined, selectorNamespaceURI is a wildcard. elementsForLocalName<SelectorQueryTrait>(rootNode, selectorLocalName, selectorLowercaseLocalName, output); } else { // Other fairly common case: both are wildcards. anyElement<SelectorQueryTrait>(rootNode, output); } } else { // Fallback: NamespaceURI is set, selectorLocalName may be starAtom. for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) { if (element.namespaceURI() == selectorNamespaceURI && localNameMatches(element, selectorLocalName, selectorLowercaseLocalName)) { SelectorQueryTrait::appendOutputForElement(output, &element); if (SelectorQueryTrait::shouldOnlyMatchFirstElement) return; } } } }
ALWAYS_INLINE void SelectorDataList::executeSingleTagNameSelectorData(const Node* rootNode, const SelectorData& selectorData, Vector<RefPtr<Node> >& matchedElements) const { ASSERT(m_selectors.size() == 1); ASSERT(isSingleTagNameSelector(selectorData.selector)); const QualifiedName& tagQualifiedName = selectorData.selector->tagQName(); const AtomicString& selectorLocalName = tagQualifiedName.localName(); const AtomicString& selectorNamespaceURI = tagQualifiedName.namespaceURI(); if (selectorNamespaceURI == starAtom) { if (selectorLocalName != starAtom) { // Common case: name defined, selectorNamespaceURI is a wildcard. elementsForLocalName<firstMatchOnly>(rootNode, selectorLocalName, matchedElements); } else { // Other fairly common case: both are wildcards. anyElement<firstMatchOnly>(rootNode, matchedElements); } } else { // Fallback: NamespaceURI is set, selectorLocalName may be starAtom. for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) { if (element->namespaceURI() == selectorNamespaceURI && (selectorLocalName == starAtom || element->localName() == selectorLocalName)) { matchedElements.append(element); if (firstMatchOnly) break; } } } #if !ASSERT_DISABLED for (size_t i = 0; i < matchedElements.size(); ++i) { ASSERT(matchedElements[i]->isElementNode()); ASSERT(SelectorChecker::tagMatches(static_cast<const Element*>(matchedElements[i].get()), tagQualifiedName)); } #endif }
ALWAYS_INLINE void SelectorDataList::execute(Node* rootNode, typename SelectorQueryTrait::OutputType& output) const { if (m_selectors.size() == 1) { const SelectorData& selectorData = m_selectors[0]; if (const CSSSelector* idSelector = selectorForIdLookup(rootNode, selectorData.selector)) executeFastPathForIdSelector<SelectorQueryTrait>(rootNode, selectorData, idSelector, output); else if (isSingleTagNameSelector(selectorData.selector)) executeSingleTagNameSelectorData<SelectorQueryTrait>(rootNode, selectorData, output); else if (isSingleClassNameSelector(selectorData.selector)) executeSingleClassNameSelectorData<SelectorQueryTrait>(rootNode, selectorData, output); else executeSingleSelectorData<SelectorQueryTrait>(rootNode, selectorData, output); return; } executeSingleMultiSelectorData<SelectorQueryTrait>(rootNode, output); }
ALWAYS_INLINE void SelectorDataList::execute(Node* rootNode, Vector<RefPtr<Node> >& matchedElements) const { if (m_selectors.size() == 1) { const SelectorData& selectorData = m_selectors[0]; if (const CSSSelector* idSelector = selectorForIdLookup(rootNode, selectorData.selector)) executeFastPathForIdSelector<firstMatchOnly>(rootNode, selectorData, idSelector, matchedElements); else if (isSingleTagNameSelector(selectorData.selector)) executeSingleTagNameSelectorData<firstMatchOnly>(rootNode, selectorData, matchedElements); else if (isSingleClassNameSelector(selectorData.selector)) executeSingleClassNameSelectorData<firstMatchOnly>(rootNode, selectorData, matchedElements); else executeSingleSelectorData<firstMatchOnly>(rootNode, selectorData, matchedElements); return; } executeSingleMultiSelectorData<firstMatchOnly>(rootNode, matchedElements); }