Bug 927349 part 30 - Cancel transitions when we have a change to a non-animatable style; r=heycam
authorBrian Birtles <birtles@gmail.com>
Tue, 06 Jan 2015 10:55:59 +0900
changeset 222168 b2c5a67125d6457a50d3fed0df8681d7c359ca8c
parent 222167 bc7e683ef708f64d1cefdc4a01762ea79ec48534
child 222169 3b5b53b73e1531425a366c408873d152ed3086cd
push id28059
push userryanvm@gmail.com
push dateTue, 06 Jan 2015 15:53:01 +0000
treeherdermozilla-central@4d91c33b351c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs927349
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 927349 part 30 - Cancel transitions when we have a change to a non-animatable style; r=heycam
dom/animation/test/css-transitions/test_animation-player-ready.html
layout/style/nsTransitionManager.cpp
--- a/dom/animation/test/css-transitions/test_animation-player-ready.html
+++ b/dom/animation/test/css-transitions/test_animation-player-ready.html
@@ -62,9 +62,41 @@ async_test(function(t) {
 
   // Now remove transform from transition-property and flush styles
   div.style.transitionProperty = 'none';
   window.getComputedStyle(div).transitionProperty;
 
 }, 'ready promise is rejected when a transition is cancelled by updating'
    + ' transition-property');
 
+async_test(function(t) {
+  var div = addDiv(t);
+
+  // Set up pending transition
+  div.style.marginLeft = '0px';
+  window.getComputedStyle(div).marginLeft;
+  div.style.transition = 'margin-left 100s';
+  div.style.marginLeft = '100px';
+  window.getComputedStyle(div).marginLeft;
+
+  var player = div.getAnimationPlayers()[0];
+  assert_equals(player.playState, 'pending', 'Player is initially pending');
+
+  // Set up listeners on ready promise
+  player.ready.then(t.step_func(function() {
+    assert_unreached('ready promise was fulfilled');
+  })).catch(t.step_func(function(err) {
+    assert_equals(err.name, 'AbortError',
+                  'ready promise is rejected with AbortError');
+    assert_equals(player.playState, 'idle',
+                  'Player is idle after transition was cancelled');
+  })).then(t.step_func(function() {
+    t.done();
+  }));
+
+  // Now update the transition to animate to something not-interpolable
+  div.style.marginLeft = 'auto';
+  window.getComputedStyle(div).marginLeft;
+
+}, 'ready promise is rejected when a transition is cancelled by changing'
+   + ' the transition property to something not interpolable');
+
 </script>
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -447,16 +447,17 @@ nsTransitionManager::ConsiderStartingTra
     if (haveCurrentTransition) {
       // We're in the middle of a transition, and just got a non-transition
       // style change to something that we can't animate.  This might happen
       // because we got a non-transition style change changing to the current
       // in-progress value (which is particularly easy to cause when we're
       // currently in the 'transition-delay').  It also might happen because we
       // just got a style change to a value that can't be interpolated.
       AnimationPlayerPtrArray& players = aElementTransitions->mPlayers;
+      players[currentIndex]->Cancel();
       oldPT = nullptr; // Clear pointer so it doesn't dangle
       players.RemoveElementAt(currentIndex);
       aElementTransitions->UpdateAnimationGeneration(mPresContext);
 
       if (players.IsEmpty()) {
         aElementTransitions->Destroy();
         // |aElementTransitions| is now a dangling pointer!
         aElementTransitions = nullptr;