Index: Source/core/css/RuleFeature.cpp |
diff --git a/Source/core/css/RuleFeature.cpp b/Source/core/css/RuleFeature.cpp |
index 6867a79efa45b493905d8b8eb4201b38b3456d54..52e2eae7f086d1b556ac455572617c2e04aa94b0 100644 |
--- a/Source/core/css/RuleFeature.cpp |
+++ b/Source/core/css/RuleFeature.cpp |
@@ -32,7 +32,9 @@ |
#include "core/HTMLNames.h" |
#include "core/css/CSSSelector.h" |
#include "core/css/CSSSelectorList.h" |
+#include "core/css/CSSValueList.h" |
#include "core/css/RuleSet.h" |
+#include "core/css/StylePropertySet.h" |
#include "core/css/StyleRule.h" |
#include "core/css/invalidation/DescendantInvalidationSet.h" |
#include "core/dom/Element.h" |
@@ -221,6 +223,8 @@ bool RuleFeatureSet::extractInvalidationSetFeature(const CSSSelector& selector, |
features.attributes.append(selector.attribute().localName()); |
else if (selector.isCustomPseudoElement()) |
features.customPseudoElement = true; |
+ else if (selector.pseudoType() == CSSSelector::PseudoBefore || selector.pseudoType() == CSSSelector::PseudoAfter) |
+ features.hasBeforeOrAfter = true; |
else |
return false; |
return true; |
@@ -268,22 +272,53 @@ DescendantInvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSS |
return nullptr; |
} |
-// Given a selector, update the descendant invalidation sets for the features found |
-// in the selector. The first step is to extract the features from the rightmost |
+// Given a rule, update the descendant invalidation sets for the features found |
+// in its selector. The first step is to extract the features from the rightmost |
// compound selector (extractInvalidationSetFeatures). Secondly, add those features |
// to the invalidation sets for the features found in the other compound selectors |
// (addFeaturesToInvalidationSets). If we find a feature in the right-most compound |
// selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the |
// rightmost compound selector as well. |
-void RuleFeatureSet::updateInvalidationSets(const CSSSelector& selector) |
+void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) |
{ |
InvalidationSetFeatures features; |
- auto result = extractInvalidationSetFeatures(selector, features, false); |
+ auto result = extractInvalidationSetFeatures(ruleData.selector(), features, false); |
if (result.first) { |
features.forceSubtree = result.second == ForceSubtree; |
addFeaturesToInvalidationSets(*result.first, features); |
} |
+ |
+ // If any ::before and ::after rules specify 'content: attr(...)', we |
+ // need to create invalidation sets for those attributes. |
+ if (features.hasBeforeOrAfter) |
+ updateInvalidationSetsForContentAttribute(ruleData); |
+} |
+ |
+void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& ruleData) |
+{ |
+ const StylePropertySet& propertySet = ruleData.rule()->properties(); |
+ |
+ int propertyIndex = propertySet.findPropertyIndex(CSSPropertyContent); |
+ |
+ if (propertyIndex == -1) |
+ return; |
+ |
+ StylePropertySet::PropertyReference contentProperty = propertySet.propertyAt(propertyIndex); |
+ CSSValue* contentValue = contentProperty.value(); |
+ |
+ if (!contentValue->isValueList()) |
+ return; |
+ |
+ for (CSSValueListIterator i = contentValue; i.hasMore(); i.advance()) { |
+ CSSValue* item = i.value(); |
+ if (!item->isPrimitiveValue()) |
+ continue; |
+ CSSPrimitiveValue* primitiveItem = toCSSPrimitiveValue(item); |
+ if (!primitiveItem->isAttr()) |
+ continue; |
+ ensureAttributeInvalidationSet(AtomicString(primitiveItem->getStringValue())); |
+ } |
} |
std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType> |
@@ -392,14 +427,9 @@ void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector, |
} |
} |
-void RuleFeatureSet::addContentAttr(const AtomicString& attributeName) |
-{ |
- ensureAttributeInvalidationSet(attributeName); |
-} |
- |
void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData) |
{ |
- updateInvalidationSets(ruleData.selector()); |
+ updateInvalidationSets(ruleData); |
FeatureMetadata metadata; |
collectFeaturesFromSelector(ruleData.selector(), metadata); |