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 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 } | 231 } |
| 232 | 232 |
| 233 RuleFeatureSet::RuleFeatureSet() | 233 RuleFeatureSet::RuleFeatureSet() |
| 234 { | 234 { |
| 235 } | 235 } |
| 236 | 236 |
| 237 RuleFeatureSet::~RuleFeatureSet() | 237 RuleFeatureSet::~RuleFeatureSet() |
| 238 { | 238 { |
| 239 } | 239 } |
| 240 | 240 |
| 241 InvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& s elector) | 241 InvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& s elector, InvalidationType type) |
| 242 { | 242 { |
| 243 if (selector.match() == CSSSelector::Class) | 243 if (selector.match() == CSSSelector::Class) |
| 244 return &ensureClassInvalidationSet(selector.value()); | 244 return &ensureClassInvalidationSet(selector.value(), type); |
| 245 if (selector.isAttributeSelector()) | 245 if (selector.isAttributeSelector()) |
| 246 return &ensureAttributeInvalidationSet(selector.attribute().localName()) ; | 246 return &ensureAttributeInvalidationSet(selector.attribute().localName(), type); |
| 247 if (selector.match() == CSSSelector::Id) | 247 if (selector.match() == CSSSelector::Id) |
| 248 return &ensureIdInvalidationSet(selector.value()); | 248 return &ensureIdInvalidationSet(selector.value(), type); |
| 249 if (selector.match() == CSSSelector::PseudoClass) { | 249 if (selector.match() == CSSSelector::PseudoClass) { |
| 250 switch (selector.pseudoType()) { | 250 switch (selector.pseudoType()) { |
| 251 case CSSSelector::PseudoEmpty: | 251 case CSSSelector::PseudoEmpty: |
| 252 case CSSSelector::PseudoLink: | 252 case CSSSelector::PseudoLink: |
| 253 case CSSSelector::PseudoVisited: | 253 case CSSSelector::PseudoVisited: |
| 254 case CSSSelector::PseudoAnyLink: | 254 case CSSSelector::PseudoAnyLink: |
| 255 case CSSSelector::PseudoAutofill: | 255 case CSSSelector::PseudoAutofill: |
| 256 case CSSSelector::PseudoHover: | 256 case CSSSelector::PseudoHover: |
| 257 case CSSSelector::PseudoFocus: | 257 case CSSSelector::PseudoFocus: |
| 258 case CSSSelector::PseudoActive: | 258 case CSSSelector::PseudoActive: |
| 259 case CSSSelector::PseudoChecked: | 259 case CSSSelector::PseudoChecked: |
| 260 case CSSSelector::PseudoEnabled: | 260 case CSSSelector::PseudoEnabled: |
| 261 case CSSSelector::PseudoDisabled: | 261 case CSSSelector::PseudoDisabled: |
| 262 case CSSSelector::PseudoOptional: | 262 case CSSSelector::PseudoOptional: |
| 263 case CSSSelector::PseudoPlaceholderShown: | 263 case CSSSelector::PseudoPlaceholderShown: |
| 264 case CSSSelector::PseudoRequired: | 264 case CSSSelector::PseudoRequired: |
| 265 case CSSSelector::PseudoValid: | 265 case CSSSelector::PseudoValid: |
| 266 case CSSSelector::PseudoInvalid: | 266 case CSSSelector::PseudoInvalid: |
| 267 case CSSSelector::PseudoIndeterminate: | 267 case CSSSelector::PseudoIndeterminate: |
| 268 case CSSSelector::PseudoTarget: | 268 case CSSSelector::PseudoTarget: |
| 269 return &ensurePseudoInvalidationSet(selector.pseudoType()); | 269 return &ensurePseudoInvalidationSet(selector.pseudoType(), type); |
| 270 default: | 270 default: |
| 271 break; | 271 break; |
| 272 } | 272 } |
| 273 } | 273 } |
| 274 return nullptr; | 274 return nullptr; |
| 275 } | 275 } |
| 276 | 276 |
| 277 // Given a rule, update the descendant invalidation sets for the features found | 277 // Given a rule, update the descendant invalidation sets for the features found |
| 278 // in its selector. The first step is to extract the features from the rightmost | 278 // in its selector. The first step is to extract the features from the rightmost |
| 279 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu res | 279 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu res |
| 280 // to the invalidation sets for the features found in the other compound selecto rs | 280 // to the invalidation sets for the features found in the other compound selecto rs |
| 281 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compo und | 281 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compo und |
| 282 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the | 282 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the |
| 283 // rightmost compound selector as well. | 283 // rightmost compound selector as well. |
| 284 | 284 |
| 285 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) | 285 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) |
| 286 { | 286 { |
| 287 InvalidationSetFeatures features; | 287 InvalidationSetFeatures features; |
| 288 auto result = extractInvalidationSetFeatures(ruleData.selector(), features, false); | 288 auto result = extractInvalidationSetFeatures(ruleData.selector(), features, false); |
| 289 | |
| 289 if (result.first) { | 290 if (result.first) { |
| 290 features.forceSubtree = result.second == ForceSubtree; | 291 features.forceSubtree = result.second == ForceSubtree; |
| 291 addFeaturesToInvalidationSets(*result.first, features); | 292 addFeaturesToInvalidationSets(result.first, features.adjacent ? &feature s : nullptr, features); |
| 292 } | 293 } |
| 293 | 294 |
| 294 // If any ::before and ::after rules specify 'content: attr(...)', we | 295 // If any ::before and ::after rules specify 'content: attr(...)', we |
| 295 // need to create invalidation sets for those attributes. | 296 // need to create invalidation sets for those attributes. |
| 296 if (features.hasBeforeOrAfter) | 297 if (features.hasBeforeOrAfter) |
| 297 updateInvalidationSetsForContentAttribute(ruleData); | 298 updateInvalidationSetsForContentAttribute(ruleData); |
| 298 } | 299 } |
| 299 | 300 |
| 300 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r uleData) | 301 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r uleData) |
| 301 { | 302 { |
| 302 const StylePropertySet& propertySet = ruleData.rule()->properties(); | 303 const StylePropertySet& propertySet = ruleData.rule()->properties(); |
| 303 | 304 |
| 304 int propertyIndex = propertySet.findPropertyIndex(CSSPropertyContent); | 305 int propertyIndex = propertySet.findPropertyIndex(CSSPropertyContent); |
| 305 | 306 |
| 306 if (propertyIndex == -1) | 307 if (propertyIndex == -1) |
| 307 return; | 308 return; |
| 308 | 309 |
| 309 StylePropertySet::PropertyReference contentProperty = propertySet.propertyAt (propertyIndex); | 310 StylePropertySet::PropertyReference contentProperty = propertySet.propertyAt (propertyIndex); |
| 310 CSSValue* contentValue = contentProperty.value(); | 311 CSSValue* contentValue = contentProperty.value(); |
| 311 | 312 |
| 312 if (!contentValue->isValueList()) | 313 if (!contentValue->isValueList()) |
| 313 return; | 314 return; |
| 314 | 315 |
| 315 for (auto& item : toCSSValueList(*contentValue)) { | 316 for (auto& item : toCSSValueList(*contentValue)) { |
| 316 if (!item->isFunctionValue()) | 317 if (!item->isFunctionValue()) |
| 317 continue; | 318 continue; |
| 318 CSSFunctionValue* functionValue = toCSSFunctionValue(item.get()); | 319 CSSFunctionValue* functionValue = toCSSFunctionValue(item.get()); |
| 319 if (functionValue->functionType() != CSSValueAttr) | 320 if (functionValue->functionType() != CSSValueAttr) |
| 320 continue; | 321 continue; |
| 321 ensureAttributeInvalidationSet(AtomicString(toCSSPrimitiveValue(function Value->item(0))->getStringValue())).setInvalidatesSelf(); | 322 ensureAttributeInvalidationSet(AtomicString(toCSSPrimitiveValue(function Value->item(0))->getStringValue()), InvalidateDescendants).setInvalidatesSelf(); |
| 322 } | 323 } |
| 323 } | 324 } |
| 324 | 325 |
| 325 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType> | 326 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType> |
| 326 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva lidationSetFeatures& features, bool negated) | 327 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva lidationSetFeatures& features, bool negated) |
| 327 { | 328 { |
| 328 bool foundFeatures = false; | 329 bool foundFeatures = false; |
| 329 for (const CSSSelector* current = &selector; current; current = current->tag History()) { | 330 for (const CSSSelector* current = &selector; current; current = current->tag History()) { |
| 330 if (!negated) | 331 if (!negated) |
| 331 foundFeatures |= extractInvalidationSetFeature(*current, features); | 332 foundFeatures |= extractInvalidationSetFeature(*current, features); |
| 332 // Initialize the entry in the invalidation set map, if supported. | 333 // Initialize the entry in the invalidation set map, if supported. |
| 333 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt)) { | 334 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, InvalidateDescendants)) { |
| 334 invalidationSet->setInvalidatesSelf(); | 335 invalidationSet->setInvalidatesSelf(); |
| 335 } else { | 336 } else { |
| 336 if (requiresSubtreeInvalidation(*current)) { | 337 if (requiresSubtreeInvalidation(*current)) { |
| 337 // Fall back to use subtree invalidations, even for features in the | 338 // Fall back to use subtree invalidations, even for features in the |
| 338 // rightmost compound selector. Returning the start &selector he re | 339 // rightmost compound selector. Returning the start &selector he re |
| 339 // will make addFeaturesToInvalidationSets start marking invalid ation | 340 // will make addFeaturesToInvalidationSets start marking invalid ation |
| 340 // sets for subtree recalc for features in the rightmost compoun d | 341 // sets for subtree recalc for features in the rightmost compoun d |
| 341 // selector. | 342 // selector. |
| 342 return std::make_pair(&selector, ForceSubtree); | 343 return std::make_pair(&selector, ForceSubtree); |
| 343 } | 344 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 357 } | 358 } |
| 358 foundFeatures |= allSubSelectorsHaveFeatures; | 359 foundFeatures |= allSubSelectorsHaveFeatures; |
| 359 } | 360 } |
| 360 } | 361 } |
| 361 | 362 |
| 362 if (current->relation() == CSSSelector::SubSelector) | 363 if (current->relation() == CSSSelector::SubSelector) |
| 363 continue; | 364 continue; |
| 364 | 365 |
| 365 features.treeBoundaryCrossing = current->isShadowSelector(); | 366 features.treeBoundaryCrossing = current->isShadowSelector(); |
| 366 features.adjacent = current->isAdjacentSelector(); | 367 features.adjacent = current->isAdjacentSelector(); |
| 368 if (current->relation() == CSSSelector::DirectAdjacent) | |
| 369 features.maxDirectAdjacentSelectors = 1; | |
| 367 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree); | 370 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree); |
| 368 } | 371 } |
| 369 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); | 372 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); |
| 370 } | 373 } |
| 371 | 374 |
| 372 // Add features extracted from the rightmost compound selector to descendant inv alidation | 375 // Add features extracted from the rightmost compound selector to descendant inv alidation |
| 373 // sets for features found in other compound selectors. | 376 // sets for features found in other compound selectors. |
| 374 // | 377 // |
| 375 // Style invalidation is currently supported for descendants only, not for sibli ng subtrees. | 378 // We use descendant invalidation for descendants, sibling invalidation for sibl ings and their subtrees. |
| 376 // We use wholeSubtree invalidation for features found left of adjacent combinat ors as | |
| 377 // SubtreeStyleChange will force sibling subtree recalc in | |
| 378 // ContainerNode::checkForChildrenAdjacentRuleChanges. | |
| 379 // | 379 // |
| 380 // As we encounter a descendant type of combinator, the features only need to be checked | 380 // As we encounter a descendant type of combinator, the features only need to be checked |
| 381 // against descendants in the same subtree only. features.adjacent is set to fal se, and | 381 // against descendants in the same subtree only. features.adjacent is set to fal se, and |
| 382 // we start adding features instead of calling setWholeSubtreeInvalid. | 382 // we start adding features to the descendant invalidation set. |
| 383 | 383 |
| 384 void RuleFeatureSet::addFeaturesToInvalidationSet(InvalidationSet& invalidationS et, const InvalidationSetFeatures& features) | 384 void RuleFeatureSet::addFeaturesToInvalidationSet(InvalidationSet& invalidationS et, const InvalidationSetFeatures& features) |
| 385 { | 385 { |
| 386 invalidationSet.updateMaxDirectAdjacentSelectors(features.maxDirectAdjacentS electors); | |
| 387 | |
| 386 if (features.treeBoundaryCrossing) | 388 if (features.treeBoundaryCrossing) |
| 387 invalidationSet.setTreeBoundaryCrossing(); | 389 invalidationSet.setTreeBoundaryCrossing(); |
| 388 if (features.insertionPointCrossing) | 390 if (features.insertionPointCrossing) |
| 389 invalidationSet.setInsertionPointCrossing(); | 391 invalidationSet.setInsertionPointCrossing(); |
| 390 if (features.useSubtreeInvalidation()) { | 392 if (features.forceSubtree) { |
| 391 invalidationSet.setWholeSubtreeInvalid(); | 393 invalidationSet.setWholeSubtreeInvalid(); |
| 392 return; | 394 return; |
| 393 } | 395 } |
| 394 if (!features.id.isEmpty()) | 396 if (!features.id.isEmpty()) |
| 395 invalidationSet.addId(features.id); | 397 invalidationSet.addId(features.id); |
| 396 if (!features.tagName.isEmpty()) | 398 if (!features.tagName.isEmpty()) |
| 397 invalidationSet.addTagName(features.tagName); | 399 invalidationSet.addTagName(features.tagName); |
| 398 for (const auto& className : features.classes) | 400 for (const auto& className : features.classes) |
| 399 invalidationSet.addClass(className); | 401 invalidationSet.addClass(className); |
| 400 for (const auto& attribute : features.attributes) | 402 for (const auto& attribute : features.attributes) |
| 401 invalidationSet.addAttribute(attribute); | 403 invalidationSet.addAttribute(attribute); |
| 402 if (features.customPseudoElement) | 404 if (features.customPseudoElement) |
| 403 invalidationSet.setCustomPseudoInvalid(); | 405 invalidationSet.setCustomPseudoInvalid(); |
| 404 } | 406 } |
| 405 | 407 |
| 406 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector, InvalidationSetFeatures& features) | 408 // selector is the selector immediately to the left of the rightmost selector. |
|
rune
2015/10/02 13:17:58
Immediately to the left of the rightmost _combinat
Eric Willigers
2015/10/14 00:25:40
Done.
| |
| 409 // siblingFeatures is null if selector is not immediately to the left of a sibli ng combinator. | |
| 410 // descendantFeatures has the features of the rightmost selector. | |
|
rune
2015/10/02 13:17:58
"rightmost compound selector"
Eric Willigers
2015/10/14 00:25:40
Done.
| |
| 411 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector, InvalidationSetFeatures* siblingFeatures, InvalidationSetFeatures& descendantFea tures) | |
| 407 { | 412 { |
| 408 for (const CSSSelector* current = &selector; current; current = current->tag History()) { | 413 // We set siblingFeatures to &localFeatures if we find a rightmost sibling c ombinator. |
| 409 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt)) { | 414 InvalidationSetFeatures localFeatures; |
| 410 addFeaturesToInvalidationSet(*invalidationSet, features); | 415 |
| 416 for (const CSSSelector* current = selector; current; current = current->tagH istory()) { | |
| 417 InvalidationType type = siblingFeatures ? InvalidateSiblings : Invalidat eDescendants; | |
| 418 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, type)) { | |
| 419 if (siblingFeatures) { | |
| 420 addFeaturesToInvalidationSet(*invalidationSet, *siblingFeatures) ; | |
| 421 if (siblingFeatures == &descendantFeatures) | |
| 422 invalidationSet->ensureDescendantInvalidationSet().setInvali datesSelf(); | |
| 423 else | |
| 424 addFeaturesToInvalidationSet(invalidationSet->ensureDescenda ntInvalidationSet(), descendantFeatures); | |
| 425 } else { | |
| 426 addFeaturesToInvalidationSet(*invalidationSet, descendantFeature s); | |
| 427 } | |
| 411 } else { | 428 } else { |
| 412 if (current->isTreeBoundaryCrossing()) | 429 if (current->isTreeBoundaryCrossing()) |
| 413 features.treeBoundaryCrossing = true; | 430 descendantFeatures.treeBoundaryCrossing = true; |
| 414 if (current->isInsertionPointCrossing()) | 431 if (current->isInsertionPointCrossing()) |
| 415 features.insertionPointCrossing = true; | 432 descendantFeatures.insertionPointCrossing = true; |
| 416 if (const CSSSelectorList* selectorList = current->selectorList()) { | 433 if (const CSSSelectorList* selectorList = current->selectorList()) { |
| 417 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType( ))); | 434 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType( ))); |
| 418 for (const CSSSelector* subSelector = selectorList->first(); sub Selector; subSelector = CSSSelectorList::next(*subSelector)) | 435 for (const CSSSelector* subSelector = selectorList->first(); sub Selector; subSelector = CSSSelectorList::next(*subSelector)) |
| 419 addFeaturesToInvalidationSets(*subSelector, features); | 436 addFeaturesToInvalidationSets(subSelector, siblingFeatures, descendantFeatures); |
| 420 } | 437 } |
| 421 } | 438 } |
| 422 | 439 |
| 423 if (current->relation() == CSSSelector::SubSelector) | 440 if (current->relation() == CSSSelector::SubSelector) |
| 424 continue; | 441 continue; |
| 425 | 442 |
| 426 if (current->isShadowSelector()) | 443 if (current->isShadowSelector()) |
| 427 features.treeBoundaryCrossing = true; | 444 descendantFeatures.treeBoundaryCrossing = true; |
| 428 | 445 |
| 429 features.adjacent = current->isAdjacentSelector(); | 446 if (!current->isAdjacentSelector()) { |
| 447 selector = current->tagHistory(); | |
|
rune
2015/10/02 13:17:58
This took a while for me to understand. It's used
Eric Willigers
2015/10/14 00:25:40
Done.
Eric Willigers
2015/10/14 00:25:40
Yes, for example when processing ".p.q + .r.s + .t
| |
| 448 siblingFeatures = nullptr; | |
| 449 continue; | |
| 450 } | |
| 451 | |
| 452 if (siblingFeatures) { | |
| 453 if (siblingFeatures->maxDirectAdjacentSelectors != std::numeric_limi ts<unsigned>::max()) { | |
| 454 if (current->relation() == CSSSelector::DirectAdjacent) | |
| 455 siblingFeatures->maxDirectAdjacentSelectors++; | |
| 456 else | |
| 457 siblingFeatures->maxDirectAdjacentSelectors = std::numeric_l imits<unsigned>::max(); | |
| 458 } | |
| 459 } else { | |
|
rune
2015/10/02 13:17:58
Could you try to get rid of some if-ery nesting he
Eric Willigers
2015/10/14 00:25:40
Done.
| |
| 460 localFeatures = InvalidationSetFeatures(); | |
| 461 auto result = extractInvalidationSetFeatures(*selector, localFeature s, false); | |
|
rune
2015/10/02 13:57:56
Note: extractInvalidationSetFeatures with requires
Eric Willigers
2015/10/14 00:25:40
Acknowledged.
| |
| 462 ASSERT(result.first); | |
| 463 localFeatures.forceSubtree = result.second == ForceSubtree; | |
| 464 | |
| 465 siblingFeatures = &localFeatures; | |
| 466 } | |
| 430 } | 467 } |
| 431 } | 468 } |
| 432 | 469 |
| 433 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData) | 470 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData) |
| 434 { | 471 { |
| 435 updateInvalidationSets(ruleData); | 472 updateInvalidationSets(ruleData); |
| 436 | 473 |
| 437 FeatureMetadata metadata; | 474 FeatureMetadata metadata; |
| 438 collectFeaturesFromSelector(ruleData.selector(), metadata); | 475 collectFeaturesFromSelector(ruleData.selector(), metadata); |
| 439 m_metadata.add(metadata); | 476 m_metadata.add(metadata); |
| 440 | 477 |
| 441 if (metadata.foundSiblingSelector) | 478 if (metadata.foundSiblingSelector) |
| 442 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin())); | 479 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin())); |
| 443 if (ruleData.containsUncommonAttributeSelector()) | 480 if (ruleData.containsUncommonAttributeSelector()) |
| 444 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin())); | 481 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin())); |
| 445 } | 482 } |
| 446 | 483 |
| 447 InvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const AtomicString& className) | |
| 448 { | |
| 449 InvalidationSetMap::AddResult addResult = m_classInvalidationSets.add(classN ame, nullptr); | |
| 450 if (addResult.isNewEntry) | |
| 451 addResult.storedValue->value = InvalidationSet::create(); | |
| 452 return *addResult.storedValue->value; | |
| 453 } | |
| 454 | |
| 455 InvalidationSet& RuleFeatureSet::ensureAttributeInvalidationSet(const AtomicStri ng& attributeName) | |
| 456 { | |
| 457 InvalidationSetMap::AddResult addResult = m_attributeInvalidationSets.add(at tributeName, nullptr); | |
| 458 if (addResult.isNewEntry) | |
| 459 addResult.storedValue->value = InvalidationSet::create(); | |
| 460 return *addResult.storedValue->value; | |
| 461 } | |
| 462 | |
| 463 InvalidationSet& RuleFeatureSet::ensureIdInvalidationSet(const AtomicString& id) | |
| 464 { | |
| 465 InvalidationSetMap::AddResult addResult = m_idInvalidationSets.add(id, nullp tr); | |
| 466 if (addResult.isNewEntry) | |
| 467 addResult.storedValue->value = InvalidationSet::create(); | |
| 468 return *addResult.storedValue->value; | |
| 469 } | |
| 470 | |
| 471 InvalidationSet& RuleFeatureSet::ensurePseudoInvalidationSet(CSSSelector::Pseudo Type pseudoType) | |
| 472 { | |
| 473 PseudoTypeInvalidationSetMap::AddResult addResult = m_pseudoInvalidationSets .add(pseudoType, nullptr); | |
| 474 if (addResult.isNewEntry) | |
| 475 addResult.storedValue->value = InvalidationSet::create(); | |
| 476 return *addResult.storedValue->value; | |
| 477 } | |
| 478 | |
| 479 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata) | 484 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata) |
| 480 { | 485 { |
| 481 unsigned maxDirectAdjacentSelectors = 0; | 486 unsigned maxDirectAdjacentSelectors = 0; |
| 482 | 487 |
| 483 for (const CSSSelector* current = &selector; current; current = current->tag History()) { | 488 for (const CSSSelector* current = &selector; current; current = current->tag History()) { |
| 484 if (current->pseudoType() == CSSSelector::PseudoFirstLine) | 489 if (current->pseudoType() == CSSSelector::PseudoFirstLine) |
| 485 metadata.usesFirstLineRules = true; | 490 metadata.usesFirstLineRules = true; |
| 486 if (current->pseudoType() == CSSSelector::PseudoWindowInactive) | 491 if (current->pseudoType() == CSSSelector::PseudoWindowInactive) |
| 487 metadata.usesWindowInactiveSelector = true; | 492 metadata.usesWindowInactiveSelector = true; |
| 488 if (current->relation() == CSSSelector::DirectAdjacent) { | 493 if (current->relation() == CSSSelector::DirectAdjacent) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 517 void RuleFeatureSet::FeatureMetadata::clear() | 522 void RuleFeatureSet::FeatureMetadata::clear() |
| 518 { | 523 { |
| 519 usesFirstLineRules = false; | 524 usesFirstLineRules = false; |
| 520 usesWindowInactiveSelector = false; | 525 usesWindowInactiveSelector = false; |
| 521 foundSiblingSelector = false; | 526 foundSiblingSelector = false; |
| 522 maxDirectAdjacentSelectors = 0; | 527 maxDirectAdjacentSelectors = 0; |
| 523 } | 528 } |
| 524 | 529 |
| 525 void RuleFeatureSet::add(const RuleFeatureSet& other) | 530 void RuleFeatureSet::add(const RuleFeatureSet& other) |
| 526 { | 531 { |
| 527 for (const auto& invalidationSet : other.m_classInvalidationSets) | 532 for (const auto& entry : other.m_classInvalidationSets) |
| 528 ensureClassInvalidationSet(invalidationSet.key).combine(*invalidationSet .value); | 533 ensureClassInvalidationData(entry.key).combine(*entry.value); |
| 529 for (const auto& invalidationSet : other.m_attributeInvalidationSets) | 534 for (const auto& entry : other.m_attributeInvalidationSets) |
| 530 ensureAttributeInvalidationSet(invalidationSet.key).combine(*invalidatio nSet.value); | 535 ensureAttributeInvalidationData(entry.key).combine(*entry.value); |
| 531 for (const auto& invalidationSet : other.m_idInvalidationSets) | 536 for (const auto& entry : other.m_idInvalidationSets) |
| 532 ensureIdInvalidationSet(invalidationSet.key).combine(*invalidationSet.va lue); | 537 ensureIdInvalidationData(entry.key).combine(*entry.value); |
| 533 for (const auto& invalidationSet : other.m_pseudoInvalidationSets) | 538 for (const auto& entry : other.m_pseudoInvalidationSets) |
| 534 ensurePseudoInvalidationSet(static_cast<CSSSelector::PseudoType>(invalid ationSet.key)).combine(*invalidationSet.value); | 539 ensurePseudoInvalidationData(static_cast<CSSSelector::PseudoType>(entry. key)).combine(*entry.value); |
| 535 | 540 |
| 536 m_metadata.add(other.m_metadata); | 541 m_metadata.add(other.m_metadata); |
| 537 | 542 |
| 538 siblingRules.appendVector(other.siblingRules); | 543 siblingRules.appendVector(other.siblingRules); |
| 539 uncommonAttributeRules.appendVector(other.uncommonAttributeRules); | 544 uncommonAttributeRules.appendVector(other.uncommonAttributeRules); |
| 540 } | 545 } |
| 541 | 546 |
| 542 void RuleFeatureSet::clear() | 547 void RuleFeatureSet::clear() |
| 543 { | 548 { |
| 544 siblingRules.clear(); | 549 siblingRules.clear(); |
| 545 uncommonAttributeRules.clear(); | 550 uncommonAttributeRules.clear(); |
| 546 m_metadata.clear(); | 551 m_metadata.clear(); |
| 547 m_classInvalidationSets.clear(); | 552 m_classInvalidationSets.clear(); |
| 548 m_attributeInvalidationSets.clear(); | 553 m_attributeInvalidationSets.clear(); |
| 549 m_idInvalidationSets.clear(); | 554 m_idInvalidationSets.clear(); |
| 550 } | 555 } |
| 551 | 556 |
| 552 void RuleFeatureSet::collectInvalidationSetsForClass(InvalidationSetVector& inva lidationSets, Element& element, const AtomicString& className) const | 557 void RuleFeatureSet::collectInvalidationSetsForClass(InvalidationLists& invalida tionLists, Element& element, const AtomicString& className) const |
| 553 { | 558 { |
| 554 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_classInvalidatio nSets.get(className)) { | 559 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_classInvalidat ionSets.get(className)) { |
| 555 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, classChange , className); | 560 if (invalidationData->descendants()) { |
| 556 invalidationSets.append(invalidationSet); | 561 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), classChange, className); |
| 562 invalidationLists.descendants.append(invalidationData->descendants() ); | |
| 563 } | |
| 564 if (invalidationData->siblings()) { | |
| 565 if (element.parentElement()) | |
| 566 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), classChange, className); | |
| 567 invalidationLists.siblings.append(invalidationData->siblings()); | |
| 568 } | |
| 557 } | 569 } |
| 558 } | 570 } |
| 559 | 571 |
| 560 void RuleFeatureSet::collectInvalidationSetsForId(InvalidationSetVector& invalid ationSets, Element& element, const AtomicString& id) const | 572 void RuleFeatureSet::collectInvalidationSetsForId(InvalidationLists& invalidatio nLists, Element& element, const AtomicString& id) const |
| 561 { | 573 { |
| 562 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_idInvalidationSe ts.get(id)) { | 574 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_idInvalidation Sets.get(id)) { |
| 563 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, idChange, i d); | 575 if (invalidationData->descendants()) { |
| 564 invalidationSets.append(invalidationSet); | 576 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), idChange, id); |
| 577 invalidationLists.descendants.append(invalidationData->descendants() ); | |
| 578 } | |
| 579 if (invalidationData->siblings()) { | |
| 580 if (element.parentElement()) | |
| 581 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), idChange, id); | |
| 582 invalidationLists.siblings.append(invalidationData->siblings()); | |
| 583 } | |
| 565 } | 584 } |
| 566 } | 585 } |
| 567 | 586 |
| 568 void RuleFeatureSet::collectInvalidationSetsForAttribute(InvalidationSetVector& invalidationSets, Element& element, const QualifiedName& attributeName) const | 587 void RuleFeatureSet::collectInvalidationSetsForAttribute(InvalidationLists& inva lidationLists, Element& element, const QualifiedName& attributeName) const |
| 569 { | 588 { |
| 570 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_attributeInvalid ationSets.get(attributeName.localName())) { | 589 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_attributeInval idationSets.get(attributeName.localName())) { |
| 571 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, attributeCh ange, attributeName); | 590 if (invalidationData->descendants()) { |
| 572 invalidationSets.append(invalidationSet); | 591 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), attributeChange, attributeName); |
| 592 invalidationLists.descendants.append(invalidationData->descendants() ); | |
| 593 } | |
| 594 if (invalidationData->siblings()) { | |
| 595 if (element.parentElement()) | |
| 596 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), attributeChange, attributeName); | |
| 597 invalidationLists.siblings.append(invalidationData->siblings()); | |
| 598 } | |
| 573 } | 599 } |
| 574 } | 600 } |
| 575 | 601 |
| 576 void RuleFeatureSet::collectInvalidationSetsForPseudoClass(InvalidationSetVector & invalidationSets, Element& element, CSSSelector::PseudoType pseudo) const | 602 void RuleFeatureSet::collectInvalidationSetsForPseudoClass(InvalidationLists& in validationLists, Element& element, CSSSelector::PseudoType pseudo) const |
| 577 { | 603 { |
| 578 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_pseudoInvalidati onSets.get(pseudo)) { | 604 if (RefPtrWillBeRawPtr<InvalidationData> invalidationData = m_pseudoInvalida tionSets.get(pseudo)) { |
| 579 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, pseudoChang e, pseudo); | 605 if (invalidationData->descendants()) { |
| 580 invalidationSets.append(invalidationSet); | 606 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationData->descen dants(), pseudoChange, pseudo); |
| 607 invalidationLists.descendants.append(invalidationData->descendants() ); | |
| 608 } | |
| 609 if (invalidationData->siblings()) { | |
| 610 if (element.parentElement()) | |
| 611 TRACE_SCHEDULE_STYLE_INVALIDATION(*element.parentElement(), *inv alidationData->siblings(), pseudoChange, pseudo); | |
| 612 invalidationLists.siblings.append(invalidationData->siblings()); | |
| 613 } | |
| 581 } | 614 } |
| 582 } | 615 } |
| 583 | 616 |
| 584 DEFINE_TRACE(RuleFeatureSet) | 617 DEFINE_TRACE(RuleFeatureSet) |
| 585 { | 618 { |
| 586 #if ENABLE(OILPAN) | 619 #if ENABLE(OILPAN) |
| 587 visitor->trace(siblingRules); | 620 visitor->trace(siblingRules); |
| 588 visitor->trace(uncommonAttributeRules); | 621 visitor->trace(uncommonAttributeRules); |
| 589 visitor->trace(m_classInvalidationSets); | 622 visitor->trace(m_classInvalidationSets); |
| 590 visitor->trace(m_attributeInvalidationSets); | 623 visitor->trace(m_attributeInvalidationSets); |
| 591 visitor->trace(m_idInvalidationSets); | 624 visitor->trace(m_idInvalidationSets); |
| 592 visitor->trace(m_pseudoInvalidationSets); | 625 visitor->trace(m_pseudoInvalidationSets); |
| 593 #endif | 626 #endif |
| 594 } | 627 } |
| 595 | 628 |
| 596 } // namespace blink | 629 } // namespace blink |
| OLD | NEW |