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 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 // Given a rule, update the descendant invalidation sets for the features | 432 // Given a rule, update the descendant invalidation sets for the features |
433 // found in its selector. The first step is to extract the features from the | 433 // found in its selector. The first step is to extract the features from the |
434 // rightmost compound selector (extractInvalidationSetFeaturesFromCompound). | 434 // rightmost compound selector (extractInvalidationSetFeaturesFromCompound). |
435 // Secondly, add those features to the invalidation sets for the features | 435 // Secondly, add those features to the invalidation sets for the features |
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 const CSSSelector* nextCompound = extractInvalidationSetFeaturesFromCompound
(ruleData.selector(), features, Subject); | 442 InvalidationSetFeatures* siblingFeatures = nullptr; |
| 443 |
| 444 const CSSSelector* lastInCompound = extractInvalidationSetFeaturesFromCompou
nd(ruleData.selector(), features, Subject); |
443 | 445 |
444 if (!features.hasFeatures()) | 446 if (!features.hasFeatures()) |
445 features.forceSubtree = true; | 447 features.forceSubtree = true; |
446 | 448 if (features.hasNthPseudo) |
447 if (nextCompound) | |
448 addFeaturesToInvalidationSets(*nextCompound, features); | |
449 else if (features.hasNthPseudo) | |
450 addFeaturesToInvalidationSet(ensureNthInvalidationSet(), features); | 449 addFeaturesToInvalidationSet(ensureNthInvalidationSet(), features); |
451 | |
452 if (features.hasBeforeOrAfter) | 450 if (features.hasBeforeOrAfter) |
453 updateInvalidationSetsForContentAttribute(ruleData); | 451 updateInvalidationSetsForContentAttribute(ruleData); |
| 452 |
| 453 const CSSSelector* nextCompound = lastInCompound ? lastInCompound->tagHistor
y() : &ruleData.selector(); |
| 454 if (!nextCompound) |
| 455 return; |
| 456 if (lastInCompound) |
| 457 updateFeaturesFromCombinator(*lastInCompound, nullptr, features, sibling
Features, features); |
| 458 |
| 459 addFeaturesToInvalidationSets(*nextCompound, siblingFeatures, features); |
454 } | 460 } |
455 | 461 |
456 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r
uleData) | 462 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r
uleData) |
457 { | 463 { |
458 // If any ::before and ::after rules specify 'content: attr(...)', we | 464 // If any ::before and ::after rules specify 'content: attr(...)', we |
459 // need to create invalidation sets for those attributes to have content | 465 // need to create invalidation sets for those attributes to have content |
460 // changes applied through style recalc. | 466 // changes applied through style recalc. |
461 | 467 |
462 const StylePropertySet& propertySet = ruleData.rule()->properties(); | 468 const StylePropertySet& propertySet = ruleData.rule()->properties(); |
463 | 469 |
(...skipping 11 matching lines...) Expand all Loading... |
475 for (auto& item : toCSSValueList(contentValue)) { | 481 for (auto& item : toCSSValueList(contentValue)) { |
476 if (!item->isFunctionValue()) | 482 if (!item->isFunctionValue()) |
477 continue; | 483 continue; |
478 const CSSFunctionValue* functionValue = toCSSFunctionValue(item.get()); | 484 const CSSFunctionValue* functionValue = toCSSFunctionValue(item.get()); |
479 if (functionValue->functionType() != CSSValueAttr) | 485 if (functionValue->functionType() != CSSValueAttr) |
480 continue; | 486 continue; |
481 ensureAttributeInvalidationSet(AtomicString(toCSSCustomIdentValue(functi
onValue->item(0)).value()), InvalidateDescendants).setInvalidatesSelf(); | 487 ensureAttributeInvalidationSet(AtomicString(toCSSCustomIdentValue(functi
onValue->item(0)).value()), InvalidateDescendants).setInvalidatesSelf(); |
482 } | 488 } |
483 } | 489 } |
484 | 490 |
485 const CSSSelector* | 491 RuleFeatureSet::FeatureInvalidationType |
486 RuleFeatureSet::extractInvalidationSetFeaturesFromSelectorList(const CSSSelector
& simpleSelector, InvalidationSetFeatures& features, PositionType position) | 492 RuleFeatureSet::extractInvalidationSetFeaturesFromSelectorList(const CSSSelector
& simpleSelector, InvalidationSetFeatures& features, PositionType position) |
487 { | 493 { |
488 const CSSSelectorList* selectorList = simpleSelector.selectorList(); | 494 const CSSSelectorList* selectorList = simpleSelector.selectorList(); |
489 if (!selectorList) | 495 if (!selectorList) |
490 return nullptr; | 496 return NormalInvalidation; |
491 | 497 |
492 DCHECK(supportsInvalidationWithSelectorList(simpleSelector.getPseudoType()))
; | 498 DCHECK(supportsInvalidationWithSelectorList(simpleSelector.getPseudoType()))
; |
493 | 499 |
494 const CSSSelector* subSelector = selectorList->first(); | 500 const CSSSelector* subSelector = selectorList->first(); |
495 | 501 |
496 bool allSubSelectorsHaveFeatures = true; | 502 bool allSubSelectorsHaveFeatures = true; |
497 InvalidationSetFeatures anyFeatures; | 503 InvalidationSetFeatures anyFeatures; |
498 | 504 |
499 for (; subSelector; subSelector = CSSSelectorList::next(*subSelector)) { | 505 for (; subSelector; subSelector = CSSSelectorList::next(*subSelector)) { |
500 InvalidationSetFeatures compoundFeatures; | 506 InvalidationSetFeatures compoundFeatures; |
501 if (extractInvalidationSetFeaturesFromCompound(*subSelector, compoundFea
tures, position, simpleSelector.getPseudoType())) { | 507 if (!extractInvalidationSetFeaturesFromCompound(*subSelector, compoundFe
atures, position, simpleSelector.getPseudoType())) { |
502 // A non-null selector return means the sub-selector contained a | 508 // A null selector return means the sub-selector contained a |
503 // selector which requiresSubtreeInvalidation(). | 509 // selector which requiresSubtreeInvalidation(). |
504 DCHECK(compoundFeatures.forceSubtree); | 510 DCHECK(compoundFeatures.forceSubtree); |
505 features.forceSubtree = true; | 511 features.forceSubtree = true; |
506 return &simpleSelector; | 512 return RequiresSubtreeInvalidation; |
507 } | 513 } |
508 if (allSubSelectorsHaveFeatures && !compoundFeatures.hasFeatures()) | 514 if (allSubSelectorsHaveFeatures && !compoundFeatures.hasFeatures()) |
509 allSubSelectorsHaveFeatures = false; | 515 allSubSelectorsHaveFeatures = false; |
510 else | 516 else |
511 anyFeatures.add(compoundFeatures); | 517 anyFeatures.add(compoundFeatures); |
512 if (compoundFeatures.hasNthPseudo) | 518 if (compoundFeatures.hasNthPseudo) |
513 features.hasNthPseudo = true; | 519 features.hasNthPseudo = true; |
514 } | 520 } |
515 // Don't add any features if one of the sub-selectors of does not contain | 521 // Don't add any features if one of the sub-selectors of does not contain |
516 // any invalidation set features. E.g. :-webkit-any(*, span). | 522 // any invalidation set features. E.g. :-webkit-any(*, span). |
517 if (allSubSelectorsHaveFeatures) | 523 if (allSubSelectorsHaveFeatures) |
518 features.add(anyFeatures); | 524 features.add(anyFeatures); |
519 return nullptr; | 525 return NormalInvalidation; |
520 } | 526 } |
521 | 527 |
522 const CSSSelector* | 528 const CSSSelector* |
523 RuleFeatureSet::extractInvalidationSetFeaturesFromCompound(const CSSSelector& co
mpound, InvalidationSetFeatures& features, PositionType position, CSSSelector::P
seudoType pseudo) | 529 RuleFeatureSet::extractInvalidationSetFeaturesFromCompound(const CSSSelector& co
mpound, InvalidationSetFeatures& features, PositionType position, CSSSelector::P
seudoType pseudo) |
524 { | 530 { |
| 531 // Extract invalidation set features and return a pointer to the the last |
| 532 // simple selector of the compound, or nullptr if one of the selectors |
| 533 // requiresSubtreeInvalidation(). |
| 534 |
525 const CSSSelector* simpleSelector = &compound; | 535 const CSSSelector* simpleSelector = &compound; |
526 for (; simpleSelector; simpleSelector = simpleSelector->tagHistory()) { | 536 for (;; simpleSelector = simpleSelector->tagHistory()) { |
527 | 537 |
528 // Fall back to use subtree invalidations, even for features in the | 538 // Fall back to use subtree invalidations, even for features in the |
529 // rightmost compound selector. Returning the start &selector here | 539 // rightmost compound selector. Returning nullptr here will make |
530 // will make addFeaturesToInvalidationSets start marking invalidation | 540 // addFeaturesToInvalidationSets start marking invalidation sets for |
531 // sets for subtree recalc for features in the rightmost compound | 541 // subtree recalc for features in the rightmost compound selector. |
532 // selector. | |
533 if (requiresSubtreeInvalidation(*simpleSelector)) { | 542 if (requiresSubtreeInvalidation(*simpleSelector)) { |
534 features.forceSubtree = true; | 543 features.forceSubtree = true; |
535 return &compound; | 544 return nullptr; |
536 } | 545 } |
537 | 546 |
538 // When inside a :not(), we should not use the found features for | 547 // When inside a :not(), we should not use the found features for |
539 // invalidation because we should invalidate elements _without_ that | 548 // invalidation because we should invalidate elements _without_ that |
540 // feature. On the other hand, we should still have invalidation sets | 549 // feature. On the other hand, we should still have invalidation sets |
541 // for the features since we are able to detect when they change. | 550 // for the features since we are able to detect when they change. |
542 // That is, ".a" should not have ".b" in its invalidation set for | 551 // That is, ".a" should not have ".b" in its invalidation set for |
543 // ".a :not(.b)", but there should be an invalidation set for ".a" in | 552 // ".a :not(.b)", but there should be an invalidation set for ".a" in |
544 // ":not(.a) .b". | 553 // ":not(.a) .b". |
545 if (pseudo != CSSSelector::PseudoNot) | 554 if (pseudo != CSSSelector::PseudoNot) |
546 extractInvalidationSetFeaturesFromSimpleSelector(*simpleSelector, fe
atures); | 555 extractInvalidationSetFeaturesFromSimpleSelector(*simpleSelector, fe
atures); |
547 | 556 |
548 // Initialize the entry in the invalidation set map for self- | 557 // Initialize the entry in the invalidation set map for self- |
549 // invalidation, if supported. | 558 // invalidation, if supported. |
550 if (InvalidationSet* invalidationSet = invalidationSetForSimpleSelector(
*simpleSelector, InvalidateDescendants)) { | 559 if (InvalidationSet* invalidationSet = invalidationSetForSimpleSelector(
*simpleSelector, InvalidateDescendants)) { |
551 if (invalidationSet == m_nthInvalidationSet) | 560 if (invalidationSet == m_nthInvalidationSet) |
552 features.hasNthPseudo = true; | 561 features.hasNthPseudo = true; |
553 else if (position == Subject) | 562 else if (position == Subject) |
554 invalidationSet->setInvalidatesSelf(); | 563 invalidationSet->setInvalidatesSelf(); |
555 } | 564 } |
556 | 565 |
557 if (extractInvalidationSetFeaturesFromSelectorList(*simpleSelector, feat
ures, position)) { | 566 if (extractInvalidationSetFeaturesFromSelectorList(*simpleSelector, feat
ures, position) == RequiresSubtreeInvalidation) { |
558 DCHECK(features.forceSubtree); | 567 DCHECK(features.forceSubtree); |
559 return &compound; | 568 return nullptr; |
560 } | 569 } |
561 | 570 |
562 if (simpleSelector->relation() == CSSSelector::SubSelector) | 571 if (!simpleSelector->tagHistory() || simpleSelector->relation() != CSSSe
lector::SubSelector) |
563 continue; | 572 return simpleSelector; |
564 | |
565 if (position == Subject) { | |
566 if (features.hasNthPseudo) { | |
567 DCHECK(m_nthInvalidationSet); | |
568 if (features.hasFeatures()) | |
569 addFeaturesToInvalidationSet(*m_nthInvalidationSet, features
); | |
570 else | |
571 m_nthInvalidationSet->setWholeSubtreeInvalid(); | |
572 } | |
573 InvalidationSetFeatures* siblingFeatures = nullptr; | |
574 updateFeaturesFromCombinator(*simpleSelector, nullptr, features, sib
lingFeatures, features); | |
575 } | |
576 return simpleSelector->tagHistory(); | |
577 } | 573 } |
578 | |
579 return nullptr; | |
580 } | 574 } |
581 | 575 |
582 // Add features extracted from the rightmost compound selector to descendant inv
alidation | 576 // Add features extracted from the rightmost compound selector to descendant inv
alidation |
583 // sets for features found in other compound selectors. | 577 // sets for features found in other compound selectors. |
584 // | 578 // |
585 // We use descendant invalidation for descendants, sibling invalidation for sibl
ings and their subtrees. | 579 // We use descendant invalidation for descendants, sibling invalidation for sibl
ings and their subtrees. |
586 // | 580 // |
587 // As we encounter a descendant type of combinator, the features only need to be
checked | 581 // 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 | 582 // against descendants in the same subtree only. features.adjacent is set to fal
se, and |
589 // we start adding features to the descendant invalidation set. | 583 // we start adding features to the descendant invalidation set. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 if (!simpleSelector->tagHistory()) | 658 if (!simpleSelector->tagHistory()) |
665 break; | 659 break; |
666 } | 660 } |
667 | 661 |
668 if (siblingFeatures && !compoundHasIdClassOrAttribute) | 662 if (siblingFeatures && !compoundHasIdClassOrAttribute) |
669 addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures, descendan
tFeatures); | 663 addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures, descendan
tFeatures); |
670 | 664 |
671 return simpleSelector; | 665 return simpleSelector; |
672 } | 666 } |
673 | 667 |
674 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector,
InvalidationSetFeatures& descendantFeatures) | 668 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector,
InvalidationSetFeatures* siblingFeatures, InvalidationSetFeatures& descendantFea
tures) |
675 { | 669 { |
676 // selector is the selector immediately to the left of the rightmost combina
tor. | 670 // selector is the selector immediately to the left of the rightmost combina
tor. |
677 // descendantFeatures has the features of the rightmost compound selector. | 671 // descendantFeatures has the features of the rightmost compound selector. |
678 | 672 |
679 InvalidationSetFeatures lastCompoundInSiblingChainFeatures; | 673 InvalidationSetFeatures lastCompoundInSiblingChainFeatures; |
680 InvalidationSetFeatures* siblingFeatures = descendantFeatures.maxDirectAdjac
entSelectors ? &descendantFeatures : nullptr; | |
681 | |
682 const CSSSelector* compound = &selector; | 674 const CSSSelector* compound = &selector; |
683 while (compound) { | 675 while (compound) { |
684 const CSSSelector* lastInCompound = addFeaturesToInvalidationSetsForComp
oundSelector(*compound, siblingFeatures, descendantFeatures); | 676 const CSSSelector* lastInCompound = addFeaturesToInvalidationSetsForComp
oundSelector(*compound, siblingFeatures, descendantFeatures); |
685 DCHECK(lastInCompound); | 677 DCHECK(lastInCompound); |
686 updateFeaturesFromCombinator(*lastInCompound, compound, lastCompoundInSi
blingChainFeatures, siblingFeatures, descendantFeatures); | 678 updateFeaturesFromCombinator(*lastInCompound, compound, lastCompoundInSi
blingChainFeatures, siblingFeatures, descendantFeatures); |
687 compound = lastInCompound->tagHistory(); | 679 compound = lastInCompound->tagHistory(); |
688 } | 680 } |
689 } | 681 } |
690 | 682 |
691 RuleFeatureSet::SelectorPreMatch RuleFeatureSet::collectFeaturesFromRuleData(con
st RuleData& ruleData) | 683 RuleFeatureSet::SelectorPreMatch RuleFeatureSet::collectFeaturesFromRuleData(con
st RuleData& ruleData) |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 bool RuleFeatureSet::InvalidationSetFeatures::hasFeatures() const | 1026 bool RuleFeatureSet::InvalidationSetFeatures::hasFeatures() const |
1035 { | 1027 { |
1036 return !classes.isEmpty() | 1028 return !classes.isEmpty() |
1037 || !attributes.isEmpty() | 1029 || !attributes.isEmpty() |
1038 || !ids.isEmpty() | 1030 || !ids.isEmpty() |
1039 || !tagNames.isEmpty() | 1031 || !tagNames.isEmpty() |
1040 || customPseudoElement; | 1032 || customPseudoElement; |
1041 } | 1033 } |
1042 | 1034 |
1043 } // namespace blink | 1035 } // namespace blink |
OLD | NEW |