Improve ending of transitions

For legacy reasons, transitions were marked as finished after updating the
style. According to the spec, they should be marked as finished when
animations are updated and before restyle. This change does that as well
as preventing replacement of finished transitions.

Having finished transitions survive a full restyle cycle and allowing
the replacement of finished transition, could lead to issues were
removed from the global list of animating transitions too soon:

 1. A transitions finishes
 2. Restyle
 3. Transitions is marked as finished and events are queued
 4. Restyle cancels finished transition and replaces it instead of
    clearing finished transition
 5. Events are sent for the incorrectly canceled transition removing it
    completely from the list of running transitions due to the extra
    event.
This commit is contained in:
Martin Robinson 2020-05-21 18:16:03 +02:00
parent 14464e49be
commit 218beb9218
6 changed files with 296 additions and 3 deletions

View file

@ -55,6 +55,8 @@ impl Animations {
); );
} }
} }
Self::finish_running_animations(set, now, &mut update);
} }
update update
} }
@ -71,7 +73,6 @@ impl Animations {
for set in sets.values_mut() { for set in sets.values_mut() {
Self::handle_canceled_animations(set, now, &mut update); Self::handle_canceled_animations(set, now, &mut update);
Self::finish_running_animations(set, now, &mut update);
Self::handle_new_animations(set, &mut update); Self::handle_new_animations(set, &mut update);
} }

View file

@ -889,7 +889,7 @@ impl ElementAnimationSet {
if let Some(old_transition) = self if let Some(old_transition) = self
.transitions .transitions
.iter_mut() .iter_mut()
.filter(|transition| transition.state != AnimationState::Canceled) .filter(|transition| transition.state == AnimationState::Running)
.find(|transition| transition.property_animation.property_id() == longhand_id) .find(|transition| transition.property_animation.property_id() == longhand_id)
{ {
// We always cancel any running transitions for the same property. // We always cancel any running transitions for the same property.

View file

@ -1,58 +1,283 @@
[properties-value-inherit-001.html] [properties-value-inherit-001.html]
[outline-width length(px) / values]
expected: FAIL
[background-position length(pt) / values] [background-position length(pt) / values]
expected: FAIL expected: FAIL
[background-position length(pt) / events] [background-position length(pt) / events]
expected: FAIL expected: FAIL
[text-indent length(pc) / values]
expected: FAIL
[outline-offset length(px) / values]
expected: FAIL
[vertical-align length(in) / values]
expected: FAIL
[outline-width length(pc) / events]
expected: FAIL
[text-indent percentage(%) / events]
expected: FAIL
[vertical-align length(px) / events]
expected: FAIL
[background-position length(px) / values] [background-position length(px) / values]
expected: FAIL expected: FAIL
[text-shadow shadow(shadow) / events]
expected: FAIL
[background-position length(cm) / events] [background-position length(cm) / events]
expected: FAIL expected: FAIL
[background-position length(mm) / values] [background-position length(mm) / values]
expected: FAIL expected: FAIL
[outline-offset length(mm) / events]
expected: FAIL
[vertical-align length(in) / events]
expected: FAIL
[vertical-align percentage(%) / values]
expected: FAIL
[background-position length(in) / events] [background-position length(in) / events]
expected: FAIL expected: FAIL
[text-indent length(ex) / values]
expected: FAIL
[text-indent length(mm) / events]
expected: FAIL
[vertical-align length(em) / events]
expected: FAIL
[vertical-align length(em) / values]
expected: FAIL
[text-indent length(px) / values]
expected: FAIL
[clip rectangle(rectangle) / values]
expected: FAIL
[vertical-align length(cm) / events]
expected: FAIL
[text-indent length(ex) / events]
expected: FAIL
[outline-offset length(cm) / events]
expected: FAIL
[background-position length(em) / events] [background-position length(em) / events]
expected: FAIL expected: FAIL
[vertical-align length(mm) / events]
expected: FAIL
[outline-offset length(em) / events]
expected: FAIL
[vertical-align length(ex) / events]
expected: FAIL
[outline-width length(em) / events]
expected: FAIL
[text-indent length(in) / events]
expected: FAIL
[outline-offset length(ex) / values]
expected: FAIL
[vertical-align length(pc) / values]
expected: FAIL
[vertical-align length(cm) / values]
expected: FAIL
[visibility visibility(keyword) / events]
expected: FAIL
[vertical-align length(ex) / values]
expected: FAIL
[text-indent length(pc) / events]
expected: FAIL
[text-indent length(em) / events]
expected: FAIL
[outline-offset length(mm) / values]
expected: FAIL
[outline-offset length(pt) / values]
expected: FAIL
[text-indent length(px) / events]
expected: FAIL
[text-indent length(cm) / events]
expected: FAIL
[vertical-align length(pt) / values]
expected: FAIL
[visibility visibility(keyword) / values] [visibility visibility(keyword) / values]
expected: FAIL expected: FAIL
[outline-width length(cm) / events]
expected: FAIL
[background-position length(ex) / values] [background-position length(ex) / values]
expected: FAIL expected: FAIL
[clip rectangle(rectangle) / events]
expected: FAIL
[text-indent length(mm) / values]
expected: FAIL
[background-position length(cm) / values] [background-position length(cm) / values]
expected: FAIL expected: FAIL
[text-indent length(pt) / events]
expected: FAIL
[outline-offset length(in) / values]
expected: FAIL
[outline-width length(pt) / values]
expected: FAIL
[outline-width length(ex) / events]
expected: FAIL
[outline-width length(mm) / events]
expected: FAIL
[outline-width length(in) / values]
expected: FAIL
[text-indent length(cm) / values]
expected: FAIL
[outline-color color(rgba) / values]
expected: FAIL
[background-position length(ex) / events] [background-position length(ex) / events]
expected: FAIL expected: FAIL
[text-indent length(pt) / values]
expected: FAIL
[vertical-align percentage(%) / events]
expected: FAIL
[outline-width length(pt) / events]
expected: FAIL
[outline-color color(rgba) / events]
expected: FAIL
[text-shadow shadow(shadow) / values]
expected: FAIL
[background-position length(pc) / events] [background-position length(pc) / events]
expected: FAIL expected: FAIL
[outline-width length(in) / events]
expected: FAIL
[outline-width length(ex) / values]
expected: FAIL
[background-position length(in) / values] [background-position length(in) / values]
expected: FAIL expected: FAIL
[outline-width length(cm) / values]
expected: FAIL
[outline-offset length(ex) / events]
expected: FAIL
[outline-width length(mm) / values]
expected: FAIL
[outline-width length(pc) / values]
expected: FAIL
[vertical-align length(px) / values]
expected: FAIL
[text-indent length(in) / values]
expected: FAIL
[vertical-align length(pc) / events]
expected: FAIL
[text-indent length(em) / values]
expected: FAIL
[background-position length(pc) / values] [background-position length(pc) / values]
expected: FAIL expected: FAIL
[background-position percentage(%) / values] [background-position percentage(%) / values]
expected: FAIL expected: FAIL
[vertical-align length(pt) / events]
expected: FAIL
[outline-width length(em) / values]
expected: FAIL
[outline-offset length(em) / values]
expected: FAIL
[outline-offset length(pt) / events]
expected: FAIL
[outline-offset length(cm) / values]
expected: FAIL
[background-position length(mm) / events] [background-position length(mm) / events]
expected: FAIL expected: FAIL
[vertical-align length(mm) / values]
expected: FAIL
[text-indent percentage(%) / values]
expected: FAIL
[outline-offset length(px) / events]
expected: FAIL
[background-position length(em) / values] [background-position length(em) / values]
expected: FAIL expected: FAIL
[outline-offset length(in) / events]
expected: FAIL
[outline-offset length(pc) / values]
expected: FAIL
[outline-width length(px) / events]
expected: FAIL
[background-position percentage(%) / events] [background-position percentage(%) / events]
expected: FAIL expected: FAIL
[background-position length(px) / events] [background-position length(px) / events]
expected: FAIL expected: FAIL
[outline-offset length(pc) / events]
expected: FAIL

View file

@ -1,7 +1,31 @@
[properties-value-inherit-003.html] [properties-value-inherit-003.html]
[text-indent length-em(em) / events]
expected: FAIL
[vertical-align length-em(em) / values]
expected: FAIL
[background-position length-em(em) / events] [background-position length-em(em) / events]
expected: FAIL expected: FAIL
[outline-width length-em(em) / values]
expected: FAIL
[outline-offset length-em(em) / events]
expected: FAIL
[background-position length-em(em) / values] [background-position length-em(em) / values]
expected: FAIL expected: FAIL
[outline-width length-em(em) / events]
expected: FAIL
[text-indent length-em(em) / values]
expected: FAIL
[outline-offset length-em(em) / values]
expected: FAIL
[vertical-align length-em(em) / events]
expected: FAIL

View file

@ -12871,7 +12871,7 @@
] ]
], ],
"faster-reversing-of-transitions.html": [ "faster-reversing-of-transitions.html": [
"8471a18f962283afd8d6a81c8ab868e5c2eedd7d", "e646a06405d3f32b37e94f797f7a99c6ca54254b",
[ [
null, null,
{} {}

View file

@ -28,6 +28,12 @@ function createTransitionElement() {
return element; return element;
} }
function waitForFrame() {
return new Promise(resolve => {
window.requestAnimationFrame(resolve);
});
}
test(function() { test(function() {
let testBinding = new window.TestBinding(); let testBinding = new window.TestBinding();
let div = createTransitionElement(); let div = createTransitionElement();
@ -121,4 +127,41 @@ test(function() {
document.body.removeChild(div); document.body.removeChild(div);
}, "Non-reversed transition changes use the full transition-duration"); }, "Non-reversed transition changes use the full transition-duration");
promise_test(async t => {
let testBinding = new window.TestBinding();
let div = createTransitionElement();
let handledTransitionEnd = false;
div.addEventListener("transitionend", () => {
handledTransitionEnd = true;
});
let handledTransitionCancel = false;
div.addEventListener("transitioncancel", () => {
handledTransitionCancel = true;
});
// Start a transition and allow 30% of it to complete.
div.style.width = "110px";
getComputedStyle(div).width;
testBinding.advanceClock(10000);
getComputedStyle(div).width;
div.style.transitionDuration = "1000s";
div.style.width = "10px";
testBinding.advanceClock(1);
getComputedStyle(div).width;
await waitForFrame();
// We should either have canceled the animation or it should have terminated.
assert_true(handledTransitionCancel || handledTransitionEnd);
assert_false(handledTransitionCancel && handledTransitionEnd);
document.body.removeChild(div);
}, "Finished transitions are not reversed");
</script> </script>