1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) 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: 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 64 const RuleData* ruleData() const { return m_ruleData; } 65 uint32_t cascadeScope() const { return m_cascadeScope; } 66 uint32_t position() const { return m_position; } 67 unsigned specificity() const { return ruleData()->specificity() + m_specificity; } 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: 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 94 void setMode(SelectorChecker::Mode mode) { m_mode = mode; } 95 void setPseudoStyleRequest(const PseudoStyleRequest& request) { m_pseudoStyleRequest = request; } 96 void setSameOriginOnly(bool f) { m_sameOriginOnly = f; } 97 void setRegionForStyling(const RenderRegion* regionForStyling) { m_regionForStyling = regionForStyling; } 98 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 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