Rename AtomicString to AtomString
[WebKit-https.git] / Source / WebCore / dom / SelectorQuery.h
1 /*
2  * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include "CSSSelectorList.h"
29 #include "ExceptionOr.h"
30 #include "NodeList.h"
31 #include "SelectorCompiler.h"
32 #include <wtf/HashMap.h>
33 #include <wtf/Vector.h>
34 #include <wtf/text/AtomStringHash.h>
35
36 namespace WebCore {
37
38 class CSSSelector;
39 class ContainerNode;
40 class Document;
41 class Element;
42
43 class SelectorDataList {
44 public:
45     explicit SelectorDataList(const CSSSelectorList&);
46     bool matches(Element&) const;
47     Element* closest(Element&) const;
48     Ref<NodeList> queryAll(ContainerNode& rootNode) const;
49     Element* queryFirst(ContainerNode& rootNode) const;
50
51 private:
52     struct SelectorData {
53         SelectorData(const CSSSelector* selector)
54             : selector(selector)
55 #if ENABLE(CSS_SELECTOR_JIT) && CSS_SELECTOR_JIT_PROFILING
56             , m_compiledSelectorUseCount(0)
57 #endif
58         {
59         }
60
61         const CSSSelector* selector;
62 #if ENABLE(CSS_SELECTOR_JIT)
63         mutable JSC::MacroAssemblerCodeRef<CSSSelectorPtrTag> compiledSelectorCodeRef;
64         mutable SelectorCompilationStatus compilationStatus;
65 #if CSS_SELECTOR_JIT_PROFILING
66         ~SelectorData()
67         {
68             if (compiledSelectorCodeRef.code().executableAddress())
69                 dataLogF("SelectorData compiled selector %d \"%s\"\n", m_compiledSelectorUseCount, selector->selectorText().utf8().data());
70         }
71         mutable unsigned m_compiledSelectorUseCount;
72         void compiledSelectorUsed() const { m_compiledSelectorUseCount++; }
73 #endif
74 #endif // ENABLE(CSS_SELECTOR_JIT)
75     };
76
77     bool selectorMatches(const SelectorData&, Element&, const ContainerNode& rootNode) const;
78     Element* selectorClosest(const SelectorData&, Element&, const ContainerNode& rootNode) const;
79
80     template <typename SelectorQueryTrait> void execute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
81     template <typename SelectorQueryTrait> void executeFastPathForIdSelector(const ContainerNode& rootNode, const SelectorData&, const CSSSelector* idSelector, typename SelectorQueryTrait::OutputType&) const;
82     template <typename SelectorQueryTrait> void executeSingleTagNameSelectorData(const ContainerNode& rootNode, const SelectorData&, typename SelectorQueryTrait::OutputType&) const;
83     template <typename SelectorQueryTrait> void executeSingleClassNameSelectorData(const ContainerNode& rootNode, const SelectorData&, typename SelectorQueryTrait::OutputType&) const;
84     template <typename SelectorQueryTrait> void executeSingleSelectorData(const ContainerNode& rootNode, const ContainerNode& searchRootNode, const SelectorData&, typename SelectorQueryTrait::OutputType&) const;
85     template <typename SelectorQueryTrait> void executeSingleMultiSelectorData(const ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
86 #if ENABLE(CSS_SELECTOR_JIT)
87     template <typename SelectorQueryTrait> void executeCompiledSimpleSelectorChecker(const ContainerNode& searchRootNode, SelectorCompiler::QuerySelectorSimpleSelectorChecker, typename SelectorQueryTrait::OutputType&, const SelectorData&) const;
88     template <typename SelectorQueryTrait> void executeCompiledSelectorCheckerWithCheckingContext(const ContainerNode& rootNode, const ContainerNode& searchRootNode, SelectorCompiler::QuerySelectorSelectorCheckerWithCheckingContext, typename SelectorQueryTrait::OutputType&, const SelectorData&) const;
89     template <typename SelectorQueryTrait> void executeCompiledSingleMultiSelectorData(const ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
90     static bool compileSelector(const SelectorData&);
91 #endif // ENABLE(CSS_SELECTOR_JIT)
92
93     Vector<SelectorData> m_selectors;
94     mutable enum MatchType {
95         CompilableSingle,
96         CompilableSingleWithRootFilter,
97         CompilableMultipleSelectorMatch,
98         CompiledSingle,
99         CompiledSingleWithRootFilter,
100         CompiledMultipleSelectorMatch,
101         SingleSelector,
102         SingleSelectorWithRootFilter,
103         RightMostWithIdMatch,
104         TagNameMatch,
105         ClassNameMatch,
106         MultipleSelectorMatch,
107     } m_matchType;
108 };
109
110 class SelectorQuery {
111     WTF_MAKE_NONCOPYABLE(SelectorQuery);
112     WTF_MAKE_FAST_ALLOCATED;
113
114 public:
115     explicit SelectorQuery(CSSSelectorList&&);
116     bool matches(Element&) const;
117     Element* closest(Element&) const;
118     Ref<NodeList> queryAll(ContainerNode& rootNode) const;
119     Element* queryFirst(ContainerNode& rootNode) const;
120
121 private:
122     CSSSelectorList m_selectorList;
123     SelectorDataList m_selectors;
124 };
125
126 class SelectorQueryCache {
127     WTF_MAKE_FAST_ALLOCATED;
128 public:
129     ExceptionOr<SelectorQuery&> add(const String&, Document&);
130 private:
131     HashMap<String, std::unique_ptr<SelectorQuery>> m_entries;
132 };
133
134 inline bool SelectorQuery::matches(Element& element) const
135 {
136     return m_selectors.matches(element);
137 }
138
139 inline Element* SelectorQuery::closest(Element& element) const
140 {
141     return m_selectors.closest(element);
142 }
143
144 inline Ref<NodeList> SelectorQuery::queryAll(ContainerNode& rootNode) const
145 {
146     return m_selectors.queryAll(rootNode);
147 }
148
149 inline Element* SelectorQuery::queryFirst(ContainerNode& rootNode) const
150 {
151     return m_selectors.queryFirst(rootNode);
152 }
153
154 } // namespace WebCore