| 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 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 lastCompoundInAdjacentChainFeatures = InvalidationSetFeatures(); | 325 lastCompoundInAdjacentChainFeatures = InvalidationSetFeatures(); |
| 326 | 326 |
| 327 siblingFeatures = nullptr; | 327 siblingFeatures = nullptr; |
| 328 | 328 |
| 329 if (lastInCompound.isShadowSelector()) | 329 if (lastInCompound.isShadowSelector()) |
| 330 descendantFeatures.treeBoundaryCrossing = true; | 330 descendantFeatures.treeBoundaryCrossing = true; |
| 331 if (lastInCompound.relation() == CSSSelector::ShadowSlot || lastInCompound.r
elationIsAffectedByPseudoContent()) | 331 if (lastInCompound.relation() == CSSSelector::ShadowSlot || lastInCompound.r
elationIsAffectedByPseudoContent()) |
| 332 descendantFeatures.insertionPointCrossing = true; | 332 descendantFeatures.insertionPointCrossing = true; |
| 333 if (lastInCompound.relationIsAffectedByPseudoContent()) | 333 if (lastInCompound.relationIsAffectedByPseudoContent()) |
| 334 descendantFeatures.contentPseudoCrossing = true; | 334 descendantFeatures.contentPseudoCrossing = true; |
| 335 if (lastInCompound.relationIsAffectedByPseudoContent() || lastInCompound.isS
hadowSelector()) |
| 336 descendantFeatures.hasInvalidationSetFeaturesInScope = false; |
| 335 } | 337 } |
| 336 | 338 |
| 337 void RuleFeatureSet::extractInvalidationSetFeaturesFromSimpleSelector(const CSSS
elector& selector, InvalidationSetFeatures& features) | 339 void RuleFeatureSet::extractInvalidationSetFeaturesFromSimpleSelector(const CSSS
elector& selector, InvalidationSetFeatures& features) |
| 338 { | 340 { |
| 339 if (selector.match() == CSSSelector::Tag && selector.tagQName().localName()
!= starAtom) { | 341 if (selector.match() == CSSSelector::Tag && selector.tagQName().localName()
!= starAtom) { |
| 340 features.tagNames.append(selector.tagQName().localName()); | 342 features.tagNames.append(selector.tagQName().localName()); |
| 341 return; | 343 return; |
| 342 } | 344 } |
| 343 if (selector.match() == CSSSelector::Id) { | 345 if (selector.match() == CSSSelector::Id) { |
| 344 features.ids.append(selector.value()); | 346 features.ids.append(selector.value()); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 // rightmost compound selector (extractInvalidationSetFeaturesFromCompound). | 436 // rightmost compound selector (extractInvalidationSetFeaturesFromCompound). |
| 435 // Secondly, add those features to the invalidation sets for the features | 437 // Secondly, add those features to the invalidation sets for the features |
| 436 // found in the other compound selectors (addFeaturesToInvalidationSets). If | 438 // found in the other compound selectors (addFeaturesToInvalidationSets). If |
| 437 // we find a feature in the right-most compound selector that requires a | 439 // we find a feature in the right-most compound selector that requires a |
| 438 // subtree recalc, nextCompound will be the rightmost compound and we will | 440 // subtree recalc, nextCompound will be the rightmost compound and we will |
| 439 // addFeaturesToInvalidationSets for that one as well. | 441 // addFeaturesToInvalidationSets for that one as well. |
| 440 | 442 |
| 441 InvalidationSetFeatures features; | 443 InvalidationSetFeatures features; |
| 442 const CSSSelector* nextCompound = extractInvalidationSetFeaturesFromCompound
(ruleData.selector(), features, Subject); | 444 const CSSSelector* nextCompound = extractInvalidationSetFeaturesFromCompound
(ruleData.selector(), features, Subject); |
| 443 | 445 |
| 444 if (!features.hasFeatures()) | 446 if (features.forceSubtree) |
| 447 features.hasInvalidationSetFeaturesInScope = false; |
| 448 else if (!features.hasFeatures()) |
| 445 features.forceSubtree = true; | 449 features.forceSubtree = true; |
| 446 | 450 |
| 447 if (nextCompound) | 451 if (nextCompound) |
| 448 addFeaturesToInvalidationSets(*nextCompound, features); | 452 addFeaturesToInvalidationSets(*nextCompound, features); |
| 449 else if (features.hasNthPseudo) | 453 else if (features.hasNthPseudo) |
| 450 addFeaturesToInvalidationSet(ensureNthInvalidationSet(), features); | 454 addFeaturesToInvalidationSet(ensureNthInvalidationSet(), features); |
| 451 | 455 |
| 452 if (features.hasBeforeOrAfter) | 456 if (features.hasBeforeOrAfter) |
| 453 updateInvalidationSetsForContentAttribute(ruleData); | 457 updateInvalidationSetsForContentAttribute(ruleData); |
| 458 |
| 459 if (!features.hasInvalidationSetFeaturesInScope) |
| 460 m_metadata.needsFullRecalcForRuleSetInvalidation = true; |
| 454 } | 461 } |
| 455 | 462 |
| 456 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r
uleData) | 463 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r
uleData) |
| 457 { | 464 { |
| 458 // If any ::before and ::after rules specify 'content: attr(...)', we | 465 // If any ::before and ::after rules specify 'content: attr(...)', we |
| 459 // need to create invalidation sets for those attributes to have content | 466 // need to create invalidation sets for those attributes to have content |
| 460 // changes applied through style recalc. | 467 // changes applied through style recalc. |
| 461 | 468 |
| 462 const StylePropertySet& propertySet = ruleData.rule()->properties(); | 469 const StylePropertySet& propertySet = ruleData.rule()->properties(); |
| 463 | 470 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 continue; | 570 continue; |
| 564 | 571 |
| 565 if (position == Subject) { | 572 if (position == Subject) { |
| 566 if (features.hasNthPseudo) { | 573 if (features.hasNthPseudo) { |
| 567 DCHECK(m_nthInvalidationSet); | 574 DCHECK(m_nthInvalidationSet); |
| 568 if (features.hasFeatures()) | 575 if (features.hasFeatures()) |
| 569 addFeaturesToInvalidationSet(*m_nthInvalidationSet, features
); | 576 addFeaturesToInvalidationSet(*m_nthInvalidationSet, features
); |
| 570 else | 577 else |
| 571 m_nthInvalidationSet->setWholeSubtreeInvalid(); | 578 m_nthInvalidationSet->setWholeSubtreeInvalid(); |
| 572 } | 579 } |
| 580 features.hasInvalidationSetFeaturesInScope = features.hasFeatures(); |
| 573 InvalidationSetFeatures* siblingFeatures = nullptr; | 581 InvalidationSetFeatures* siblingFeatures = nullptr; |
| 574 updateFeaturesFromCombinator(*simpleSelector, nullptr, features, sib
lingFeatures, features); | 582 updateFeaturesFromCombinator(*simpleSelector, nullptr, features, sib
lingFeatures, features); |
| 575 } | 583 } |
| 576 return simpleSelector->tagHistory(); | 584 return simpleSelector->tagHistory(); |
| 577 } | 585 } |
| 578 | 586 |
| 587 features.hasInvalidationSetFeaturesInScope = features.hasFeatures(); |
| 579 return nullptr; | 588 return nullptr; |
| 580 } | 589 } |
| 581 | 590 |
| 582 // Add features extracted from the rightmost compound selector to descendant inv
alidation | 591 // Add features extracted from the rightmost compound selector to descendant inv
alidation |
| 583 // sets for features found in other compound selectors. | 592 // sets for features found in other compound selectors. |
| 584 // | 593 // |
| 585 // We use descendant invalidation for descendants, sibling invalidation for sibl
ings and their subtrees. | 594 // We use descendant invalidation for descendants, sibling invalidation for sibl
ings and their subtrees. |
| 586 // | 595 // |
| 587 // As we encounter a descendant type of combinator, the features only need to be
checked | 596 // As we encounter a descendant type of combinator, the features only need to be
checked |
| 588 // against descendants in the same subtree only. features.adjacent is set to fal
se, and | 597 // against descendants in the same subtree only. features.adjacent is set to fal
se, and |
| (...skipping 25 matching lines...) Expand all Loading... |
| 614 } | 623 } |
| 615 | 624 |
| 616 | 625 |
| 617 void RuleFeatureSet::addFeaturesToInvalidationSetsForSelectorList(const CSSSelec
tor& simpleSelector, InvalidationSetFeatures* siblingFeatures, InvalidationSetFe
atures& descendantFeatures) | 626 void RuleFeatureSet::addFeaturesToInvalidationSetsForSelectorList(const CSSSelec
tor& simpleSelector, InvalidationSetFeatures* siblingFeatures, InvalidationSetFe
atures& descendantFeatures) |
| 618 { | 627 { |
| 619 if (!simpleSelector.selectorList()) | 628 if (!simpleSelector.selectorList()) |
| 620 return; | 629 return; |
| 621 | 630 |
| 622 DCHECK(supportsInvalidationWithSelectorList(simpleSelector.getPseudoType()))
; | 631 DCHECK(supportsInvalidationWithSelectorList(simpleSelector.getPseudoType()))
; |
| 623 | 632 |
| 624 for (const CSSSelector* subSelector = simpleSelector.selectorList()->first()
; subSelector; subSelector = CSSSelectorList::next(*subSelector)) | 633 bool hadInvalidationSetFeaturesInScope = descendantFeatures.hasInvalidationS
etFeaturesInScope; |
| 634 bool selectorListContainsUniversal = simpleSelector.getPseudoType() == CSSSe
lector::PseudoNot |
| 635 || simpleSelector.getPseudoType() == CSSSelector::PseudoHostContext; |
| 636 |
| 637 for (const CSSSelector* subSelector = simpleSelector.selectorList()->first()
; subSelector; subSelector = CSSSelectorList::next(*subSelector)) { |
| 638 descendantFeatures.hasInvalidationSetFeaturesInScope = false; |
| 639 |
| 625 addFeaturesToInvalidationSetsForCompoundSelector(*subSelector, siblingFe
atures, descendantFeatures); | 640 addFeaturesToInvalidationSetsForCompoundSelector(*subSelector, siblingFe
atures, descendantFeatures); |
| 641 |
| 642 if (!descendantFeatures.hasInvalidationSetFeaturesInScope) |
| 643 selectorListContainsUniversal = true; |
| 644 } |
| 645 |
| 646 descendantFeatures.hasInvalidationSetFeaturesInScope = hadInvalidationSetFea
turesInScope || !selectorListContainsUniversal; |
| 626 } | 647 } |
| 627 | 648 |
| 628 void RuleFeatureSet::addFeaturesToInvalidationSetsForSimpleSelector(const CSSSel
ector& simpleSelector, InvalidationSetFeatures* siblingFeatures, InvalidationSet
Features& descendantFeatures) | 649 void RuleFeatureSet::addFeaturesToInvalidationSetsForSimpleSelector(const CSSSel
ector& simpleSelector, InvalidationSetFeatures* siblingFeatures, InvalidationSet
Features& descendantFeatures) |
| 629 { | 650 { |
| 630 if (InvalidationSet* invalidationSet = invalidationSetForSimpleSelector(simp
leSelector, siblingFeatures ? InvalidateSiblings : InvalidateDescendants)) { | 651 if (InvalidationSet* invalidationSet = invalidationSetForSimpleSelector(simp
leSelector, siblingFeatures ? InvalidateSiblings : InvalidateDescendants)) { |
| 631 if (!siblingFeatures || invalidationSet == m_nthInvalidationSet) { | 652 if (!siblingFeatures || invalidationSet == m_nthInvalidationSet) { |
| 632 addFeaturesToInvalidationSet(*invalidationSet, descendantFeatures); | 653 addFeaturesToInvalidationSet(*invalidationSet, descendantFeatures); |
| 633 return; | 654 return; |
| 634 } | 655 } |
| 635 | 656 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 650 | 671 |
| 651 addFeaturesToInvalidationSetsForSelectorList(simpleSelector, siblingFeatures
, descendantFeatures); | 672 addFeaturesToInvalidationSetsForSelectorList(simpleSelector, siblingFeatures
, descendantFeatures); |
| 652 } | 673 } |
| 653 | 674 |
| 654 const CSSSelector* RuleFeatureSet::addFeaturesToInvalidationSetsForCompoundSelec
tor(const CSSSelector& compound, InvalidationSetFeatures* siblingFeatures, Inval
idationSetFeatures& descendantFeatures) | 675 const CSSSelector* RuleFeatureSet::addFeaturesToInvalidationSetsForCompoundSelec
tor(const CSSSelector& compound, InvalidationSetFeatures* siblingFeatures, Inval
idationSetFeatures& descendantFeatures) |
| 655 { | 676 { |
| 656 bool compoundHasIdClassOrAttribute = false; | 677 bool compoundHasIdClassOrAttribute = false; |
| 657 const CSSSelector* simpleSelector = &compound; | 678 const CSSSelector* simpleSelector = &compound; |
| 658 for (; simpleSelector; simpleSelector = simpleSelector->tagHistory()) { | 679 for (; simpleSelector; simpleSelector = simpleSelector->tagHistory()) { |
| 659 addFeaturesToInvalidationSetsForSimpleSelector(*simpleSelector, siblingF
eatures, descendantFeatures); | 680 addFeaturesToInvalidationSetsForSimpleSelector(*simpleSelector, siblingF
eatures, descendantFeatures); |
| 660 if (siblingFeatures) | 681 if (simpleSelector->isIdClassOrAttributeSelector()) |
| 661 compoundHasIdClassOrAttribute |= simpleSelector->isIdClassOrAttribut
eSelector(); | 682 compoundHasIdClassOrAttribute = true; |
| 662 if (simpleSelector->relation() != CSSSelector::SubSelector) | 683 if (simpleSelector->relation() != CSSSelector::SubSelector) |
| 663 break; | 684 break; |
| 664 if (!simpleSelector->tagHistory()) | 685 if (!simpleSelector->tagHistory()) |
| 665 break; | 686 break; |
| 666 } | 687 } |
| 667 | 688 |
| 668 if (siblingFeatures && !compoundHasIdClassOrAttribute) | 689 if (compoundHasIdClassOrAttribute) |
| 690 descendantFeatures.hasInvalidationSetFeaturesInScope = true; |
| 691 else if (siblingFeatures) |
| 669 addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures, descendan
tFeatures); | 692 addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures, descendan
tFeatures); |
| 670 | 693 |
| 671 return simpleSelector; | 694 return simpleSelector; |
| 672 } | 695 } |
| 673 | 696 |
| 674 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector,
InvalidationSetFeatures& descendantFeatures) | 697 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector,
InvalidationSetFeatures& descendantFeatures) |
| 675 { | 698 { |
| 676 // selector is the selector immediately to the left of the rightmost combina
tor. | 699 // selector is the selector immediately to the left of the rightmost combina
tor. |
| 677 // descendantFeatures has the features of the rightmost compound selector. | 700 // descendantFeatures has the features of the rightmost compound selector. |
| 678 | 701 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 if (!metadata.foundInsertionPointCrossing && current->isAdjacentSelector
()) | 796 if (!metadata.foundInsertionPointCrossing && current->isAdjacentSelector
()) |
| 774 metadata.foundSiblingSelector = true; | 797 metadata.foundSiblingSelector = true; |
| 775 } | 798 } |
| 776 | 799 |
| 777 DCHECK(!maxDirectAdjacentSelectors); | 800 DCHECK(!maxDirectAdjacentSelectors); |
| 778 return SelectorMayMatch; | 801 return SelectorMayMatch; |
| 779 } | 802 } |
| 780 | 803 |
| 781 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other) | 804 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other) |
| 782 { | 805 { |
| 783 usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules; | 806 usesFirstLineRules |= other.usesFirstLineRules; |
| 784 usesWindowInactiveSelector = usesWindowInactiveSelector || other.usesWindowI
nactiveSelector; | 807 usesWindowInactiveSelector |= other.usesWindowInactiveSelector; |
| 785 maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxD
irectAdjacentSelectors); | 808 maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxD
irectAdjacentSelectors); |
| 786 } | 809 } |
| 787 | 810 |
| 788 void RuleFeatureSet::FeatureMetadata::clear() | 811 void RuleFeatureSet::FeatureMetadata::clear() |
| 789 { | 812 { |
| 790 usesFirstLineRules = false; | 813 usesFirstLineRules = false; |
| 791 usesWindowInactiveSelector = false; | 814 usesWindowInactiveSelector = false; |
| 792 foundSiblingSelector = false; | 815 foundSiblingSelector = false; |
| 793 foundInsertionPointCrossing = false; | 816 foundInsertionPointCrossing = false; |
| 817 needsFullRecalcForRuleSetInvalidation = false; |
| 794 maxDirectAdjacentSelectors = 0; | 818 maxDirectAdjacentSelectors = 0; |
| 795 } | 819 } |
| 796 | 820 |
| 797 void RuleFeatureSet::add(const RuleFeatureSet& other) | 821 void RuleFeatureSet::add(const RuleFeatureSet& other) |
| 798 { | 822 { |
| 799 RELEASE_ASSERT(m_isAlive); | 823 RELEASE_ASSERT(m_isAlive); |
| 800 RELEASE_ASSERT(other.m_isAlive); | 824 RELEASE_ASSERT(other.m_isAlive); |
| 801 RELEASE_ASSERT(&other != this); | 825 RELEASE_ASSERT(&other != this); |
| 802 for (const auto& entry : other.m_classInvalidationSets) | 826 for (const auto& entry : other.m_classInvalidationSets) |
| 803 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t
ype()).combine(*entry.value); | 827 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t
ype()).combine(*entry.value); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 bool RuleFeatureSet::InvalidationSetFeatures::hasFeatures() const | 1058 bool RuleFeatureSet::InvalidationSetFeatures::hasFeatures() const |
| 1035 { | 1059 { |
| 1036 return !classes.isEmpty() | 1060 return !classes.isEmpty() |
| 1037 || !attributes.isEmpty() | 1061 || !attributes.isEmpty() |
| 1038 || !ids.isEmpty() | 1062 || !ids.isEmpty() |
| 1039 || !tagNames.isEmpty() | 1063 || !tagNames.isEmpty() |
| 1040 || customPseudoElement; | 1064 || customPseudoElement; |
| 1041 } | 1065 } |
| 1042 | 1066 |
| 1043 } // namespace blink | 1067 } // namespace blink |
| OLD | NEW |