Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) |
| 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) | 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) |
| 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All r ights reserved. | 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All r ights reserved. |
| 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
| 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> | 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> |
| 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) |
| 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
| 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 #include "core/css/StylePropertySet.h" | 39 #include "core/css/StylePropertySet.h" |
| 40 #include "core/css/StyleRule.h" | 40 #include "core/css/StyleRule.h" |
| 41 #include "core/css/invalidation/InvalidationSet.h" | 41 #include "core/css/invalidation/InvalidationSet.h" |
| 42 #include "core/dom/Element.h" | 42 #include "core/dom/Element.h" |
| 43 #include "core/dom/Node.h" | 43 #include "core/dom/Node.h" |
| 44 #include "core/inspector/InspectorTraceEvents.h" | 44 #include "core/inspector/InspectorTraceEvents.h" |
| 45 #include "wtf/BitVector.h" | 45 #include "wtf/BitVector.h" |
| 46 | 46 |
| 47 namespace blink { | 47 namespace blink { |
| 48 | 48 |
| 49 namespace { | |
| 50 | |
| 49 #if ENABLE(ASSERT) | 51 #if ENABLE(ASSERT) |
| 50 | 52 |
| 51 static bool supportsInvalidation(CSSSelector::Match match) | 53 bool supportsInvalidation(CSSSelector::Match match) |
| 52 { | 54 { |
| 53 switch (match) { | 55 switch (match) { |
| 54 case CSSSelector::Tag: | 56 case CSSSelector::Tag: |
| 55 case CSSSelector::Id: | 57 case CSSSelector::Id: |
| 56 case CSSSelector::Class: | 58 case CSSSelector::Class: |
| 57 case CSSSelector::AttributeExact: | 59 case CSSSelector::AttributeExact: |
| 58 case CSSSelector::AttributeSet: | 60 case CSSSelector::AttributeSet: |
| 59 case CSSSelector::AttributeHyphen: | 61 case CSSSelector::AttributeHyphen: |
| 60 case CSSSelector::AttributeList: | 62 case CSSSelector::AttributeList: |
| 61 case CSSSelector::AttributeContain: | 63 case CSSSelector::AttributeContain: |
| 62 case CSSSelector::AttributeBegin: | 64 case CSSSelector::AttributeBegin: |
| 63 case CSSSelector::AttributeEnd: | 65 case CSSSelector::AttributeEnd: |
| 64 return true; | 66 return true; |
| 65 case CSSSelector::Unknown: | 67 case CSSSelector::Unknown: |
| 66 case CSSSelector::PagePseudoClass: | 68 case CSSSelector::PagePseudoClass: |
| 67 // These should not appear in StyleRule selectors. | 69 // These should not appear in StyleRule selectors. |
| 68 ASSERT_NOT_REACHED(); | 70 ASSERT_NOT_REACHED(); |
| 69 return false; | 71 return false; |
| 70 default: | 72 default: |
| 71 // New match type added. Figure out if it needs a subtree invalidation o r not. | 73 // New match type added. Figure out if it needs a subtree invalidation o r not. |
| 72 ASSERT_NOT_REACHED(); | 74 ASSERT_NOT_REACHED(); |
| 73 return false; | 75 return false; |
| 74 } | 76 } |
| 75 } | 77 } |
| 76 | 78 |
| 77 static bool supportsInvalidation(CSSSelector::PseudoType type) | 79 bool supportsInvalidation(CSSSelector::PseudoType type) |
| 78 { | 80 { |
| 79 switch (type) { | 81 switch (type) { |
| 80 case CSSSelector::PseudoEmpty: | 82 case CSSSelector::PseudoEmpty: |
| 81 case CSSSelector::PseudoFirstChild: | 83 case CSSSelector::PseudoFirstChild: |
| 82 case CSSSelector::PseudoFirstOfType: | 84 case CSSSelector::PseudoFirstOfType: |
| 83 case CSSSelector::PseudoLastChild: | 85 case CSSSelector::PseudoLastChild: |
| 84 case CSSSelector::PseudoLastOfType: | 86 case CSSSelector::PseudoLastOfType: |
| 85 case CSSSelector::PseudoOnlyChild: | 87 case CSSSelector::PseudoOnlyChild: |
| 86 case CSSSelector::PseudoOnlyOfType: | 88 case CSSSelector::PseudoOnlyOfType: |
| 87 case CSSSelector::PseudoNthChild: | 89 case CSSSelector::PseudoNthChild: |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 // These should not appear in StyleRule selectors. | 161 // These should not appear in StyleRule selectors. |
| 160 ASSERT_NOT_REACHED(); | 162 ASSERT_NOT_REACHED(); |
| 161 return false; | 163 return false; |
| 162 default: | 164 default: |
| 163 // New pseudo type added. Figure out if it needs a subtree invalidation or not. | 165 // New pseudo type added. Figure out if it needs a subtree invalidation or not. |
| 164 ASSERT_NOT_REACHED(); | 166 ASSERT_NOT_REACHED(); |
| 165 return false; | 167 return false; |
| 166 } | 168 } |
| 167 } | 169 } |
| 168 | 170 |
| 169 static bool supportsInvalidationWithSelectorList(CSSSelector::PseudoType pseudo) | 171 bool supportsInvalidationWithSelectorList(CSSSelector::PseudoType pseudo) |
| 170 { | 172 { |
| 171 return pseudo == CSSSelector::PseudoAny | 173 return pseudo == CSSSelector::PseudoAny |
| 172 || pseudo == CSSSelector::PseudoCue | 174 || pseudo == CSSSelector::PseudoCue |
| 173 || pseudo == CSSSelector::PseudoHost | 175 || pseudo == CSSSelector::PseudoHost |
| 174 || pseudo == CSSSelector::PseudoHostContext | 176 || pseudo == CSSSelector::PseudoHostContext |
| 175 || pseudo == CSSSelector::PseudoNot; | 177 || pseudo == CSSSelector::PseudoNot; |
| 176 } | 178 } |
| 177 | 179 |
| 178 #endif // ENABLE(ASSERT) | 180 #endif // ENABLE(ASSERT) |
| 179 | 181 |
| 180 static bool requiresSubtreeInvalidation(const CSSSelector& selector) | 182 bool requiresSubtreeInvalidation(const CSSSelector& selector) |
| 181 { | 183 { |
| 182 if (selector.match() != CSSSelector::PseudoElement && selector.match() != CS SSelector::PseudoClass) { | 184 if (selector.match() != CSSSelector::PseudoElement && selector.match() != CS SSelector::PseudoClass) { |
| 183 ASSERT(supportsInvalidation(selector.match())); | 185 ASSERT(supportsInvalidation(selector.match())); |
| 184 return false; | 186 return false; |
| 185 } | 187 } |
| 186 | 188 |
| 187 switch (selector.pseudoType()) { | 189 switch (selector.pseudoType()) { |
| 188 case CSSSelector::PseudoFirstLine: | 190 case CSSSelector::PseudoFirstLine: |
| 189 case CSSSelector::PseudoFirstLetter: | 191 case CSSSelector::PseudoFirstLetter: |
| 190 // FIXME: Most pseudo classes/elements above can be supported and moved | 192 // FIXME: Most pseudo classes/elements above can be supported and moved |
| 191 // to assertSupportedPseudo(). Move on a case-by-case basis. If they | 193 // to assertSupportedPseudo(). Move on a case-by-case basis. If they |
| 192 // require subtree invalidation, document why. | 194 // require subtree invalidation, document why. |
| 193 case CSSSelector::PseudoHostContext: | 195 case CSSSelector::PseudoHostContext: |
| 194 // :host-context matches a shadow host, yet the simple selectors inside | 196 // :host-context matches a shadow host, yet the simple selectors inside |
| 195 // :host-context matches an ancestor of the shadow host. | 197 // :host-context matches an ancestor of the shadow host. |
| 196 return true; | 198 return true; |
| 197 default: | 199 default: |
| 198 ASSERT(supportsInvalidation(selector.pseudoType())); | 200 ASSERT(supportsInvalidation(selector.pseudoType())); |
| 199 return false; | 201 return false; |
| 200 } | 202 } |
| 201 } | 203 } |
| 202 | 204 |
| 205 template<class Map> | |
| 206 InvalidationData& ensureInvalidationData(Map& map, const typename Map::KeyType& key) | |
| 207 { | |
| 208 typename Map::AddResult addResult = map.add(key, nullptr); | |
| 209 if (addResult.isNewEntry) | |
| 210 addResult.storedValue->value = InvalidationData::create(); | |
| 211 return *addResult.storedValue->value; | |
| 212 } | |
| 213 | |
| 214 } // anonymous namespace | |
| 215 | |
| 203 RuleFeature::RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocume ntSecurityOrigin) | 216 RuleFeature::RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocume ntSecurityOrigin) |
| 204 : rule(rule) | 217 : rule(rule) |
| 205 , selectorIndex(selectorIndex) | 218 , selectorIndex(selectorIndex) |
| 206 , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin) | 219 , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin) |
| 207 { | 220 { |
| 208 } | 221 } |
| 209 | 222 |
| 210 DEFINE_TRACE(RuleFeature) | 223 DEFINE_TRACE(RuleFeature) |
| 211 { | 224 { |
| 212 visitor->trace(rule); | 225 visitor->trace(rule); |
| 213 } | 226 } |
| 214 | 227 |
| 228 RuleFeatureSet::RuleFeatureSet() | |
| 229 { | |
| 230 } | |
| 231 | |
| 232 RuleFeatureSet::~RuleFeatureSet() | |
| 233 { | |
| 234 } | |
| 235 | |
| 236 InvalidationData& RuleFeatureSet::ensureClassInvalidationData(const AtomicString & className) | |
| 237 { | |
| 238 return ensureInvalidationData(m_classInvalidationSets, className); | |
| 239 } | |
| 240 | |
| 241 InvalidationData& RuleFeatureSet::ensureAttributeInvalidationData(const AtomicSt ring& attributeName) | |
| 242 { | |
| 243 return ensureInvalidationData(m_attributeInvalidationSets, attributeName); | |
| 244 } | |
| 245 | |
| 246 InvalidationData& RuleFeatureSet::ensureIdInvalidationData(const AtomicString& i d) | |
| 247 { | |
| 248 return ensureInvalidationData(m_idInvalidationSets, id); | |
| 249 } | |
| 250 | |
| 251 InvalidationData& RuleFeatureSet::ensurePseudoInvalidationData(CSSSelector::Pseu doType pseudoType) | |
| 252 { | |
| 253 return ensureInvalidationData(m_pseudoInvalidationSets, pseudoType); | |
| 254 } | |
| 255 | |
| 215 bool RuleFeatureSet::extractInvalidationSetFeature(const CSSSelector& selector, InvalidationSetFeatures& features) | 256 bool RuleFeatureSet::extractInvalidationSetFeature(const CSSSelector& selector, InvalidationSetFeatures& features) |
| 216 { | 257 { |
| 217 if (selector.match() == CSSSelector::Tag && selector.tagQName().localName() != starAtom) | 258 if (selector.match() == CSSSelector::Tag && selector.tagQName().localName() != starAtom) |
| 218 features.tagName = selector.tagQName().localName(); | 259 features.tagName = selector.tagQName().localName(); |
| 219 else if (selector.match() == CSSSelector::Id) | 260 else if (selector.match() == CSSSelector::Id) |
| 220 features.id = selector.value(); | 261 features.id = selector.value(); |
| 221 else if (selector.match() == CSSSelector::Class) | 262 else if (selector.match() == CSSSelector::Class) |
| 222 features.classes.append(selector.value()); | 263 features.classes.append(selector.value()); |
| 223 else if (selector.isAttributeSelector()) | 264 else if (selector.isAttributeSelector()) |
| 224 features.attributes.append(selector.attribute().localName()); | 265 features.attributes.append(selector.attribute().localName()); |
| 225 else if (selector.pseudoType() == CSSSelector::PseudoWebKitCustomElement) | 266 else if (selector.pseudoType() == CSSSelector::PseudoWebKitCustomElement) |
| 226 features.customPseudoElement = true; | 267 features.customPseudoElement = true; |
| 227 else if (selector.pseudoType() == CSSSelector::PseudoBefore || selector.pseu doType() == CSSSelector::PseudoAfter) | 268 else if (selector.pseudoType() == CSSSelector::PseudoBefore || selector.pseu doType() == CSSSelector::PseudoAfter) |
| 228 features.hasBeforeOrAfter = true; | 269 features.hasBeforeOrAfter = true; |
| 229 else | 270 else |
| 230 return false; | 271 return false; |
| 231 return true; | 272 return true; |
| 232 } | 273 } |
| 233 | 274 |
| 234 RuleFeatureSet::RuleFeatureSet() | 275 InvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& s elector, InvalidationType type) |
| 235 { | |
| 236 } | |
| 237 | |
| 238 RuleFeatureSet::~RuleFeatureSet() | |
| 239 { | |
| 240 } | |
| 241 | |
| 242 InvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& s elector) | |
| 243 { | 276 { |
| 244 if (selector.match() == CSSSelector::Class) | 277 if (selector.match() == CSSSelector::Class) |
| 245 return &ensureClassInvalidationSet(selector.value()); | 278 return &ensureClassInvalidationSet(selector.value(), type); |
| 246 if (selector.isAttributeSelector()) | 279 if (selector.isAttributeSelector()) |
| 247 return &ensureAttributeInvalidationSet(selector.attribute().localName()) ; | 280 return &ensureAttributeInvalidationSet(selector.attribute().localName(), type); |
| 248 if (selector.match() == CSSSelector::Id) | 281 if (selector.match() == CSSSelector::Id) |
| 249 return &ensureIdInvalidationSet(selector.value()); | 282 return &ensureIdInvalidationSet(selector.value(), type); |
| 250 if (selector.match() == CSSSelector::PseudoClass) { | 283 if (selector.match() == CSSSelector::PseudoClass) { |
| 251 switch (selector.pseudoType()) { | 284 switch (selector.pseudoType()) { |
| 252 case CSSSelector::PseudoEmpty: | 285 case CSSSelector::PseudoEmpty: |
| 253 case CSSSelector::PseudoLink: | 286 case CSSSelector::PseudoLink: |
| 254 case CSSSelector::PseudoVisited: | 287 case CSSSelector::PseudoVisited: |
| 255 case CSSSelector::PseudoAnyLink: | 288 case CSSSelector::PseudoAnyLink: |
| 256 case CSSSelector::PseudoAutofill: | 289 case CSSSelector::PseudoAutofill: |
| 257 case CSSSelector::PseudoHover: | 290 case CSSSelector::PseudoHover: |
| 258 case CSSSelector::PseudoFocus: | 291 case CSSSelector::PseudoFocus: |
| 259 case CSSSelector::PseudoActive: | 292 case CSSSelector::PseudoActive: |
| 260 case CSSSelector::PseudoChecked: | 293 case CSSSelector::PseudoChecked: |
| 261 case CSSSelector::PseudoEnabled: | 294 case CSSSelector::PseudoEnabled: |
| 262 case CSSSelector::PseudoDisabled: | 295 case CSSSelector::PseudoDisabled: |
| 263 case CSSSelector::PseudoOptional: | 296 case CSSSelector::PseudoOptional: |
| 264 case CSSSelector::PseudoPlaceholderShown: | 297 case CSSSelector::PseudoPlaceholderShown: |
| 265 case CSSSelector::PseudoRequired: | 298 case CSSSelector::PseudoRequired: |
| 266 case CSSSelector::PseudoValid: | 299 case CSSSelector::PseudoValid: |
| 267 case CSSSelector::PseudoInvalid: | 300 case CSSSelector::PseudoInvalid: |
| 268 case CSSSelector::PseudoIndeterminate: | 301 case CSSSelector::PseudoIndeterminate: |
| 269 case CSSSelector::PseudoTarget: | 302 case CSSSelector::PseudoTarget: |
| 270 return &ensurePseudoInvalidationSet(selector.pseudoType()); | 303 return &ensurePseudoInvalidationSet(selector.pseudoType(), type); |
| 271 default: | 304 default: |
| 272 break; | 305 break; |
| 273 } | 306 } |
| 274 } | 307 } |
| 275 return nullptr; | 308 return nullptr; |
| 276 } | 309 } |
| 277 | 310 |
| 278 // Given a rule, update the descendant invalidation sets for the features found | 311 // Given a rule, update the descendant invalidation sets for the features found |
| 279 // in its selector. The first step is to extract the features from the rightmost | 312 // in its selector. The first step is to extract the features from the rightmost |
| 280 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu res | 313 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu res |
| 281 // to the invalidation sets for the features found in the other compound selecto rs | 314 // to the invalidation sets for the features found in the other compound selecto rs |
| 282 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compo und | 315 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compo und |
| 283 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the | 316 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the |
| 284 // rightmost compound selector as well. | 317 // rightmost compound selector as well. |
| 285 | 318 |
| 286 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) | 319 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) |
| 287 { | 320 { |
| 288 InvalidationSetFeatures features; | 321 InvalidationSetFeatures features; |
| 289 auto result = extractInvalidationSetFeatures(ruleData.selector(), features, false); | 322 auto result = extractInvalidationSetFeatures(ruleData.selector(), features, false); |
| 323 | |
| 290 if (result.first) { | 324 if (result.first) { |
| 291 features.forceSubtree = result.second == ForceSubtree; | 325 features.forceSubtree = result.second == ForceSubtree; |
| 292 addFeaturesToInvalidationSets(*result.first, features); | 326 addFeaturesToInvalidationSets(result.first, features.adjacent ? &feature s : nullptr, features); |
| 293 } | 327 } |
| 294 | 328 |
| 295 // If any ::before and ::after rules specify 'content: attr(...)', we | 329 // If any ::before and ::after rules specify 'content: attr(...)', we |
| 296 // need to create invalidation sets for those attributes. | 330 // need to create invalidation sets for those attributes. |
| 297 if (features.hasBeforeOrAfter) | 331 if (features.hasBeforeOrAfter) |
| 298 updateInvalidationSetsForContentAttribute(ruleData); | 332 updateInvalidationSetsForContentAttribute(ruleData); |
| 299 } | 333 } |
| 300 | 334 |
| 301 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r uleData) | 335 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r uleData) |
| 302 { | 336 { |
| 303 const StylePropertySet& propertySet = ruleData.rule()->properties(); | 337 const StylePropertySet& propertySet = ruleData.rule()->properties(); |
| 304 | 338 |
| 305 int propertyIndex = propertySet.findPropertyIndex(CSSPropertyContent); | 339 int propertyIndex = propertySet.findPropertyIndex(CSSPropertyContent); |
| 306 | 340 |
| 307 if (propertyIndex == -1) | 341 if (propertyIndex == -1) |
| 308 return; | 342 return; |
| 309 | 343 |
| 310 StylePropertySet::PropertyReference contentProperty = propertySet.propertyAt (propertyIndex); | 344 StylePropertySet::PropertyReference contentProperty = propertySet.propertyAt (propertyIndex); |
| 311 CSSValue* contentValue = contentProperty.value(); | 345 CSSValue* contentValue = contentProperty.value(); |
| 312 | 346 |
| 313 if (!contentValue->isValueList()) | 347 if (!contentValue->isValueList()) |
| 314 return; | 348 return; |
| 315 | 349 |
| 316 for (auto& item : toCSSValueList(*contentValue)) { | 350 for (auto& item : toCSSValueList(*contentValue)) { |
| 317 if (!item->isFunctionValue()) | 351 if (!item->isFunctionValue()) |
| 318 continue; | 352 continue; |
| 319 CSSFunctionValue* functionValue = toCSSFunctionValue(item.get()); | 353 CSSFunctionValue* functionValue = toCSSFunctionValue(item.get()); |
| 320 if (functionValue->functionType() != CSSValueAttr) | 354 if (functionValue->functionType() != CSSValueAttr) |
| 321 continue; | 355 continue; |
| 322 ensureAttributeInvalidationSet(AtomicString(toCSSCustomIdentValue(functi onValue->item(0))->value())).setInvalidatesSelf(); | 356 ensureAttributeInvalidationSet(AtomicString(toCSSCustomIdentValue(functi onValue->item(0))->value()), InvalidateDescendants).setInvalidatesSelf(); |
| 323 } | 357 } |
| 324 } | 358 } |
| 325 | 359 |
| 326 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType> | 360 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType> |
| 327 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva lidationSetFeatures& features, bool negated) | 361 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva lidationSetFeatures& features, bool negated) |
| 328 { | 362 { |
| 329 bool foundFeatures = false; | 363 bool foundFeatures = false; |
| 330 for (const CSSSelector* current = &selector; current; current = current->tag History()) { | 364 for (const CSSSelector* current = &selector; current; current = current->tag History()) { |
| 331 if (!negated) | 365 if (!negated) |
| 332 foundFeatures |= extractInvalidationSetFeature(*current, features); | 366 foundFeatures |= extractInvalidationSetFeature(*current, features); |
| 333 // Initialize the entry in the invalidation set map, if supported. | 367 // Initialize the entry in the invalidation set map, if supported. |
| 334 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt)) { | 368 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, InvalidateDescendants)) { |
| 335 invalidationSet->setInvalidatesSelf(); | 369 invalidationSet->setInvalidatesSelf(); |
| 336 } else { | 370 } else { |
| 337 if (requiresSubtreeInvalidation(*current)) { | 371 if (requiresSubtreeInvalidation(*current)) { |
| 338 // Fall back to use subtree invalidations, even for features in the | 372 // Fall back to use subtree invalidations, even for features in the |
| 339 // rightmost compound selector. Returning the start &selector he re | 373 // rightmost compound selector. Returning the start &selector he re |
| 340 // will make addFeaturesToInvalidationSets start marking invalid ation | 374 // will make addFeaturesToInvalidationSets start marking invalid ation |
| 341 // sets for subtree recalc for features in the rightmost compoun d | 375 // sets for subtree recalc for features in the rightmost compoun d |
| 342 // selector. | 376 // selector. |
| 343 return std::make_pair(&selector, ForceSubtree); | 377 return std::make_pair(&selector, ForceSubtree); |
| 344 } | 378 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 358 } | 392 } |
| 359 foundFeatures |= allSubSelectorsHaveFeatures; | 393 foundFeatures |= allSubSelectorsHaveFeatures; |
| 360 } | 394 } |
| 361 } | 395 } |
| 362 | 396 |
| 363 if (current->relation() == CSSSelector::SubSelector) | 397 if (current->relation() == CSSSelector::SubSelector) |
| 364 continue; | 398 continue; |
| 365 | 399 |
| 366 features.treeBoundaryCrossing = current->isShadowSelector(); | 400 features.treeBoundaryCrossing = current->isShadowSelector(); |
| 367 features.adjacent = current->isAdjacentSelector(); | 401 features.adjacent = current->isAdjacentSelector(); |
| 402 if (current->relation() == CSSSelector::DirectAdjacent) | |
| 403 features.maxDirectAdjacentSelectors = 1; | |
| 368 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree); | 404 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree); |
| 369 } | 405 } |
| 370 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); | 406 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); |
| 371 } | 407 } |
| 372 | 408 |
| 373 // Add features extracted from the rightmost compound selector to descendant inv alidation | 409 // Add features extracted from the rightmost compound selector to descendant inv alidation |
| 374 // sets for features found in other compound selectors. | 410 // sets for features found in other compound selectors. |
| 375 // | 411 // |
| 376 // Style invalidation is currently supported for descendants only, not for sibli ng subtrees. | 412 // We use descendant invalidation for descendants, sibling invalidation for sibl ings and their subtrees. |
| 377 // We use wholeSubtree invalidation for features found left of adjacent combinat ors as | |
| 378 // SubtreeStyleChange will force sibling subtree recalc in | |
| 379 // ContainerNode::checkForChildrenAdjacentRuleChanges. | |
| 380 // | 413 // |
| 381 // As we encounter a descendant type of combinator, the features only need to be checked | 414 // As we encounter a descendant type of combinator, the features only need to be checked |
| 382 // against descendants in the same subtree only. features.adjacent is set to fal se, and | 415 // against descendants in the same subtree only. features.adjacent is set to fal se, and |
| 383 // we start adding features instead of calling setWholeSubtreeInvalid. | 416 // we start adding features to the descendant invalidation set. |
| 384 | 417 |
| 385 void RuleFeatureSet::addFeaturesToInvalidationSet(InvalidationSet& invalidationS et, const InvalidationSetFeatures& features) | 418 void RuleFeatureSet::addFeaturesToInvalidationSet(InvalidationSet& invalidationS et, const InvalidationSetFeatures& features) |
| 386 { | 419 { |
| 387 if (features.treeBoundaryCrossing) | 420 if (features.treeBoundaryCrossing) |
| 388 invalidationSet.setTreeBoundaryCrossing(); | 421 invalidationSet.setTreeBoundaryCrossing(); |
| 389 if (features.insertionPointCrossing) | 422 if (features.insertionPointCrossing) |
| 390 invalidationSet.setInsertionPointCrossing(); | 423 invalidationSet.setInsertionPointCrossing(); |
| 391 if (features.useSubtreeInvalidation()) { | 424 if (features.forceSubtree) { |
| 392 invalidationSet.setWholeSubtreeInvalid(); | 425 invalidationSet.setWholeSubtreeInvalid(); |
| 393 return; | 426 return; |
| 394 } | 427 } |
| 395 if (!features.id.isEmpty()) | 428 if (!features.id.isEmpty()) |
| 396 invalidationSet.addId(features.id); | 429 invalidationSet.addId(features.id); |
| 397 if (!features.tagName.isEmpty()) | 430 if (!features.tagName.isEmpty()) |
| 398 invalidationSet.addTagName(features.tagName); | 431 invalidationSet.addTagName(features.tagName); |
| 399 for (const auto& className : features.classes) | 432 for (const auto& className : features.classes) |
| 400 invalidationSet.addClass(className); | 433 invalidationSet.addClass(className); |
| 401 for (const auto& attribute : features.attributes) | 434 for (const auto& attribute : features.attributes) |
| 402 invalidationSet.addAttribute(attribute); | 435 invalidationSet.addAttribute(attribute); |
| 403 if (features.customPseudoElement) | 436 if (features.customPseudoElement) |
| 404 invalidationSet.setCustomPseudoInvalid(); | 437 invalidationSet.setCustomPseudoInvalid(); |
| 405 } | 438 } |
| 406 | 439 |
| 407 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector, InvalidationSetFeatures& features) | 440 // selector is the selector immediately to the left of the rightmost combinator. |
| 441 // siblingFeatures is null if selector is not immediately to the left of a sibli ng combinator. | |
| 442 // descendantFeatures has the features of the rightmost compound selector. | |
| 443 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector, InvalidationSetFeatures* siblingFeatures, InvalidationSetFeatures& descendantFea tures) | |
| 408 { | 444 { |
| 409 for (const CSSSelector* current = &selector; current; current = current->tag History()) { | 445 const CSSSelector* lastCompoundSelectorInAdjacentChain = selector; |
| 410 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt)) { | 446 |
| 411 addFeaturesToInvalidationSet(*invalidationSet, features); | 447 // We set siblingFeatures to &localFeatures if we find a rightmost sibling c ombinator. |
| 448 InvalidationSetFeatures localFeatures; | |
| 449 | |
| 450 for (const CSSSelector* current = selector; current; current = current->tagH istory()) { | |
| 451 InvalidationType type = siblingFeatures ? InvalidateSiblings : Invalidat eDescendants; | |
| 452 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, type)) { | |
| 453 if (siblingFeatures) { | |
| 454 SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvali dationSet(invalidationSet); | |
| 455 siblingInvalidationSet->updateMaxDirectAdjacentSelectors(sibling Features->maxDirectAdjacentSelectors); | |
| 456 | |
| 457 addFeaturesToInvalidationSet(*invalidationSet, *siblingFeatures) ; | |
| 458 if (siblingFeatures == &descendantFeatures) | |
| 459 siblingInvalidationSet->descendants().setInvalidatesSelf(); | |
| 460 else | |
| 461 addFeaturesToInvalidationSet(siblingInvalidationSet->descend ants(), descendantFeatures); | |
| 462 } else { | |
| 463 addFeaturesToInvalidationSet(*invalidationSet, descendantFeature s); | |
| 464 } | |
| 412 } else { | 465 } else { |
| 413 if (current->isTreeBoundaryCrossing()) | 466 if (current->isTreeBoundaryCrossing()) |
| 414 features.treeBoundaryCrossing = true; | 467 descendantFeatures.treeBoundaryCrossing = true; |
| 415 if (current->isInsertionPointCrossing()) | 468 if (current->isInsertionPointCrossing()) |
| 416 features.insertionPointCrossing = true; | 469 descendantFeatures.insertionPointCrossing = true; |
| 417 if (const CSSSelectorList* selectorList = current->selectorList()) { | 470 if (const CSSSelectorList* selectorList = current->selectorList()) { |
| 418 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType( ))); | 471 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType( ))); |
| 419 for (const CSSSelector* subSelector = selectorList->first(); sub Selector; subSelector = CSSSelectorList::next(*subSelector)) | 472 for (const CSSSelector* subSelector = selectorList->first(); sub Selector; subSelector = CSSSelectorList::next(*subSelector)) |
| 420 addFeaturesToInvalidationSets(*subSelector, features); | 473 addFeaturesToInvalidationSets(subSelector, siblingFeatures, descendantFeatures); |
| 421 } | 474 } |
| 422 } | 475 } |
| 423 | 476 |
| 424 if (current->relation() == CSSSelector::SubSelector) | 477 if (current->relation() == CSSSelector::SubSelector) |
| 425 continue; | 478 continue; |
| 426 | 479 |
| 427 if (current->isShadowSelector()) | 480 if (current->isShadowSelector()) |
| 428 features.treeBoundaryCrossing = true; | 481 descendantFeatures.treeBoundaryCrossing = true; |
| 429 | 482 |
| 430 features.adjacent = current->isAdjacentSelector(); | 483 if (!current->isAdjacentSelector()) { |
| 484 lastCompoundSelectorInAdjacentChain = current->tagHistory(); | |
| 485 siblingFeatures = nullptr; | |
| 486 continue; | |
| 487 } | |
| 488 | |
| 489 if (siblingFeatures) { | |
| 490 if (siblingFeatures->maxDirectAdjacentSelectors == std::numeric_limi ts<unsigned>::max()) | |
| 491 continue; | |
| 492 | |
| 493 if (current->relation() == CSSSelector::DirectAdjacent) | |
| 494 siblingFeatures->maxDirectAdjacentSelectors++; | |
| 495 else | |
| 496 siblingFeatures->maxDirectAdjacentSelectors = std::numeric_limit s<unsigned>::max(); | |
|
esprehn
2015/10/26 21:20:14
I'd just use UINT_MAX for all of these, this std::
Eric Willigers
2015/10/28 23:09:08
Done. https://codereview.chromium.org/1424783003/
| |
| 497 continue; | |
| 498 } | |
| 499 | |
| 500 localFeatures = InvalidationSetFeatures(); | |
| 501 auto result = extractInvalidationSetFeatures(*lastCompoundSelectorInAdja centChain, localFeatures, false); | |
| 502 ASSERT(result.first); | |
| 503 localFeatures.forceSubtree = result.second == ForceSubtree; | |
| 504 siblingFeatures = &localFeatures; | |
| 431 } | 505 } |
| 432 } | 506 } |
| 433 | 507 |
| 434 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData) | 508 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData) |
| 435 { | 509 { |
| 436 updateInvalidationSets(ruleData); | 510 updateInvalidationSets(ruleData); |
| 437 | 511 |
| 438 FeatureMetadata metadata; | 512 FeatureMetadata metadata; |
| 439 collectFeaturesFromSelector(ruleData.selector(), metadata); | 513 collectFeaturesFromSelector(ruleData.selector(), metadata); |
| 440 m_metadata.add(metadata); | 514 m_metadata.add(metadata); |
| 441 | 515 |
| 442 if (metadata.foundSiblingSelector) | 516 if (metadata.foundSiblingSelector) |
| 443 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin())); | 517 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin())); |
| 444 if (ruleData.containsUncommonAttributeSelector()) | 518 if (ruleData.containsUncommonAttributeSelector()) |
| 445 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin())); | 519 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin())); |
| 446 } | 520 } |
| 447 | 521 |
| 448 InvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const AtomicString& className) | |
| 449 { | |
| 450 InvalidationSetMap::AddResult addResult = m_classInvalidationSets.add(classN ame, nullptr); | |
| 451 if (addResult.isNewEntry) | |
| 452 addResult.storedValue->value = InvalidationSet::create(); | |
| 453 return *addResult.storedValue->value; | |
| 454 } | |
| 455 | |
| 456 InvalidationSet& RuleFeatureSet::ensureAttributeInvalidationSet(const AtomicStri ng& attributeName) | |
| 457 { | |
| 458 InvalidationSetMap::AddResult addResult = m_attributeInvalidationSets.add(at tributeName, nullptr); | |
| 459 if (addResult.isNewEntry) | |
| 460 addResult.storedValue->value = InvalidationSet::create(); | |
| 461 return *addResult.storedValue->value; | |
| 462 } | |
| 463 | |
| 464 InvalidationSet& RuleFeatureSet::ensureIdInvalidationSet(const AtomicString& id) | |
| 465 { | |
| 466 InvalidationSetMap::AddResult addResult = m_idInvalidationSets.add(id, nullp tr); | |
| 467 if (addResult.isNewEntry) | |
| 468 addResult.storedValue->value = InvalidationSet::create(); | |
| 469 return *addResult.storedValue->value; | |
| 470 } | |
| 471 | |
| 472 InvalidationSet& RuleFeatureSet::ensurePseudoInvalidationSet(CSSSelector::Pseudo Type pseudoType) | |
| 473 { | |
| 474 PseudoTypeInvalidationSetMap::AddResult addResult = m_pseudoInvalidationSets .add(pseudoType, nullptr); | |
| 475 if (addResult.isNewEntry) | |
| 476 addResult.storedValue->value = InvalidationSet::create(); | |
| 477 return *addResult.storedValue->value; | |
| 478 } | |
| 479 | |
| 480 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata) | 522 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata) |
| 481 { | 523 { |
| 482 unsigned maxDirectAdjacentSelectors = 0; | 524 unsigned maxDirectAdjacentSelectors = 0; |
| 483 | 525 |
| 484 for (const CSSSelector* current = &selector; current; current = current->tag History()) { | 526 for (const CSSSelector* current = &selector; current; current = current->tag History()) { |
| 485 if (current->pseudoType() == CSSSelector::PseudoFirstLine) | 527 if (current->pseudoType() == CSSSelector::PseudoFirstLine) |
| 486 metadata.usesFirstLineRules = true; | 528 metadata.usesFirstLineRules = true; |
| 487 if (current->pseudoType() == CSSSelector::PseudoWindowInactive) | 529 if (current->pseudoType() == CSSSelector::PseudoWindowInactive) |
| 488 metadata.usesWindowInactiveSelector = true; | 530 metadata.usesWindowInactiveSelector = true; |
| 489 if (current->relation() == CSSSelector::DirectAdjacent) { | 531 if (current->relation() == CSSSelector::DirectAdjacent) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 518 void RuleFeatureSet::FeatureMetadata::clear() | 560 void RuleFeatureSet::FeatureMetadata::clear() |
| 519 { | 561 { |
| 520 usesFirstLineRules = false; | 562 usesFirstLineRules = false; |
| 521 usesWindowInactiveSelector = false; | 563 usesWindowInactiveSelector = false; |
| 522 foundSiblingSelector = false; | 564 foundSiblingSelector = false; |
| 523 maxDirectAdjacentSelectors = 0; | 565 maxDirectAdjacentSelectors = 0; |
| 524 } | 566 } |
| 525 | 567 |
| 526 void RuleFeatureSet::add(const RuleFeatureSet& other) | 568 void RuleFeatureSet::add(const RuleFeatureSet& other) |
| 527 { | 569 { |
| 528 for (const auto& invalidationSet : other.m_classInvalidationSets) | 570 for (const auto& entry : other.m_classInvalidationSets) |
| 529 ensureClassInvalidationSet(invalidationSet.key).combine(*invalidationSet .value); | 571 ensureClassInvalidationData(entry.key).combine(*entry.value); |
| 530 for (const auto& invalidationSet : other.m_attributeInvalidationSets) | 572 for (const auto& entry : other.m_attributeInvalidationSets) |
| 531 ensureAttributeInvalidationSet(invalidationSet.key).combine(*invalidatio nSet.value); | 573 ensureAttributeInvalidationData(entry.key).combine(*entry.value); |
| 532 for (const auto& invalidationSet : other.m_idInvalidationSets) | 574 for (const auto& entry : other.m_idInvalidationSets) |
| 533 ensureIdInvalidationSet(invalidationSet.key).combine(*invalidationSet.va lue); | 575 ensureIdInvalidationData(entry.key).combine(*entry.value); |
| 534 for (const auto& invalidationSet : other.m_pseudoInvalidationSets) | 576 for (const auto& entry : other.m_pseudoInvalidationSets) |
| 535 ensurePseudoInvalidationSet(static_cast<CSSSelector::PseudoType>(invalid ationSet.key)).combine(*invalidationSet.value); | 577 ensurePseudoInvalidationData(static_cast<CSSSelector::PseudoType>(entry. key)).combine(*entry.value); |
| 536 | 578 |
| 537 m_metadata.add(other.m_metadata); | 579 m_metadata.add(other.m_metadata); |
| 538 | 580 |
| 539 siblingRules.appendVector(other.siblingRules); | 581 siblingRules.appendVector(other.siblingRules); |
| 540 uncommonAttributeRules.appendVector(other.uncommonAttributeRules); | 582 uncommonAttributeRules.appendVector(other.uncommonAttributeRules); |
| 541 } | 583 } |
| 542 | 584 |
| 543 void RuleFeatureSet::clear() | 585 void RuleFeatureSet::clear() |
| 544 { | 586 { |
| 545 siblingRules.clear(); | 587 siblingRules.clear(); |
| 546 uncommonAttributeRules.clear(); | 588 uncommonAttributeRules.clear(); |
| 547 m_metadata.clear(); | 589 m_metadata.clear(); |
| 548 m_classInvalidationSets.clear(); | 590 m_classInvalidationSets.clear(); |
| 549 m_attributeInvalidationSets.clear(); | 591 m_attributeInvalidationSets.clear(); |
| 550 m_idInvalidationSets.clear(); | 592 m_idInvalidationSets.clear(); |
| 551 m_pseudoInvalidationSets.clear(); | 593 m_pseudoInvalidationSets.clear(); |
| 552 } | 594 } |
| 553 | 595 |
| 554 void RuleFeatureSet::collectInvalidationSetsForClass(InvalidationSetVector& inva lidationSets, Element& element, const AtomicString& className) const | 596 void RuleFeatureSet::collectInvalidationSetsForClass(InvalidationLists& invalida tionLists, Element& element, const AtomicString& className) const |
| 555 { | 597 { |
| 556 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_classInvalidatio nSets.get(className)) { | 598 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_classInvalidat ionSets.get(className)) { |
| 557 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, classChange , className); | 599 if (invalidationData->descendants()) { |
| 558 invalidationSets.append(invalidationSet); | 600 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), classChange, className); |
| 601 invalidationLists.descendants.append(invalidationData->descendants() ); | |
| 602 } | |
| 603 if (invalidationData->siblings()) { | |
| 604 if (element.parentElement()) | |
|
esprehn
2015/10/26 21:20:14
Why are you checking parentElement()? For what rea
| |
| 605 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), classChange, className); | |
| 606 invalidationLists.siblings.append(invalidationData->siblings()); | |
| 607 } | |
| 559 } | 608 } |
| 560 } | 609 } |
| 561 | 610 |
| 562 void RuleFeatureSet::collectInvalidationSetsForId(InvalidationSetVector& invalid ationSets, Element& element, const AtomicString& id) const | 611 void RuleFeatureSet::collectInvalidationSetsForId(InvalidationLists& invalidatio nLists, Element& element, const AtomicString& id) const |
| 563 { | 612 { |
| 564 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_idInvalidationSe ts.get(id)) { | 613 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_idInvalidation Sets.get(id)) { |
| 565 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, idChange, i d); | 614 if (invalidationData->descendants()) { |
| 566 invalidationSets.append(invalidationSet); | 615 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), idChange, id); |
| 616 invalidationLists.descendants.append(invalidationData->descendants() ); | |
| 617 } | |
| 618 if (invalidationData->siblings()) { | |
| 619 if (element.parentElement()) | |
|
esprehn
2015/10/26 21:20:14
ditto, this parentElement() check doesn't seem rig
| |
| 620 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), idChange, id); | |
| 621 invalidationLists.siblings.append(invalidationData->siblings()); | |
| 622 } | |
| 567 } | 623 } |
| 568 } | 624 } |
| 569 | 625 |
| 570 void RuleFeatureSet::collectInvalidationSetsForAttribute(InvalidationSetVector& invalidationSets, Element& element, const QualifiedName& attributeName) const | 626 void RuleFeatureSet::collectInvalidationSetsForAttribute(InvalidationLists& inva lidationLists, Element& element, const QualifiedName& attributeName) const |
| 571 { | 627 { |
| 572 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_attributeInvalid ationSets.get(attributeName.localName())) { | 628 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_attributeInval idationSets.get(attributeName.localName())) { |
| 573 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, attributeCh ange, attributeName); | 629 if (invalidationData->descendants()) { |
| 574 invalidationSets.append(invalidationSet); | 630 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), attributeChange, attributeName); |
| 631 invalidationLists.descendants.append(invalidationData->descendants() ); | |
| 632 } | |
| 633 if (invalidationData->siblings()) { | |
| 634 if (element.parentElement()) | |
|
esprehn
2015/10/26 21:20:14
ditto
| |
| 635 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), attributeChange, attributeName); | |
| 636 invalidationLists.siblings.append(invalidationData->siblings()); | |
| 637 } | |
| 575 } | 638 } |
| 576 } | 639 } |
| 577 | 640 |
| 578 void RuleFeatureSet::collectInvalidationSetsForPseudoClass(InvalidationSetVector & invalidationSets, Element& element, CSSSelector::PseudoType pseudo) const | 641 void RuleFeatureSet::collectInvalidationSetsForPseudoClass(InvalidationLists& in validationLists, Element& element, CSSSelector::PseudoType pseudo) const |
| 579 { | 642 { |
| 580 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_pseudoInvalidati onSets.get(pseudo)) { | 643 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_pseudoInvalida tionSets.get(pseudo)) { |
| 581 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, pseudoChang e, pseudo); | 644 if (invalidationData->descendants()) { |
| 582 invalidationSets.append(invalidationSet); | 645 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), pseudoChange, pseudo); |
| 646 invalidationLists.descendants.append(invalidationData->descendants() ); | |
| 647 } | |
| 648 if (invalidationData->siblings()) { | |
| 649 if (element.parentElement()) | |
|
esprehn
2015/10/26 21:20:14
ditto
| |
| 650 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), pseudoChange, pseudo); | |
| 651 invalidationLists.siblings.append(invalidationData->siblings()); | |
| 652 } | |
| 583 } | 653 } |
| 584 } | 654 } |
| 585 | 655 |
| 586 DEFINE_TRACE(RuleFeatureSet) | 656 DEFINE_TRACE(RuleFeatureSet) |
| 587 { | 657 { |
| 588 #if ENABLE(OILPAN) | 658 #if ENABLE(OILPAN) |
| 589 visitor->trace(siblingRules); | 659 visitor->trace(siblingRules); |
| 590 visitor->trace(uncommonAttributeRules); | 660 visitor->trace(uncommonAttributeRules); |
| 591 #endif | 661 #endif |
| 592 } | 662 } |
| 593 | 663 |
| 594 } // namespace blink | 664 } // namespace blink |
| OLD | NEW |