CSSTransition-canceling.tentative.html (8558B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <title>Canceling a CSS transition</title> 4 <link rel="help" href="https://drafts.csswg.org/css-transitions/#starting"> 5 <!-- TODO: Add a more specific link for this once it is specified. --> 6 <link rel="help" href="https://drafts.csswg.org/css-transitions-2/#csstransition"> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <script src="support/helper.js"></script> 10 <div id="log"></div> 11 <script> 12 'use strict'; 13 14 promise_test(async t => { 15 const div = addDiv(t, { style: 'margin-left: 0px' }); 16 getComputedStyle(div).marginLeft; 17 18 div.style.transition = 'margin-left 100s'; 19 div.style.marginLeft = '1000px'; 20 21 const transition = div.getAnimations()[0]; 22 await transition.ready; 23 await waitForFrame(); 24 25 assert_not_equals(getComputedStyle(div).marginLeft, '1000px', 26 'transform style is animated before canceling'); 27 transition.cancel(); 28 assert_equals(getComputedStyle(div).marginLeft, div.style.marginLeft, 29 'transform style is no longer animated after canceling'); 30 }, 'Animated style is cleared after canceling a running CSS transition'); 31 32 promise_test(async t => { 33 const div = addDiv(t, { style: 'margin-left: 0px' }); 34 getComputedStyle(div).marginLeft; 35 36 div.style.transition = 'margin-left 100s'; 37 div.style.marginLeft = '1000px'; 38 39 const transition = div.getAnimations()[0]; 40 await transition.ready; 41 42 transition.cancel(); 43 assert_equals(getComputedStyle(div).marginLeft, '1000px', 44 'margin-left style is not animated after canceling'); 45 transition.play(); 46 assert_equals(getComputedStyle(div).marginLeft, '0px', 47 'margin-left style is animated after re-starting transition'); 48 49 await transition.ready; 50 51 assert_equals(transition.playState, 'running', 52 'Transition succeeds in running after being re-started'); 53 }, 'After canceling a transition, it can still be re-used'); 54 55 promise_test(async t => { 56 const div = addDiv(t, { style: 'margin-left: 0px' }); 57 getComputedStyle(div).marginLeft; 58 59 div.style.transition = 'margin-left 100s'; 60 div.style.marginLeft = '1000px'; 61 62 const transition = div.getAnimations()[0]; 63 await transition.ready; 64 65 transition.finish(); 66 transition.cancel(); 67 assert_equals(getComputedStyle(div).marginLeft, '1000px', 68 'margin-left style is not animated after canceling'); 69 transition.play(); 70 assert_equals(getComputedStyle(div).marginLeft, '0px', 71 'margin-left style is animated after re-starting transition'); 72 73 await transition.ready; 74 75 assert_equals(transition.playState, 'running', 76 'Transition succeeds in running after being re-started'); 77 }, 'After canceling a finished transition, it can still be re-used'); 78 79 test(t => { 80 const div = addDiv(t, { style: 'margin-left: 0px' }); 81 getComputedStyle(div).marginLeft; 82 83 div.style.transition = 'margin-left 100s'; 84 div.style.marginLeft = '1000px'; 85 86 const transition = div.getAnimations()[0]; 87 transition.cancel(); 88 assert_equals(getComputedStyle(div).marginLeft, '1000px', 89 'margin-left style is not animated after canceling'); 90 91 // Trigger a change to a transition property and check that this 92 // doesn't cause the animation to become live again 93 div.style.transitionDuration = '200s'; 94 getComputedStyle(div).marginLeft; 95 assert_equals(getComputedStyle(div).marginLeft, '1000px', 96 'margin-left style is still not animated after updating' 97 + ' transition-duration'); 98 assert_equals(transition.playState, 'idle', 99 'Transition is still idle after updating transition-duration'); 100 }, 'After canceling a transition, updating transition properties doesn\'t make' 101 + ' it live again'); 102 103 promise_test(async t => { 104 const div = addDiv(t, { style: 'margin-left: 0px' }); 105 getComputedStyle(div).marginLeft; 106 107 div.style.transition = 'margin-left 100s'; 108 div.style.marginLeft = '1000px'; 109 110 const transition = div.getAnimations()[0]; 111 await transition.ready; 112 113 assert_equals(transition.playState, 'running'); 114 div.style.display = 'none'; 115 116 await waitForFrame(); 117 118 assert_equals(transition.playState, 'idle'); 119 assert_equals(getComputedStyle(div).marginLeft, '1000px'); 120 }, 'Setting display:none on an element cancels its transitions'); 121 122 promise_test(async t => { 123 const parentDiv = addDiv(t); 124 const childDiv = document.createElement('div'); 125 parentDiv.appendChild(childDiv); 126 childDiv.setAttribute('style', 'margin-left: 0px'); 127 128 getComputedStyle(childDiv).marginLeft; 129 130 childDiv.style.transition = 'margin-left 100s'; 131 childDiv.style.marginLeft = '1000px'; 132 133 const transition = childDiv.getAnimations()[0]; 134 await transition.ready; 135 136 assert_equals(transition.playState, 'running'); 137 parentDiv.style.display = 'none'; 138 await waitForFrame(); 139 140 assert_equals(transition.playState, 'idle'); 141 assert_equals(getComputedStyle(childDiv).marginLeft, '1000px'); 142 }, 'Setting display:none cancels transitions on a child element'); 143 144 promise_test(async t => { 145 const div = addDiv(t, { style: 'margin-left: 0px' }); 146 getComputedStyle(div).marginLeft; 147 148 div.style.transition = 'margin-left 100s'; 149 div.style.marginLeft = '1000px'; 150 151 const transition = div.getAnimations()[0]; 152 await transition.ready; 153 154 assert_equals(transition.playState, 'running'); 155 // Set an unrecognized property value 156 div.style.transitionProperty = 'none'; 157 getComputedStyle(div).marginLeft; 158 await waitForFrame(); 159 160 assert_equals(transition.playState, 'idle'); 161 assert_equals(getComputedStyle(div).marginLeft, '1000px'); 162 }, 'Removing a property from transition-property cancels transitions on that '+ 163 'property'); 164 165 promise_test(async t => { 166 const div = addDiv(t, { style: 'margin-left: 0px' }); 167 getComputedStyle(div).marginLeft; 168 169 div.style.transition = 'margin-left 100s'; 170 div.style.marginLeft = '1000px'; 171 172 const transition = div.getAnimations()[0]; 173 await transition.ready; 174 175 assert_equals(transition.playState, 'running'); 176 div.style.transition = 'margin-left 10s -10s'; // combined duration is zero 177 178 // Note that simply setting the combined duration to zero is not enough to 179 // cancel the transition. We must also update the end value so that the, 180 // "the end value of the running transition is not equal to the value of the 181 // property in the after-change style" condition is true. 182 // 183 // (And note that the zero combined duration is not strictly necessary to 184 // cancel the original transition--but it does ensure another transition is 185 // not generated in its place.) 186 187 div.style.marginLeft = '2000px'; 188 getComputedStyle(div).marginLeft; 189 await waitForFrame(); 190 191 assert_equals(transition.playState, 'idle'); 192 assert_equals(getComputedStyle(div).marginLeft, '2000px'); 193 }, 'Setting zero combined duration'); 194 195 promise_test(async t => { 196 const div = addDiv(t, { style: 'margin-left: 0px' }); 197 getComputedStyle(div).marginLeft; 198 199 div.style.transition = 'margin-left 100s'; 200 div.style.marginLeft = '1000px'; 201 202 const transition = div.getAnimations()[0]; 203 await transition.ready; 204 205 assert_equals(transition.playState, 'running'); 206 div.style.marginLeft = '2000px'; 207 getComputedStyle(div).marginLeft; 208 await waitForFrame(); 209 210 assert_equals(transition.playState, 'idle'); 211 }, 'Changing style to another interpolable value cancels the original ' + 212 'transition'); 213 214 promise_test(async t => { 215 const div = addDiv(t, { style: 'margin-left: 0px' }); 216 getComputedStyle(div).marginLeft; 217 218 div.style.transition = 'margin-left 100s'; 219 div.style.marginLeft = '1000px'; 220 221 const transition = div.getAnimations()[0]; 222 await transition.ready; 223 224 assert_equals(transition.playState, 'running'); 225 div.style.marginLeft = 'auto'; 226 getComputedStyle(div).marginLeft; 227 await waitForFrame(); 228 229 assert_equals(div.getAnimations().length, 0, 230 'There should be no transitions'); 231 assert_equals(transition.playState, 'idle'); 232 }, 'An after-change style value can\'t be interpolated'); 233 234 promise_test(async t => { 235 const div = addDiv(t, { style: 'margin-left: 0px' }); 236 getComputedStyle(div).marginLeft; 237 238 div.style.transition = 'margin-left 100s'; 239 div.style.marginLeft = '1000px'; 240 241 const transition = div.getAnimations()[0]; 242 await transition.ready; 243 244 assert_equals(transition.playState, 'running'); 245 div.style.marginLeft = '0px'; 246 getComputedStyle(div).marginLeft; 247 await waitForFrame(); 248 249 assert_equals(transition.playState, 'idle'); 250 }, 'Reversing a running transition cancels the original transition'); 251 252 </script>