haikuwebkit/LayoutTests/webanimations/updating-property-targeted-...

55 lines
1.9 KiB
HTML
Raw Permalink Normal View History

Hardware fill-forwards animation and transitions don't interact correctly https://bugs.webkit.org/show_bug.cgi?id=187839 <rdar://problem/42410412> Reviewed by Simon Fraser. LayoutTests/imported/w3c: Mark a progression for a WPT test. * web-platform-tests/web-animations/interfaces/Animation/style-change-events-expected.txt: Source/WebCore: Test: webanimations/updating-property-targeted-by-css-transition-during-css-animation.html We didn't follow the CSS Transitions spec closely enough when it came to defining the correct before and after change styles during a style change event. We now correctly set the before-change style as one of three possible values: 1. if there are running CSS-originated animations, we ensure those are updated to the current time and resolve them to get the style, 2. otherwise we use the RenderStyle recorded in Style::TreeResolver::createAnimatedElementUpdate() prior to applying animations during the last style change event, 3. otherwise we use the previous computed style, which should not have any animated values. As for the after-change style, we also need to ensure any running CSS Animations are update to the current time and resolve them to get the style. Otherwise, we just use the current computed style prior to applying animations. Finally, we can exit from AnimationTimeline::updateCSSTransitionsForElementAndProperty() early if we find that we have a JS-originated animation running for the given property on the given element since we know that that animation will yield an overriding value for both the before and after change styles since JS-originated animations have the hightest composite order. This means we no longer need to track the unanimated style on KeyframeEffect. * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::updateCSSAnimationsForElement): (WebCore::AnimationTimeline::updateCSSTransitionsForElementAndProperty): (WebCore::AnimationTimeline::updateCSSTransitionsForElement): * animation/AnimationTimeline.h: * animation/ElementAnimationRareData.h: (WebCore::ElementAnimationRareData::lastStyleChangeEventStyle const): (WebCore::ElementAnimationRareData::setLastStyleChangeEventStyle): * animation/KeyframeEffect.cpp: (WebCore::KeyframeEffect::clearBlendingKeyframes): (WebCore::KeyframeEffect::apply): (WebCore::KeyframeEffect::applyPendingAcceleratedActions): * animation/KeyframeEffect.h: (WebCore::KeyframeEffect::unanimatedStyle const): Deleted. * dom/Element.cpp: (WebCore::Element::lastStyleChangeEventStyle const): (WebCore::Element::setLastStyleChangeEventStyle): * dom/Element.h: * style/StyleTreeResolver.cpp: (WebCore::Style::TreeResolver::createAnimatedElementUpdate): LayoutTests: Add a new test that reproduces the issue shown by the original test case for this bug. While an animation is running for a CSS property, we change the underlying value for that animated property which is also set as the transition-property value. The correct behavior is to not start a CSS Transition either when changing the underlying value during the CSS Animation nor at the end of the CSS Animation. * webanimations/updating-property-targeted-by-css-transition-during-css-animation-expected.txt: Added. * webanimations/updating-property-targeted-by-css-transition-during-css-animation.html: Added. Canonical link: https://commits.webkit.org/225215@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262154 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-26 19:12:22 +00:00
<!DOCTYPE html>
<meta charset="utf-8">
<title>Updating a CSS property set as a transition-property while a CSS Animation is already animating that property</title>
<style>
.target {
animation: animation 2s;
transition: margin-left 1s;
}
.target.in-flight {
margin-left: 200px;
}
@keyframes animation {
from { margin-left: 50px }
to { margin-left: 100px }
}
</style>
<body>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script>
'use strict';
test(test => {
const target = document.body.appendChild(document.createElement("div"));
target.classList.add("target");
let animations = target.getAnimations();
assert_equals(animations.length, 1, "There is one animation applied to the target after starting the test.");
const animation = animations[0];
assert_true(animation instanceof CSSAnimation, 1, "There is one CSS Animation applied to the target after starting the test.");
// Update opacity while the CSS Animation is running. This should not initiate a CSS Transition.
target.classList.add("in-flight");
animations = target.getAnimations();
assert_equals(animations.length, 1, "There is one animation applied to the target after updating the animated property.");
assert_equals(animations[0], animation, "The single running animation is the original CSS Animation.");
// Finish the animation and check there is no transition started then either.
animation.finish();
assert_equals(target.getAnimations().length, 0, "There is no animation running after finishing the CSS Animation.");
assert_equals(getComputedStyle(target).marginLeft, "200px", "The final value for the property is the one set during the animation.");
target.remove();
}, `Updating a CSS property set as a transition-property while a CSS Animation is already animating that property.`);
</script>
</body>