• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 #ifndef ElementRuleCollector_h
23 #define ElementRuleCollector_h
24 
25 #include "core/css/PseudoStyleRequest.h"
26 #include "core/css/SelectorChecker.h"
27 #include "core/css/resolver/ElementResolveContext.h"
28 #include "core/css/resolver/MatchRequest.h"
29 #include "core/css/resolver/MatchResult.h"
30 #include "core/css/resolver/StyleResolverIncludes.h"
31 #include "wtf/RefPtr.h"
32 #include "wtf/Vector.h"
33 
34 namespace WebCore {
35 
36 class CSSRuleList;
37 class RenderRegion;
38 class RuleData;
39 class RuleSet;
40 class ScopedStyleResolver;
41 class SelectorFilter;
42 class StaticCSSRuleList;
43 
44 typedef unsigned CascadeScope;
45 typedef unsigned CascadeOrder;
46 
47 const CascadeScope ignoreCascadeScope = 0;
48 const CascadeOrder ignoreCascadeOrder = 0;
49 
50 class MatchedRule {
51     WTF_MAKE_FAST_ALLOCATED;
52 public:
MatchedRule(const RuleData * ruleData,unsigned specificity,CascadeScope cascadeScope,CascadeOrder cascadeOrder,unsigned styleSheetIndex)53     explicit MatchedRule(const RuleData* ruleData, unsigned specificity, CascadeScope cascadeScope, CascadeOrder cascadeOrder, unsigned styleSheetIndex)
54         : m_ruleData(ruleData)
55         , m_specificity(specificity)
56         , m_cascadeScope(cascadeScope)
57         , m_styleSheetIndex(styleSheetIndex)
58     {
59         ASSERT(m_ruleData);
60         static const unsigned BitsForPositionInRuleData = 18;
61         m_position = (cascadeOrder << BitsForPositionInRuleData) + m_ruleData->position();
62     }
63 
ruleData()64     const RuleData* ruleData() const { return m_ruleData; }
cascadeScope()65     uint32_t cascadeScope() const { return m_cascadeScope; }
position()66     uint32_t position() const { return m_position; }
specificity()67     unsigned specificity() const { return ruleData()->specificity() + m_specificity; }
styleSheetIndex()68     uint32_t styleSheetIndex() const { return m_styleSheetIndex; }
69 
70 private:
71     const RuleData* m_ruleData;
72     unsigned m_specificity;
73     CascadeScope m_cascadeScope;
74     uint32_t m_position;
75     uint32_t m_styleSheetIndex;
76 };
77 
78 class StyleRuleList : public RefCounted<StyleRuleList> {
79 public:
create()80     static PassRefPtr<StyleRuleList> create() { return adoptRef(new StyleRuleList()); }
81     Vector<StyleRule*> m_list;
82 };
83 
84 // ElementRuleCollector is designed to be used as a stack object.
85 // Create one, ask what rules the ElementResolveContext matches
86 // and then let it go out of scope.
87 // FIXME: Currently it modifies the RenderStyle but should not!
88 class ElementRuleCollector {
89     WTF_MAKE_NONCOPYABLE(ElementRuleCollector);
90 public:
91     ElementRuleCollector(const ElementResolveContext&, const SelectorFilter&, RenderStyle* = 0, ShouldIncludeStyleSheetInCSSOMWrapper = IncludeStyleSheetInCSSOMWrapper);
92     ~ElementRuleCollector();
93 
setMode(SelectorChecker::Mode mode)94     void setMode(SelectorChecker::Mode mode) { m_mode = mode; }
setPseudoStyleRequest(const PseudoStyleRequest & request)95     void setPseudoStyleRequest(const PseudoStyleRequest& request) { m_pseudoStyleRequest = request; }
setSameOriginOnly(bool f)96     void setSameOriginOnly(bool f) { m_sameOriginOnly = f; }
setRegionForStyling(const RenderRegion * regionForStyling)97     void setRegionForStyling(const RenderRegion* regionForStyling) { m_regionForStyling = regionForStyling; }
98 
setMatchingUARules(bool matchingUARules)99     void setMatchingUARules(bool matchingUARules) { m_matchingUARules = matchingUARules; }
100     bool hasAnyMatchingRules(RuleSet*);
101 
102     MatchResult& matchedResult();
103     PassRefPtr<StyleRuleList> matchedStyleRuleList();
104     PassRefPtr<CSSRuleList> matchedCSSRuleList();
105 
106     void collectMatchingRules(const MatchRequest&, RuleRange&, SelectorChecker::BehaviorAtBoundary = SelectorChecker::DoesNotCrossBoundary, CascadeScope = ignoreCascadeScope, CascadeOrder = ignoreCascadeOrder);
107     void collectMatchingRulesForRegion(const MatchRequest&, RuleRange&, SelectorChecker::BehaviorAtBoundary = SelectorChecker::DoesNotCrossBoundary, CascadeScope = ignoreCascadeScope, CascadeOrder = ignoreCascadeOrder);
108     void sortAndTransferMatchedRules();
109     void clearMatchedRules();
110     void addElementStyleProperties(const StylePropertySet*, bool isCacheable = true);
111 
lastMatchedRulesPosition()112     unsigned lastMatchedRulesPosition() const { return m_matchedRules ? m_matchedRules->size() : 0; }
113     void sortMatchedRulesFrom(unsigned position);
114     void sortAndTransferMatchedRulesWithOnlySortBySpecificity();
115 
116 private:
117     void collectRuleIfMatches(const RuleData&, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
118     void collectMatchingRulesForList(const Vector<RuleData>*, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
119     void collectMatchingRulesForList(const RuleData*, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
120     bool ruleMatches(const RuleData&, const ContainerNode* scope, SelectorChecker::BehaviorAtBoundary, SelectorChecker::MatchResult*);
121 
122     void appendCSSOMWrapperForRule(StyleRule*);
123 
124     void sortMatchedRules();
125     void addMatchedRule(const RuleData*, unsigned specificity, CascadeScope, CascadeOrder);
126     void addMatchedRule(const RuleData*, unsigned specificity, CascadeScope, CascadeOrder, unsigned styleSheetIndex);
127 
128     StaticCSSRuleList* ensureRuleList();
129     StyleRuleList* ensureStyleRuleList();
130 
131 private:
132     const ElementResolveContext& m_context;
133     const SelectorFilter& m_selectorFilter;
134     RefPtr<RenderStyle> m_style; // FIXME: This can be mutated during matching!
135 
136     const RenderRegion* m_regionForStyling;
137     PseudoStyleRequest m_pseudoStyleRequest;
138     SelectorChecker::Mode m_mode;
139     bool m_canUseFastReject;
140     bool m_sameOriginOnly;
141     bool m_matchingUARules;
142     bool m_includeStyleSheet;
143 
144     OwnPtr<Vector<MatchedRule, 32> > m_matchedRules;
145 
146     // Output.
147     RefPtr<StaticCSSRuleList> m_cssRuleList;
148     RefPtr<StyleRuleList> m_styleRuleList;
149     MatchResult m_result;
150 };
151 
152 } // namespace WebCore
153 
154 #endif // ElementRuleCollector_h
155