namespace WebCore {
+class Document;
+class ShadowRoot;
class StyleRule;
class CSSSelector;
class CSSSelectorList;
class RuleData;
+class SpaceSplitString;
struct RuleFeature {
RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin)
class RuleFeatureSet {
public:
- RuleFeatureSet() { }
+ RuleFeatureSet();
void add(const RuleFeatureSet&);
void clear();
- void collectFeaturesFromSelector(const CSSSelector*);
+ void collectFeaturesFromSelector(const CSSSelector&);
void collectFeaturesFromRuleData(const RuleData&);
bool usesSiblingRules() const { return !siblingRules.isEmpty(); }
inline bool hasSelectorForClass(const AtomicString& classValue) const
{
ASSERT(!classValue.isEmpty());
- return m_metadata.classesInRules.contains(classValue);
+ return m_classInvalidationSets.get(classValue);
+
}
inline bool hasSelectorForId(const AtomicString& idValue) const
return m_metadata.idsInRules.contains(idValue);
}
+ void scheduleStyleInvalidationForClassChange(const SpaceSplitString& changedClasses, Element*);
+ void scheduleStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element*);
+
+ void computeStyleInvalidation(Document&);
+
int hasIdsInSelectors() const
{
return m_metadata.idsInRules.size() > 0;
private:
typedef HashMap<AtomicString, RefPtr<DescendantInvalidationSet> > InvalidationSetMap;
+ typedef Vector<DescendantInvalidationSet*> InvalidationList;
+ typedef HashMap<Element*, InvalidationList*> PendingInvalidationMap;
struct FeatureMetadata {
FeatureMetadata()
: usesFirstLineRules(false)
bool foundSiblingSelector;
unsigned maxDirectAdjacentSelectors;
HashSet<AtomicString> idsInRules;
- HashSet<AtomicString> classesInRules;
HashSet<AtomicString> attrsInRules;
};
- void collectFeaturesFromSelector(const CSSSelector*, FeatureMetadata&);
- void collectFeaturesFromSelectorList(const CSSSelectorList*, FeatureMetadata&);
+ // These return true if setNeedsStyleRecalc() should be run on the Element, as a fallback.
+ bool computeInvalidationSetsForClassChange(const SpaceSplitString& changedClasses, Element*);
+ bool computeInvalidationSetsForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element*);
+
+ enum SelectorFeatureCollectionMode {
+ ProcessClasses,
+ DontProcessClasses
+ };
+
+ void collectFeaturesFromSelector(const CSSSelector&, FeatureMetadata&, SelectorFeatureCollectionMode processClasses);
+ void collectFeaturesFromSelectorList(const CSSSelectorList*, FeatureMetadata&, SelectorFeatureCollectionMode processClasses);
+
+ bool classInvalidationRequiresSubtreeRecalc(const AtomicString& className);
DescendantInvalidationSet& ensureClassInvalidationSet(const AtomicString& className);
- bool updateClassInvalidationSets(const CSSSelector*);
+ bool updateClassInvalidationSets(const CSSSelector&);
+
+ void addClassToInvalidationSet(const AtomicString& className, Element*);
+
+ bool invalidateStyleForClassChange(Element*, Vector<AtomicString>&, bool foundInvalidationSet);
+ bool invalidateStyleForClassChangeOnChildren(Element*, Vector<AtomicString>& invalidationClasses, bool foundInvalidationSet);
+
+ InvalidationList& ensurePendingInvalidationList(Element*);
- InvalidationSetMap m_classInvalidationSets;
FeatureMetadata m_metadata;
+ InvalidationSetMap m_classInvalidationSets;
+ PendingInvalidationMap m_pendingInvalidationMap;
+
+ bool m_targetedStyleRecalcEnabled;
};
} // namespace WebCore