Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: c376374b3d92bdcd4fff4a80d60b13672e318e17
https://github.com/WebKit/WebKit/commit/c376374b3d92bdcd4fff4a80d60b13672e318e17
Author: Antti Koivisto <[email protected]>
Date: 2026-05-15 (Fri, 15 May 2026)
Changed paths:
M LayoutTests/TestExpectations
M
LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/host-has-shadow-tree-element-at-nonsubject-position-expected.txt
M
LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/host-has-shadow-tree-element-at-subject-position-expected.txt
M Source/WebCore/css/SelectorChecker.cpp
M Source/WebCore/css/SelectorChecker.h
M Source/WebCore/style/ChildChangeInvalidation.cpp
M Source/WebCore/style/RuleFeature.cpp
M Source/WebCore/style/RuleFeature.h
M Source/WebCore/style/StyleInvalidator.cpp
Log Message:
-----------
Support :host:has()
https://bugs.webkit.org/show_bug.cgi?id=282687
rdar://139799278
Reviewed by Alan Baradlay.
Per-spec :host:has(.descendant) should match against shadow tree descendants.
https://drafts.csswg.org/css-shadow/#host-selector
Match-time, root the :has() argument traversal at the host's shadow root
when the :has() is matching the host as a :host pseudo. The signal is
LocalContext::mustMatchHostPseudoClass, which matchRecursively already
sets when the subject is the host (styleScopeOrdinal == Shadow) and when
the ancestor walk has crossed the shadow root upward. The implicit
HasScope sentinel inside the argument is allowed through the
mustMatchHostPseudoClass early-out and treated as satisfying :host when
it lands on the host.
Invalidation, classify the features statically. When :has() is in a
compound that also contains :host, the inner Child/Descendant
has-relation is collapsed to a new HasRelation::HostDescendant. The
invalidator has dedicated arms for it in subject and non-subject
positions: subject reaches the host via containingShadowRoot();
non-subject invalidates the host's shadow tree where the subjects live.
Improves 50 of the 52 subtests in the host-has-shadow-tree-element-at-
{subject,nonsubject}-position WPTs from 1 PASS to 25 PASS each.
Remaining FAIL is a :host-context() chained-:has() case.
*
LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/host-has-shadow-tree-element-at-nonsubject-position-expected.txt:
*
LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/host-has-shadow-tree-element-at-subject-position-expected.txt:
Rebaseline: 50 previously-failing subtests now pass.
* Source/WebCore/css/SelectorChecker.h:
Plumb a matchingHost bool through matchHasPseudoClass and
matchHasArgumentSelector.
* Source/WebCore/css/SelectorChecker.cpp:
(WebCore::SelectorChecker::checkOne const):
Pass context.mustMatchHostPseudoClass through. Allow Match::HasScope
through the mustMatchHostPseudoClass early-out and treat HasScope on
the host as having matched :host.
(WebCore::SelectorChecker::matchHasPseudoClass const):
(WebCore::SelectorChecker::matchHasArgumentSelector const):
Root :has() traversal at the host's shadow root when matchingHost is
set. Sibling traversals bail (the host has no shadow-tree siblings);
JIT and light-tree-only caches are skipped on the shadow path.
* Source/WebCore/style/RuleFeature.h:
Add HasRelation::HostDescendant.
* Source/WebCore/style/RuleFeature.cpp:
(WebCore::Style::compoundContainsHostPseudoClass):
Walk compound members from lastInCompound() to firstInCompound() with
storage increment. WebKit's "first in complex selector" flag is on the
subject (rightmost in source, storage[0]).
(WebCore::Style::computeSubSelectorMatchElement):
When :has() sits in a :host compound, collapse Child/Descendant to
HostDescendant.
(WebCore::Style::isHasScopeBreakingCombinator):
* Source/WebCore/style/ChildChangeInvalidation.cpp:
(WebCore::Style::isSiblingHasRelation):
(WebCore::Style::ChildChangeInvalidation::invalidateForChangedElement):
Cover HostDescendant in the existing switches.
* Source/WebCore/style/StyleInvalidator.cpp:
(WebCore::Style::Invalidator::invalidateStyleWithMatchElement):
Subject-position HostDescendant invalidates the host;
non-subject-position invalidates the host's shadow tree and the host.
Canonical link: https://commits.webkit.org/313350@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications