Home | History | Annotate | Download | only in css
      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