Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
1 <!DOCTYPE HTML>
2 <html>
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id=435441
5 -->
6 <head>
7 <title>Test for Bug 435441</title>
8 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
9 <script type="application/javascript" src="animation_utils.js"></script>
10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
11 <style type="text/css">
13 #display p { margin-top: 0; margin-bottom: 0; }
14 #display .before, #display .after {
15 width: -moz-fit-content; border: 1px solid black;
16 }
17 #display .before::before, #display .after::after {
18 display: block;
19 width: 0;
20 text-indent: 0;
21 }
22 #display .before.started::before, #display .after.started::after {
23 width: 100px;
24 text-indent: 100px;
25 transition: 8s width ease-in-out, 8s text-indent ease-in-out;
26 }
27 #display .before::before {
28 content: "Before";
29 }
30 #display .after::after {
31 content: "After";
32 }
34 </style>
35 </head>
36 <body>
37 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435441">Mozilla Bug 435441</a>
38 <div id="display">
40 </div>
41 <pre id="test">
42 <script type="application/javascript">
44 /** Test for Bug 435441 **/
46 // Run tests simultaneously so we don't have to take up too much time.
47 SimpleTest.waitForExplicitFinish();
48 var gTestsRunning = 0;
49 function TestStarted() { ++gTestsRunning; }
50 function TestFinished() { if (--gTestsRunning == 0) SimpleTest.finish(); }
52 // An array of arrays of functions to be called at the outer index number
53 // of seconds after the present.
54 var gFutureCalls = [];
56 function add_future_call(index, func)
57 {
58 if (!(index in gFutureCalls)) {
59 gFutureCalls[index] = [];
60 }
61 gFutureCalls[index].push(func);
62 TestStarted();
63 }
64 var gStartTime1, gStartTime2;
65 var gCurrentTime;
66 var gSetupComplete = false;
68 function process_future_calls(index)
69 {
70 var calls = gFutureCalls[index];
71 if (!calls)
72 return;
73 gCurrentTime = Date.now();
74 for (var i = 0; i < calls.length; ++i) {
75 calls[i]();
76 TestFinished();
77 }
78 }
80 var timingFunctions = {
81 // a map from the value of 'transition-timing-function' to an array of
82 // the portions this function yields at 0 (always 0), 1/4, 1/2, and
83 // 3/4 and all (always 1) of the way through the time of the
84 // transition. Each portion is represented as a value and an
85 // acceptable error tolerance (based on a time error of 1%) for that
86 // value.
88 // ease
89 "ease": bezier(0.25, 0.1, 0.25, 1),
90 "cubic-bezier(0.25, 0.1, 0.25, 1.0)": bezier(0.25, 0.1, 0.25, 1),
92 // linear and various synonyms for it
93 "linear": function(x) { return x; },
94 "cubic-bezier(0.0, 0.0, 1.0, 1.0)": function(x) { return x; },
95 "cubic-bezier(0, 0, 1, 1)": function(x) { return x; },
96 "cubic-bezier(0, 0, 0, 0.0)": function(x) { return x; },
97 "cubic-bezier(1.0, 1, 0, 0)": function(x) { return x; },
99 // ease-in
100 "ease-in": bezier(0.42, 0, 1, 1),
101 "cubic-bezier(0.42, 0, 1.0, 1.0)": bezier(0.42, 0, 1, 1),
103 // ease-out
104 "ease-out": bezier(0, 0, 0.58, 1),
105 "cubic-bezier(0, 0, 0.58, 1.0)": bezier(0, 0, 0.58, 1),
107 // ease-in-out
108 "ease-in-out": bezier(0.42, 0, 0.58, 1),
109 "cubic-bezier(0.42, 0, 0.58, 1.0)": bezier(0.42, 0, 0.58, 1),
111 // other cubic-bezier values
112 "cubic-bezier(0.4, 0.1, 0.7, 0.95)": bezier(0.4, 0.1, 0.7, 0.95),
113 "cubic-bezier(1, 0, 0, 1)": bezier(1, 0, 0, 1),
114 "cubic-bezier(0, 1, 1, 0)": bezier(0, 1, 1, 0),
116 };
118 var div = document.getElementById("display");
120 // Set up all the elements on which we are going to start transitions.
122 // We have two reference elements to check the expected timing range.
123 // They both have 8s linear transitions from 0 to 1000px.
124 function make_reference_p() {
125 var p = document.createElement("p");
126 p.appendChild(document.createTextNode("reference"));
127 p.style.textIndent = "0px";
128 p.style.transition = "8s text-indent linear";
129 div.appendChild(p);
130 return p;
131 }
132 var earlyref = make_reference_p();
133 var earlyrefcs = getComputedStyle(earlyref, "");
135 // Test all timing functions using a set of 8-second transitions, which
136 // we check at times 0, 2s, 4s, 6s, and 8s.
137 var tftests = [];
138 for (var tf in timingFunctions) {
139 var p = document.createElement("p");
140 var t = document.createTextNode("transition-timing-function: " + tf);
141 p.appendChild(t);
142 p.style.textIndent = "0px";
143 p.style.transition = "8s text-indent linear";
144 p.style.transitionTimingFunction = tf;
145 div.appendChild(p);
146 is(getComputedStyle(p, "").textIndent, "0px",
147 "should be zero before changing value");
148 tftests.push([ p, tf ]);
149 }
151 // Check that the timing function continues even when we restyle in the
152 // middle.
153 var interrupt_tests = [];
154 for (var restyleParent of [true, false]) {
155 for (var itime = 2; itime < 8; itime += 2) {
156 var p = document.createElement("p");
157 var t = document.createTextNode("interrupt on " +
158 (restyleParent ? "parent" : "node itself") +
159 " at " + itime + "s");
160 p.appendChild(t);
161 p.style.textIndent = "0px";
162 p.style.transition = "8s text-indent cubic-bezier(0, 1, 1, 0)";
163 if (restyleParent) {
164 var d = document.createElement("div");
165 d.appendChild(p);
166 div.appendChild(d);
167 } else {
168 div.appendChild(p);
169 }
170 is(getComputedStyle(p, "").textIndent, "0px",
171 "should be zero before changing value");
172 setTimeout("interrupt_tests[" + interrupt_tests.length + "]" +
173 "[0]" + (restyleParent ? ".parentNode" : "") +
174 ".style.color = 'blue';" +
175 "check_interrupt_tests()", itime*1000);
176 interrupt_tests.push([ p, itime ]);
177 }
178 }
180 // Test transition-delay values of -4s through 4s on a 4s transition
181 // with 'ease-out' timing function.
182 var delay_tests = {};
183 for (var d = -4; d <= 4; ++d) {
184 var p = document.createElement("p");
185 var delay = d + "s";
186 var t = document.createTextNode("transition-delay: " + delay);
187 p.appendChild(t);
188 p.style.marginLeft = "0px";
189 p.style.transition = "4s margin-left ease-out " + delay;
190 div.appendChild(p);
191 is(getComputedStyle(p, "").marginLeft, "0px",
192 "should be zero before changing value");
193 delay_tests[d] = p;
194 }
196 // Test transition-delay values of -4s through 4s on a 4s transition
197 // with duration of zero.
198 var delay_zero_tests = {};
199 for (var d = -4; d <= 4; ++d) {
200 var p = document.createElement("p");
201 var delay = d + "s";
202 var t = document.createTextNode("transition-delay: " + delay);
203 p.appendChild(t);
204 p.style.marginLeft = "0px";
205 p.style.transition = "0s margin-left linear " + delay;
206 div.appendChild(p);
207 is(getComputedStyle(p, "").marginLeft, "0px",
208 "should be zero before changing value");
209 delay_zero_tests[d] = p;
210 }
212 // Test that changing the value on an already-running transition to the
213 // value it currently happens to have resets the transition.
214 function make_reset_test(transition, description)
215 {
216 var p = document.createElement("p");
217 var t = document.createTextNode(description);
218 p.appendChild(t);
219 p.style.marginLeft = "0px";
220 p.style.transition = transition;
221 div.appendChild(p);
222 is(getComputedStyle(p, "").marginLeft, "0px",
223 "should be zero before changing value");
224 return p;
225 }
226 var reset_test = make_reset_test("4s margin-left ease-out 4s", "transition-delay reset to starting point");
227 var reset_test_reference = make_reset_test("4s margin-left linear -3s", "reference for previous test (reset test)");
229 // Test that transitions on descendants do not trigger when the
230 // inherited value is itself transitioning. In other words, when
231 // ancestor and descendant both have a transition for the same property,
232 // and the descendant inherits the property from the ancestor, the
233 // descendant's transition is ignored (as part of the idea of not
234 // starting transitions on changes that result from animation).
235 // See http://lists.w3.org/Archives/Public/www-style/2009Jun/0121.html
236 // and http://lists.w3.org/Archives/Public/www-style/2009Jul/0050.html
237 var descendant_tests = [
238 { parent_transition: "",
239 child_transition: "4s text-indent" },
240 { parent_transition: "4s text-indent",
241 child_transition: "" },
242 { parent_transition: "4s text-indent",
243 child_transition: "16s text-indent" },
244 { parent_transition: "4s text-indent",
245 child_transition: "1s text-indent" },
246 { parent_transition: "8s letter-spacing",
247 child_transition: "4s text-indent" },
248 { parent_transition: "4s text-indent",
249 child_transition: "8s letter-spacing" },
250 { parent_transition: "4s text-indent",
251 child_transition: "8s all" },
252 { parent_transition: "8s text-indent",
253 child_transition: "4s all" },
254 // examples with positive and negative delay
255 { parent_transition: "4s text-indent 1s",
256 child_transition: "8s text-indent" },
257 { parent_transition: "4s text-indent -1s",
258 child_transition: "8s text-indent" }
259 ];
261 for (var i in descendant_tests) {
262 var test = descendant_tests[i];
263 test.parentNode = document.createElement("div");
264 test.childNode = document.createElement("p");
265 test.parentNode.appendChild(test.childNode);
266 test.childNode.appendChild(document.createTextNode(
267 "parent with \"" + test.parent_transition + "\" and " +
268 "child with \"" + test.child_transition + "\""));
269 test.parentNode.style.transition = test.parent_transition;
270 test.childNode.style.transition = test.child_transition;
271 test.parentNode.style.textIndent = "50px"; // transition from 50 to 150
272 test.parentNode.style.letterSpacing = "10px"; // transition from 10 to 5
273 div.appendChild(test.parentNode);
274 var parentCS = getComputedStyle(test.parentNode, "");
275 var childCS = getComputedStyle(test.childNode, "");
276 is(parentCS.textIndent, "50px",
277 "parent text-indent should be 50px before changing");
278 is(parentCS.letterSpacing, "10px",
279 "parent letter-spacing should be 10px before changing");
280 is(childCS.textIndent, "50px",
281 "child text-indent should be 50px before changing");
282 is(childCS.letterSpacing, "10px",
283 "child letter-spacing should be 10px before changing");
284 test.childCS = childCS;
285 }
287 // For all of these transitions, the transition for margin-left should
288 // have a duration of 8s, and the default timing function (ease) and
289 // delay (0).
290 // This is because we're implementing the proposal in
291 // http://lists.w3.org/Archives/Public/www-style/2009Aug/0109.html
292 var number_tests = [
293 { style: "transition: 4s margin, 8s margin-left" },
294 { style: "transition: 4s margin-left, 8s margin" },
295 { style: "transition-property: margin-left; " +
296 "transition-duration: 8s, 2s" },
297 { style: "transition-property: margin-left, margin-left; " +
298 "transition-duration: 2s, 8s" },
299 { style: "transition-property: margin-left, margin-left, margin-left; " +
300 "transition-duration: 8s, 2s" },
301 { style: "transition-property: margin-left; " +
302 "transition-duration: 8s, 16s" },
303 { style: "transition-property: margin-left, margin-left; " +
304 "transition-duration: 16s, 8s" },
305 { style: "transition-property: margin-left, margin-left, margin-left; " +
306 "transition-duration: 8s, 16s" },
307 { style: "transition-property: text-indent,word-spacing,margin-left; " +
308 "transition-duration: 8s; " +
309 "transition-delay: 0, 8s" },
310 { style: "transition-property: text-indent,word-spacing,margin-left; " +
311 "transition-duration: 8s, 16s; " +
312 "transition-delay: 8s, 8s, 0, 8s, 8s, 8s" },
313 ];
315 for (var i in number_tests) {
316 var test = number_tests[i];
317 var p = document.createElement("p");
318 p.setAttribute("style", test.style);
319 var t = document.createTextNode(test.style);
320 p.appendChild(t);
321 p.style.marginLeft = "100px";
322 div.appendChild(p);
323 is(getComputedStyle(p, "").marginLeft, "100px",
324 "should be 100px before changing value");
325 test.node = p;
326 }
328 // Test transitions that are also from-display:none, to-display:none, and
329 // display:none throughout.
330 var from_none_test, to_none_test, always_none_test;
331 function make_display_test(initially_none, text)
332 {
333 var p = document.createElement("p");
334 p.appendChild(document.createTextNode(text));
335 p.style.textIndent = "0px";
336 p.style.transition = "8s text-indent ease-in-out";
337 if (initially_none)
338 p.style.display = "none";
339 div.appendChild(p);
340 return p;
341 }
342 from_none_test = make_display_test(true, "transition from display:none");
343 to_none_test = make_display_test(false, "transition to display:none");
344 always_none_test = make_display_test(true, "transition always display:none");
345 var display_tests = [ from_none_test, to_none_test, always_none_test ];
347 // Test transitions on pseudo-elements
348 var before_test, after_test;
349 function make_pseudo_elem_test(pseudo)
350 {
351 var p = document.createElement("p");
352 p.className = pseudo;
353 div.appendChild(p);
354 return {"pseudo": pseudo, element: p};
355 }
356 before_test = make_pseudo_elem_test("before");
357 after_test = make_pseudo_elem_test("after");
358 var pseudo_element_tests = [ before_test, after_test ];
360 // FIXME (Bug 522599): Test a transition that reverses partway through.
362 var lateref = make_reference_p();
363 var laterefcs = getComputedStyle(lateref, "");
365 // flush style changes
366 var x = getComputedStyle(div, "").color;
368 // Start our timer as close as possible to when we start the first
369 // transition.
370 // Do not use setInterval because once it gets off in time, it stays off.
371 for (var i = 1; i <= 8; ++i) {
372 setTimeout(process_future_calls, i * 1000, i);
373 }
374 gStartTime1 = Date.now(); // set before any transitions have started
376 // Start all the transitions.
377 earlyref.style.textIndent = "1000px";
378 for (var test in tftests) {
379 var p = tftests[test][0];
380 p.style.textIndent = "100px";
381 }
382 for (var test in interrupt_tests) {
383 var p = interrupt_tests[test][0];
384 p.style.textIndent = "100px";
385 }
386 for (var d in delay_tests) {
387 var p = delay_tests[d];
388 p.style.marginLeft = "100px";
389 }
390 for (var d in delay_zero_tests) {
391 var p = delay_zero_tests[d];
392 p.style.marginLeft = "100px";
393 }
394 reset_test.style.marginLeft = "100px";
395 reset_test_reference.style.marginLeft = "100px";
396 for (var i in descendant_tests) {
397 var test = descendant_tests[i];
398 test.parentNode.style.textIndent = "150px";
399 test.parentNode.style.letterSpacing = "5px";
400 }
401 for (var i in number_tests) {
402 var test = number_tests[i];
403 test.node.style.marginLeft = "50px";
404 }
405 from_none_test.style.textIndent = "100px";
406 from_none_test.style.display = "";
407 to_none_test.style.textIndent = "100px";
408 to_none_test.style.display = "none";
409 always_none_test.style.textIndent = "100px";
410 for (var i in pseudo_element_tests) {
411 var test = pseudo_element_tests[i];
412 test.element.classList.add("started");
413 }
414 lateref.style.textIndent = "1000px";
416 // flush style changes
417 x = getComputedStyle(div, "").color;
419 gStartTime2 = Date.now(); // set after all transitions have started
420 gCurrentTime = gStartTime2;
422 /**
423 * Assert that a transition whose timing function yields the bezier
424 * |func|, running from |start_time| to |end_time| (both in seconds
425 * relative to when the transitions were started) should have produced
426 * computed value |cval| given that the transition was from
427 * |start_value| to |end_value| (both numbers in CSS pixels).
428 */
429 function check_transition_value(func, start_time, end_time,
430 start_value, end_value, cval, desc,
431 xfail)
432 {
433 /**
434 * Compute the value at a given time |elapsed|, by normalizing the
435 * input to the timing function using start_time and end_time and
436 * then turning the output into a value using start_value and
437 * end_value.
438 *
439 * The |error_direction| argument should be either -1, 0, or 1,
440 * suggesting adding on a little bit of error, to allow for the
441 * cubic-bezier calculation being an approximation. The amount of
442 * error is proportional to the slope of the timing function, since
443 * the error is added to the *input* of the timing function (after
444 * normalization to 0-1 based on start_time and end_time).
445 */
446 function value_at(elapsed, error_direction) {
447 var time_portion = (elapsed - start_time) / (end_time - start_time);
448 if (time_portion < 0)
449 time_portion = 0;
450 else if (time_portion > 1)
451 time_portion = 1;
452 // Assume a small error since bezier computation can be off slightly.
453 // (This test's computation is probably more accurate than Mozilla's.)
454 var value_portion = func(time_portion + error_direction * 0.0005);
455 if (value_portion < 0)
456 value_portion = 0;
457 else if (value_portion > 1)
458 value_portion = 1;
459 var value = (1 - value_portion) * start_value + value_portion * end_value;
460 if (start_value > end_value)
461 error_direction = -error_direction;
462 // Computed values get rounded to 1/60th of a pixel.
463 return value + error_direction * 0.02;
464 }
466 var time_range; // in seconds
467 var uns_range; // |range| before being sorted (so errors give it
468 // in the original order
469 if (!gSetupComplete) {
470 // No timers involved
471 time_range = [0, 0];
472 if (start_time < 0) {
473 uns_range = [ value_at(0, -1), value_at(0, 1) ];
474 } else {
475 var val = value_at(0, 0);
476 uns_range = [val, val];
477 }
478 } else {
479 time_range = [ px_to_num(earlyrefcs.textIndent) / 125,
480 px_to_num(laterefcs.textIndent) / 125 ];
481 // seconds
482 uns_range = [ value_at(time_range[0], -1),
483 value_at(time_range[1], 1) ];
484 }
485 var range = uns_range.concat(). /* concat to clone array */
486 sort(function compareNumbers(a,b) { return a - b; });
487 var actual = px_to_num(cval);
489 var fn = ok;
490 if (xfail && xfail(range))
491 fn = todo;
493 fn(range[0] <= actual && actual <= range[1],
494 desc + ": computed value " + cval + " should be between " +
495 uns_range[0].toFixed(6) + "px and " + uns_range[1].toFixed(6) +
496 "px at time between " + time_range[0] + "s and " + time_range[1] + "s.");
497 }
499 function check_ref_range()
500 {
501 // This is the only test where we compare the progress of the
502 // transitions to an actual time; we need considerable tolerance at
503 // the low end (we are using half a second).
504 var expected_range = [ (gCurrentTime - gStartTime2 - 40) / 8,
505 (Date.now() - gStartTime1 + 20) / 8 ];
506 if (expected_range[0] > 1000) {
507 expected_range[0] = 1000;
508 }
509 if (expected_range[1] > 1000) {
510 expected_range[1] = 1000;
511 }
512 function check(desc, value) {
513 // The timing on the unit test VMs is not reliable, so make this
514 // test report PASS when it succeeds and TODO when it fails.
515 var passed = expected_range[0] <= value && value <= expected_range[1];
516 (passed ? ok : todo)(passed,
517 desc + ": computed value " + value + "px should be between " +
518 expected_range[0].toFixed(6) + "px and " +
519 expected_range[1].toFixed(6) + "px at time between " +
520 expected_range[0]/125 + "s and " + expected_range[1]/125 + "s.");
521 }
522 check("early reference", px_to_num(earlyrefcs.textIndent));
523 check("late reference", px_to_num(laterefcs.textIndent));
524 }
526 for (var i = 1; i <= 8; ++i) {
527 add_future_call(i, check_ref_range);
528 }
530 function check_tf_test()
531 {
532 for (var test in tftests) {
533 var p = tftests[test][0];
534 var tf = tftests[test][1];
536 check_transition_value(timingFunctions[tf], 0, 8, 0, 100,
537 getComputedStyle(p, "").textIndent,
538 "timing function test for timing function " + tf);
540 }
542 check_interrupt_tests();
543 }
545 check_tf_test();
546 add_future_call(2, check_tf_test);
547 add_future_call(4, check_tf_test);
548 add_future_call(6, check_tf_test);
549 add_future_call(8, check_tf_test);
551 function check_interrupt_tests()
552 {
553 for (var test in interrupt_tests) {
554 var p = interrupt_tests[test][0];
555 var itime = interrupt_tests[test][1];
557 check_transition_value(timingFunctions["cubic-bezier(0, 1, 1, 0)"],
558 0, 8, 0, 100,
559 getComputedStyle(p, "").textIndent,
560 "interrupt " +
561 (p.parentNode == div ? "" : "on parent ") +
562 "test for time " + itime + "s");
563 }
564 }
566 // check_interrupt_tests is called from check_tf_test and from
567 // where we reset the interrupts
569 function check_delay_test(time)
570 {
571 var tf = timingFunctions["ease-out"];
572 for (var d in delay_tests) {
573 var p = delay_tests[d];
575 check_transition_value(tf, Number(d), Number(d) + 4, 0, 100,
576 getComputedStyle(p, "").marginLeft,
577 "delay test for delay " + d + "s");
578 }
579 }
581 check_delay_test(0);
582 for (var i = 1; i <= 8; ++i) {
583 add_future_call(i, check_delay_test);
584 }
586 function check_delay_zero_test(time)
587 {
588 for (var d in delay_zero_tests) {
589 var p = delay_zero_tests[d];
591 time_range = [ px_to_num(earlyrefcs.textIndent) / 125,
592 px_to_num(laterefcs.textIndent) / 125 ];
593 var m = getComputedStyle(p, "").marginLeft;
594 var desc = "delay_zero test for delay " + d + "s";
595 if (time_range[0] < d && time_range[1] < d) {
596 is(m, "0px", desc);
597 } else if ((time_range[0] > d && time_range[1] > d) ||
598 (d == 0 && time == 0)) {
599 is(m, "100px", desc);
600 }
601 }
602 }
604 check_delay_zero_test(0);
605 for (var i = 1; i <= 8; ++i) {
606 add_future_call(i, check_delay_zero_test);
607 }
609 function reset_reset_test(time)
610 {
611 reset_test.style.marginLeft = "0px";
612 }
613 function check_reset_test(time)
614 {
615 is(getComputedStyle(reset_test, "").marginLeft, "0px",
616 "reset test value at time " + time + "s.");
617 }
618 check_reset_test(0);
619 // reset the reset test right now so we don't have to worry about clock skew
620 // To make sure that this is valid, check that a pretty-much-identical test is
621 // already transitioning.
622 is(getComputedStyle(reset_test_reference, "").marginLeft, "75px",
623 "reset test reference value");
624 reset_reset_test();
625 check_reset_test(0);
626 for (var i = 1; i <= 8; ++i) {
627 (function(j) {
628 add_future_call(j, function() { check_reset_test(j); });
629 })(i);
630 }
632 check_descendant_tests();
633 add_future_call(2, check_descendant_tests);
634 add_future_call(6, check_descendant_tests);
636 function check_descendant_tests() {
637 // text-indent: transition from 50px to 150px
638 // letter-spacing: transition from 10px to 5px
639 var values = {};
640 values["text-indent"] = [ 50, 150 ];
641 values["letter-spacing"] = [ 10, 5 ];
642 var tf = timingFunctions["ease"];
644 for (var i in descendant_tests) {
645 var test = descendant_tests[i];
647 /* ti=text-indent, ls=letter-spacing */
648 var child_ti_duration = 0;
649 var child_ls_duration = 0;
650 var child_ti_delay = 0;
651 var child_ls_delay = 0;
653 if (test.parent_transition != "") {
654 var props = test.parent_transition.split(" ");
655 var duration = parseInt(props[0]);
656 var delay = (props.length > 2) ? parseInt(props[2]) : 0;
657 var property = props[1];
658 if (property == "text-indent") {
659 child_ti_duration = duration;
660 child_ti_delay = delay;
661 } else if (property == "letter-spacing") {
662 child_ls_duration = duration;
663 child_ls_delay = delay;
664 } else {
665 ok(false, "fix this test (unexpected transition-property " +
666 property + " on parent)");
667 }
668 }
670 if (test.child_transition != "") {
671 var props = test.child_transition.split(" ");
672 var duration = parseInt(props[0]);
673 var delay = (props.length > 2) ? parseInt(props[2]) : 0;
674 var property = props[1];
675 if (property != "text-indent" && property != "letter-spacing" &&
676 property != "all") {
677 ok(false, "fix this test (unexpected transition-property " +
678 property + " on child)");
679 }
681 if (property != "letter-spacing" && child_ti_duration == 0) {
682 child_ti_duration = duration;
683 child_ti_delay = delay;
684 }
685 if (property != "text-indent" && child_ls_duration == 0) {
686 child_ls_duration = duration;
687 child_ls_delay = delay;
688 }
689 }
691 var time_portions = {
692 "text-indent":
693 { duration: child_ti_duration, delay: child_ti_delay },
694 "letter-spacing":
695 { duration: child_ls_duration, delay: child_ls_delay },
696 };
698 for (var prop in {"text-indent": true, "letter-spacing": true}) {
699 var time_portion = time_portions[prop];
701 if (time_portion.duration == 0) {
702 time_portion.duration = 0.01;
703 time_portion.delay = -1;
704 }
706 check_transition_value(tf, time_portion.delay,
707 time_portion.delay + time_portion.duration,
708 values[prop][0], values[prop][1],
709 test.childCS.getPropertyValue(prop),
710 "descendant test, property " + prop);
711 }
712 }
713 }
715 function check_number_tests()
716 {
717 var tf = timingFunctions["ease"];
718 for (var d in number_tests) {
719 var test = number_tests[d];
720 var p = test.node;
722 check_transition_value(tf, 0, 8, 100, 50,
723 getComputedStyle(p, "").marginLeft,
724 "number of transitions test for style " +
725 test.style);
726 }
727 }
729 check_number_tests(0);
730 add_future_call(2, check_number_tests);
731 add_future_call(4, check_number_tests);
732 add_future_call(6, check_number_tests);
733 add_future_call(8, check_number_tests);
735 function check_display_tests(time)
736 {
737 var tf = timingFunctions["ease-in-out"];
738 for (var i in display_tests) {
739 var p = display_tests[i];
741 check_transition_value(tf, 0, 8, 0, 100,
742 getComputedStyle(p, "").textIndent,
743 "display test for test with " +
744 p.childNodes[0].data,
745 // TODO: Making transitions work on 'display:none' elements is
746 // still not implemented.
747 function(range) { return p != to_none_test &&
748 range[1] < 100 });
749 }
750 }
752 check_display_tests(0);
753 add_future_call(2, function() { check_display_tests(2); });
754 add_future_call(4, function() { check_display_tests(4); });
755 add_future_call(6, function() { check_display_tests(6); });
756 add_future_call(8, function() { check_display_tests(8); });
758 function check_pseudo_element_tests(time)
759 {
760 var tf = timingFunctions["ease-in-out"];
761 for (var i in pseudo_element_tests) {
762 var test = pseudo_element_tests[i];
764 check_transition_value(tf, 0, 8, 0, 100,
765 getComputedStyle(test.element, "").width,
766 "::"+test.pseudo+" test");
767 check_transition_value(tf, 0, 8, 0, 100,
768 getComputedStyle(test.element,
769 "::"+test.pseudo).textIndent,
770 "::"+test.pseudo+" indent test");
771 }
772 }
773 check_pseudo_element_tests(0);
774 add_future_call(2, function() { check_pseudo_element_tests(2); });
775 add_future_call(4, function() { check_pseudo_element_tests(4); });
776 add_future_call(6, function() { check_pseudo_element_tests(6); });
777 add_future_call(8, function() { check_pseudo_element_tests(8); });
779 gSetupComplete = true;
780 </script>
781 </pre>
782 </body>
783 </html>