Remove excessive include directives from WebCore/css
[WebKit-https.git] / Source / WebCore / css / RuleSet.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2003-2014 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21
22 #pragma once
23
24 #include "RuleFeature.h"
25 #include "SelectorCompiler.h"
26 #include "StyleRule.h"
27 #include <wtf/Forward.h>
28 #include <wtf/HashMap.h>
29 #include <wtf/text/AtomicString.h>
30 #include <wtf/text/AtomicStringHash.h>
31
32 namespace WebCore {
33
34 enum AddRuleFlags {
35     RuleHasNoSpecialState         = 0,
36     RuleHasDocumentSecurityOrigin = 1,
37     RuleIsInRegionRule            = 1 << 1,
38 };
39     
40 enum PropertyWhitelistType {
41     PropertyWhitelistNone   = 0,
42     PropertyWhitelistRegion,
43 #if ENABLE(VIDEO_TRACK)
44     PropertyWhitelistCue
45 #endif
46 };
47
48 class CSSSelector;
49 class ContainerNode;
50 class MediaQueryEvaluator;
51 class Node;
52 class StyleResolver;
53 class StyleRuleRegion;
54 class StyleSheetContents;
55
56 enum class MatchBasedOnRuleHash : unsigned {
57     None,
58     Universal,
59     ClassA,
60     ClassB,
61     ClassC
62 };
63
64 class RuleData {
65 public:
66     static const unsigned maximumSelectorComponentCount = 8192;
67
68     RuleData(StyleRule*, unsigned selectorIndex, unsigned position, AddRuleFlags);
69
70     unsigned position() const { return m_position; }
71     StyleRule* rule() const { return m_rule.get(); }
72     const CSSSelector* selector() const { return m_rule->selectorList().selectorAt(m_selectorIndex); }
73     unsigned selectorIndex() const { return m_selectorIndex; }
74
75     bool canMatchPseudoElement() const { return m_canMatchPseudoElement; }
76     MatchBasedOnRuleHash matchBasedOnRuleHash() const { return static_cast<MatchBasedOnRuleHash>(m_matchBasedOnRuleHash); }
77     bool containsUncommonAttributeSelector() const { return m_containsUncommonAttributeSelector; }
78     unsigned linkMatchType() const { return m_linkMatchType; }
79     bool hasDocumentSecurityOrigin() const { return m_hasDocumentSecurityOrigin; }
80     PropertyWhitelistType propertyWhitelistType() const { return static_cast<PropertyWhitelistType>(m_propertyWhitelistType); }
81     // Try to balance between memory usage (there can be lots of RuleData objects) and good filtering performance.
82     static const unsigned maximumIdentifierCount = 4;
83     const unsigned* descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; }
84
85     void disableSelectorFiltering() { m_descendantSelectorIdentifierHashes[0] = 0; }
86
87 #if ENABLE(CSS_SELECTOR_JIT)
88     SelectorCompilationStatus compilationStatus() const { return m_compilationStatus; }
89     JSC::MacroAssemblerCodeRef compiledSelectorCodeRef() const { return m_compiledSelectorCodeRef; }
90     void setCompiledSelector(SelectorCompilationStatus status, JSC::MacroAssemblerCodeRef codeRef) const
91     {
92         m_compilationStatus = status;
93         m_compiledSelectorCodeRef = codeRef;
94     }
95 #if CSS_SELECTOR_JIT_PROFILING
96     ~RuleData()
97     {
98         if (m_compiledSelectorCodeRef.code().executableAddress())
99             dataLogF("RuleData compiled selector %d \"%s\"\n", m_compiledSelectorUseCount, selector()->selectorText().utf8().data());
100     }
101     void compiledSelectorUsed() const { m_compiledSelectorUseCount++; }
102 #endif
103 #endif // ENABLE(CSS_SELECTOR_JIT)
104
105 private:
106     RefPtr<StyleRule> m_rule;
107     unsigned m_selectorIndex : 13;
108     unsigned m_hasDocumentSecurityOrigin : 1;
109     // This number was picked fairly arbitrarily. We can probably lower it if we need to.
110     // Some simple testing showed <100,000 RuleData's on large sites.
111     unsigned m_position : 18;
112     unsigned m_matchBasedOnRuleHash : 3;
113     unsigned m_canMatchPseudoElement : 1;
114     unsigned m_containsUncommonAttributeSelector : 1;
115     unsigned m_linkMatchType : 2; //  SelectorChecker::LinkMatchMask
116     unsigned m_propertyWhitelistType : 2;
117     // Use plain array instead of a Vector to minimize memory overhead.
118     unsigned m_descendantSelectorIdentifierHashes[maximumIdentifierCount];
119 #if ENABLE(CSS_SELECTOR_JIT)
120     mutable SelectorCompilationStatus m_compilationStatus;
121     mutable JSC::MacroAssemblerCodeRef m_compiledSelectorCodeRef;
122 #if CSS_SELECTOR_JIT_PROFILING
123     mutable unsigned m_compiledSelectorUseCount;
124 #endif
125 #endif // ENABLE(CSS_SELECTOR_JIT)
126 };
127     
128 struct SameSizeAsRuleData {
129 #if ENABLE(CSS_SELECTOR_JIT)
130     unsigned compilationStatus;
131     void* compiledSelectorPointer;
132     void* codeRefPtr;
133 #if CSS_SELECTOR_JIT_PROFILING
134     unsigned compiledSelectorUseCount;
135 #endif
136 #endif // ENABLE(CSS_SELECTOR_JIT)
137
138     void* a;
139     unsigned b;
140     unsigned c;
141     unsigned d[4];
142 };
143
144 COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_stay_small);
145
146 class RuleSet {
147     WTF_MAKE_NONCOPYABLE(RuleSet); WTF_MAKE_FAST_ALLOCATED;
148 public:
149     struct RuleSetSelectorPair {
150         RuleSetSelectorPair(const CSSSelector* selector, std::unique_ptr<RuleSet> ruleSet) : selector(selector), ruleSet(WTFMove(ruleSet)) { }
151         RuleSetSelectorPair(const RuleSetSelectorPair& pair) : selector(pair.selector), ruleSet(const_cast<RuleSetSelectorPair*>(&pair)->ruleSet.release()) { }
152
153         const CSSSelector* selector;
154         std::unique_ptr<RuleSet> ruleSet;
155     };
156
157     RuleSet();
158     ~RuleSet();
159
160     typedef Vector<RuleData, 1> RuleDataVector;
161     typedef HashMap<AtomicString, std::unique_ptr<RuleDataVector>> AtomRuleMap;
162
163     void addRulesFromSheet(StyleSheetContents&, const MediaQueryEvaluator&, StyleResolver* = 0);
164
165     void addStyleRule(StyleRule*, AddRuleFlags);
166     void addRule(StyleRule*, unsigned selectorIndex, AddRuleFlags);
167     void addPageRule(StyleRulePage*);
168     void addToRuleSet(const AtomicString& key, AtomRuleMap&, const RuleData&);
169     void addRegionRule(StyleRuleRegion*, bool hasDocumentSecurityOrigin);
170     void shrinkToFit();
171     void disableAutoShrinkToFit() { m_autoShrinkToFitEnabled = false; }
172
173     const RuleFeatureSet& features() const { return m_features; }
174
175     const RuleDataVector* idRules(const AtomicString& key) const { return m_idRules.get(key); }
176     const RuleDataVector* classRules(const AtomicString& key) const { return m_classRules.get(key); }
177     const RuleDataVector* tagRules(const AtomicString& key, bool isHTMLName) const;
178     const RuleDataVector* shadowPseudoElementRules(const AtomicString& key) const { return m_shadowPseudoElementRules.get(key); }
179     const RuleDataVector* linkPseudoClassRules() const { return &m_linkPseudoClassRules; }
180 #if ENABLE(VIDEO_TRACK)
181     const RuleDataVector* cuePseudoRules() const { return &m_cuePseudoRules; }
182 #endif
183     const RuleDataVector& hostPseudoClassRules() const { return m_hostPseudoClassRules; }
184     const RuleDataVector& slottedPseudoElementRules() const { return m_slottedPseudoElementRules; }
185     const RuleDataVector* focusPseudoClassRules() const { return &m_focusPseudoClassRules; }
186     const RuleDataVector* universalRules() const { return &m_universalRules; }
187
188     const Vector<StyleRulePage*>& pageRules() const { return m_pageRules; }
189     const Vector<RuleSetSelectorPair>& regionSelectorsAndRuleSets() const { return m_regionSelectorsAndRuleSets; }
190
191     unsigned ruleCount() const { return m_ruleCount; }
192
193     bool hasShadowPseudoElementRules() const;
194     bool hasHostPseudoClassRulesMatchingInShadowTree() const { return m_hasHostPseudoClassRulesMatchingInShadowTree; }
195
196 private:
197     void addChildRules(const Vector<RefPtr<StyleRuleBase>>&, const MediaQueryEvaluator& medium, StyleResolver*, bool hasDocumentSecurityOrigin, bool isInitiatingElementInUserAgentShadowTree, AddRuleFlags);
198
199     AtomRuleMap m_idRules;
200     AtomRuleMap m_classRules;
201     AtomRuleMap m_tagLocalNameRules;
202     AtomRuleMap m_tagLowercaseLocalNameRules;
203     AtomRuleMap m_shadowPseudoElementRules;
204     RuleDataVector m_linkPseudoClassRules;
205 #if ENABLE(VIDEO_TRACK)
206     RuleDataVector m_cuePseudoRules;
207 #endif
208     RuleDataVector m_hostPseudoClassRules;
209     RuleDataVector m_slottedPseudoElementRules;
210     RuleDataVector m_focusPseudoClassRules;
211     RuleDataVector m_universalRules;
212     Vector<StyleRulePage*> m_pageRules;
213     unsigned m_ruleCount { 0 };
214     bool m_hasHostPseudoClassRulesMatchingInShadowTree { false };
215     bool m_autoShrinkToFitEnabled { true };
216     RuleFeatureSet m_features;
217     Vector<RuleSetSelectorPair> m_regionSelectorsAndRuleSets;
218 };
219
220 inline const RuleSet::RuleDataVector* RuleSet::tagRules(const AtomicString& key, bool isHTMLName) const
221 {
222     const AtomRuleMap* tagRules;
223     if (isHTMLName)
224         tagRules = &m_tagLowercaseLocalNameRules;
225     else
226         tagRules = &m_tagLocalNameRules;
227     return tagRules->get(key);
228 }
229
230 } // namespace WebCore
231
232 namespace WTF {
233
234 // RuleData is simple enough that initializing to 0 and moving with memcpy will totally work.
235 template<> struct VectorTraits<WebCore::RuleData> : SimpleClassVectorTraits { };
236
237 } // namespace WTF