Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: c9ce4c233320ea539524620f7242b5092a47bfc4
https://github.com/WebKit/WebKit/commit/c9ce4c233320ea539524620f7242b5092a47bfc4
Author: Kiet Ho <[email protected]>
Date: 2025-11-01 (Sat, 01 Nov 2025)
Changed paths:
A
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-001-expected.html
A
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-001-ref.html
A
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-001.html
A
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-002-expected.html
A
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-002-ref.html
A
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-002.html
R
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-expected.html
R
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-ref.html
R
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none.html
M Source/WebCore/animation/WebAnimationUtilities.cpp
M Source/WebCore/animation/WebAnimationUtilities.h
M Source/WebCore/style/StyleTreeResolver.cpp
M Source/WebCore/style/Styleable.cpp
Log Message:
-----------
[css-anchor-position-1] Transitioning from display: block to none repeatedly
tears down and re-creates anchor positioned element's renderer
rdar://162963994
https://bugs.webkit.org/show_bug.cgi?id=301056
Reviewed by Antti Koivisto.
This condition in TreeResolver::createAnimatedElementUpdate prevents
applyAnimations from applying animated (and transitioned) property value
until anchor resolution is finished:
auto applyAnimations = [&]() -> std::pair<std::unique_ptr<RenderStyle>,
OptionSet<AnimationImpact>> {
if (hasUnresolvedAnchorPosition)
return { WTFMove(resolvedStyle.style), OptionSet<AnimationImpact> { } };
If an anchor-positioned element transitions from display: (any value) to none:
* On the first interleaved resolution, resolvedStyle.style->display() == none
(because we're transitioning to display: none). hasUnresolvedAnchorPosition
is true
(because anchor resolution always takes at least two resolutions to
complete). Therefore
applyAnimations won't apply the animated value of display (which stays the
same until
when the transition ends, then it's none). The final style (accounting for
animation)
will then have display: none. This leads to RenderTreeUpdater tearing down
the renderer
because display: none
* On the second interleaved style:
* AnchorPositionEvaluator::evaluate marks the element as resolved, but since
the element
doesn't have a renderer, it couldn't resolve the anchor function.
* When createAnimatedElementUpdate runs: hasUnresolvedAnchorPosition is
false, so
applyAnimations applies the animated value of display (which is the value
before transition)
This value is different than none, and currently the element doesn't have a
renderer,
so RenderTreeUpdater will create a new renderer.
This leads to two consequences:
* We needlessly tear down and create new renderer every time
Document::resolveStyle is called.
Since this is called for every animation tick, the result is we tear down and
re-create new
renderer every animation tick.
* More importantly, on the second interleaved resolution, we can't resolve
anchor functions.
So when the transition is running, the position of the anchor-positioned
element is as if it
can't resolve anchor functions. This results in the anchor-positioned element
jumping
to a position different than the position before the transition runs.
Fix this by manually patching the display property of the returned style. If
(1) we're skipping
applying animation due to unresolved anchor position, (2) there will be a
transition to
display: none, then we manually patch the display property to the old value.
This is valid
since when transitioning from any display value to none, the animated value is
the original value,
and only becomes none when the transition is complete.
Also renamed anchored-transition-display-none.html to
anchored-transition-display-none-001.html
now that we have two tests for this scenario.
Test:
imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-002.html
*
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-001-expected.html:
Renamed from
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-expected.html.
*
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-001-ref.html:
Renamed from
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-ref.html.
*
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-001.html:
Renamed from
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none.html.
*
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-002-expected.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-002-ref.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchored-transition-display-none-002.html:
Added.
* Source/WebCore/animation/WebAnimationUtilities.cpp:
(WebCore::styleHasDisplayTransition):
* Source/WebCore/animation/WebAnimationUtilities.h:
* Source/WebCore/style/StyleTreeResolver.cpp:
(WebCore::Style::TreeResolver::createAnimatedElementUpdate):
* Source/WebCore/style/Styleable.cpp:
(WebCore::Styleable::updateCSSTransitions const):
Canonical link: https://commits.webkit.org/302431@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications