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

Reply via email to