Optimized querySelector(All) when selector contains #id
[WebKit-https.git] / Source / WebCore / dom / SelectorQuery.h
1 /*
2  * Copyright (C) 2011, 2013, 2014 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 #ifndef SelectorQuery_h
27 #define SelectorQuery_h
28
29 #include "CSSSelectorList.h"
30 #include "NodeList.h"
31 #include "SelectorCompiler.h"
32 #include <wtf/HashMap.h>
33 #include <wtf/Vector.h>
34 #include <wtf/text/AtomicStringHash.h>
35
36 namespace WebCore {
37
38 typedef int ExceptionCode;
39     
40 class CSSSelector;
41 class ContainerNode;
42 class Document;
43 class Element;
44 class Node;
45 class NodeList;
46
47 class SelectorDataList {
48 public:
49     explicit SelectorDataList(const CSSSelectorList&);
50     bool matches(Element&) const;
51     RefPtr<NodeList> queryAll(ContainerNode& rootNode) const;
52     Element* queryFirst(ContainerNode& rootNode) const;
53
54 private:
55     struct SelectorData {
56         SelectorData(const CSSSelector* selector, bool isFastCheckable)
57             : selector(selector)
58             , isFastCheckable(isFastCheckable)
59         {
60         }
61
62         const CSSSelector* selector;
63 #if ENABLE(CSS_SELECTOR_JIT)
64         mutable JSC::MacroAssemblerCodeRef compiledSelectorCodeRef;
65         mutable SelectorCompilationStatus compilationStatus;
66 #endif // ENABLE(CSS_SELECTOR_JIT)
67         bool isFastCheckable;
68     };
69
70     bool selectorMatches(const SelectorData&, Element&, const ContainerNode& rootNode) const;
71
72     template <typename SelectorQueryTrait> void execute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
73     template <typename SelectorQueryTrait> void executeFastPathForIdSelector(const ContainerNode& rootNode, const SelectorData&, const CSSSelector* idSelector, typename SelectorQueryTrait::OutputType&) const;
74     template <typename SelectorQueryTrait> void executeSingleTagNameSelectorData(const ContainerNode& rootNode, const SelectorData&, typename SelectorQueryTrait::OutputType&) const;
75     template <typename SelectorQueryTrait> void executeSingleClassNameSelectorData(const ContainerNode& rootNode, const SelectorData&, typename SelectorQueryTrait::OutputType&) const;
76     template <typename SelectorQueryTrait> void executeSingleSelectorData(const ContainerNode& rootNode, const SelectorData&, typename SelectorQueryTrait::OutputType&) const;
77     template <typename SelectorQueryTrait> void executeSingleMultiSelectorData(const ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
78 #if ENABLE(CSS_SELECTOR_JIT)
79     template <typename SelectorQueryTrait> void executeCompiledSimpleSelectorChecker(const ContainerNode& rootNode, SelectorCompiler::SimpleSelectorChecker, typename SelectorQueryTrait::OutputType&) const;
80 #endif // ENABLE(CSS_SELECTOR_JIT)
81
82     Vector<SelectorData> m_selectors;
83     mutable enum MatchType {
84         CompilableSingle,
85         CompilableSingleWithRootFilter,
86         CompiledSingle,
87         CompiledSingleWithRootFilter,
88         SingleSelector,
89         RightMostWithIdMatch,
90         TagNameMatch,
91         ClassNameMatch,
92         MultipleSelectorMatch,
93     } m_matchType;
94 };
95
96 class SelectorQuery {
97     WTF_MAKE_NONCOPYABLE(SelectorQuery);
98     WTF_MAKE_FAST_ALLOCATED;
99
100 public:
101     explicit SelectorQuery(CSSSelectorList&&);
102     bool matches(Element&) const;
103     RefPtr<NodeList> queryAll(ContainerNode& rootNode) const;
104     Element* queryFirst(ContainerNode& rootNode) const;
105
106 private:
107     CSSSelectorList m_selectorList;
108     SelectorDataList m_selectors;
109 };
110
111 class SelectorQueryCache {
112     WTF_MAKE_FAST_ALLOCATED;
113
114 public:
115     SelectorQuery* add(const String&, Document&, ExceptionCode&);
116     void invalidate();
117
118 private:
119     HashMap<String, std::unique_ptr<SelectorQuery>> m_entries;
120 };
121
122 inline bool SelectorQuery::matches(Element& element) const
123 {
124     return m_selectors.matches(element);
125 }
126
127 inline RefPtr<NodeList> SelectorQuery::queryAll(ContainerNode& rootNode) const
128 {
129     return m_selectors.queryAll(rootNode);
130 }
131
132 inline Element* SelectorQuery::queryFirst(ContainerNode& rootNode) const
133 {
134     return m_selectors.queryFirst(rootNode);
135 }
136
137 }
138
139 #endif