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 |