test_transitions_events.html (9563B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=531585 5 --> 6 <head> 7 <title>Test for Bug 531585 (transitionend event)</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 10 </head> 11 <style type="text/css"> 12 13 .bar { margin: 10px; } 14 15 #one { transition-duration: 500ms; transition-property: all; } 16 #two { transition: margin-left 1s; } 17 #three { transition: margin 0.5s 0.25s; } 18 19 #four, #five, #six, #seven::before, #seven::after { 20 transition: 500ms color; 21 border-color: black; /* don't derive from color */ 22 column-rule-color: black; /* don't derive from color */ 23 text-decoration-color: black; /* don't derive from color */ 24 outline-color: black; /* don't derive from color */ 25 } 26 27 #four { 28 /* give the reversing transition a long duration; the reversing will 29 still be quick */ 30 transition-duration: 30s; 31 transition-timing-function: cubic-bezier(0, 1, 1, 0); 32 } 33 34 #seven::before, #seven::after { 35 content: "x"; 36 transition-duration: 50ms; 37 } 38 #seven[foo]::before, #seven[foo]::after { color: lime; } 39 40 </style> 41 <body> 42 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=531585">Mozilla Bug 531585</a> 43 <p id="display"> 44 45 <span id="one" style="color:blue"></span> 46 <span id="two"></span> 47 <span id="three"></span> 48 <span id="four" style="color: blue"></span> 49 <span id="five" style="color: blue"></span> 50 <span id="six" style="color: blue"></span> 51 <span id="seven" style="color: blue"></span> 52 53 </p> 54 <pre id="test"> 55 <script type="application/javascript"> 56 57 /** Test for Bug 531585 (transitionend event) */ 58 59 SimpleTest.waitForExplicitFinish(); 60 SimpleTest.requestFlakyTimeout("untriaged"); 61 var gTestCount = 0; 62 function started_test() { ++gTestCount; } 63 function finished_test() { if (--gTestCount == 0) { SimpleTest.finish(); } } 64 65 function $(id) { return document.getElementById(id); } 66 function cs(id) { return getComputedStyle($(id), ""); } 67 68 var got_one_root = false; 69 var got_one_target = false; 70 var got_two_target = false; 71 var got_three_top = false; 72 var got_three_right = false; 73 var got_three_bottom = false; 74 var got_three_left = false; 75 var got_four_root = false; 76 var got_body = false; 77 var did_finish_five = false; 78 var did_finish_six = false; 79 var got_before = false; 80 var got_after = false; 81 82 // Flush layout to guarantee consistent transitions. 83 document.body.getBoundingClientRect(); 84 85 document.documentElement.addEventListener("transitionend", 86 function(event) { 87 if (event.target == $("one")) { 88 ok(!got_one_root, "transitionend on one on root"); 89 is(event.propertyName, "border-right-color", 90 "propertyName for transitionend on one"); 91 is(event.elapsedTime, 0.5, 92 "elapsedTime for transitionend on one"); 93 is(cs("one").borderRightColor, "rgb(0, 255, 0)", 94 "computed style for transitionend on one"); 95 got_one_root = true; 96 finished_test(); 97 } else if (event.target == $("four")) { 98 ok(!got_four_root, "transitionend on four on root"); 99 is(event.propertyName, "color", 100 "propertyName for transitionend on four"); 101 // Reported time should (really?) be shortened by reversing. 102 ok(event.elapsedTime < 30, 103 "elapsedTime for transitionend on four"); 104 is(cs("four").color, "rgb(0, 0, 255)", 105 "computed style for transitionend on four (end of reverse transition)"); 106 got_four_root = true; 107 finished_test(); 108 } else if (event.target == document.body) { 109 // A synthesized event. 110 ok(!got_body, "transitionend on body on root"); 111 is(event.propertyName, "some-unknown-prop", 112 "propertyName for transitionend on body"); 113 // Reported time should (really?) be shortened by reversing. 114 is(event.elapsedTime, 0.5, 115 "elapsedTime for transitionend on body"); 116 got_body = true; 117 finished_test(); 118 } else if (event.target == $("seven")) { 119 if (!got_before) { 120 got_before = true; 121 is(event.pseudoElement, "::before"); 122 } else { 123 ok(!got_after, "transitionend on #seven::after"); 124 got_after = true; 125 is(event.pseudoElement, "::after"); 126 } 127 is(event.propertyName, "color"); 128 is(event.isTrusted, true); 129 finished_test(); 130 } else { 131 if ((event.target == $("five") && did_finish_five) || 132 (event.target == $("six") && did_finish_six)) { 133 todo(false, 134 "it seems that transitionstart and transitionend had been " + 135 "processed in the same frame"); 136 return; 137 } 138 ok(false, 139 "unexpected event on " + event.target.nodeName + 140 " element with id '" + event.target.id + "' " + 141 "elapsedTime=" + event.elapsedTime + 142 " propertyName='" + event.propertyName + "'"); 143 } 144 }); 145 146 $("one").addEventListener("transitionend", 147 function(event) { 148 is(event.propertyName, "color", "unexpected " + 149 "property name for transitionend on one on target"); 150 ok(!got_one_target, 151 "transitionend on one on target (color)"); 152 got_one_target = true; 153 event.stopPropagation(); 154 is(event.elapsedTime, 0.5, 155 "elapsedTime for transitionend on one"); 156 is(cs("one").getPropertyValue(event.propertyName), "rgb(0, 255, 0)", 157 "computed style of " + event.propertyName + " for transitionend on one"); 158 finished_test(); 159 }); 160 161 started_test(); // color on #one 162 $("one").style.color = "lime"; 163 164 165 $("two").addEventListener("transitionend", 166 function(event) { 167 event.stopPropagation(); 168 169 ok(!got_two_target, "transitionend on two on target"); 170 is(event.propertyName, "margin-left", 171 "propertyName for transitionend on two"); 172 is(event.elapsedTime, 1, 173 "elapsedTime for transitionend on two"); 174 is(event.bubbles, true, 175 "transitionend events should bubble"); 176 is(event.cancelable, false, 177 "transitionend events should not be cancelable"); 178 is(cs("two").marginLeft, "10px", 179 "computed style for transitionend on two"); 180 got_two_target = true; 181 finished_test(); 182 }); 183 184 started_test(); // #two 185 $("two").className = "bar"; 186 187 $("three").addEventListener("transitionend", 188 function(event) { 189 event.stopPropagation(); 190 191 switch (event.propertyName) { 192 case "margin-top": 193 ok(!got_three_top, "should only get margin-top once"); 194 got_three_top = true; 195 break; 196 case "margin-right": 197 ok(!got_three_right, "should only get margin-right once"); 198 got_three_right = true; 199 break; 200 case "margin-bottom": 201 ok(!got_three_bottom, "should only get margin-bottom once"); 202 got_three_bottom = true; 203 break; 204 case "margin-left": 205 ok(!got_three_left, "should only get margin-left once"); 206 got_three_left = true; 207 break; 208 default: 209 ok(false, "unexpected property name " + event.propertyName + 210 " for transitionend on three"); 211 } 212 is(event.elapsedTime, 0.5, 213 "elapsedTime for transitionend on three"); 214 is(cs("three").getPropertyValue(event.propertyName), "10px", 215 "computed style for transitionend on three"); 216 finished_test(); 217 }, true); 218 219 started_test(); // margin-top on #three 220 started_test(); // margin-right on #three 221 started_test(); // margin-bottom on #three 222 started_test(); // margin-left on #three 223 $("three").className = "bar"; 224 225 // We reverse the transition on four, and we should only get an event 226 // at the end of the second transition. 227 started_test(); // #four (listener on root) 228 $("four").style.color = "lime"; 229 230 // We cancel the transition on five by changing 'transition-property', 231 // and should thus get no event. 232 $("five").style.color = "lime"; 233 234 // We cancel the transition on six by changing 'transition-duration' and 235 // then changing the value, so we should get no event. 236 $("six").style.color = "lime"; 237 238 started_test(); // #seven::before (listener on root) 239 started_test(); // #seven::after (listener on root) 240 $("seven").setAttribute("foo", "bar"); 241 242 $("five").addEventListener("transitionstart", function() { 243 if (cs("five").color == "rgb(0, 255, 0)") { 244 // The transition has finished already. 245 did_finish_five = true; 246 } 247 $("five").style.transitionProperty = "margin-left"; 248 }); 249 250 $("six").addEventListener("transitionstart", function() { 251 if (cs("six").color == "rgb(0, 255, 0)") { 252 // The transition has finished already. 253 did_finish_six = true; 254 } 255 $("six").style.transitionDuration = "0s"; 256 $("six").style.transitionDelay = "0s"; 257 $("six").style.color = "blue"; 258 }); 259 260 function poll_start_reversal() { 261 if (cs("four").color != "rgb(0, 0, 255)") { 262 // The forward transition has started. 263 $("four").style.color = "blue"; 264 } else { 265 // The forward transition has not started yet. 266 setTimeout(poll_start_reversal, 20); 267 } 268 } 269 setTimeout(poll_start_reversal, 200); 270 271 // And make our own event to dispatch to the body. 272 started_test(); // synthesized event to body (listener on root) 273 274 var e = new TransitionEvent("transitionend", 275 { 276 bubbles: true, 277 cancelable: true, 278 propertyName: "some-unknown-prop", 279 elapsedTime: 0.5, 280 pseudoElement: "pseudo" 281 }); 282 is(e.bubbles, true); 283 is(e.cancelable, true); 284 is(e.propertyName, "some-unknown-prop"); 285 is(e.elapsedTime, 0.5); 286 is(e.pseudoElement, "pseudo"); 287 is(e.isTrusted, false) 288 289 document.body.dispatchEvent(e); 290 291 </script> 292 </pre> 293 </body> 294 </html>