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 "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