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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 case CSSSelector::PseudoIndeterminate: | 344 case CSSSelector::PseudoIndeterminate: |
| 345 case CSSSelector::PseudoTarget: | 345 case CSSSelector::PseudoTarget: |
| 346 case CSSSelector::PseudoLang: | 346 case CSSSelector::PseudoLang: |
| 347 case CSSSelector::PseudoFullScreen: | 347 case CSSSelector::PseudoFullScreen: |
| 348 case CSSSelector::PseudoFullScreenAncestor: | 348 case CSSSelector::PseudoFullScreenAncestor: |
| 349 case CSSSelector::PseudoInRange: | 349 case CSSSelector::PseudoInRange: |
| 350 case CSSSelector::PseudoOutOfRange: | 350 case CSSSelector::PseudoOutOfRange: |
| 351 case CSSSelector::PseudoUnresolved: | 351 case CSSSelector::PseudoUnresolved: |
| 352 case CSSSelector::PseudoDefined: | 352 case CSSSelector::PseudoDefined: |
| 353 return &ensurePseudoInvalidationSet(selector.getPseudoType(), type); | 353 return &ensurePseudoInvalidationSet(selector.getPseudoType(), type); |
| 354 case CSSSelector::PseudoFirstOfType: | |
| 355 case CSSSelector::PseudoLastOfType: | |
| 356 case CSSSelector::PseudoOnlyOfType: | |
| 357 case CSSSelector::PseudoNthChild: | |
| 358 case CSSSelector::PseudoNthOfType: | |
| 359 case CSSSelector::PseudoNthLastChild: | |
| 360 case CSSSelector::PseudoNthLastOfType: | |
| 361 return &ensureNthInvalidationSet(); | |
| 354 default: | 362 default: |
| 355 break; | 363 break; |
| 356 } | 364 } |
| 357 } | 365 } |
| 358 return nullptr; | 366 return nullptr; |
| 359 } | 367 } |
| 360 | 368 |
| 361 // Given a rule, update the descendant invalidation sets for the features found | 369 // Given a rule, update the descendant invalidation sets for the features found |
| 362 // in its selector. The first step is to extract the features from the rightmost | 370 // in its selector. The first step is to extract the features from the rightmost |
| 363 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu res | 371 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu res |
| 364 // to the invalidation sets for the features found in the other compound selecto rs | 372 // to the invalidation sets for the features found in the other compound selecto rs |
| 365 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compo und | 373 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compo und |
| 366 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the | 374 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the |
| 367 // rightmost compound selector as well. | 375 // rightmost compound selector as well. |
| 368 | 376 |
| 369 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) | 377 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) |
| 370 { | 378 { |
| 371 InvalidationSetFeatures features; | 379 InvalidationSetFeatures features; |
| 372 auto result = extractInvalidationSetFeatures(ruleData.selector(), features, Subject); | 380 auto result = extractInvalidationSetFeatures(ruleData.selector(), features, Subject); |
| 373 | 381 |
| 382 features.forceSubtree = result.second == ForceSubtree; | |
| 374 if (result.first) { | 383 if (result.first) { |
| 375 features.forceSubtree = result.second == ForceSubtree; | |
| 376 addFeaturesToInvalidationSets(result.first, features.adjacent ? &feature s : nullptr, features); | 384 addFeaturesToInvalidationSets(result.first, features.adjacent ? &feature s : nullptr, features); |
| 385 } else if (features.hasNthPseudo) { | |
| 386 DCHECK(m_nthInvalidationSet); | |
| 387 addFeaturesToInvalidationSet(*m_nthInvalidationSet, features); | |
| 377 } | 388 } |
| 378 | 389 |
| 379 // If any ::before and ::after rules specify 'content: attr(...)', we | 390 // If any ::before and ::after rules specify 'content: attr(...)', we |
| 380 // need to create invalidation sets for those attributes. | 391 // need to create invalidation sets for those attributes. |
| 381 if (features.hasBeforeOrAfter) | 392 if (features.hasBeforeOrAfter) |
| 382 updateInvalidationSetsForContentAttribute(ruleData); | 393 updateInvalidationSetsForContentAttribute(ruleData); |
| 383 } | 394 } |
| 384 | 395 |
| 385 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r uleData) | 396 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r uleData) |
| 386 { | 397 { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 409 | 420 |
| 410 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType> | 421 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType> |
| 411 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva lidationSetFeatures& features, PositionType position, CSSSelector::PseudoType ps eudo) | 422 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva lidationSetFeatures& features, PositionType position, CSSSelector::PseudoType ps eudo) |
| 412 { | 423 { |
| 413 bool foundFeatures = false; | 424 bool foundFeatures = false; |
| 414 for (const CSSSelector* current = &selector; current; current = current->tag History()) { | 425 for (const CSSSelector* current = &selector; current; current = current->tag History()) { |
| 415 if (pseudo != CSSSelector::PseudoNot) | 426 if (pseudo != CSSSelector::PseudoNot) |
| 416 foundFeatures |= extractInvalidationSetFeature(*current, features); | 427 foundFeatures |= extractInvalidationSetFeature(*current, features); |
| 417 // Initialize the entry in the invalidation set map, if supported. | 428 // Initialize the entry in the invalidation set map, if supported. |
| 418 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, InvalidateDescendants)) { | 429 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, InvalidateDescendants)) { |
| 419 if (position == Subject) | 430 if (position == Subject) { |
| 420 invalidationSet->setInvalidatesSelf(); | 431 if (invalidationSet == m_nthInvalidationSet) |
| 432 features.hasNthPseudo = true; | |
| 433 else | |
| 434 invalidationSet->setInvalidatesSelf(); | |
| 435 } | |
| 421 } else { | 436 } else { |
| 422 if (requiresSubtreeInvalidation(*current)) { | 437 if (requiresSubtreeInvalidation(*current)) { |
| 423 // Fall back to use subtree invalidations, even for features in the | 438 // Fall back to use subtree invalidations, even for features in the |
| 424 // rightmost compound selector. Returning the start &selector he re | 439 // rightmost compound selector. Returning the start &selector he re |
| 425 // will make addFeaturesToInvalidationSets start marking invalid ation | 440 // will make addFeaturesToInvalidationSets start marking invalid ation |
| 426 // sets for subtree recalc for features in the rightmost compoun d | 441 // sets for subtree recalc for features in the rightmost compoun d |
| 427 // selector. | 442 // selector. |
| 428 return std::make_pair(&selector, ForceSubtree); | 443 return std::make_pair(&selector, ForceSubtree); |
| 429 } | 444 } |
| 430 if (const CSSSelectorList* selectorList = current->selectorList()) { | 445 if (const CSSSelectorList* selectorList = current->selectorList()) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 445 } | 460 } |
| 446 allSubSelectorsHaveFeatures &= result.second == UseFeatures; | 461 allSubSelectorsHaveFeatures &= result.second == UseFeatures; |
| 447 } | 462 } |
| 448 foundFeatures |= allSubSelectorsHaveFeatures; | 463 foundFeatures |= allSubSelectorsHaveFeatures; |
| 449 } | 464 } |
| 450 } | 465 } |
| 451 | 466 |
| 452 if (current->relation() == CSSSelector::SubSelector) | 467 if (current->relation() == CSSSelector::SubSelector) |
| 453 continue; | 468 continue; |
| 454 | 469 |
| 470 if (features.hasNthPseudo && position == Subject) { | |
| 471 DCHECK(m_nthInvalidationSet); | |
| 472 addFeaturesToInvalidationSet(*m_nthInvalidationSet, features); | |
| 473 if (!foundFeatures) | |
| 474 m_nthInvalidationSet->setWholeSubtreeInvalid(); | |
|
esprehn
2016/08/11 10:32:55
If we're going to mark it for the whole subtree wh
rune
2016/08/12 11:03:14
Will fix.
| |
| 475 } | |
| 476 | |
| 455 features.treeBoundaryCrossing = current->isShadowSelector(); | 477 features.treeBoundaryCrossing = current->isShadowSelector(); |
| 456 if (current->relationIsAffectedByPseudoContent()) { | 478 if (current->relationIsAffectedByPseudoContent()) { |
| 457 features.contentPseudoCrossing = true; | 479 features.contentPseudoCrossing = true; |
| 458 features.insertionPointCrossing = true; | 480 features.insertionPointCrossing = true; |
| 459 } | 481 } |
| 460 features.adjacent = current->isAdjacentSelector(); | 482 features.adjacent = current->isAdjacentSelector(); |
| 461 if (current->relation() == CSSSelector::DirectAdjacent) | 483 if (current->relation() == CSSSelector::DirectAdjacent) |
| 462 features.maxDirectAdjacentSelectors = 1; | 484 features.maxDirectAdjacentSelectors = 1; |
| 463 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree); | 485 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree); |
| 464 } | 486 } |
| 465 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); | 487 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); |
| 466 } | 488 } |
| 467 | 489 |
| 468 // Add features extracted from the rightmost compound selector to descendant inv alidation | 490 // Add features extracted from the rightmost compound selector to descendant inv alidation |
| 469 // sets for features found in other compound selectors. | 491 // sets for features found in other compound selectors. |
| 470 // | 492 // |
| 471 // We use descendant invalidation for descendants, sibling invalidation for sibl ings and their subtrees. | 493 // We use descendant invalidation for descendants, sibling invalidation for sibl ings and their subtrees. |
| 472 // | 494 // |
| 473 // As we encounter a descendant type of combinator, the features only need to be checked | 495 // As we encounter a descendant type of combinator, the features only need to be checked |
| 474 // against descendants in the same subtree only. features.adjacent is set to fal se, and | 496 // against descendants in the same subtree only. features.adjacent is set to fal se, and |
| 475 // we start adding features to the descendant invalidation set. | 497 // we start adding features to the descendant invalidation set. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 509 // We set siblingFeatures to &localFeatures if we find a rightmost sibling c ombinator. | 531 // We set siblingFeatures to &localFeatures if we find a rightmost sibling c ombinator. |
| 510 InvalidationSetFeatures localFeatures; | 532 InvalidationSetFeatures localFeatures; |
| 511 | 533 |
| 512 bool universalCompound = true; | 534 bool universalCompound = true; |
| 513 | 535 |
| 514 for (const CSSSelector* current = selector; current; current = current->tagH istory()) { | 536 for (const CSSSelector* current = selector; current; current = current->tagH istory()) { |
| 515 InvalidationType type = siblingFeatures ? InvalidateSiblings : Invalidat eDescendants; | 537 InvalidationType type = siblingFeatures ? InvalidateSiblings : Invalidat eDescendants; |
| 516 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, type)) { | 538 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, type)) { |
| 517 if (current->match() != CSSSelector::PseudoClass) | 539 if (current->match() != CSSSelector::PseudoClass) |
| 518 universalCompound = false; | 540 universalCompound = false; |
| 519 if (siblingFeatures) { | 541 if (siblingFeatures && invalidationSet != m_nthInvalidationSet) { |
| 520 SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvali dationSet(invalidationSet); | 542 SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvali dationSet(invalidationSet); |
| 521 siblingInvalidationSet->updateMaxDirectAdjacentSelectors(sibling Features->maxDirectAdjacentSelectors); | 543 siblingInvalidationSet->updateMaxDirectAdjacentSelectors(sibling Features->maxDirectAdjacentSelectors); |
| 522 | 544 |
| 523 addFeaturesToInvalidationSet(*invalidationSet, *siblingFeatures) ; | 545 addFeaturesToInvalidationSet(*invalidationSet, *siblingFeatures) ; |
| 524 if (siblingFeatures == &descendantFeatures) | 546 if (siblingFeatures == &descendantFeatures) |
| 525 siblingInvalidationSet->setInvalidatesSelf(); | 547 siblingInvalidationSet->setInvalidatesSelf(); |
| 526 else | 548 else |
| 527 addFeaturesToInvalidationSet(siblingInvalidationSet->ensureS iblingDescendants(), descendantFeatures); | 549 addFeaturesToInvalidationSet(siblingInvalidationSet->ensureS iblingDescendants(), descendantFeatures); |
| 528 } else { | 550 } else { |
| 529 addFeaturesToInvalidationSet(*invalidationSet, descendantFeature s); | 551 addFeaturesToInvalidationSet(*invalidationSet, descendantFeature s); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 691 for (const auto& entry : other.m_classInvalidationSets) | 713 for (const auto& entry : other.m_classInvalidationSets) |
| 692 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t ype()).combine(*entry.value); | 714 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t ype()).combine(*entry.value); |
| 693 for (const auto& entry : other.m_attributeInvalidationSets) | 715 for (const auto& entry : other.m_attributeInvalidationSets) |
| 694 ensureInvalidationSet(m_attributeInvalidationSets, entry.key, entry.valu e->type()).combine(*entry.value); | 716 ensureInvalidationSet(m_attributeInvalidationSets, entry.key, entry.valu e->type()).combine(*entry.value); |
| 695 for (const auto& entry : other.m_idInvalidationSets) | 717 for (const auto& entry : other.m_idInvalidationSets) |
| 696 ensureInvalidationSet(m_idInvalidationSets, entry.key, entry.value->type ()).combine(*entry.value); | 718 ensureInvalidationSet(m_idInvalidationSets, entry.key, entry.value->type ()).combine(*entry.value); |
| 697 for (const auto& entry : other.m_pseudoInvalidationSets) | 719 for (const auto& entry : other.m_pseudoInvalidationSets) |
| 698 ensureInvalidationSet(m_pseudoInvalidationSets, static_cast<CSSSelector: :PseudoType>(entry.key), entry.value->type()).combine(*entry.value); | 720 ensureInvalidationSet(m_pseudoInvalidationSets, static_cast<CSSSelector: :PseudoType>(entry.key), entry.value->type()).combine(*entry.value); |
| 699 if (other.m_universalSiblingInvalidationSet) | 721 if (other.m_universalSiblingInvalidationSet) |
| 700 ensureUniversalSiblingInvalidationSet().combine(*other.m_universalSiblin gInvalidationSet); | 722 ensureUniversalSiblingInvalidationSet().combine(*other.m_universalSiblin gInvalidationSet); |
| 723 if (other.m_nthInvalidationSet) | |
| 724 ensureNthInvalidationSet().combine(*other.m_nthInvalidationSet); | |
| 701 | 725 |
| 702 m_metadata.add(other.m_metadata); | 726 m_metadata.add(other.m_metadata); |
| 703 | 727 |
| 704 siblingRules.appendVector(other.siblingRules); | 728 siblingRules.appendVector(other.siblingRules); |
| 705 uncommonAttributeRules.appendVector(other.uncommonAttributeRules); | 729 uncommonAttributeRules.appendVector(other.uncommonAttributeRules); |
| 706 } | 730 } |
| 707 | 731 |
| 708 void RuleFeatureSet::clear() | 732 void RuleFeatureSet::clear() |
| 709 { | 733 { |
| 710 siblingRules.clear(); | 734 siblingRules.clear(); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 860 invalidationLists.siblings.append(m_universalSiblingInvalidationSet); | 884 invalidationLists.siblings.append(m_universalSiblingInvalidationSet); |
| 861 } | 885 } |
| 862 | 886 |
| 863 SiblingInvalidationSet& RuleFeatureSet::ensureUniversalSiblingInvalidationSet() | 887 SiblingInvalidationSet& RuleFeatureSet::ensureUniversalSiblingInvalidationSet() |
| 864 { | 888 { |
| 865 if (!m_universalSiblingInvalidationSet) | 889 if (!m_universalSiblingInvalidationSet) |
| 866 m_universalSiblingInvalidationSet = SiblingInvalidationSet::create(nullp tr); | 890 m_universalSiblingInvalidationSet = SiblingInvalidationSet::create(nullp tr); |
| 867 return *m_universalSiblingInvalidationSet; | 891 return *m_universalSiblingInvalidationSet; |
| 868 } | 892 } |
| 869 | 893 |
| 894 void RuleFeatureSet::collectNthInvalidationSet(InvalidationLists& invalidationLi sts) const | |
| 895 { | |
| 896 if (m_nthInvalidationSet) | |
| 897 invalidationLists.descendants.append(m_nthInvalidationSet); | |
| 898 } | |
| 899 | |
| 900 DescendantInvalidationSet& RuleFeatureSet::ensureNthInvalidationSet() | |
| 901 { | |
| 902 if (!m_nthInvalidationSet) | |
| 903 m_nthInvalidationSet = DescendantInvalidationSet::create(); | |
| 904 return *m_nthInvalidationSet; | |
| 905 } | |
| 906 | |
| 870 void RuleFeatureSet::addFeaturesToUniversalSiblingInvalidationSet(const Invalida tionSetFeatures& siblingFeatures, const InvalidationSetFeatures& descendantFeatu res) | 907 void RuleFeatureSet::addFeaturesToUniversalSiblingInvalidationSet(const Invalida tionSetFeatures& siblingFeatures, const InvalidationSetFeatures& descendantFeatu res) |
| 871 { | 908 { |
| 872 SiblingInvalidationSet& universalSet = ensureUniversalSiblingInvalidationSet (); | 909 SiblingInvalidationSet& universalSet = ensureUniversalSiblingInvalidationSet (); |
| 873 addFeaturesToInvalidationSet(universalSet, siblingFeatures); | 910 addFeaturesToInvalidationSet(universalSet, siblingFeatures); |
| 874 universalSet.updateMaxDirectAdjacentSelectors(siblingFeatures.maxDirectAdjac entSelectors); | 911 universalSet.updateMaxDirectAdjacentSelectors(siblingFeatures.maxDirectAdjac entSelectors); |
| 875 | 912 |
| 876 if (&siblingFeatures == &descendantFeatures) | 913 if (&siblingFeatures == &descendantFeatures) |
| 877 universalSet.setInvalidatesSelf(); | 914 universalSet.setInvalidatesSelf(); |
| 878 else | 915 else |
| 879 addFeaturesToInvalidationSet(universalSet.ensureSiblingDescendants(), de scendantFeatures); | 916 addFeaturesToInvalidationSet(universalSet.ensureSiblingDescendants(), de scendantFeatures); |
| 880 } | 917 } |
| 881 | 918 |
| 882 DEFINE_TRACE(RuleFeatureSet) | 919 DEFINE_TRACE(RuleFeatureSet) |
| 883 { | 920 { |
| 884 visitor->trace(siblingRules); | 921 visitor->trace(siblingRules); |
| 885 visitor->trace(uncommonAttributeRules); | 922 visitor->trace(uncommonAttributeRules); |
| 886 } | 923 } |
| 887 | 924 |
| 888 } // namespace blink | 925 } // namespace blink |
| OLD | NEW |