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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 return true; | 296 return true; |
297 } | 297 } |
298 if (selector.isAttributeSelector()) { | 298 if (selector.isAttributeSelector()) { |
299 features.attributes.append(selector.attribute().localName()); | 299 features.attributes.append(selector.attribute().localName()); |
300 return true; | 300 return true; |
301 } | 301 } |
302 if (selector.getPseudoType() == CSSSelector::PseudoWebKitCustomElement || se
lector.getPseudoType() == CSSSelector::PseudoBlinkInternalElement) { | 302 if (selector.getPseudoType() == CSSSelector::PseudoWebKitCustomElement || se
lector.getPseudoType() == CSSSelector::PseudoBlinkInternalElement) { |
303 features.customPseudoElement = true; | 303 features.customPseudoElement = true; |
304 return true; | 304 return true; |
305 } | 305 } |
| 306 // Returning false for ::before and ::after as they are not used as |
| 307 // invalidation set features, only used later to generate invalidation sets |
| 308 // for attributes present in "content: attr(...)" declarations. |
306 if (selector.getPseudoType() == CSSSelector::PseudoBefore || selector.getPse
udoType() == CSSSelector::PseudoAfter) | 309 if (selector.getPseudoType() == CSSSelector::PseudoBefore || selector.getPse
udoType() == CSSSelector::PseudoAfter) |
307 features.hasBeforeOrAfter = true; | 310 features.hasBeforeOrAfter = true; |
308 return false; | 311 return false; |
309 } | 312 } |
310 | 313 |
311 InvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& s
elector, InvalidationType type) | 314 InvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& s
elector, InvalidationType type) |
312 { | 315 { |
313 if (selector.match() == CSSSelector::Class) | 316 if (selector.match() == CSSSelector::Class) |
314 return &ensureClassInvalidationSet(selector.value(), type); | 317 return &ensureClassInvalidationSet(selector.value(), type); |
315 if (selector.isAttributeSelector()) | 318 if (selector.isAttributeSelector()) |
(...skipping 28 matching lines...) Expand all Loading... |
344 case CSSSelector::PseudoIndeterminate: | 347 case CSSSelector::PseudoIndeterminate: |
345 case CSSSelector::PseudoTarget: | 348 case CSSSelector::PseudoTarget: |
346 case CSSSelector::PseudoLang: | 349 case CSSSelector::PseudoLang: |
347 case CSSSelector::PseudoFullScreen: | 350 case CSSSelector::PseudoFullScreen: |
348 case CSSSelector::PseudoFullScreenAncestor: | 351 case CSSSelector::PseudoFullScreenAncestor: |
349 case CSSSelector::PseudoInRange: | 352 case CSSSelector::PseudoInRange: |
350 case CSSSelector::PseudoOutOfRange: | 353 case CSSSelector::PseudoOutOfRange: |
351 case CSSSelector::PseudoUnresolved: | 354 case CSSSelector::PseudoUnresolved: |
352 case CSSSelector::PseudoDefined: | 355 case CSSSelector::PseudoDefined: |
353 return &ensurePseudoInvalidationSet(selector.getPseudoType(), type); | 356 return &ensurePseudoInvalidationSet(selector.getPseudoType(), type); |
| 357 case CSSSelector::PseudoFirstOfType: |
| 358 case CSSSelector::PseudoLastOfType: |
| 359 case CSSSelector::PseudoOnlyOfType: |
| 360 case CSSSelector::PseudoNthChild: |
| 361 case CSSSelector::PseudoNthOfType: |
| 362 case CSSSelector::PseudoNthLastChild: |
| 363 case CSSSelector::PseudoNthLastOfType: |
| 364 return &ensureNthInvalidationSet(); |
354 default: | 365 default: |
355 break; | 366 break; |
356 } | 367 } |
357 } | 368 } |
358 return nullptr; | 369 return nullptr; |
359 } | 370 } |
360 | 371 |
361 // Given a rule, update the descendant invalidation sets for the features found | 372 // 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 | 373 // in its selector. The first step is to extract the features from the rightmost |
363 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu
res | 374 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu
res |
364 // to the invalidation sets for the features found in the other compound selecto
rs | 375 // 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 | 376 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compo
und |
366 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for
the | 377 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for
the |
367 // rightmost compound selector as well. | 378 // rightmost compound selector as well. |
368 | 379 |
369 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) | 380 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) |
370 { | 381 { |
371 InvalidationSetFeatures features; | 382 InvalidationSetFeatures features; |
372 auto result = extractInvalidationSetFeatures(ruleData.selector(), features,
Subject); | 383 auto result = extractInvalidationSetFeatures(ruleData.selector(), features,
Subject); |
373 | 384 |
| 385 features.forceSubtree = result.second == ForceSubtree; |
374 if (result.first) { | 386 if (result.first) { |
375 features.forceSubtree = result.second == ForceSubtree; | |
376 addFeaturesToInvalidationSets(result.first, features.adjacent ? &feature
s : nullptr, features); | 387 addFeaturesToInvalidationSets(result.first, features.adjacent ? &feature
s : nullptr, features); |
| 388 } else if (features.hasNthPseudo) { |
| 389 DCHECK(m_nthInvalidationSet); |
| 390 addFeaturesToInvalidationSet(*m_nthInvalidationSet, features); |
377 } | 391 } |
378 | 392 |
379 // If any ::before and ::after rules specify 'content: attr(...)', we | 393 // If any ::before and ::after rules specify 'content: attr(...)', we |
380 // need to create invalidation sets for those attributes. | 394 // need to create invalidation sets for those attributes. |
381 if (features.hasBeforeOrAfter) | 395 if (features.hasBeforeOrAfter) |
382 updateInvalidationSetsForContentAttribute(ruleData); | 396 updateInvalidationSetsForContentAttribute(ruleData); |
383 } | 397 } |
384 | 398 |
385 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r
uleData) | 399 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r
uleData) |
386 { | 400 { |
(...skipping 22 matching lines...) Expand all Loading... |
409 | 423 |
410 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType> | 424 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType> |
411 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva
lidationSetFeatures& features, PositionType position, CSSSelector::PseudoType ps
eudo) | 425 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva
lidationSetFeatures& features, PositionType position, CSSSelector::PseudoType ps
eudo) |
412 { | 426 { |
413 bool foundFeatures = false; | 427 bool foundFeatures = false; |
414 for (const CSSSelector* current = &selector; current; current = current->tag
History()) { | 428 for (const CSSSelector* current = &selector; current; current = current->tag
History()) { |
415 if (pseudo != CSSSelector::PseudoNot) | 429 if (pseudo != CSSSelector::PseudoNot) |
416 foundFeatures |= extractInvalidationSetFeature(*current, features); | 430 foundFeatures |= extractInvalidationSetFeature(*current, features); |
417 // Initialize the entry in the invalidation set map, if supported. | 431 // Initialize the entry in the invalidation set map, if supported. |
418 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre
nt, InvalidateDescendants)) { | 432 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre
nt, InvalidateDescendants)) { |
419 if (position == Subject) | 433 if (position == Subject) { |
420 invalidationSet->setInvalidatesSelf(); | 434 if (invalidationSet == m_nthInvalidationSet) |
| 435 features.hasNthPseudo = true; |
| 436 else |
| 437 invalidationSet->setInvalidatesSelf(); |
| 438 } |
421 } else { | 439 } else { |
422 if (requiresSubtreeInvalidation(*current)) { | 440 if (requiresSubtreeInvalidation(*current)) { |
423 // Fall back to use subtree invalidations, even for features in
the | 441 // Fall back to use subtree invalidations, even for features in
the |
424 // rightmost compound selector. Returning the start &selector he
re | 442 // rightmost compound selector. Returning the start &selector he
re |
425 // will make addFeaturesToInvalidationSets start marking invalid
ation | 443 // will make addFeaturesToInvalidationSets start marking invalid
ation |
426 // sets for subtree recalc for features in the rightmost compoun
d | 444 // sets for subtree recalc for features in the rightmost compoun
d |
427 // selector. | 445 // selector. |
428 return std::make_pair(&selector, ForceSubtree); | 446 return std::make_pair(&selector, ForceSubtree); |
429 } | 447 } |
430 if (const CSSSelectorList* selectorList = current->selectorList()) { | 448 if (const CSSSelectorList* selectorList = current->selectorList()) { |
(...skipping 14 matching lines...) Expand all Loading... |
445 } | 463 } |
446 allSubSelectorsHaveFeatures &= result.second == UseFeatures; | 464 allSubSelectorsHaveFeatures &= result.second == UseFeatures; |
447 } | 465 } |
448 foundFeatures |= allSubSelectorsHaveFeatures; | 466 foundFeatures |= allSubSelectorsHaveFeatures; |
449 } | 467 } |
450 } | 468 } |
451 | 469 |
452 if (current->relation() == CSSSelector::SubSelector) | 470 if (current->relation() == CSSSelector::SubSelector) |
453 continue; | 471 continue; |
454 | 472 |
| 473 if (features.hasNthPseudo && position == Subject) { |
| 474 DCHECK(m_nthInvalidationSet); |
| 475 if (foundFeatures) |
| 476 addFeaturesToInvalidationSet(*m_nthInvalidationSet, features); |
| 477 else |
| 478 m_nthInvalidationSet->setWholeSubtreeInvalid(); |
| 479 } |
| 480 |
455 features.treeBoundaryCrossing = current->isShadowSelector(); | 481 features.treeBoundaryCrossing = current->isShadowSelector(); |
456 if (current->relationIsAffectedByPseudoContent()) { | 482 if (current->relationIsAffectedByPseudoContent()) { |
457 features.contentPseudoCrossing = true; | 483 features.contentPseudoCrossing = true; |
458 features.insertionPointCrossing = true; | 484 features.insertionPointCrossing = true; |
459 } | 485 } |
460 features.adjacent = current->isAdjacentSelector(); | 486 features.adjacent = current->isAdjacentSelector(); |
461 if (current->relation() == CSSSelector::DirectAdjacent) | 487 if (current->relation() == CSSSelector::DirectAdjacent) |
462 features.maxDirectAdjacentSelectors = 1; | 488 features.maxDirectAdjacentSelectors = 1; |
463 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures
: ForceSubtree); | 489 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures
: ForceSubtree); |
464 } | 490 } |
465 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); | 491 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); |
466 } | 492 } |
467 | 493 |
468 // Add features extracted from the rightmost compound selector to descendant inv
alidation | 494 // Add features extracted from the rightmost compound selector to descendant inv
alidation |
469 // sets for features found in other compound selectors. | 495 // sets for features found in other compound selectors. |
470 // | 496 // |
471 // We use descendant invalidation for descendants, sibling invalidation for sibl
ings and their subtrees. | 497 // We use descendant invalidation for descendants, sibling invalidation for sibl
ings and their subtrees. |
472 // | 498 // |
473 // As we encounter a descendant type of combinator, the features only need to be
checked | 499 // 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 | 500 // 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. | 501 // 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. | 535 // We set siblingFeatures to &localFeatures if we find a rightmost sibling c
ombinator. |
510 InvalidationSetFeatures localFeatures; | 536 InvalidationSetFeatures localFeatures; |
511 | 537 |
512 bool universalCompound = true; | 538 bool universalCompound = true; |
513 | 539 |
514 for (const CSSSelector* current = selector; current; current = current->tagH
istory()) { | 540 for (const CSSSelector* current = selector; current; current = current->tagH
istory()) { |
515 InvalidationType type = siblingFeatures ? InvalidateSiblings : Invalidat
eDescendants; | 541 InvalidationType type = siblingFeatures ? InvalidateSiblings : Invalidat
eDescendants; |
516 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre
nt, type)) { | 542 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre
nt, type)) { |
517 if (current->match() != CSSSelector::PseudoClass) | 543 if (current->match() != CSSSelector::PseudoClass) |
518 universalCompound = false; | 544 universalCompound = false; |
519 if (siblingFeatures) { | 545 if (siblingFeatures && invalidationSet != m_nthInvalidationSet) { |
520 SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvali
dationSet(invalidationSet); | 546 SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvali
dationSet(invalidationSet); |
521 siblingInvalidationSet->updateMaxDirectAdjacentSelectors(sibling
Features->maxDirectAdjacentSelectors); | 547 siblingInvalidationSet->updateMaxDirectAdjacentSelectors(sibling
Features->maxDirectAdjacentSelectors); |
522 | 548 |
523 addFeaturesToInvalidationSet(*invalidationSet, *siblingFeatures)
; | 549 addFeaturesToInvalidationSet(*invalidationSet, *siblingFeatures)
; |
524 if (siblingFeatures == &descendantFeatures) | 550 if (siblingFeatures == &descendantFeatures) |
525 siblingInvalidationSet->setInvalidatesSelf(); | 551 siblingInvalidationSet->setInvalidatesSelf(); |
526 else | 552 else |
527 addFeaturesToInvalidationSet(siblingInvalidationSet->ensureS
iblingDescendants(), descendantFeatures); | 553 addFeaturesToInvalidationSet(siblingInvalidationSet->ensureS
iblingDescendants(), descendantFeatures); |
528 } else { | 554 } else { |
529 addFeaturesToInvalidationSet(*invalidationSet, descendantFeature
s); | 555 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) | 717 for (const auto& entry : other.m_classInvalidationSets) |
692 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t
ype()).combine(*entry.value); | 718 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t
ype()).combine(*entry.value); |
693 for (const auto& entry : other.m_attributeInvalidationSets) | 719 for (const auto& entry : other.m_attributeInvalidationSets) |
694 ensureInvalidationSet(m_attributeInvalidationSets, entry.key, entry.valu
e->type()).combine(*entry.value); | 720 ensureInvalidationSet(m_attributeInvalidationSets, entry.key, entry.valu
e->type()).combine(*entry.value); |
695 for (const auto& entry : other.m_idInvalidationSets) | 721 for (const auto& entry : other.m_idInvalidationSets) |
696 ensureInvalidationSet(m_idInvalidationSets, entry.key, entry.value->type
()).combine(*entry.value); | 722 ensureInvalidationSet(m_idInvalidationSets, entry.key, entry.value->type
()).combine(*entry.value); |
697 for (const auto& entry : other.m_pseudoInvalidationSets) | 723 for (const auto& entry : other.m_pseudoInvalidationSets) |
698 ensureInvalidationSet(m_pseudoInvalidationSets, static_cast<CSSSelector:
:PseudoType>(entry.key), entry.value->type()).combine(*entry.value); | 724 ensureInvalidationSet(m_pseudoInvalidationSets, static_cast<CSSSelector:
:PseudoType>(entry.key), entry.value->type()).combine(*entry.value); |
699 if (other.m_universalSiblingInvalidationSet) | 725 if (other.m_universalSiblingInvalidationSet) |
700 ensureUniversalSiblingInvalidationSet().combine(*other.m_universalSiblin
gInvalidationSet); | 726 ensureUniversalSiblingInvalidationSet().combine(*other.m_universalSiblin
gInvalidationSet); |
| 727 if (other.m_nthInvalidationSet) |
| 728 ensureNthInvalidationSet().combine(*other.m_nthInvalidationSet); |
701 | 729 |
702 m_metadata.add(other.m_metadata); | 730 m_metadata.add(other.m_metadata); |
703 | 731 |
704 siblingRules.appendVector(other.siblingRules); | 732 siblingRules.appendVector(other.siblingRules); |
705 uncommonAttributeRules.appendVector(other.uncommonAttributeRules); | 733 uncommonAttributeRules.appendVector(other.uncommonAttributeRules); |
706 } | 734 } |
707 | 735 |
708 void RuleFeatureSet::clear() | 736 void RuleFeatureSet::clear() |
709 { | 737 { |
710 siblingRules.clear(); | 738 siblingRules.clear(); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 invalidationLists.siblings.append(m_universalSiblingInvalidationSet); | 888 invalidationLists.siblings.append(m_universalSiblingInvalidationSet); |
861 } | 889 } |
862 | 890 |
863 SiblingInvalidationSet& RuleFeatureSet::ensureUniversalSiblingInvalidationSet() | 891 SiblingInvalidationSet& RuleFeatureSet::ensureUniversalSiblingInvalidationSet() |
864 { | 892 { |
865 if (!m_universalSiblingInvalidationSet) | 893 if (!m_universalSiblingInvalidationSet) |
866 m_universalSiblingInvalidationSet = SiblingInvalidationSet::create(nullp
tr); | 894 m_universalSiblingInvalidationSet = SiblingInvalidationSet::create(nullp
tr); |
867 return *m_universalSiblingInvalidationSet; | 895 return *m_universalSiblingInvalidationSet; |
868 } | 896 } |
869 | 897 |
| 898 void RuleFeatureSet::collectNthInvalidationSet(InvalidationLists& invalidationLi
sts) const |
| 899 { |
| 900 if (m_nthInvalidationSet) |
| 901 invalidationLists.descendants.append(m_nthInvalidationSet); |
| 902 } |
| 903 |
| 904 DescendantInvalidationSet& RuleFeatureSet::ensureNthInvalidationSet() |
| 905 { |
| 906 if (!m_nthInvalidationSet) |
| 907 m_nthInvalidationSet = DescendantInvalidationSet::create(); |
| 908 return *m_nthInvalidationSet; |
| 909 } |
| 910 |
870 void RuleFeatureSet::addFeaturesToUniversalSiblingInvalidationSet(const Invalida
tionSetFeatures& siblingFeatures, const InvalidationSetFeatures& descendantFeatu
res) | 911 void RuleFeatureSet::addFeaturesToUniversalSiblingInvalidationSet(const Invalida
tionSetFeatures& siblingFeatures, const InvalidationSetFeatures& descendantFeatu
res) |
871 { | 912 { |
872 SiblingInvalidationSet& universalSet = ensureUniversalSiblingInvalidationSet
(); | 913 SiblingInvalidationSet& universalSet = ensureUniversalSiblingInvalidationSet
(); |
873 addFeaturesToInvalidationSet(universalSet, siblingFeatures); | 914 addFeaturesToInvalidationSet(universalSet, siblingFeatures); |
874 universalSet.updateMaxDirectAdjacentSelectors(siblingFeatures.maxDirectAdjac
entSelectors); | 915 universalSet.updateMaxDirectAdjacentSelectors(siblingFeatures.maxDirectAdjac
entSelectors); |
875 | 916 |
876 if (&siblingFeatures == &descendantFeatures) | 917 if (&siblingFeatures == &descendantFeatures) |
877 universalSet.setInvalidatesSelf(); | 918 universalSet.setInvalidatesSelf(); |
878 else | 919 else |
879 addFeaturesToInvalidationSet(universalSet.ensureSiblingDescendants(), de
scendantFeatures); | 920 addFeaturesToInvalidationSet(universalSet.ensureSiblingDescendants(), de
scendantFeatures); |
880 } | 921 } |
881 | 922 |
882 DEFINE_TRACE(RuleFeatureSet) | 923 DEFINE_TRACE(RuleFeatureSet) |
883 { | 924 { |
884 visitor->trace(siblingRules); | 925 visitor->trace(siblingRules); |
885 visitor->trace(uncommonAttributeRules); | 926 visitor->trace(uncommonAttributeRules); |
886 } | 927 } |
887 | 928 |
888 } // namespace blink | 929 } // namespace blink |
OLD | NEW |