Changeset 286365 in webkit
- Timestamp:
- Dec 1, 2021 9:04:27 AM (8 months ago)
- Location:
- trunk
- Files:
-
- 2 added
- 7 edited
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/has-sibling-expected.txt (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/has-sibling.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/css/SelectorChecker.cpp (modified) (1 diff)
-
Source/WebCore/style/ChildChangeInvalidation.cpp (modified) (2 diffs)
-
Source/WebCore/style/RuleFeature.cpp (modified) (3 diffs)
-
Source/WebCore/style/RuleFeature.h (modified) (1 diff)
-
Source/WebCore/style/StyleInvalidator.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r286363 r286365 1 2021-12-01 Antti Koivisto <antti@apple.com> 2 3 [:has() pseudo-class] Sibling combinator invalidation 4 https://bugs.webkit.org/show_bug.cgi?id=233696 5 6 Reviewed by Simon Fraser. 7 8 * web-platform-tests/css/selectors/invalidation/has-sibling-expected.txt: Added. 9 * web-platform-tests/css/selectors/invalidation/has-sibling.html: Added. 10 1 11 2021-12-01 Patrick Griffis <pgriffis@igalia.com> 2 12 -
trunk/Source/WebCore/ChangeLog
r286364 r286365 1 2021-12-01 Antti Koivisto <antti@apple.com> 2 3 [:has() pseudo-class] Sibling combinator invalidation 4 https://bugs.webkit.org/show_bug.cgi?id=233696 5 6 Reviewed by Simon Fraser. 7 8 Invalidate style correctly for sibling combinators in :has() arguments. 9 10 Also add new MatchElement::HasSiblingDescendant value used for :has() arguments that 11 match the subject elements siblings descendants, like ':has(~ div .descendant)'. 12 Use it to avoid unnecessary big tree traversals in simple cases. 13 14 Test: imported/w3c/web-platform-tests/css/selectors/invalidation/has-sibling.html 15 16 * css/SelectorChecker.cpp: 17 (WebCore::SelectorChecker::matchHasPseudoClass const): 18 19 Minimal traversals for HasSibling and HasSiblingDescendant. 20 21 * style/ChildChangeInvalidation.cpp: 22 (WebCore::Style::needsTraversal): 23 (WebCore::Style::needsDescendantTraversal): 24 * style/RuleFeature.cpp: 25 (WebCore::Style::isSiblingOrSubject): 26 (WebCore::Style::isHasPseudoClassMatchElement): 27 (WebCore::Style::computeHasPseudoClassMatchElement): 28 * style/RuleFeature.h: 29 * style/StyleInvalidator.cpp: 30 (WebCore::Style::Invalidator::invalidateStyleWithMatchElement): 31 32 Invalidation traversal. 33 1 34 2021-12-01 Youenn Fablet <youenn@apple.com> 2 35 -
trunk/Source/WebCore/css/SelectorChecker.cpp
r286302 r286365 1316 1316 if (checkRelative(*sibling)) 1317 1317 return true; 1318 } 1319 break; 1320 case Style::MatchElement::HasSiblingDescendant: 1321 for (auto* sibling = element.nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) { 1318 1322 if (checkDescendants(*sibling)) 1319 1323 return true; 1320 1324 } 1321 1325 break; 1326 1322 1327 default: 1323 1328 ASSERT_NOT_REACHED(); -
trunk/Source/WebCore/style/ChildChangeInvalidation.cpp
r286226 r286365 112 112 if (features.usesMatchElement(MatchElement::HasDescendant)) 113 113 return true; 114 if (features.usesMatchElement(MatchElement::HasSiblingDescendant)) 115 return true; 114 116 return features.usesMatchElement(MatchElement::HasSibling) && childChange.previousSiblingElement; 115 117 }; … … 117 119 static bool needsDescendantTraversal(const RuleFeatureSet& features) 118 120 { 119 return features.usesMatchElement(MatchElement::HasDescendant) ;121 return features.usesMatchElement(MatchElement::HasDescendant) || features.usesMatchElement(MatchElement::HasSiblingDescendant); 120 122 }; 121 123 -
trunk/Source/WebCore/style/RuleFeature.cpp
r286292 r286365 53 53 case MatchElement::HasChild: 54 54 case MatchElement::HasDescendant: 55 case MatchElement::HasSiblingDescendant: 55 56 return false; 56 57 } … … 62 63 { 63 64 switch (matchElement) { 64 case MatchElement::HasSibling:65 65 case MatchElement::HasChild: 66 66 case MatchElement::HasDescendant: 67 case MatchElement::HasSibling: 68 case MatchElement::HasSiblingDescendant: 67 69 return true; 68 70 default: … … 147 149 case MatchElement::IndirectSibling: 148 150 case MatchElement::DirectSibling: 151 case MatchElement::AnySibling: 152 return MatchElement::HasSibling; 149 153 case MatchElement::ParentSibling: 150 154 case MatchElement::AncestorSibling: 151 case MatchElement::AnySibling: 152 return MatchElement::HasSibling; 155 return MatchElement::HasSiblingDescendant; 153 156 case MatchElement::HasChild: 154 157 case MatchElement::HasDescendant: 155 158 case MatchElement::HasSibling: 159 case MatchElement::HasSiblingDescendant: 156 160 case MatchElement::Host: 157 161 ASSERT_NOT_REACHED(); -
trunk/Source/WebCore/style/RuleFeature.h
r286226 r286365 37 37 class RuleData; 38 38 39 enum class MatchElement : uint8_t { Subject, Parent, Ancestor, DirectSibling, IndirectSibling, AnySibling, ParentSibling, AncestorSibling, HasChild, HasDescendant, HasSibling, Host }; 39 enum class MatchElement : uint8_t { 40 Subject, 41 Parent, 42 Ancestor, 43 DirectSibling, 44 IndirectSibling, 45 AnySibling, 46 ParentSibling, 47 AncestorSibling, 48 HasChild, 49 HasDescendant, 50 HasSibling, 51 HasSiblingDescendant, 52 Host 53 }; 40 54 constexpr unsigned matchElementCount = static_cast<unsigned>(MatchElement::Host) + 1; 41 55 -
trunk/Source/WebCore/style/StyleInvalidator.cpp
r286135 r286365 323 323 } 324 324 case MatchElement::HasSibling: { 325 if (auto* sibling = element.previousElementSibling()) { 326 SelectorMatchingState selectorMatchingState; 327 selectorMatchingState.selectorFilter.pushParentInitializingIfNeeded(*element.parentElement()); 328 329 for (; sibling; sibling = sibling->previousElementSibling()) 330 invalidateIfNeeded(*sibling, &selectorMatchingState); 331 } 332 break; 333 } 334 case MatchElement::HasSiblingDescendant: { 335 Vector<Element*, 16> elementAndAncestors; 336 elementAndAncestors.append(&element); 337 for (auto* parent = element.parentElement(); parent; parent = parent->parentElement()) 338 elementAndAncestors.append(parent); 339 325 340 SelectorMatchingState selectorMatchingState; 326 for (auto* sibling = element.previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) { 327 selectorMatchingState.selectorFilter.popParentsUntil(element.parentElement()); 328 invalidateStyleForDescendants(*sibling, &selectorMatchingState); 341 for (auto* elementOrAncestor : makeReversedRange(elementAndAncestors)) { 342 for (auto* sibling = elementOrAncestor->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) 343 invalidateIfNeeded(*sibling, &selectorMatchingState); 344 345 selectorMatchingState.selectorFilter.pushParent(elementOrAncestor); 329 346 } 330 347 break;
Note: See TracChangeset
for help on using the changeset viewer.