disconnected-element-001.html (5676B)
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset=utf-8> 5 <title>CSS Transitions Test: Transitions do not run for a disconnected element</title> 6 <meta name="assert" content="If an element is not in the document during that 7 style change event or was not in the document during the previous style change 8 event, then transitions are not started for that element in that style change 9 event."> 10 <meta name="assert" content="If an element is no longer in the document, 11 implementations must cancel any running transitions on it and remove transitions 12 on it from the completed transitions."> 13 <link rel="help" title="Starting transitions" 14 href="https://drafts.csswg.org/css-transitions/#starting"> 15 16 <script src="/resources/testharness.js" type="text/javascript"></script> 17 <script src="/resources/testharnessreport.js" type="text/javascript"></script> 18 <script src="./support/helper.js" type="text/javascript"></script> 19 20 </head> 21 <body> 22 <div id="log"></div> 23 24 <script> 25 promise_test(async t => { 26 // Create element and remove it from the document 27 const div = addDiv(t, { 28 style: 'transition: background-color 100s; background-color: red', 29 }); 30 div.remove(); 31 32 // Attach event listeners 33 div.addEventListener('transitionrun', t.step_func(() => { 34 assert_unreached('transitionrun event should not be fired'); 35 })); 36 37 // Resolve before-change style 38 getComputedStyle(div).backgroundColor; 39 40 // Set up and resolve after-change style 41 div.style.backgroundColor = 'green'; 42 getComputedStyle(div).backgroundColor; 43 44 // There should be no events received for the triggered transition. 45 await waitForFrame(); 46 await waitForFrame(); 47 }, 'Transitions do not run on an element not in the document'); 48 49 test(t => { 50 // Create element but do not attach it to the document 51 const div = addDiv(t, { 52 style: 'transition: background-color 100s; background-color: red', 53 }); 54 div.remove(); 55 56 // Resolve before-change style 57 getComputedStyle(div).backgroundColor; 58 59 // Add to document 60 document.documentElement.append(div); 61 62 // Set up and resolve after-change style 63 div.style.backgroundColor = 'green'; 64 getComputedStyle(div).backgroundColor; 65 66 // We should have jumped immediately to the after-change style rather than 67 // transitioning to it. 68 assert_equals( 69 getComputedStyle(div).backgroundColor, 70 'rgb(0, 128, 0)', 71 'No transition should run' 72 ); 73 }, 'Transitions do not run for an element newly added to the document'); 74 75 promise_test(async t => { 76 // Create element and attach it to the document 77 const div = addDiv(t, { 78 style: 'transition: background-color 100s; background-color: red', 79 }); 80 81 // Attach event listeners 82 div.addEventListener('transitionrun', t.step_func(() => { 83 assert_unreached('transitionrun event should not be fired'); 84 })); 85 86 // Resolve before-change style 87 getComputedStyle(div).backgroundColor; 88 89 // Set up after-change style 90 div.style.backgroundColor = 'green'; 91 92 // But remove the document before the next style change event 93 div.remove(); 94 95 // There should be no events received for the triggered transition. 96 await waitForFrame(); 97 await waitForFrame(); 98 }, 'Transitions do not run for an element newly removed from the document'); 99 100 promise_test(async t => { 101 // Create element and attach it to the document 102 const div = addDiv(t, { 103 style: 'transition: background-color 100s; background-color: red', 104 }); 105 106 // Attach event listeners 107 const eventWatcher = new EventWatcher(t, div, [ 108 'transitionrun', 109 'transitioncancel', 110 ]); 111 112 // Trigger transition 113 getComputedStyle(div).backgroundColor; 114 div.style.backgroundColor = 'green'; 115 getComputedStyle(div).backgroundColor; 116 117 await eventWatcher.wait_for('transitionrun'); 118 119 // Remove the element from the document 120 div.remove(); 121 122 await eventWatcher.wait_for('transitioncancel'); 123 }, 'Transitions are canceled when an element is removed from the document'); 124 125 promise_test(async t => { 126 // Create a container element. We'll need this later. 127 const container = addDiv(t); 128 129 // Create element and attach it to the document 130 const div = addDiv(t, { 131 style: 'transition: background-color 100s; background-color: red', 132 }); 133 134 // Attach event listeners 135 const eventWatcher = new EventWatcher(t, div, [ 136 'transitionrun', 137 'transitioncancel', 138 ]); 139 140 // Trigger transition 141 getComputedStyle(div).backgroundColor; 142 div.style.backgroundColor = 'green'; 143 getComputedStyle(div).backgroundColor; 144 145 await eventWatcher.wait_for('transitionrun'); 146 147 // Re-parent element 148 container.append(div); 149 150 await eventWatcher.wait_for('transitioncancel'); 151 assert_equals( 152 getComputedStyle(div).backgroundColor, 153 'rgb(0, 128, 0)', 154 'There should be no transition after re-parenting' 155 ); 156 }, 'Transitions are canceled when an element is re-parented'); 157 158 promise_test(async t => { 159 // Create element and attach it to the document 160 const div = addDiv(t, { 161 style: 'transition: background-color 100s; background-color: red', 162 }); 163 164 // Attach event listeners 165 const eventWatcher = new EventWatcher(t, div, [ 166 'transitionrun', 167 'transitioncancel', 168 ]); 169 170 // Trigger transition 171 getComputedStyle(div).backgroundColor; 172 div.style.backgroundColor = 'green'; 173 getComputedStyle(div).backgroundColor; 174 175 await eventWatcher.wait_for('transitionrun'); 176 177 // Re-parent element to same parent 178 document.documentElement.append(div); 179 180 await eventWatcher.wait_for('transitioncancel'); 181 assert_equals( 182 getComputedStyle(div).backgroundColor, 183 'rgb(0, 128, 0)', 184 'There should be no transition after re-parenting' 185 ); 186 }, 'Transitions are canceled when an element is re-parented to the same node'); 187 </script> 188 189 </body> 190 </html>