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 |