Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 108882fa38bbbc35c63c7048cd5670ec6af5344e
https://github.com/WebKit/WebKit/commit/108882fa38bbbc35c63c7048cd5670ec6af5344e
Author: Antti Koivisto <[email protected]>
Date: 2026-04-27 (Mon, 27 Apr 2026)
Changed paths:
M LayoutTests/fast/selectors/has-invalidation-traversal-size-expected.txt
R LayoutTests/fast/selectors/has-scope-breaking-classification-expected.txt
R LayoutTests/fast/selectors/has-scope-breaking-classification.html
M
LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/has-with-nth-child-expected.txt
M Source/WebCore/css/SelectorChecker.cpp
M Source/WebCore/style/ChildChangeInvalidation.cpp
M Source/WebCore/style/ChildChangeInvalidation.h
M Source/WebCore/style/ClassChangeInvalidation.cpp
M Source/WebCore/style/RuleFeature.cpp
M Source/WebCore/style/RuleFeature.h
M Source/WebCore/style/StyleInvalidator.cpp
M Source/WebCore/style/StyleInvalidator.h
M Source/WebCore/style/StyleScopeRuleSets.cpp
M Source/WebCore/style/StyleScopeRuleSets.h
M Source/WebCore/testing/Internals.cpp
M Source/WebCore/testing/Internals.h
M Source/WebCore/testing/Internals.idl
Log Message:
-----------
[:has() perf] Remove separate handling of scope breaking selectors
https://bugs.webkit.org/show_bug.cgi?id=313420
rdar://175668439
Reviewed by Alan Baradlay.
With this patch we can handle scope breaking cases like
:has(:is(.this-breaks-scope .foo))
within our normal invalidation system. Scope-breaking entries are now
emitted with no scope selector (instead of being collected into a
separate rule set that triggered full-document traversal on every
mutation). This also lets us emit and properly bound entries for
combinators inside :is()/:not() that stay within the :has() scope.
* LayoutTests/fast/selectors/has-invalidation-traversal-size-expected.txt:
c6 (:has(:is(.trigger + .other))) now invalidates correctly:
count goes from 0 (FAIL) to 14 (PASS).
* LayoutTests/fast/selectors/has-scope-breaking-classification-expected.txt:
Removed.
* LayoutTests/fast/selectors/has-scope-breaking-classification.html: Removed.
Test deleted along with the SPI it tested.
*
LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/has-with-nth-child-expected.txt:
Two :nth-child() in non-subject FAILs become PASSes.
* Source/WebCore/css/SelectorChecker.cpp:
(WebCore::SelectorChecker::matchHasPseudoClass const):
Forward DescendantsAffectedByForward/BackwardPositionalRules to the
directional AffectedByHasWith*SiblingRelationship flags so positional
rules inside :has() get proper sibling invalidation.
* Source/WebCore/style/ChildChangeInvalidation.cpp:
(WebCore::Style::isSiblingHasRelation):
(WebCore::Style::ChildChangeInvalidation::invalidateForHasBeforeMutation):
(WebCore::Style::ChildChangeInvalidation::invalidateForHasAfterMutation):
(WebCore::Style::ChildChangeInvalidation::invalidateForChangeOutsideHasScope):
Deleted.
* Source/WebCore/style/ChildChangeInvalidation.h:
Drop the per-mutation full-document traversal helper.
* Source/WebCore/style/ClassChangeInvalidation.cpp:
(WebCore::Style::ClassChangeInvalidation::computeInvalidation):
Drop the ScopeBreaking-forces-before-and-after special case.
* Source/WebCore/style/RuleFeature.cpp:
(WebCore::Style::isHasScopeBreakingCombinator):
Now classifies a combinator inside :is()/:not() within :has() as
scope-breaking based on the combinator and the :has() argument's
relation to the bearer.
(WebCore::Style::RuleFeatureSet::recursivelyCollectFeaturesFromSelector):
Track isNestedInLogicalCombination and crossedScopeBreakingCombinator
in the recursion context. Emit per-compound entries inside :is()/:not()
at sibling-combinator and positional-pseudo-class boundaries, attaching
a scope selector unless we crossed a scope-breaking combinator.
(WebCore::Style::RuleFeatureSet::collectFeatures):
(WebCore::Style::RuleFeatureSet::add):
(WebCore::Style::RuleFeatureSet::clear):
(WebCore::Style::RuleFeatureSet::shrinkToFit):
Remove scopeBreakingHasPseudoClassRules bookkeeping.
* Source/WebCore/style/RuleFeature.h:
Remove MatchElement::HasRelation::ScopeBreaking enum value and the
scopeBreakingHasPseudoClassRules vector.
* Source/WebCore/style/StyleInvalidator.cpp:
(WebCore::Style::Invalidator::invalidateStyleWithMatchElement):
Drop the ScopeBreaking-takes-the-whole-document early return.
(WebCore::Style::Invalidator::invalidateWithScopeBreakingHasPseudoClassRuleSet):
Deleted.
* Source/WebCore/style/StyleInvalidator.h:
* Source/WebCore/style/StyleScopeRuleSets.cpp:
(WebCore::Style::ScopeRuleSets::collectFeatures const):
(WebCore::Style::makeRuleSet): Deleted.
* Source/WebCore/style/StyleScopeRuleSets.h:
(WebCore::Style::ScopeRuleSets::scopeBreakingHasPseudoClassInvalidationRuleSet
const): Deleted.
Drop the separate scope-breaking rule set and its plumbing.
* Source/WebCore/testing/Internals.cpp:
(WebCore::Internals::hasScopeBreakingHasSelectors const): Deleted.
* Source/WebCore/testing/Internals.h:
* Source/WebCore/testing/Internals.idl:
Drop the hasScopeBreakingHasSelectors test SPI together with its
backing classification test.
Canonical link: https://commits.webkit.org/312103@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications