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 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 // found in the other compound selectors (addFeaturesToInvalidationSets). If | 436 // found in the other compound selectors (addFeaturesToInvalidationSets). If |
437 // we find a feature in the right-most compound selector that requires a | 437 // 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 | 438 // subtree recalc, nextCompound will be the rightmost compound and we will |
439 // addFeaturesToInvalidationSets for that one as well. | 439 // addFeaturesToInvalidationSets for that one as well. |
440 | 440 |
441 InvalidationSetFeatures features; | 441 InvalidationSetFeatures features; |
442 InvalidationSetFeatures* siblingFeatures = nullptr; | 442 InvalidationSetFeatures* siblingFeatures = nullptr; |
443 | 443 |
444 const CSSSelector* lastInCompound = extractInvalidationSetFeaturesFromCompou
nd(ruleData.selector(), features, Subject); | 444 const CSSSelector* lastInCompound = extractInvalidationSetFeaturesFromCompou
nd(ruleData.selector(), features, Subject); |
445 | 445 |
446 if (!features.hasFeatures()) | 446 if (features.forceSubtree) |
| 447 features.hasFeaturesForRuleSetInvalidation = false; |
| 448 else if (!features.hasFeatures()) |
447 features.forceSubtree = true; | 449 features.forceSubtree = true; |
448 if (features.hasNthPseudo) | 450 if (features.hasNthPseudo) |
449 addFeaturesToInvalidationSet(ensureNthInvalidationSet(), features); | 451 addFeaturesToInvalidationSet(ensureNthInvalidationSet(), features); |
450 if (features.hasBeforeOrAfter) | 452 if (features.hasBeforeOrAfter) |
451 updateInvalidationSetsForContentAttribute(ruleData); | 453 updateInvalidationSetsForContentAttribute(ruleData); |
452 | 454 |
453 const CSSSelector* nextCompound = lastInCompound ? lastInCompound->tagHistor
y() : &ruleData.selector(); | 455 const CSSSelector* nextCompound = lastInCompound ? lastInCompound->tagHistor
y() : &ruleData.selector(); |
454 if (!nextCompound) | 456 if (!nextCompound) { |
| 457 if (!features.hasFeaturesForRuleSetInvalidation) |
| 458 m_metadata.needsFullRecalcForRuleSetInvalidation = true; |
455 return; | 459 return; |
| 460 } |
456 if (lastInCompound) | 461 if (lastInCompound) |
457 updateFeaturesFromCombinator(*lastInCompound, nullptr, features, sibling
Features, features); | 462 updateFeaturesFromCombinator(*lastInCompound, nullptr, features, sibling
Features, features); |
458 | 463 |
459 addFeaturesToInvalidationSets(*nextCompound, siblingFeatures, features); | 464 addFeaturesToInvalidationSets(*nextCompound, siblingFeatures, features); |
| 465 |
| 466 if (!features.hasFeaturesForRuleSetInvalidation) |
| 467 m_metadata.needsFullRecalcForRuleSetInvalidation = true; |
460 } | 468 } |
461 | 469 |
462 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r
uleData) | 470 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r
uleData) |
463 { | 471 { |
464 // If any ::before and ::after rules specify 'content: attr(...)', we | 472 // If any ::before and ::after rules specify 'content: attr(...)', we |
465 // need to create invalidation sets for those attributes to have content | 473 // need to create invalidation sets for those attributes to have content |
466 // changes applied through style recalc. | 474 // changes applied through style recalc. |
467 | 475 |
468 const StylePropertySet& propertySet = ruleData.rule()->properties(); | 476 const StylePropertySet& propertySet = ruleData.rule()->properties(); |
469 | 477 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 features.hasNthPseudo = true; | 571 features.hasNthPseudo = true; |
564 else if (position == Subject) | 572 else if (position == Subject) |
565 invalidationSet->setInvalidatesSelf(); | 573 invalidationSet->setInvalidatesSelf(); |
566 } | 574 } |
567 | 575 |
568 if (extractInvalidationSetFeaturesFromSelectorList(*simpleSelector, feat
ures, position) == RequiresSubtreeInvalidation) { | 576 if (extractInvalidationSetFeaturesFromSelectorList(*simpleSelector, feat
ures, position) == RequiresSubtreeInvalidation) { |
569 DCHECK(features.forceSubtree); | 577 DCHECK(features.forceSubtree); |
570 return nullptr; | 578 return nullptr; |
571 } | 579 } |
572 | 580 |
573 if (!simpleSelector->tagHistory() || simpleSelector->relation() != CSSSe
lector::SubSelector) | 581 if (!simpleSelector->tagHistory() || simpleSelector->relation() != CSSSe
lector::SubSelector) { |
| 582 features.hasFeaturesForRuleSetInvalidation = features.hasTagIdClassO
rAttribute(); |
574 return simpleSelector; | 583 return simpleSelector; |
| 584 } |
575 } | 585 } |
576 } | 586 } |
577 | 587 |
578 // Add features extracted from the rightmost compound selector to descendant inv
alidation | 588 // Add features extracted from the rightmost compound selector to descendant inv
alidation |
579 // sets for features found in other compound selectors. | 589 // sets for features found in other compound selectors. |
580 // | 590 // |
581 // We use descendant invalidation for descendants, sibling invalidation for sibl
ings and their subtrees. | 591 // We use descendant invalidation for descendants, sibling invalidation for sibl
ings and their subtrees. |
582 // | 592 // |
583 // As we encounter a descendant type of combinator, the features only need to be
checked | 593 // As we encounter a descendant type of combinator, the features only need to be
checked |
584 // against descendants in the same subtree only. features.adjacent is set to fal
se, and | 594 // against descendants in the same subtree only. features.adjacent is set to fal
se, and |
(...skipping 25 matching lines...) Expand all Loading... |
610 } | 620 } |
611 | 621 |
612 | 622 |
613 void RuleFeatureSet::addFeaturesToInvalidationSetsForSelectorList(const CSSSelec
tor& simpleSelector, InvalidationSetFeatures* siblingFeatures, InvalidationSetFe
atures& descendantFeatures) | 623 void RuleFeatureSet::addFeaturesToInvalidationSetsForSelectorList(const CSSSelec
tor& simpleSelector, InvalidationSetFeatures* siblingFeatures, InvalidationSetFe
atures& descendantFeatures) |
614 { | 624 { |
615 if (!simpleSelector.selectorList()) | 625 if (!simpleSelector.selectorList()) |
616 return; | 626 return; |
617 | 627 |
618 DCHECK(supportsInvalidationWithSelectorList(simpleSelector.getPseudoType()))
; | 628 DCHECK(supportsInvalidationWithSelectorList(simpleSelector.getPseudoType()))
; |
619 | 629 |
620 for (const CSSSelector* subSelector = simpleSelector.selectorList()->first()
; subSelector; subSelector = CSSSelectorList::next(*subSelector)) | 630 bool hadFeaturesForRuleSetInvalidation = descendantFeatures.hasFeaturesForRu
leSetInvalidation; |
| 631 bool selectorListContainsUniversal = simpleSelector.getPseudoType() == CSSSe
lector::PseudoNot |
| 632 || simpleSelector.getPseudoType() == CSSSelector::PseudoHostContext; |
| 633 |
| 634 for (const CSSSelector* subSelector = simpleSelector.selectorList()->first()
; subSelector; subSelector = CSSSelectorList::next(*subSelector)) { |
| 635 descendantFeatures.hasFeaturesForRuleSetInvalidation = false; |
| 636 |
621 addFeaturesToInvalidationSetsForCompoundSelector(*subSelector, siblingFe
atures, descendantFeatures); | 637 addFeaturesToInvalidationSetsForCompoundSelector(*subSelector, siblingFe
atures, descendantFeatures); |
| 638 |
| 639 if (!descendantFeatures.hasFeaturesForRuleSetInvalidation) |
| 640 selectorListContainsUniversal = true; |
| 641 } |
| 642 |
| 643 descendantFeatures.hasFeaturesForRuleSetInvalidation = hadFeaturesForRuleSet
Invalidation || !selectorListContainsUniversal; |
622 } | 644 } |
623 | 645 |
624 void RuleFeatureSet::addFeaturesToInvalidationSetsForSimpleSelector(const CSSSel
ector& simpleSelector, InvalidationSetFeatures* siblingFeatures, InvalidationSet
Features& descendantFeatures) | 646 void RuleFeatureSet::addFeaturesToInvalidationSetsForSimpleSelector(const CSSSel
ector& simpleSelector, InvalidationSetFeatures* siblingFeatures, InvalidationSet
Features& descendantFeatures) |
625 { | 647 { |
626 if (InvalidationSet* invalidationSet = invalidationSetForSimpleSelector(simp
leSelector, siblingFeatures ? InvalidateSiblings : InvalidateDescendants)) { | 648 if (InvalidationSet* invalidationSet = invalidationSetForSimpleSelector(simp
leSelector, siblingFeatures ? InvalidateSiblings : InvalidateDescendants)) { |
627 if (!siblingFeatures || invalidationSet == m_nthInvalidationSet) { | 649 if (!siblingFeatures || invalidationSet == m_nthInvalidationSet) { |
628 addFeaturesToInvalidationSet(*invalidationSet, descendantFeatures); | 650 addFeaturesToInvalidationSet(*invalidationSet, descendantFeatures); |
629 return; | 651 return; |
630 } | 652 } |
631 | 653 |
(...skipping 14 matching lines...) Expand all Loading... |
646 | 668 |
647 addFeaturesToInvalidationSetsForSelectorList(simpleSelector, siblingFeatures
, descendantFeatures); | 669 addFeaturesToInvalidationSetsForSelectorList(simpleSelector, siblingFeatures
, descendantFeatures); |
648 } | 670 } |
649 | 671 |
650 const CSSSelector* RuleFeatureSet::addFeaturesToInvalidationSetsForCompoundSelec
tor(const CSSSelector& compound, InvalidationSetFeatures* siblingFeatures, Inval
idationSetFeatures& descendantFeatures) | 672 const CSSSelector* RuleFeatureSet::addFeaturesToInvalidationSetsForCompoundSelec
tor(const CSSSelector& compound, InvalidationSetFeatures* siblingFeatures, Inval
idationSetFeatures& descendantFeatures) |
651 { | 673 { |
652 bool compoundHasIdClassOrAttribute = false; | 674 bool compoundHasIdClassOrAttribute = false; |
653 const CSSSelector* simpleSelector = &compound; | 675 const CSSSelector* simpleSelector = &compound; |
654 for (; simpleSelector; simpleSelector = simpleSelector->tagHistory()) { | 676 for (; simpleSelector; simpleSelector = simpleSelector->tagHistory()) { |
655 addFeaturesToInvalidationSetsForSimpleSelector(*simpleSelector, siblingF
eatures, descendantFeatures); | 677 addFeaturesToInvalidationSetsForSimpleSelector(*simpleSelector, siblingF
eatures, descendantFeatures); |
656 if (siblingFeatures) | 678 if (simpleSelector->isIdClassOrAttributeSelector()) |
657 compoundHasIdClassOrAttribute |= simpleSelector->isIdClassOrAttribut
eSelector(); | 679 compoundHasIdClassOrAttribute = true; |
658 if (simpleSelector->relation() != CSSSelector::SubSelector) | 680 if (simpleSelector->relation() != CSSSelector::SubSelector) |
659 break; | 681 break; |
660 if (!simpleSelector->tagHistory()) | 682 if (!simpleSelector->tagHistory()) |
661 break; | 683 break; |
662 } | 684 } |
663 | 685 |
664 if (siblingFeatures && !compoundHasIdClassOrAttribute) | 686 if (compoundHasIdClassOrAttribute) |
| 687 descendantFeatures.hasFeaturesForRuleSetInvalidation = true; |
| 688 else if (siblingFeatures) |
665 addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures, descendan
tFeatures); | 689 addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures, descendan
tFeatures); |
666 | 690 |
667 return simpleSelector; | 691 return simpleSelector; |
668 } | 692 } |
669 | 693 |
670 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector,
InvalidationSetFeatures* siblingFeatures, InvalidationSetFeatures& descendantFea
tures) | 694 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector,
InvalidationSetFeatures* siblingFeatures, InvalidationSetFeatures& descendantFea
tures) |
671 { | 695 { |
672 // selector is the selector immediately to the left of the rightmost combina
tor. | 696 // selector is the selector immediately to the left of the rightmost combina
tor. |
673 // descendantFeatures has the features of the rightmost compound selector. | 697 // descendantFeatures has the features of the rightmost compound selector. |
674 | 698 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 if (!metadata.foundInsertionPointCrossing && current->isAdjacentSelector
()) | 791 if (!metadata.foundInsertionPointCrossing && current->isAdjacentSelector
()) |
768 metadata.foundSiblingSelector = true; | 792 metadata.foundSiblingSelector = true; |
769 } | 793 } |
770 | 794 |
771 DCHECK(!maxDirectAdjacentSelectors); | 795 DCHECK(!maxDirectAdjacentSelectors); |
772 return SelectorMayMatch; | 796 return SelectorMayMatch; |
773 } | 797 } |
774 | 798 |
775 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other) | 799 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other) |
776 { | 800 { |
777 usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules; | 801 usesFirstLineRules |= other.usesFirstLineRules; |
778 usesWindowInactiveSelector = usesWindowInactiveSelector || other.usesWindowI
nactiveSelector; | 802 usesWindowInactiveSelector |= other.usesWindowInactiveSelector; |
779 maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxD
irectAdjacentSelectors); | 803 maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxD
irectAdjacentSelectors); |
780 } | 804 } |
781 | 805 |
782 void RuleFeatureSet::FeatureMetadata::clear() | 806 void RuleFeatureSet::FeatureMetadata::clear() |
783 { | 807 { |
784 usesFirstLineRules = false; | 808 usesFirstLineRules = false; |
785 usesWindowInactiveSelector = false; | 809 usesWindowInactiveSelector = false; |
786 foundSiblingSelector = false; | 810 foundSiblingSelector = false; |
787 foundInsertionPointCrossing = false; | 811 foundInsertionPointCrossing = false; |
| 812 needsFullRecalcForRuleSetInvalidation = false; |
788 maxDirectAdjacentSelectors = 0; | 813 maxDirectAdjacentSelectors = 0; |
789 } | 814 } |
790 | 815 |
791 void RuleFeatureSet::add(const RuleFeatureSet& other) | 816 void RuleFeatureSet::add(const RuleFeatureSet& other) |
792 { | 817 { |
793 RELEASE_ASSERT(m_isAlive); | 818 RELEASE_ASSERT(m_isAlive); |
794 RELEASE_ASSERT(other.m_isAlive); | 819 RELEASE_ASSERT(other.m_isAlive); |
795 RELEASE_ASSERT(&other != this); | 820 RELEASE_ASSERT(&other != this); |
796 for (const auto& entry : other.m_classInvalidationSets) | 821 for (const auto& entry : other.m_classInvalidationSets) |
797 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t
ype()).combine(*entry.value); | 822 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t
ype()).combine(*entry.value); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 | 1052 |
1028 bool RuleFeatureSet::InvalidationSetFeatures::hasFeatures() const | 1053 bool RuleFeatureSet::InvalidationSetFeatures::hasFeatures() const |
1029 { | 1054 { |
1030 return !classes.isEmpty() | 1055 return !classes.isEmpty() |
1031 || !attributes.isEmpty() | 1056 || !attributes.isEmpty() |
1032 || !ids.isEmpty() | 1057 || !ids.isEmpty() |
1033 || !tagNames.isEmpty() | 1058 || !tagNames.isEmpty() |
1034 || customPseudoElement; | 1059 || customPseudoElement; |
1035 } | 1060 } |
1036 | 1061 |
| 1062 bool RuleFeatureSet::InvalidationSetFeatures::hasTagIdClassOrAttribute() const |
| 1063 { |
| 1064 return !classes.isEmpty() |
| 1065 || !attributes.isEmpty() |
| 1066 || !ids.isEmpty() |
| 1067 || !tagNames.isEmpty(); |
| 1068 } |
| 1069 |
1037 } // namespace blink | 1070 } // namespace blink |
OLD | NEW |