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 RuleFeature_h
     23 #define RuleFeature_h
     24 
     25 #include "core/css/CSSSelector.h"
     26 #include "core/css/invalidation/StyleInvalidator.h"
     27 #include "wtf/Forward.h"
     28 #include "wtf/HashSet.h"
     29 #include "wtf/text/AtomicStringHash.h"
     30 
     31 namespace blink {
     32 
     33 class CSSSelectorList;
     34 class DescendantInvalidationSet;
     35 class QualifiedName;
     36 class RuleData;
     37 class SpaceSplitString;
     38 class StyleRule;
     39 
     40 struct RuleFeature {
     41     ALLOW_ONLY_INLINE_ALLOCATION();
     42 public:
     43     RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin);
     44 
     45     void trace(Visitor*);
     46 
     47     RawPtrWillBeMember<StyleRule> rule;
     48     unsigned selectorIndex;
     49     bool hasDocumentSecurityOrigin;
     50 };
     51 
     52 class RuleFeatureSet {
     53     DISALLOW_ALLOCATION();
     54 public:
     55     RuleFeatureSet();
     56     ~RuleFeatureSet();
     57 
     58     void add(const RuleFeatureSet&);
     59     void clear();
     60 
     61     void collectFeaturesFromRuleData(const RuleData&);
     62 
     63     bool usesSiblingRules() const { return !siblingRules.isEmpty(); }
     64     bool usesFirstLineRules() const { return m_metadata.usesFirstLineRules; }
     65 
     66     unsigned maxDirectAdjacentSelectors() const { return m_metadata.maxDirectAdjacentSelectors; }
     67     void setMaxDirectAdjacentSelectors(unsigned value)  { m_metadata.maxDirectAdjacentSelectors = std::max(value, m_metadata.maxDirectAdjacentSelectors); }
     68 
     69     bool hasSelectorForAttribute(const AtomicString& attributeName) const
     70     {
     71         ASSERT(!attributeName.isEmpty());
     72         return m_attributeInvalidationSets.contains(attributeName);
     73     }
     74 
     75     bool hasSelectorForClass(const AtomicString& classValue) const
     76     {
     77         ASSERT(!classValue.isEmpty());
     78         return m_classInvalidationSets.contains(classValue);
     79     }
     80 
     81     bool hasSelectorForId(const AtomicString& idValue) const { return m_idInvalidationSets.contains(idValue); }
     82     bool hasSelectorForPseudoType(CSSSelector::PseudoType pseudo) const { return m_pseudoInvalidationSets.contains(pseudo); }
     83 
     84     void scheduleStyleInvalidationForClassChange(const SpaceSplitString& changedClasses, Element&);
     85     void scheduleStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element&);
     86     void scheduleStyleInvalidationForAttributeChange(const QualifiedName& attributeName, Element&);
     87     void scheduleStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, Element&);
     88     void scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoType, Element&);
     89 
     90     bool hasIdsInSelectors() const
     91     {
     92         return m_idInvalidationSets.size() > 0;
     93     }
     94 
     95     // Marks the given attribute name as "appearing in a selector". Used for
     96     // CSS properties such as content: ... attr(...) ...
     97     // FIXME: record these internally to this class instead calls from StyleResolver to here.
     98     void addContentAttr(const AtomicString& attributeName);
     99 
    100     StyleInvalidator& styleInvalidator();
    101 
    102     void trace(Visitor*);
    103 
    104     WillBeHeapVector<RuleFeature> siblingRules;
    105     WillBeHeapVector<RuleFeature> uncommonAttributeRules;
    106 
    107 protected:
    108     DescendantInvalidationSet* invalidationSetForSelector(const CSSSelector&);
    109 
    110 private:
    111     typedef WillBeHeapHashMap<AtomicString, RefPtrWillBeMember<DescendantInvalidationSet> > InvalidationSetMap;
    112     typedef WillBeHeapHashMap<CSSSelector::PseudoType, RefPtrWillBeMember<DescendantInvalidationSet>, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > PseudoTypeInvalidationSetMap;
    113 
    114     struct FeatureMetadata {
    115         FeatureMetadata()
    116             : usesFirstLineRules(false)
    117             , foundSiblingSelector(false)
    118             , maxDirectAdjacentSelectors(0)
    119         { }
    120         void add(const FeatureMetadata& other);
    121         void clear();
    122 
    123         bool usesFirstLineRules;
    124         bool foundSiblingSelector;
    125         unsigned maxDirectAdjacentSelectors;
    126     };
    127 
    128     enum InvalidationSetMode {
    129         AddFeatures,
    130         UseLocalStyleChange,
    131         UseSubtreeStyleChange
    132     };
    133 
    134     static InvalidationSetMode invalidationSetModeForSelector(const CSSSelector&);
    135 
    136     void collectFeaturesFromSelector(const CSSSelector&, FeatureMetadata&, InvalidationSetMode);
    137     void collectFeaturesFromSelectorList(const CSSSelectorList*, FeatureMetadata&, InvalidationSetMode);
    138 
    139     DescendantInvalidationSet& ensureClassInvalidationSet(const AtomicString& className);
    140     DescendantInvalidationSet& ensureAttributeInvalidationSet(const AtomicString& attributeName);
    141     DescendantInvalidationSet& ensureIdInvalidationSet(const AtomicString& attributeName);
    142     DescendantInvalidationSet& ensurePseudoInvalidationSet(CSSSelector::PseudoType);
    143 
    144     InvalidationSetMode updateInvalidationSets(const CSSSelector&);
    145 
    146     struct InvalidationSetFeatures {
    147         InvalidationSetFeatures()
    148             : customPseudoElement(false)
    149             , treeBoundaryCrossing(false)
    150             , wholeSubtree(false)
    151         { }
    152         Vector<AtomicString> classes;
    153         Vector<AtomicString> attributes;
    154         AtomicString id;
    155         AtomicString tagName;
    156         bool customPseudoElement;
    157         bool treeBoundaryCrossing;
    158         bool wholeSubtree;
    159     };
    160 
    161     static void extractInvalidationSetFeature(const CSSSelector&, InvalidationSetFeatures&);
    162     const CSSSelector* extractInvalidationSetFeatures(const CSSSelector&, InvalidationSetFeatures&, bool negated);
    163     void addFeaturesToInvalidationSets(const CSSSelector&, InvalidationSetFeatures&);
    164 
    165     void addClassToInvalidationSet(const AtomicString& className, Element&);
    166 
    167     FeatureMetadata m_metadata;
    168     InvalidationSetMap m_classInvalidationSets;
    169     InvalidationSetMap m_attributeInvalidationSets;
    170     InvalidationSetMap m_idInvalidationSets;
    171     PseudoTypeInvalidationSetMap m_pseudoInvalidationSets;
    172     StyleInvalidator m_styleInvalidator;
    173 };
    174 
    175 
    176 } // namespace blink
    177 
    178 namespace WTF {
    179 
    180 template <> struct VectorTraits<blink::RuleFeature> : VectorTraitsBase<blink::RuleFeature> {
    181     static const bool needsDestruction = false;
    182     static const bool canInitializeWithMemset = true;
    183     static const bool canMoveWithMemcpy = true;
    184 };
    185 
    186 } // namespace WTF
    187 
    188 #endif // RuleFeature_h
    189