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 34namespace WebCore { 35 36class CSSRuleList; 37class RenderRegion; 38class RuleData; 39class RuleSet; 40class ScopedStyleResolver; 41class SelectorFilter; 42class StaticCSSRuleList; 43 44typedef unsigned CascadeScope; 45typedef unsigned CascadeOrder; 46 47const CascadeScope ignoreCascadeScope = 0; 48const CascadeOrder ignoreCascadeOrder = 0; 49 50class MatchedRule { 51 WTF_MAKE_FAST_ALLOCATED; 52public: 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 70private: 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 78class StyleRuleList : public RefCounted<StyleRuleList> { 79public: 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! 88class ElementRuleCollector { 89 WTF_MAKE_NONCOPYABLE(ElementRuleCollector); 90public: 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 116private: 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 131private: 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