• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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 
usesSiblingRules()63     bool usesSiblingRules() const { return !siblingRules.isEmpty(); }
usesFirstLineRules()64     bool usesFirstLineRules() const { return m_metadata.usesFirstLineRules; }
65 
maxDirectAdjacentSelectors()66     unsigned maxDirectAdjacentSelectors() const { return m_metadata.maxDirectAdjacentSelectors; }
setMaxDirectAdjacentSelectors(unsigned value)67     void setMaxDirectAdjacentSelectors(unsigned value)  { m_metadata.maxDirectAdjacentSelectors = std::max(value, m_metadata.maxDirectAdjacentSelectors); }
68 
hasSelectorForAttribute(const AtomicString & attributeName)69     bool hasSelectorForAttribute(const AtomicString& attributeName) const
70     {
71         ASSERT(!attributeName.isEmpty());
72         return m_attributeInvalidationSets.contains(attributeName);
73     }
74 
hasSelectorForClass(const AtomicString & classValue)75     bool hasSelectorForClass(const AtomicString& classValue) const
76     {
77         ASSERT(!classValue.isEmpty());
78         return m_classInvalidationSets.contains(classValue);
79     }
80 
hasSelectorForId(const AtomicString & idValue)81     bool hasSelectorForId(const AtomicString& idValue) const { return m_idInvalidationSets.contains(idValue); }
hasSelectorForPseudoType(CSSSelector::PseudoType pseudo)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 
hasIdsInSelectors()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 {
FeatureMetadataFeatureMetadata115         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 {
InvalidationSetFeaturesInvalidationSetFeatures147         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