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 "wtf/RefPtr.h" 31 #include "wtf/Vector.h" 32 33 namespace WebCore { 34 35 class CSSRuleList; 36 class DocumentRuleSets; 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, CascadeScope cascadeScope, CascadeOrder cascadeOrder) 54 : m_ruleData(ruleData) 55 , m_cascadeScope(cascadeScope) 56 { 57 ASSERT(m_ruleData); 58 static const unsigned BitsForPositionInRuleData = 18; 59 m_position = (cascadeOrder << BitsForPositionInRuleData) + m_ruleData->position(); 60 } 61 62 const RuleData* ruleData() const { return m_ruleData; } 63 uint32_t cascadeScope() const { return m_cascadeScope; } 64 uint32_t position() const { return m_position; } 65 66 private: 67 const RuleData* m_ruleData; 68 CascadeScope m_cascadeScope; 69 uint32_t m_position; 70 }; 71 72 // ElementRuleCollector is designed to be used as a stack object. 73 // Create one, ask what rules the ElementResolveContext matches 74 // and then let it go out of scope. 75 // FIXME: Currently it modifies the RenderStyle but should not! 76 class ElementRuleCollector { 77 WTF_MAKE_NONCOPYABLE(ElementRuleCollector); 78 public: 79 ElementRuleCollector(const ElementResolveContext&, const SelectorFilter&, RenderStyle*); 80 81 void setBehaviorAtBoundary(SelectorChecker::BehaviorAtBoundary boundary) { m_behaviorAtBoundary = boundary; } 82 SelectorChecker::BehaviorAtBoundary behaviorAtBoundary() const { return m_behaviorAtBoundary; } 83 void setCanUseFastReject(bool canUseFastReject) { m_canUseFastReject = canUseFastReject; } 84 bool canUseFastReject() const { return m_canUseFastReject; } 85 86 void setMode(SelectorChecker::Mode mode) { m_mode = mode; } 87 void setPseudoStyleRequest(const PseudoStyleRequest& request) { m_pseudoStyleRequest = request; } 88 void setSameOriginOnly(bool f) { m_sameOriginOnly = f; } 89 void setRegionForStyling(const RenderRegion* regionForStyling) { m_regionForStyling = regionForStyling; } 90 91 void setMatchingUARules(bool matchingUARules) { m_matchingUARules = matchingUARules; } 92 bool hasAnyMatchingRules(RuleSet*); 93 94 MatchResult& matchedResult(); 95 PassRefPtr<CSSRuleList> matchedRuleList(); 96 97 void collectMatchingRules(const MatchRequest&, RuleRange&, CascadeScope = ignoreCascadeScope, CascadeOrder = ignoreCascadeOrder); 98 void collectMatchingRulesForRegion(const MatchRequest&, RuleRange&, CascadeScope = ignoreCascadeScope, CascadeOrder = ignoreCascadeOrder); 99 void sortAndTransferMatchedRules(); 100 void clearMatchedRules(); 101 void addElementStyleProperties(const StylePropertySet*, bool isCacheable = true); 102 103 unsigned lastMatchedRulesPosition() const { return m_matchedRules ? m_matchedRules->size() : 0; } 104 void sortMatchedRulesFrom(unsigned position); 105 void sortAndTransferMatchedRulesWithOnlySortBySpecificity(); 106 107 private: 108 Document* document() { return m_context.document(); } 109 110 void collectRuleIfMatches(const RuleData&, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&); 111 void collectMatchingRulesForList(const Vector<RuleData>*, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&); 112 void collectMatchingRulesForList(const RuleData*, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&); 113 bool ruleMatches(const RuleData&, const ContainerNode* scope, PseudoId&); 114 115 void sortMatchedRules(); 116 void addMatchedRule(const RuleData*, CascadeScope, CascadeOrder); 117 118 StaticCSSRuleList* ensureRuleList(); 119 120 private: 121 const ElementResolveContext& m_context; 122 const SelectorFilter& m_selectorFilter; 123 RefPtr<RenderStyle> m_style; // FIXME: This can be mutated during matching! 124 125 const RenderRegion* m_regionForStyling; 126 PseudoStyleRequest m_pseudoStyleRequest; 127 SelectorChecker::Mode m_mode; 128 SelectorChecker::BehaviorAtBoundary m_behaviorAtBoundary; 129 bool m_canUseFastReject; 130 bool m_sameOriginOnly; 131 bool m_matchingUARules; 132 133 OwnPtr<Vector<MatchedRule, 32> > m_matchedRules; 134 135 // Output. 136 RefPtr<StaticCSSRuleList> m_ruleList; 137 MatchResult m_result; 138 }; 139 140 } // namespace WebCore 141 142 #endif // ElementRuleCollector_h 143