ALWAYS_INLINE void SelectorDataList::executeCompiledSingleMultiSelectorData(const ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
{
    SelectorChecker::CheckingContext checkingContext(SelectorChecker::Mode::QueryingRules);
    checkingContext.scope = rootNode.isDocumentNode() ? nullptr : &rootNode;
    for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
        for (auto& selector : m_selectors) {
#if CSS_SELECTOR_JIT_PROFILING
            selector.compiledSelectorUsed();
#endif
            bool matched = false;
            void* compiledSelectorChecker = selector.compiledSelectorCodeRef.code().executableAddress();
            if (selector.compilationStatus == SelectorCompilationStatus::SimpleSelectorChecker) {
                auto selectorChecker = SelectorCompiler::querySelectorSimpleSelectorCheckerFunction(compiledSelectorChecker, selector.compilationStatus);
                matched = selectorChecker(&element);
            } else {
                ASSERT(selector.compilationStatus == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
                auto selectorChecker = SelectorCompiler::querySelectorSelectorCheckerFunctionWithCheckingContext(compiledSelectorChecker, selector.compilationStatus);
                matched = selectorChecker(&element, &checkingContext);
            }
            if (matched) {
                SelectorQueryTrait::appendOutputForElement(output, &element);
                if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
                    return;
                break;
            }
        }
    }
}
Example #2
0
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& 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 (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
            if (element.namespaceURI() == selectorNamespaceURI && (selectorLocalName == starAtom || element.tagQName().localName() == selectorLocalName)) {
                SelectorQueryTrait::appendOutputForElement(output, &element);
                if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
                    return;
            }
        }
    }
}
Example #3
0
static inline void anyElement(const ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output)
{
    for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
        SelectorQueryTrait::appendOutputForElement(output, &element);
        if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
            return;
    }
}
Example #4
0
ALWAYS_INLINE void SelectorDataList::executeCompiledSimpleSelectorChecker(const ContainerNode& rootNode, SelectorCompiler::SimpleSelectorChecker selectorChecker, typename SelectorQueryTrait::OutputType& output) const
{
    for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
        if (selectorChecker(&element)) {
            SelectorQueryTrait::appendOutputForElement(output, &element);
            if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
                return;
        }
    }
}
Example #5
0
static inline void elementsForLocalName(const ContainerNode& rootNode, const AtomicString& localName, typename SelectorQueryTrait::OutputType& output)
{
    for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
        if (element.tagQName().localName() == localName) {
            SelectorQueryTrait::appendOutputForElement(output, &element);
            if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
                return;
        }
    }
}
Example #6
0
ALWAYS_INLINE void SelectorDataList::executeSingleSelectorData(const ContainerNode& rootNode, const SelectorData& selectorData, typename SelectorQueryTrait::OutputType& output) const
{
    ASSERT(m_selectors.size() == 1);

    for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
        if (selectorMatches(selectorData, element, rootNode)) {
            SelectorQueryTrait::appendOutputForElement(output, &element);
            if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
                return;
        }
    }
}
ALWAYS_INLINE void SelectorDataList::executeSingleMultiSelectorData(const ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
{
    for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
        for (auto& selector : m_selectors) {
            if (selectorMatches(selector, element, rootNode)) {
                SelectorQueryTrait::appendOutputForElement(output, &element);
                if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
                    return;
                break;
            }
        }
    }
}
Example #8
0
Element* DocumentFragment::getElementById(const AtomicString& id) const
{
    // Fast path for ShadowRoot, where we are both a DocumentFragment and a TreeScope.
    if (isTreeScope())
        return treeScope().getElementById(id);

    // Otherwise, fall back to iterating all of the element descendants.
    for (auto& element : elementDescendants(*this)) {
        if (element.getIdAttribute() == id)
            return const_cast<Element*>(&element);
    }

    return nullptr;
}
Example #9
0
ALWAYS_INLINE void SelectorDataList::executeSingleMultiSelectorData(const ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
{
    unsigned selectorCount = m_selectors.size();
    for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
        for (unsigned i = 0; i < selectorCount; ++i) {
            if (selectorMatches(m_selectors[i], element, rootNode)) {
                SelectorQueryTrait::appendOutputForElement(output, &element);
                if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
                    return;
                break;
            }
        }
    }
}
Example #10
0
ALWAYS_INLINE void SelectorDataList::executeSingleClassNameSelectorData(const ContainerNode& rootNode, const SelectorData& selectorData, typename SelectorQueryTrait::OutputType& output) const
{
    ASSERT(m_selectors.size() == 1);
    ASSERT(isSingleClassNameSelector(*selectorData.selector));

    const AtomicString& className = selectorData.selector->value();
    for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
        if (element.hasClass() && element.classNames().contains(className)) {
            SelectorQueryTrait::appendOutputForElement(output, &element);
            if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
                return;
        }
    }
}
Example #11
0
ALWAYS_INLINE void SelectorDataList::executeCompiledSimpleSelectorChecker(const ContainerNode& searchRootNode, SelectorCompiler::QuerySelectorSimpleSelectorChecker selectorChecker, typename SelectorQueryTrait::OutputType& output, const SelectorData& selectorData) const
{
    for (auto& element : elementDescendants(const_cast<ContainerNode&>(searchRootNode))) {
#if CSS_SELECTOR_JIT_PROFILING
        selectorData.compiledSelectorUsed();
#else
        UNUSED_PARAM(selectorData);
#endif
        if (selectorChecker(&element)) {
            SelectorQueryTrait::appendOutputForElement(output, &element);
            if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
                return;
        }
    }
}
Example #12
0
ALWAYS_INLINE void SelectorDataList::executeCompiledSelectorCheckerWithCheckingContext(const ContainerNode& rootNode, const ContainerNode& searchRootNode, SelectorCompiler::QuerySelectorSelectorCheckerWithCheckingContext selectorChecker, typename SelectorQueryTrait::OutputType& output, const SelectorData& selectorData) const
{
    SelectorChecker::CheckingContext checkingContext(SelectorChecker::Mode::QueryingRules);
    checkingContext.scope = rootNode.isDocumentNode() ? nullptr : &rootNode;

    for (auto& element : elementDescendants(const_cast<ContainerNode&>(searchRootNode))) {
#if CSS_SELECTOR_JIT_PROFILING
        selectorData.compiledSelectorUsed();
#else
        UNUSED_PARAM(selectorData);
#endif
        if (selectorChecker(&element, &checkingContext)) {
            SelectorQueryTrait::appendOutputForElement(output, &element);
            if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
                return;
        }
    }
}