layout/style/test/test_transitions_per_property.html

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

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.)

michael@0 1 <!DOCTYPE HTML>
michael@0 2 <html>
michael@0 3 <!--
michael@0 4 https://bugzilla.mozilla.org/show_bug.cgi?id=435441
michael@0 5 -->
michael@0 6 <head>
michael@0 7 <title>Test for Bug 435441</title>
michael@0 8 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
michael@0 9 <script type="text/javascript" src="property_database.js"></script>
michael@0 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
michael@0 11 <style type="text/css">
michael@0 12
michael@0 13 #display > p { margin-top: 0; margin-bottom: 0; }
michael@0 14
michael@0 15 </style>
michael@0 16 </head>
michael@0 17 <body>
michael@0 18 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435441">Mozilla Bug 435441</a>
michael@0 19
michael@0 20 <!--
michael@0 21 fixed-height container so percentage heights compute to different
michael@0 22 (i.e., nonzero) values
michael@0 23 fixed-width container so that percentages for margin-top and
michael@0 24 margin-bottom are all relative to the same size container (rather than
michael@0 25 one that depends on whether we're tall enough to need a scrollbar)
michael@0 26
michael@0 27 Use a 20px font size and line-height so that percentage line-height
michael@0 28 and vertical-align doesn't accumulate rounding error.
michael@0 29 -->
michael@0 30 <div style="height: 50px; width: 300px; font-size: 20px; line-height: 20px">
michael@0 31
michael@0 32 <div id="display">
michael@0 33 </div>
michael@0 34
michael@0 35 <div id="transformTest" style="height:100px; width:200px; background-color:blue;">
michael@0 36 </div>
michael@0 37
michael@0 38 </div>
michael@0 39 <pre id="test">
michael@0 40 <script type="application/javascript">
michael@0 41
michael@0 42 /** Test for Bug 435441 **/
michael@0 43
michael@0 44 SimpleTest.requestLongerTimeout(2);
michael@0 45 SimpleTest.waitForExplicitFinish();
michael@0 46
michael@0 47 function has_num(str)
michael@0 48 {
michael@0 49 return !!String(str).match(/^([\d.]+)/);
michael@0 50 }
michael@0 51
michael@0 52 function any_unit_to_num(str)
michael@0 53 {
michael@0 54 return Number(String(str).match(/^([\d.]+)/)[1]);
michael@0 55 }
michael@0 56
michael@0 57 var FUNC_NEGATIVE = "cubic-bezier(0.25, -2, 0.75, 1)";
michael@0 58 var FUNC_OVERONE = "cubic-bezier(0.25, 0, 0.75, 3)";
michael@0 59
michael@0 60 var supported_properties = {
michael@0 61 "border-bottom-left-radius": [ test_radius_transition ],
michael@0 62 "border-bottom-right-radius": [ test_radius_transition ],
michael@0 63 "border-top-left-radius": [ test_radius_transition ],
michael@0 64 "border-top-right-radius": [ test_radius_transition ],
michael@0 65 "-moz-box-flex": [ test_float_zeroToOne_transition,
michael@0 66 test_float_aboveOne_transition,
michael@0 67 test_float_zeroToOne_clamped ],
michael@0 68 "box-shadow": [ test_shadow_transition ],
michael@0 69 "-moz-column-count": [ test_pos_integer_or_auto_transition,
michael@0 70 test_integer_at_least_one_clamping ],
michael@0 71 "-moz-column-gap": [ test_length_transition,
michael@0 72 test_length_clamped ],
michael@0 73 "-moz-column-rule-color": [ test_color_transition,
michael@0 74 test_border_color_transition ],
michael@0 75 "-moz-column-rule-width": [ test_length_transition,
michael@0 76 test_length_clamped ],
michael@0 77 "-moz-column-width": [ test_length_transition,
michael@0 78 test_length_clamped ],
michael@0 79 "-moz-image-region": [ test_rect_transition ],
michael@0 80 "-moz-outline-radius-bottomleft": [ test_radius_transition ],
michael@0 81 "-moz-outline-radius-bottomright": [ test_radius_transition ],
michael@0 82 "-moz-outline-radius-topleft": [ test_radius_transition ],
michael@0 83 "-moz-outline-radius-topright": [ test_radius_transition ],
michael@0 84 "-moz-text-decoration-color": [ test_color_transition,
michael@0 85 test_border_color_transition ],
michael@0 86 "background-color": [ test_color_transition ],
michael@0 87 "background-position": [ test_background_position_transition,
michael@0 88 // FIXME: We don't currently test clamping,
michael@0 89 // since background-position uses calc() as
michael@0 90 // an intermediate form.
michael@0 91 /* test_length_percent_pair_unclamped */ ],
michael@0 92 "background-size": [ test_background_size_transition,
michael@0 93 // FIXME: We don't currently test clamping,
michael@0 94 // since background-size uses calc() as an
michael@0 95 // intermediate form.
michael@0 96 /* test_length_percent_pair_clamped */ ],
michael@0 97 "border-bottom-color": [ test_color_transition,
michael@0 98 test_border_color_transition ],
michael@0 99 "border-bottom-width": [ test_length_transition,
michael@0 100 test_length_clamped ],
michael@0 101 "border-left-color": [ test_color_transition,
michael@0 102 test_border_color_transition ],
michael@0 103 "border-left-width": [ test_length_transition,
michael@0 104 test_length_clamped ],
michael@0 105 "border-right-color": [ test_color_transition,
michael@0 106 test_border_color_transition ],
michael@0 107 "border-right-width": [ test_length_transition,
michael@0 108 test_length_clamped ],
michael@0 109 "border-spacing": [ test_length_pair_transition,
michael@0 110 test_length_pair_transition_clamped ],
michael@0 111 "border-top-color": [ test_color_transition,
michael@0 112 test_border_color_transition ],
michael@0 113 "border-top-width": [ test_length_transition,
michael@0 114 test_length_clamped ],
michael@0 115 "bottom": [ test_length_transition, test_percent_transition,
michael@0 116 test_length_percent_calc_transition,
michael@0 117 test_length_unclamped, test_percent_unclamped ],
michael@0 118 "clip": [ test_rect_transition ],
michael@0 119 "color": [ test_color_transition ],
michael@0 120 "fill": [ test_color_transition ],
michael@0 121 "fill-opacity" : [ test_float_zeroToOne_transition,
michael@0 122 // opacity is clamped in computed style
michael@0 123 // (not parsing/interpolation)
michael@0 124 test_float_zeroToOne_clamped ],
michael@0 125 "filter" : [ test_filter_transition ],
michael@0 126 "flex-basis": [ test_length_transition, test_percent_transition,
michael@0 127 test_length_clamped, test_percent_clamped ],
michael@0 128 "flex-grow": [ test_float_zeroToOne_transition,
michael@0 129 test_float_aboveOne_transition ],
michael@0 130 "flex-shrink": [ test_float_zeroToOne_transition,
michael@0 131 test_float_aboveOne_transition ],
michael@0 132 "flood-color": [ test_color_transition ],
michael@0 133 "flood-opacity" : [ test_float_zeroToOne_transition,
michael@0 134 // opacity is clamped in computed style
michael@0 135 // (not parsing/interpolation)
michael@0 136 test_float_zeroToOne_clamped ],
michael@0 137 "font-size": [ test_length_transition, test_percent_transition,
michael@0 138 test_length_percent_calc_transition,
michael@0 139 test_length_clamped, test_percent_clamped ],
michael@0 140 "font-size-adjust": [ test_float_zeroToOne_transition,
michael@0 141 test_float_aboveOne_transition,
michael@0 142 /* FIXME: font-size-adjust treats zero specially */
michael@0 143 /* test_float_zeroToOne_clamped */ ],
michael@0 144 "font-stretch": [ test_font_stretch ],
michael@0 145 "font-weight": [ test_font_weight ],
michael@0 146 "height": [ test_length_transition, test_percent_transition,
michael@0 147 test_length_percent_calc_transition,
michael@0 148 test_length_clamped, test_percent_clamped ],
michael@0 149 "left": [ test_length_transition, test_percent_transition,
michael@0 150 test_length_percent_calc_transition,
michael@0 151 test_length_unclamped, test_percent_unclamped ],
michael@0 152 "letter-spacing": [ test_length_transition, test_length_unclamped ],
michael@0 153 "lighting-color": [ test_color_transition ],
michael@0 154 // NOTE: when calc() is supported on 'line-height', we should add
michael@0 155 // test_length_percent_calc_transition.
michael@0 156 "line-height": [ test_length_transition, test_percent_transition,
michael@0 157 test_length_clamped, test_percent_clamped ],
michael@0 158 "margin-bottom": [ test_length_transition, test_percent_transition,
michael@0 159 test_length_percent_calc_transition,
michael@0 160 test_length_unclamped, test_percent_unclamped ],
michael@0 161 "margin-left": [ test_length_transition, test_percent_transition,
michael@0 162 test_length_percent_calc_transition,
michael@0 163 test_length_unclamped, test_percent_unclamped ],
michael@0 164 "margin-right": [ test_length_transition, test_percent_transition,
michael@0 165 test_length_percent_calc_transition,
michael@0 166 test_length_unclamped, test_percent_unclamped ],
michael@0 167 "margin-top": [ test_length_transition, test_percent_transition,
michael@0 168 test_length_percent_calc_transition,
michael@0 169 test_length_unclamped, test_percent_unclamped ],
michael@0 170 "marker-offset": [ test_length_transition,
michael@0 171 test_length_unclamped ],
michael@0 172 "max-height": [ test_length_transition, test_percent_transition,
michael@0 173 test_length_percent_calc_transition,
michael@0 174 test_length_clamped, test_percent_clamped ],
michael@0 175 "max-width": [ test_length_transition, test_percent_transition,
michael@0 176 test_length_percent_calc_transition,
michael@0 177 test_length_clamped, test_percent_clamped ],
michael@0 178 "min-height": [ test_length_transition, test_percent_transition,
michael@0 179 test_length_percent_calc_transition,
michael@0 180 test_length_clamped, test_percent_clamped ],
michael@0 181 "min-width": [ test_length_transition, test_percent_transition,
michael@0 182 test_length_percent_calc_transition,
michael@0 183 test_length_clamped, test_percent_clamped ],
michael@0 184 "opacity" : [ test_float_zeroToOne_transition,
michael@0 185 // opacity is clamped in computed style
michael@0 186 // (not parsing/interpolation)
michael@0 187 test_float_zeroToOne_clamped ],
michael@0 188 "order": [ test_integer_transition ],
michael@0 189 "outline-color": [ test_color_transition ],
michael@0 190 "outline-offset": [ test_length_transition, test_length_unclamped ],
michael@0 191 "outline-width": [ test_length_transition, test_length_clamped ],
michael@0 192 "padding-bottom": [ test_length_transition, test_percent_transition,
michael@0 193 test_length_percent_calc_transition,
michael@0 194 test_length_clamped, test_percent_clamped ],
michael@0 195 "padding-left": [ test_length_transition, test_percent_transition,
michael@0 196 test_length_percent_calc_transition,
michael@0 197 test_length_clamped, test_percent_clamped ],
michael@0 198 "padding-right": [ test_length_transition, test_percent_transition,
michael@0 199 test_length_percent_calc_transition,
michael@0 200 test_length_clamped, test_percent_clamped ],
michael@0 201 "padding-top": [ test_length_transition, test_percent_transition,
michael@0 202 test_length_percent_calc_transition,
michael@0 203 test_length_clamped, test_percent_clamped ],
michael@0 204 "perspective": [ test_length_transition ],
michael@0 205 "perspective-origin": [ test_length_pair_transition,
michael@0 206 test_length_percent_pair_transition,
michael@0 207 test_length_percent_pair_unclamped ],
michael@0 208 "right": [ test_length_transition, test_percent_transition,
michael@0 209 test_length_percent_calc_transition,
michael@0 210 test_length_unclamped, test_percent_unclamped ],
michael@0 211 "stop-color": [ test_color_transition ],
michael@0 212 "stop-opacity" : [ test_float_zeroToOne_transition,
michael@0 213 // opacity is clamped in computed style
michael@0 214 // (not parsing/interpolation)
michael@0 215 test_float_zeroToOne_clamped ],
michael@0 216 "stroke": [ test_color_transition ],
michael@0 217 "stroke-dasharray": [ test_dasharray_transition ],
michael@0 218 // NOTE: when calc() is supported on 'stroke-dashoffset', we should
michael@0 219 // add test_length_percent_calc_transition.
michael@0 220 "stroke-dashoffset": [ test_length_transition, test_percent_transition,
michael@0 221 test_length_unclamped, test_percent_unclamped ],
michael@0 222 "stroke-miterlimit": [ test_float_aboveOne_transition,
michael@0 223 test_float_aboveOne_clamped ],
michael@0 224 "stroke-opacity" : [ test_float_zeroToOne_transition,
michael@0 225 // opacity is clamped in computed style
michael@0 226 // (not parsing/interpolation)
michael@0 227 test_float_zeroToOne_clamped ],
michael@0 228 // NOTE: when calc() is supported on 'stroke-width', we should add
michael@0 229 // test_length_percent_calc_transition.
michael@0 230 "stroke-width": [ test_length_transition, test_percent_transition,
michael@0 231 test_length_clamped, test_percent_clamped ],
michael@0 232 "text-indent": [ test_length_transition, test_percent_transition,
michael@0 233 test_length_percent_calc_transition,
michael@0 234 test_length_unclamped, test_percent_unclamped ],
michael@0 235 "text-shadow": [ test_shadow_transition ],
michael@0 236 "top": [ test_length_transition, test_percent_transition,
michael@0 237 test_length_percent_calc_transition,
michael@0 238 test_length_unclamped, test_percent_unclamped ],
michael@0 239 "transform": [ test_transform_transition ],
michael@0 240 "transform-origin": [ test_length_pair_transition,
michael@0 241 test_length_percent_pair_transition,
michael@0 242 test_length_percent_pair_unclamped ],
michael@0 243 "vertical-align": [ test_length_transition, test_percent_transition,
michael@0 244 test_length_percent_calc_transition,
michael@0 245 test_length_unclamped, test_percent_unclamped ],
michael@0 246 "visibility": [ test_visibility_transition ],
michael@0 247 "width": [ test_length_transition, test_percent_transition,
michael@0 248 test_length_percent_calc_transition,
michael@0 249 test_length_clamped, test_percent_clamped ],
michael@0 250 "word-spacing": [ test_length_transition, test_length_unclamped ],
michael@0 251 "z-index": [ test_integer_transition, test_pos_integer_or_auto_transition ],
michael@0 252 };
michael@0 253
michael@0 254 var div = document.getElementById("display");
michael@0 255 var OMTAdiv = document.getElementById("transformTest");
michael@0 256 var cs = getComputedStyle(div, "");
michael@0 257 var OMTACs = getComputedStyle(OMTAdiv, "");
michael@0 258 var winUtils = SpecialPowers.getDOMWindowUtils(window);
michael@0 259
michael@0 260 function computeMatrix(v) {
michael@0 261 div.style.setProperty("transform", v, "");
michael@0 262 var result = cs.getPropertyValue("transform");
michael@0 263 div.style.removeProperty("transform");
michael@0 264 return result;
michael@0 265 }
michael@0 266 var c_rot_15 = computeMatrix("rotate(15deg)");
michael@0 267 is(c_rot_15.substring(0,6), "matrix", "should compute to matrix value");
michael@0 268 var c_rot_60 = computeMatrix("rotate(60deg)");
michael@0 269 is(c_rot_60.substring(0,6), "matrix", "should compute to matrix value");
michael@0 270
michael@0 271 var transformTestIndex = 0;
michael@0 272 var transformTests = [
michael@0 273 // rotate
michael@0 274 { start: 'none', end: 'rotate(60deg)',
michael@0 275 expected_uncomputed: 'rotate(15deg)',
michael@0 276 expected: c_rot_15 },
michael@0 277 { start: 'rotate(0)', end: 'rotate(60deg)',
michael@0 278 expected_uncomputed: 'rotate(15deg)',
michael@0 279 expected: c_rot_15 },
michael@0 280 { start: 'rotate(0deg)', end: 'rotate(60deg)',
michael@0 281 expected_uncomputed: 'rotate(15deg)',
michael@0 282 expected: c_rot_15 },
michael@0 283 { start: 'none', end: c_rot_60,
michael@0 284 expected: c_rot_15 },
michael@0 285 { start: 'none', end: 'rotate(360deg)',
michael@0 286 expected_uncomputed: 'rotate(90deg)',
michael@0 287 expected: computeMatrix('rotate(90deg)') },
michael@0 288 { start: 'none', end: 'rotatez(360deg)',
michael@0 289 expected_uncomputed: 'rotate(90deg)',
michael@0 290 expected: computeMatrix('rotate(90deg)') },
michael@0 291 { start: 'none', end: 'rotate(720deg)',
michael@0 292 expected_uncomputed: 'rotate(180deg)',
michael@0 293 expected: computeMatrix('rotate(180deg)') },
michael@0 294 { start: 'none', end: 'rotate(720deg)',
michael@0 295 expected_uncomputed: 'rotatez(180deg)',
michael@0 296 expected: computeMatrix('rotate(180deg)') },
michael@0 297 { start: 'none', end: 'rotate(1080deg)',
michael@0 298 expected_uncomputed: 'rotate(270deg)',
michael@0 299 expected: computeMatrix('rotate(270deg)') },
michael@0 300 { start: 'none', end: 'rotate(1080deg)',
michael@0 301 expected_uncomputed: 'rotate(270deg)',
michael@0 302 expected: computeMatrix('rotatez(270deg)') },
michael@0 303 { start: 'none', end: 'rotate(1440deg)',
michael@0 304 expected_uncomputed: 'rotate(360deg)',
michael@0 305 expected: computeMatrix('scale(1)'),
michael@0 306 round_error_ok: true },
michael@0 307 { start: 'none', end: 'rotatey(60deg)',
michael@0 308 expected_uncomputed: 'rotatey(15deg)',
michael@0 309 expected: computeMatrix('rotatey(15deg)') },
michael@0 310 { start: 'none', end: 'rotatey(720deg)',
michael@0 311 expected_uncomputed: 'rotatey(180deg)',
michael@0 312 expected: computeMatrix('rotatey(180deg)') },
michael@0 313 { start: 'none', end: 'rotatex(60deg)',
michael@0 314 expected_uncomputed: 'rotatex(15deg)',
michael@0 315 expected: computeMatrix('rotatex(15deg)') },
michael@0 316 { start: 'none', end: 'rotatex(720deg)',
michael@0 317 expected_uncomputed: 'rotatex(180deg)',
michael@0 318 expected: computeMatrix('rotatex(180deg)') },
michael@0 319
michael@0 320 // translate
michael@0 321 { start: 'translate(20px)', end: 'none',
michael@0 322 expected_uncomputed: 'translate(15px)',
michael@0 323 expected: 'matrix(1, 0, 0, 1, 15, 0)' },
michael@0 324 { start: 'translate(20px, 12px)', end: 'none',
michael@0 325 expected_uncomputed: 'translate(15px, 9px)',
michael@0 326 expected: 'matrix(1, 0, 0, 1, 15, 9)' },
michael@0 327 { start: 'translateX(-20px)', end: 'none',
michael@0 328 expected_uncomputed: 'translateX(-15px)',
michael@0 329 expected: 'matrix(1, 0, 0, 1, -15, 0)' },
michael@0 330 { start: 'translateY(-40px)', end: 'none',
michael@0 331 expected_uncomputed: 'translateY(-30px)',
michael@0 332 expected: 'matrix(1, 0, 0, 1, 0, -30)' },
michael@0 333 { start: 'translateZ(40px)', end: 'none',
michael@0 334 expected_uncomputed: 'translateZ(30px)',
michael@0 335 expected: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 30, 1)' },
michael@0 336 { start: 'none', end: 'translate3D(40px, 60px, -40px)',
michael@0 337 expected_uncomputed: 'translate3D(10px, 15px, -10px)',
michael@0 338 expected: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 15, -10, 1)' },
michael@0 339 // percentages are relative to 300px (width) and 50px (height)
michael@0 340 // per the prerequisites in property_database.js
michael@0 341 { start: 'translate(20%)', end: 'none',
michael@0 342 expected_uncomputed: 'translate(15%)',
michael@0 343 expected: 'matrix(1, 0, 0, 1, 45, 0)',
michael@0 344 round_error_ok: true },
michael@0 345 { start: 'translate(20%, 12%)', end: 'none',
michael@0 346 expected_uncomputed: 'translate(15%, 9%)',
michael@0 347 expected: 'matrix(1, 0, 0, 1, 45, 4.5)',
michael@0 348 round_error_ok: true },
michael@0 349 { start: 'translateX(-20%)', end: 'none',
michael@0 350 expected_uncomputed: 'translateX(-15%)',
michael@0 351 expected: 'matrix(1, 0, 0, 1, -45, 0)',
michael@0 352 round_error_ok: true },
michael@0 353 { start: 'translateY(-40%)', end: 'none',
michael@0 354 expected_uncomputed: 'translateY(-30%)',
michael@0 355 expected: 'matrix(1, 0, 0, 1, 0, -15)',
michael@0 356 round_error_ok: true,
michael@0 357 big_omta_round_error: true },
michael@0 358 { start: 'none', end: 'rotate(90deg) translate(20%, 20%) rotate(-90deg)',
michael@0 359 expected_uncomputed: 'rotate(22.5deg) translate(5%, 5%) rotate(-22.5deg)',
michael@0 360 round_error_ok: true },
michael@0 361 { start: 'none', end: 'rotate(-90deg) translate(20%, 20%) rotate(90deg)',
michael@0 362 expected_uncomputed: 'rotate(-22.5deg) translate(5%, 5%) rotate(22.5deg)',
michael@0 363 round_error_ok: true },
michael@0 364 // test percent translation using matrix decomposition
michael@0 365 { start: 'rotate(45deg) rotate(-45deg)',
michael@0 366 end: 'rotate(90deg) translate(20%, 20%) rotate(-90deg)',
michael@0 367 expected: 'matrix(1, 0, 0, 1, -2.5, 15)',
michael@0 368 round_error_ok: true },
michael@0 369 { start: 'rotate(45deg) rotate(-45deg)',
michael@0 370 end: 'rotate(-90deg) translate(20%, 20%) rotate(90deg)',
michael@0 371 expected: 'matrix(1, 0, 0, 1, 2.5, -15)',
michael@0 372 round_error_ok: true },
michael@0 373 // test calc() in translate
michael@0 374 // Note that font-size: is 20px, and that percentages are relative
michael@0 375 // to 300px (width) and 50px (height) per the prerequisites in
michael@0 376 // property_database.js
michael@0 377 { start: 'translateX(20%)', /* 60px */
michael@0 378 end: 'translateX(calc(10% + 1em))', /* 30px + 20px = 50px */
michael@0 379 expected_uncomputed: 'translateX(calc(17.5% + 0.25em))',
michael@0 380 expected: 'matrix(1, 0, 0, 1, 57.5, 0)',
michael@0 381 big_omta_round_error: true },
michael@0 382 { start: 'translate(calc(0.75 * 3em + 1.5 * 10%), calc(0.5 * 5em + 0.5 * 8%))', /* 90px, 52px */
michael@0 383 end: 'rotate(90deg) translateY(20%) rotate(90deg) translateY(calc(10% + 0.5em)) rotate(180deg)', /* -10px, -15px */
michael@0 384 expected: 'matrix(1, 0, 0, 1, 65, 35.25)',
michael@0 385 big_omta_round_error: true },
michael@0 386
michael@0 387 // scale
michael@0 388 { start: 'scale(2)', end: 'none',
michael@0 389 expected_uncomputed: 'scale(1.75)',
michael@0 390 expected: 'matrix(1.75, 0, 0, 1.75, 0, 0)' },
michael@0 391 { start: 'none', end: 'scale(0.4)',
michael@0 392 expected_uncomputed: 'scale(0.85)',
michael@0 393 expected: 'matrix(0.85, 0, 0, 0.85, 0, 0)',
michael@0 394 round_error_ok: true },
michael@0 395 { start: 'scale(2)', end: 'scale(-2)',
michael@0 396 expected_uncomputed: 'scale(1)',
michael@0 397 expected: 'matrix(1, 0, 0, 1, 0, 0)' },
michael@0 398 { start: 'scale(2)', end: 'scale(-6)',
michael@0 399 expected_uncomputed: 'scale(0)',
michael@0 400 expected: 'matrix(0, 0, 0, 0, 0, 0)' },
michael@0 401 { start: 'scale(2, 0.4)', end: 'none',
michael@0 402 expected_uncomputed: 'scale(1.75, 0.55)',
michael@0 403 expected: 'matrix(1.75, 0, 0, 0.55, 0, 0)',
michael@0 404 round_error_ok: true },
michael@0 405 { start: 'scaleX(3)', end: 'none',
michael@0 406 expected_uncomputed: 'scaleX(2.5)',
michael@0 407 expected: 'matrix(2.5, 0, 0, 1, 0, 0)' },
michael@0 408 { start: 'scaleY(5)', end: 'none',
michael@0 409 expected_uncomputed: 'scaleY(4)',
michael@0 410 expected: 'matrix(1, 0, 0, 4, 0, 0)' },
michael@0 411 { start: 'scaleZ(5)', end: 'none',
michael@0 412 expected_uncomputed: 'scaleZ(4)',
michael@0 413 expected: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1)' },
michael@0 414 { start: 'none', end: 'scale3D(5, 5, 5)',
michael@0 415 expected_uncomputed: 'scale3D(2, 2, 2)',
michael@0 416 expected: 'matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1)' },
michael@0 417
michael@0 418 // skew
michael@0 419 { start: 'skewX(45deg)', end: 'none',
michael@0 420 expected_uncomputed: 'skewX(33.75deg)' },
michael@0 421 { start: 'skewY(45deg)', end: 'none',
michael@0 422 expected_uncomputed: 'skewY(33.75deg)' },
michael@0 423 { start: 'skew(45deg)', end: 'none',
michael@0 424 expected_uncomputed: 'skew(33.75deg)' },
michael@0 425 { start: 'skew(45deg, 45deg)', end: 'none',
michael@0 426 expected_uncomputed: 'skew(33.75deg, 33.75deg)' },
michael@0 427 { start: 'skewX(45deg)', end: 'skewX(-45deg)',
michael@0 428 expected_uncomputed: 'skewX(22.5deg)' },
michael@0 429 { start: 'skewX(0)', end: 'skewX(-45deg)',
michael@0 430 expected_uncomputed: 'skewX(-11.25deg)' },
michael@0 431 { start: 'skewY(45deg)', end: 'skewY(-45deg)',
michael@0 432 expected_uncomputed: 'skewY(22.5deg)' },
michael@0 433
michael@0 434 // matrix : skewX
michael@0 435 { start: 'matrix(1, 0, 3, 1, 0, 0)', end: 'none',
michael@0 436 expected: 'matrix(1, 0, ' + 3 * 0.75 + ', 1, 0, 0)',
michael@0 437 round_error_ok: true },
michael@0 438 { start: 'skewX(0)', end: 'skewX(-45deg) translate(0)',
michael@0 439 expected: 'matrix(1, 0, -0.25, 1, 0, 0)',
michael@0 440 round_error_ok: true },
michael@0 441 // matrix : rotate
michael@0 442 { start: 'rotate(-30deg)', end: 'matrix(0, 1, -1, 0, 0, 0)',
michael@0 443 expected: 'matrix(1, 0, 0, 1, 0, 0)',
michael@0 444 round_error_ok: true },
michael@0 445 { start: 'rotate(-30deg) translateX(0)',
michael@0 446 end: 'translateX(0) rotate(-90deg)',
michael@0 447 expected: computeMatrix('rotate(-45deg)'),
michael@0 448 round_error_ok: true },
michael@0 449 // matrix decomposition of skewY
michael@0 450 { start: 'skewY(60deg)', end: 'skewY(-60deg) translateX(0)',
michael@0 451 /* rotate(30deg) skewX(60deg)/2 scale(2, 0.5) */
michael@0 452 expected: computeMatrix('rotate(30deg) skewX(' + Math.atan(Math.tan(Math.PI * 60/180) / 2) + 'rad) scale(2, 0.5)'),
michael@0 453 round_error_ok: true },
michael@0 454
michael@0 455 // matrix decomposition
michael@0 456
michael@0 457 // Four pairs of the same matrix expressed different ways.
michael@0 458 { start: 'matrix(-1, 0, 0, -1, 0, 0)', /* rotate(180deg) */
michael@0 459 end: 'matrix(1, 0, 0, 1, 0, 0)',
michael@0 460 expected: computeMatrix('rotate(135deg)') },
michael@0 461 { start: 'scale(-1)', end: 'none',
michael@0 462 expected_uncomputed: 'scale(-0.5)',
michael@0 463 expected: 'matrix(-0.5, 0, 0, -0.5, 0, 0)' },
michael@0 464 { start: 'rotate(180deg)', end: 'none',
michael@0 465 expected_uncomputed: 'rotate(135deg)' },
michael@0 466 { start: 'rotate(-180deg)', end: 'none',
michael@0 467 expected_uncomputed: 'rotate(-135deg)',
michael@0 468 expected: computeMatrix('rotate(225deg)') },
michael@0 469
michael@0 470 // matrix followed by scale
michael@0 471 { start: 'matrix(2, 0, 0, 2, 10, 20) scale(2)',
michael@0 472 end: 'none',
michael@0 473 expected: 'matrix(3.0625, 0, 0, 3.0625, 7.5, 15)' },
michael@0 474
michael@0 475 // ... and a bunch of similar possibilities. The spec isn't settled
michael@0 476 // here; there are multiple options. See:
michael@0 477 // http://lists.w3.org/Archives/Public/www-style/2010Jun/0602.html
michael@0 478 { start: 'matrix(-1, 0, 0, 1, 0, 0)', /* scaleX(-1) */
michael@0 479 end: 'matrix(1, 0, 0, 1, 0, 0)',
michael@0 480 expected: computeMatrix('scaleX(-0.5)') },
michael@0 481
michael@0 482 { start: 'matrix(1, 0, 0, -1, 0, 0)', /* rotate(-180deg) scaleX(-1) */
michael@0 483 end: 'matrix(1, 0, 0, 1, 0, 0)',
michael@0 484 expected: computeMatrix('rotate(-135deg) scaleX(-0.5)') },
michael@0 485
michael@0 486 { start: 'matrix(0, 1, 1, 0, 0, 0)', /* rotate(-90deg) scaleX(-1) */
michael@0 487 end: 'matrix(1, 0, 0, 1, 0, 0)',
michael@0 488 expected: computeMatrix('rotate(-67.5deg) scaleX(-0.5)') },
michael@0 489
michael@0 490 { start: 'matrix(0, -1, 1, 0, 0, 0)', /* rotate(-90deg) */
michael@0 491 end: 'matrix(1, 0, 0, 1, 0, 0)',
michael@0 492 expected: computeMatrix('rotate(-67.5deg)') },
michael@0 493
michael@0 494 { start: 'matrix(0, 1, -1, 0, 0, 0)', /* rotate(90deg) */
michael@0 495 end: 'matrix(1, 0, 0, 1, 0, 0)',
michael@0 496 expected: computeMatrix('rotate(67.5deg)') },
michael@0 497
michael@0 498 { start: 'matrix(0, -1, -1, 0, 0, 0)', /* rotate(90deg) scaleX(-1) */
michael@0 499 end: 'matrix(1, 0, 0, 1, 0, 0)',
michael@0 500 expected: computeMatrix('rotate(67.5deg) scaleX(-0.5)') },
michael@0 501
michael@0 502 // Similar decomposition tests, but with skewX. I checked visually
michael@0 503 // that the sign of the skew was correct by checking visually that
michael@0 504 // the animations in
michael@0 505 // http://dbaron.org/css/test/2010/transition-negative-determinant
michael@0 506 // don't flip when they finish, and then wrote tests corresponding
michael@0 507 // to the current code's behavior.
michael@0 508 // ... start with four with positive determinants
michael@0 509 { start: 'none',
michael@0 510 end: 'matrix(1, 0, 1.5, 1, 0, 0)',
michael@0 511 /* skewX(atan(1.5)) */
michael@0 512 expected: 'matrix(1, 0, ' + 1.5 * 0.25 + ', 1, 0, 0)',
michael@0 513 round_error_ok: true },
michael@0 514 { start: 'none',
michael@0 515 end: 'matrix(-1, 0, 2, -1, 0, 0)',
michael@0 516 /* rotate(180deg) skewX(atan(-2)) */
michael@0 517 expected: computeMatrix('rotate(45deg) matrix(1, 0, ' + -2 * 0.25 + ', 1, 0, 0)'),
michael@0 518 round_error_ok: true },
michael@0 519 { start: 'none',
michael@0 520 end: 'matrix(0, -1, 1, -3, 0, 0)',
michael@0 521 /* rotate(-90deg) skewX(atan(3)) */
michael@0 522 expected: computeMatrix('rotate(-22.5deg) matrix(1, 0, ' + 3 * 0.25 + ', 1, 0, 0)'),
michael@0 523 round_error_ok: true },
michael@0 524 { start: 'none',
michael@0 525 end: 'matrix(0, 1, -1, 4, 0, 0)',
michael@0 526 /* rotate(90deg) skewX(atan(4)) */
michael@0 527 expected: computeMatrix('rotate(22.5deg) matrix(1, 0, ' + 4 * 0.25 + ', 1, 0, 0)'),
michael@0 528 round_error_ok: true },
michael@0 529 // and then four with negative determinants
michael@0 530 { start: 'none',
michael@0 531 end: 'matrix(1, 0, 1, -1, 0, 0)',
michael@0 532 /* rotate(-180deg) skewX(atan(-1)) scaleX(-1) */
michael@0 533 expected: computeMatrix('rotate(-45deg) matrix(1, 0, ' + -1 * 0.25 + ', 1, 0, 0) scaleX(0.5)'),
michael@0 534 round_error_ok: true },
michael@0 535 { start: 'none',
michael@0 536 end: 'matrix(-1, 0, -1, 1, 0, 0)',
michael@0 537 /* skewX(atan(-1)) scaleX(-1) */
michael@0 538 expected: computeMatrix('matrix(1, 0, ' + -1 * 0.25 + ', 1, 0, 0) scaleX(0.5)') },
michael@0 539 { start: 'none',
michael@0 540 end: 'matrix(0, 1, 1, -2, 0, 0)',
michael@0 541 /* rotate(-90deg) skewX(atan(2)) scaleX(-1) */
michael@0 542 expected: computeMatrix('rotate(-22.5deg) matrix(1, 0, ' + 2 * 0.25 + ', 1, 0, 0) scaleX(0.5)'),
michael@0 543 round_error_ok: true },
michael@0 544 { start: 'none',
michael@0 545 end: 'matrix(0, -1, -1, 0.5, 0, 0)',
michael@0 546 /* rotate(90deg) skewX(atan(0.5)) scaleX(-1) */
michael@0 547 expected: computeMatrix('rotate(22.5deg) matrix(1, 0, ' + 0.5 * 0.25 + ', 1, 0, 0) scaleX(0.5)'),
michael@0 548 round_error_ok: true },
michael@0 549
michael@0 550 // lists vs. matrix decomposition
michael@0 551 { start: 'translate(10px) skewY(45deg)',
michael@0 552 end: 'translate(30px) skewY(-45deg)',
michael@0 553 expected_uncomputed: 'translate(15px) skewY(22.5deg)' },
michael@0 554 { start: 'skewY(45deg) rotate(90deg)',
michael@0 555 end: 'skewY(-45deg) rotate(90deg)',
michael@0 556 expected_uncomputed: 'skewY(22.5deg) rotate(90deg)' },
michael@0 557 { start: 'skewY(45deg) rotate(90deg) translate(0)',
michael@0 558 end: 'skewY(-45deg) rotate(90deg)',
michael@0 559 expected: 'matrix(0, 1, -1, -0.5, 0, 0)',
michael@0 560 round_error_ok: true },
michael@0 561 { start: 'skewX(45deg) rotate(90deg)',
michael@0 562 end: 'skewX(-45deg) rotate(90deg)',
michael@0 563 expected_uncomputed: 'skewX(22.5deg) rotate(90deg)' },
michael@0 564 { start: 'skewX(-60deg) rotate(90deg) translate(0)',
michael@0 565 end: 'skewX(60deg) rotate(90deg)',
michael@0 566 expected: computeMatrix('rotate(120deg) skewX(' + Math.atan(Math.tan(Math.PI * 60/180) / 2) + 'rad) scale(2, 0.5)'),
michael@0 567 round_error_ok: true },
michael@0 568 ];
michael@0 569
michael@0 570 var filterTests = [
michael@0 571 { start: "none", end: "none",
michael@0 572 expected: ["none"] },
michael@0 573 // function from none (number/length)
michael@0 574 { start: "none", end: "brightness(0.5)",
michael@0 575 expected: ["brightness", 0.875] },
michael@0 576 { start: "none", end: "contrast(0.5)",
michael@0 577 expected: ["contrast", 0.875] },
michael@0 578 { start: "none", end: "grayscale(0.5)",
michael@0 579 expected: ["grayscale", 0.125] },
michael@0 580 { start: "none", end: "invert(0.5)",
michael@0 581 expected: ["invert", 0.125] },
michael@0 582 { start: "none", end: "opacity(0.5)",
michael@0 583 expected: ["opacity", 0.875] },
michael@0 584 { start: "none", end: "saturate(0.5)",
michael@0 585 expected: ["saturate", 0.875] },
michael@0 586 { start: "none", end: "sepia(0.5)",
michael@0 587 expected: ["sepia", 0.125] },
michael@0 588 { start: "none", end: "blur(50px)",
michael@0 589 expected: ["blur", 12.5] },
michael@0 590 // function to none (number/length)
michael@0 591 { start: "brightness(0.5)", end: "none",
michael@0 592 expected: ["brightness", 0.625] },
michael@0 593 { start: "contrast(0.5)", end: "none",
michael@0 594 expected: ["contrast", 0.625] },
michael@0 595 { start: "grayscale(0.5)", end: "none",
michael@0 596 expected: ["grayscale", 0.375] },
michael@0 597 { start: "invert(0.5)", end: "none",
michael@0 598 expected: ["invert", 0.375] },
michael@0 599 { start: "opacity(0.5)", end: "none",
michael@0 600 expected: ["opacity", 0.625] },
michael@0 601 { start: "saturate(0.5)", end: "none",
michael@0 602 expected: ["saturate", 0.625] },
michael@0 603 { start: "sepia(0.5)", end: "none",
michael@0 604 expected: ["sepia", 0.375] },
michael@0 605 { start: "blur(50px)", end: "none",
michael@0 606 expected: ["blur", 37.5] },
michael@0 607 // function to same function (number/length)
michael@0 608 { start: "brightness(0.25)", end: "brightness(0.75)",
michael@0 609 expected: ["brightness", 0.375] },
michael@0 610 { start: "contrast(0.25)", end: "contrast(0.75)",
michael@0 611 expected: ["contrast", 0.375] },
michael@0 612 { start: "grayscale(0.25)", end: "grayscale(0.75)",
michael@0 613 expected: ["grayscale", 0.375] },
michael@0 614 { start: "invert(0.25)", end: "invert(0.75)",
michael@0 615 expected: ["invert", 0.375] },
michael@0 616 { start: "opacity(0.25)", end: "opacity(0.75)",
michael@0 617 expected: ["opacity", 0.375] },
michael@0 618 { start: "saturate(0.25)", end: "saturate(0.75)",
michael@0 619 expected: ["saturate", 0.375] },
michael@0 620 { start: "sepia(0.25)", end: "sepia(0.75)",
michael@0 621 expected: ["sepia", 0.375] },
michael@0 622 { start: "blur(25px)", end: "blur(75px)",
michael@0 623 expected: ["blur", 37.5] },
michael@0 624 // function to same function (percent)
michael@0 625 { start: "brightness(25%)", end: "brightness(75%)",
michael@0 626 expected: ["brightness", 0.375] },
michael@0 627 { start: "contrast(25%)", end: "contrast(75%)",
michael@0 628 expected: ["contrast", 0.375] },
michael@0 629 { start: "grayscale(25%)", end: "grayscale(75%)",
michael@0 630 expected: ["grayscale", 0.375] },
michael@0 631 { start: "invert(25%)", end: "invert(75%)",
michael@0 632 expected: ["invert", 0.375] },
michael@0 633 { start: "opacity(25%)", end: "opacity(75%)",
michael@0 634 expected: ["opacity", 0.375] },
michael@0 635 { start: "saturate(25%)", end: "saturate(75%)",
michael@0 636 expected: ["saturate", 0.375] },
michael@0 637 { start: "sepia(25%)", end: "sepia(75%)",
michael@0 638 expected: ["sepia", 0.375] },
michael@0 639 // function to same function (percent, number/length)
michael@0 640 { start: "brightness(0.25)", end: "brightness(75%)",
michael@0 641 expected: ["brightness", 0.375] },
michael@0 642 { start: "contrast(25%)", end: "contrast(0.75)",
michael@0 643 expected: ["contrast", 0.375] },
michael@0 644 // hue-rotate with different angle values
michael@0 645 { start: "hue-rotate(0deg)", end: "hue-rotate(720deg)",
michael@0 646 expected: ["hue-rotate", Math.PI.toFixed(5)] },
michael@0 647 { start: "hue-rotate(0rad)", end: "hue-rotate("+4*Math.PI+"rad)",
michael@0 648 expected: ["hue-rotate", Math.PI.toFixed(5)] },
michael@0 649 { start: "hue-rotate(0grad)", end: "hue-rotate(800grad)",
michael@0 650 expected: ["hue-rotate", Math.PI.toFixed(5)] },
michael@0 651 { start: "hue-rotate(0turn)", end: "hue-rotate(2turn)",
michael@0 652 expected: ["hue-rotate", Math.PI.toFixed(5)] },
michael@0 653 { start: "hue-rotate(0deg)", end: "hue-rotate("+4*Math.PI+"rad)",
michael@0 654 expected: ["hue-rotate", Math.PI.toFixed(5)] },
michael@0 655 { start: "hue-rotate(0turn)", end: "hue-rotate(800grad)",
michael@0 656 expected: ["hue-rotate", Math.PI.toFixed(5)] },
michael@0 657 { start: "hue-rotate(0grad)", end: "hue-rotate("+4*Math.PI+"rad)",
michael@0 658 expected: ["hue-rotate", Math.PI.toFixed(5)] },
michael@0 659 { start: "hue-rotate(0grad)", end: "hue-rotate(0turn)",
michael@0 660 expected: ["hue-rotate", 0] },
michael@0 661 // multiple matching functions, same length
michael@0 662 { start: "contrast(25%) brightness(0.25) blur(25px) sepia(75%)",
michael@0 663 end: "contrast(75%) brightness(0.75) blur(75px) sepia(25%)",
michael@0 664 expected: ["contrast", 0.375, "brightness", 0.375, "blur", 37.5, "sepia", 0.625] },
michael@0 665 { start: "invert(25%) brightness(0.25) blur(25px) invert(50%) brightness(0.5) blur(50px)",
michael@0 666 end: "invert(75%) brightness(0.75) blur(75px)",
michael@0 667 expected: ["invert", 0.375, "brightness", 0.375, "blur", 37.5, "invert", 0.375, "brightness", 0.625, "blur", 37.5] },
michael@0 668 // multiple matching functions, different length
michael@0 669 { start: "contrast(25%) brightness(0.5) blur(50px)",
michael@0 670 end: "contrast(75%)",
michael@0 671 expected: ["contrast", 0.375, "brightness", 0.625, "blur", 37.5] },
michael@0 672 // mismatching filter functions
michael@0 673 { start: "contrast(0%)", end: "blur(10px)",
michael@0 674 expected: ["blur", 10] },
michael@0 675 // not supported interpolations
michael@0 676 { start: "none", end: "url('#b')",
michael@0 677 expected: ["url", "\""+document.URL+"#b\""] },
michael@0 678 { start: "url('#a')", end: "none",
michael@0 679 expected: ["none"] },
michael@0 680 { start: "url('#a')", end: "url('#b')",
michael@0 681 expected: ["url", "\""+document.URL+"#b\""] },
michael@0 682 { start: "url('#a')", end: "blur(10px)",
michael@0 683 expected: ["blur", 10] },
michael@0 684 { start: "blur(10px)", end: "url('#a')",
michael@0 685 expected: ["url", "\""+document.URL+"#a\""] },
michael@0 686 { start: "blur(0px) url('#a')", end: "blur(20px)",
michael@0 687 expected: ["blur", 20] },
michael@0 688 { start: "blur(0px)", end: "blur(20px) url('#a')",
michael@0 689 expected: ["blur", 20, "url", "\""+document.URL+"#a\""] },
michael@0 690 { start: "contrast(0.25) brightness(0.25) blur(25px)",
michael@0 691 end: "contrast(0.75) url('#a')",
michael@0 692 expected: ["contrast", 0.75, "url", "\""+document.URL+"#a\""] },
michael@0 693 { start: "contrast(0.25) brightness(0.25) blur(75px)",
michael@0 694 end: "brightness(0.75) contrast(0.75) blur(25px)",
michael@0 695 expected: ["brightness", 0.75, "contrast", 0.75, "blur", 25] },
michael@0 696 { start: "contrast(0.25) brightness(0.25) blur(25px)",
michael@0 697 end: "contrast(0.75) brightness(0.75) contrast(0.75)",
michael@0 698 expected: ["contrast", 0.75, "brightness", 0.75, "contrast", 0.75] },
michael@0 699 // drop-shadow animation
michael@0 700 { start: "none",
michael@0 701 end: "drop-shadow(rgb(0, 0, 0) 4px 4px 0px)",
michael@0 702 expected: ["drop-shadow", "rgba(0, 0, 0, 0.25) 1px 1px 0px"] },
michael@0 703 { start: "drop-shadow(rgb(0, 0, 0) 0px 0px 0px)",
michael@0 704 end: "drop-shadow(rgb(0, 0, 0) 4px 4px 0px)",
michael@0 705 expected: ["drop-shadow", "rgb(0, 0, 0) 1px 1px 0px"] },
michael@0 706 { start: "drop-shadow(#038000 4px 4px)",
michael@0 707 end: "drop-shadow(8px 8px 8px red)",
michael@0 708 expected: ["drop-shadow", "rgb(66, 96, 0) 5px 5px 2px"] },
michael@0 709 { start: "blur(25px) drop-shadow(8px 8px)",
michael@0 710 end: "blur(75px)",
michael@0 711 expected: ["blur", 37.5, "drop-shadow", "rgb(0, 0, 0) 6px 6px 0px"] },
michael@0 712 { start: "blur(75px)",
michael@0 713 end: "blur(25px) drop-shadow(8px 8px)",
michael@0 714 expected: ["blur", 62.5, "drop-shadow", "rgb(0, 0, 0) 2px 2px 0px"] },
michael@0 715 { start: "drop-shadow(2px 2px blue)",
michael@0 716 end: "none",
michael@0 717 expected: ["drop-shadow", "rgba(0, 0, 255, 0.75) 1.5px 1.5px 0px"] },
michael@0 718 ];
michael@0 719
michael@0 720 var prop;
michael@0 721 for (prop in supported_properties) {
michael@0 722 // Test that prop is in the property database.
michael@0 723 ok(prop in gCSSProperties, "property " + prop + " in gCSSProperties");
michael@0 724
michael@0 725 // Test that the entry has at least one test function.
michael@0 726 ok(supported_properties[prop].length > 0,
michael@0 727 "property " + prop + " must have at least one test function");
michael@0 728 }
michael@0 729
michael@0 730 // Return a consistent sampling of |count| values out of |array|.
michael@0 731 function sample_array(array, count) {
michael@0 732 if (count <= 0) {
michael@0 733 ok(false, "unexpected count");
michael@0 734 return [];
michael@0 735 }
michael@0 736 var ratio = array.length / count;
michael@0 737 if (ratio <= 1) {
michael@0 738 return array;
michael@0 739 }
michael@0 740 var result = new Array(count);
michael@0 741 for (var i = 0; i < count; ++i) {
michael@0 742 result[i] = array[Math.floor(i * ratio)];
michael@0 743 }
michael@0 744 return result;
michael@0 745 }
michael@0 746
michael@0 747 // Test that transitions don't do anything (i.e., aren't supported) on
michael@0 748 // the properties not in our test list above (and not transition
michael@0 749 // properties themselves).
michael@0 750 for (prop in gCSSProperties) {
michael@0 751 var info = gCSSProperties[prop];
michael@0 752 if (!(prop in supported_properties) &&
michael@0 753 info.type != CSS_TYPE_TRUE_SHORTHAND &&
michael@0 754 !("alias_for" in info) &&
michael@0 755 !prop.match(/^transition-/) &&
michael@0 756 // FIXME (Bug 119078): THIS SHOULD REALLY NOT BE NEEDED!
michael@0 757 prop != "-moz-binding") {
michael@0 758
michael@0 759 if ("prerequisites" in info) {
michael@0 760 var prereqs = info.prerequisites;
michael@0 761 for (var prereq in prereqs) {
michael@0 762 div.style.setProperty(prereq, prereqs[prereq], "");
michael@0 763 }
michael@0 764 }
michael@0 765
michael@0 766 var all_values = info.initial_values.concat(info.other_values);
michael@0 767
michael@0 768 if (all_values.length > 50) {
michael@0 769 // Since we're using an O(N^2) algorithm here, reduce the list of
michael@0 770 // values that we want to test. (This test is really only testing
michael@0 771 // that somebody didn't make a property animatable without
michael@0 772 // modifying this test. The odds of somebody doing that without
michael@0 773 // making at least one of the many pairs of values we have left
michael@0 774 // animatable seems pretty low, at least relative to the chance
michael@0 775 // that any pair of the values listed in property_database.js is
michael@0 776 // animatable.)
michael@0 777 //
michael@0 778 // That said, we still try to use all of the start of the list on
michael@0 779 // the assumption that the more basic values are likely to be at
michael@0 780 // the beginning of the list.
michael@0 781 all_values = [].concat(info.initial_values.slice(0,2),
michael@0 782 sample_array(info.initial_values.slice(2), 6),
michael@0 783 info.other_values.slice(0, 10),
michael@0 784 sample_array(info.other_values.slice(10), 40));
michael@0 785 }
michael@0 786
michael@0 787 var all_computed = [];
michael@0 788 for (var idx in all_values) {
michael@0 789 var val = all_values[idx];
michael@0 790 div.style.setProperty(prop, val, "");
michael@0 791 all_computed.push(cs.getPropertyValue(prop));
michael@0 792 }
michael@0 793 div.style.removeProperty(prop);
michael@0 794
michael@0 795 div.style.setProperty("transition", prop + " 20s linear", "");
michael@0 796 for (var i = 0; i < all_values.length; ++i) {
michael@0 797 for (var j = i + 1; j < all_values.length; ++j) {
michael@0 798 div.style.setProperty(prop, all_values[i], "");
michael@0 799 is(cs.getPropertyValue(prop), all_computed[i],
michael@0 800 "transitions not supported for property " + prop +
michael@0 801 " value " + all_values[i]);
michael@0 802 div.style.setProperty(prop, all_values[j], "");
michael@0 803 is(cs.getPropertyValue(prop), all_computed[j],
michael@0 804 "transitions not supported for property " + prop +
michael@0 805 " value " + all_values[j]);
michael@0 806 }
michael@0 807 }
michael@0 808
michael@0 809 div.style.removeProperty("transition");
michael@0 810 div.style.removeProperty(prop);
michael@0 811 if ("prerequisites" in info) {
michael@0 812 var prereqs = info.prerequisites;
michael@0 813 for (var prereq in prereqs) {
michael@0 814 div.style.removeProperty(prereq);
michael@0 815 }
michael@0 816 }
michael@0 817 }
michael@0 818 }
michael@0 819
michael@0 820 // Do 4-second linear transitions with -1 second transition delay and
michael@0 821 // linear timing function so that we can expect the transition to be
michael@0 822 // one quarter of the way through the value space right after changing
michael@0 823 // the property.
michael@0 824 div.style.setProperty("transition-duration", "4s", "");
michael@0 825 div.style.setProperty("transition-delay", "-1s", "");
michael@0 826 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 827 for (prop in supported_properties) {
michael@0 828 var tinfo = supported_properties[prop];
michael@0 829 var info = gCSSProperties[prop];
michael@0 830
michael@0 831 isnot(info.type, CSS_TYPE_TRUE_SHORTHAND,
michael@0 832 prop + " must not be a shorthand");
michael@0 833 if ("prerequisites" in info) {
michael@0 834 var prereqs = info.prerequisites;
michael@0 835 for (var prereq in prereqs) {
michael@0 836 // We don't want the 19px font-size prereq of line-height, since we
michael@0 837 // want to leave it 20px.
michael@0 838 if (prop != "line-height" || prereq != "font-size") {
michael@0 839 div.style.setProperty(prereq, prereqs[prereq], "");
michael@0 840 }
michael@0 841 }
michael@0 842 }
michael@0 843
michael@0 844 for (var idx in tinfo) {
michael@0 845 tinfo[idx](prop);
michael@0 846 }
michael@0 847
michael@0 848 // Make sure to unset the property and stop transitions on it.
michael@0 849 div.style.setProperty("transition-property", "none", "");
michael@0 850 div.style.removeProperty(prop);
michael@0 851 cs.getPropertyValue(prop);
michael@0 852
michael@0 853 if ("prerequisites" in info) {
michael@0 854 var prereqs = info.prerequisites;
michael@0 855 for (var prereq in prereqs) {
michael@0 856 div.style.removeProperty(prereq);
michael@0 857 }
michael@0 858 }
michael@0 859 }
michael@0 860 div.style.removeProperty("transition");
michael@0 861
michael@0 862 function get_distance(prop, v1, v2)
michael@0 863 {
michael@0 864 return SpecialPowers.DOMWindowUtils
michael@0 865 .computeAnimationDistance(div, prop, v1, v2);
michael@0 866 }
michael@0 867
michael@0 868 function check_distance(prop, start, quarter, end)
michael@0 869 {
michael@0 870 var sq = get_distance(prop, start, quarter);
michael@0 871 var se = get_distance(prop, start, end);
michael@0 872 var qe = get_distance(prop, quarter, end);
michael@0 873
michael@0 874 ok(Math.abs((sq * 4 - se) / se) < 0.0001, "property '" + prop + "': distance " + sq + " from start '" + start + "' to quarter '" + quarter + "' should be quarter distance " + se + " from start '" + start + "' to end '" + end + "'");
michael@0 875 ok(Math.abs((qe * 4 - se * 3) / se) < 0.0001, "property '" + prop + "': distance " + qe + " from quarter '" + quarter + "' to end '" + end + "' should be three quarters distance " + se + " from start '" + start + "' to end '" + end + "'");
michael@0 876 }
michael@0 877
michael@0 878 function test_length_transition(prop) {
michael@0 879 div.style.setProperty("transition-property", "none", "");
michael@0 880 div.style.setProperty(prop, "4px", "");
michael@0 881 is(cs.getPropertyValue(prop), "4px",
michael@0 882 "length-valued property " + prop + ": computed value before transition");
michael@0 883 div.style.setProperty("transition-property", prop, "");
michael@0 884 div.style.setProperty(prop, "12px", "");
michael@0 885 is(cs.getPropertyValue(prop), "6px",
michael@0 886 "length-valued property " + prop + ": interpolation of lengths");
michael@0 887 check_distance(prop, "4px", "6px", "12px");
michael@0 888 }
michael@0 889
michael@0 890 function test_length_clamped(prop) {
michael@0 891 test_length_clamped_or_unclamped(prop, true);
michael@0 892 }
michael@0 893
michael@0 894 function test_length_unclamped(prop) {
michael@0 895 test_length_clamped_or_unclamped(prop, false);
michael@0 896 }
michael@0 897
michael@0 898 function test_length_clamped_or_unclamped(prop, is_clamped) {
michael@0 899 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 900 div.style.setProperty("transition-property", "none", "");
michael@0 901 div.style.setProperty(prop, "0px", "");
michael@0 902 is(cs.getPropertyValue(prop), "0px",
michael@0 903 "length-valued property " + prop + ": flush before clamping test");
michael@0 904 div.style.setProperty("transition-property", prop, "");
michael@0 905 div.style.setProperty(prop, "100px", "");
michael@0 906 (is_clamped ? is : isnot)(cs.getPropertyValue(prop), "0px",
michael@0 907 "length-valued property " + prop + ": clamping of negatives");
michael@0 908 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 909 }
michael@0 910
michael@0 911 // Test using float values in the range [0, 1] (e.g. opacity)
michael@0 912 function test_float_zeroToOne_transition(prop) {
michael@0 913 div.style.setProperty("transition-property", "none", "");
michael@0 914 div.style.setProperty(prop, "0.3", "");
michael@0 915 is(cs.getPropertyValue(prop), "0.3",
michael@0 916 "float-valued property " + prop + ": computed value before transition");
michael@0 917 div.style.setProperty("transition-property", prop, "");
michael@0 918 div.style.setProperty(prop, "0.8", "");
michael@0 919 is(cs.getPropertyValue(prop), "0.425",
michael@0 920 "float-valued property " + prop + ": interpolation of floats");
michael@0 921 check_distance(prop, "0.3", "0.425", "0.8");
michael@0 922 }
michael@0 923
michael@0 924 function test_float_zeroToOne_clamped(prop) {
michael@0 925 test_float_zeroToOne_clamped_or_unclamped(prop, true);
michael@0 926 }
michael@0 927 function test_float_zeroToOne_unclamped(prop) {
michael@0 928 test_float_zeroToOne_clamped_or_unclamped(prop, false);
michael@0 929 }
michael@0 930
michael@0 931 function test_float_zeroToOne_clamped_or_unclamped(prop, is_clamped) {
michael@0 932 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 933 div.style.setProperty("transition-property", "none", "");
michael@0 934 div.style.setProperty(prop, "0", "");
michael@0 935 is(cs.getPropertyValue(prop), "0",
michael@0 936 "float-valued property " + prop + ": flush before clamping test");
michael@0 937 div.style.setProperty("transition-property", prop, "");
michael@0 938 div.style.setProperty(prop, "1", "");
michael@0 939 (is_clamped ? is : isnot)(cs.getPropertyValue(prop), "0",
michael@0 940 "float-valued property " + prop + ": clamping of negatives");
michael@0 941 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 942 }
michael@0 943
michael@0 944 // Test using float values in the range [1, infinity) (e.g. stroke-miterlimit)
michael@0 945 function test_float_aboveOne_transition(prop) {
michael@0 946 div.style.setProperty("transition-property", "none", "");
michael@0 947 div.style.setProperty(prop, "1", "");
michael@0 948 is(cs.getPropertyValue(prop), "1",
michael@0 949 "float-valued property " + prop + ": computed value before transition");
michael@0 950 div.style.setProperty("transition-property", prop, "");
michael@0 951 div.style.setProperty(prop, "2.1", "");
michael@0 952 is(cs.getPropertyValue(prop), "1.275",
michael@0 953 "float-valued property " + prop + ": interpolation of floats");
michael@0 954 check_distance(prop, "1", "1.275", "2.1");
michael@0 955 }
michael@0 956
michael@0 957 function test_float_aboveOne_clamped(prop) {
michael@0 958 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 959 div.style.setProperty("transition-property", "none", "");
michael@0 960 div.style.setProperty(prop, "1", "");
michael@0 961 is(cs.getPropertyValue(prop), "1",
michael@0 962 "float-valued property " + prop + ": flush before clamping test");
michael@0 963 div.style.setProperty("transition-property", prop, "");
michael@0 964 div.style.setProperty(prop, "5", "");
michael@0 965 is(cs.getPropertyValue(prop), "1",
michael@0 966 "float-valued property " + prop + ": clamping of negatives");
michael@0 967 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 968 }
michael@0 969
michael@0 970 function test_percent_transition(prop) {
michael@0 971 div.style.setProperty("transition-property", "none", "");
michael@0 972 div.style.setProperty(prop, "25%", "");
michael@0 973 var av = cs.getPropertyValue(prop);
michael@0 974 var a = any_unit_to_num(av);
michael@0 975 div.style.setProperty(prop, "75%", "");
michael@0 976 var bv = cs.getPropertyValue(prop);
michael@0 977 var b = any_unit_to_num(bv);
michael@0 978 isnot(b, a, "different percentages (" + av + " and " + bv +
michael@0 979 ") should be different for " + prop);
michael@0 980 div.style.setProperty("transition-property", prop, "");
michael@0 981 div.style.setProperty(prop, "25%", "");
michael@0 982 var res = cs.getPropertyValue(prop);
michael@0 983 is(any_unit_to_num(res) * 4, 3 * b + a,
michael@0 984 "percent-valued property " + prop + ": interpolation of percents: " +
michael@0 985 res + " should be a quarter of the way between " + bv + " and " + av);
michael@0 986 ok(has_num(res),
michael@0 987 "percent-valued property " + prop + ": percent computes to number");
michael@0 988 check_distance(prop, "25%", "37.5%", "75%");
michael@0 989 }
michael@0 990
michael@0 991 function test_percent_clamped(prop) {
michael@0 992 test_percent_clamped_or_unclamped(prop, true);
michael@0 993 }
michael@0 994
michael@0 995 function test_percent_unclamped(prop) {
michael@0 996 test_percent_clamped_or_unclamped(prop, false);
michael@0 997 }
michael@0 998
michael@0 999 function test_percent_clamped_or_unclamped(prop, is_clamped) {
michael@0 1000 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1001 div.style.setProperty("transition-property", "none", "");
michael@0 1002 div.style.setProperty(prop, "0%", "");
michael@0 1003 var zero_val = cs.getPropertyValue(prop); // flushes too
michael@0 1004 div.style.setProperty("transition-property", prop, "");
michael@0 1005 div.style.setProperty(prop, "150%", "");
michael@0 1006 (is_clamped ? is : isnot)(cs.getPropertyValue(prop), zero_val,
michael@0 1007 "percent-valued property " + prop + ": clamping of negatives");
michael@0 1008 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1009 }
michael@0 1010
michael@0 1011 function test_length_percent_calc_transition(prop) {
michael@0 1012 div.style.setProperty("transition-property", "none", "");
michael@0 1013 div.style.setProperty(prop, "0%", "");
michael@0 1014 var av = cs.getPropertyValue(prop);
michael@0 1015 var a = any_unit_to_num(av);
michael@0 1016 div.style.setProperty(prop, "100%", "");
michael@0 1017 var bv = cs.getPropertyValue(prop);
michael@0 1018 var b = any_unit_to_num(bv);
michael@0 1019 div.style.setProperty(prop, "100px", "");
michael@0 1020 var cv = cs.getPropertyValue(prop);
michael@0 1021 var c = any_unit_to_num(cv);
michael@0 1022 isnot(b, a, "different percentages (" + av + " and " + bv +
michael@0 1023 ") should be different for " + prop);
michael@0 1024
michael@0 1025 div.style.setProperty(prop, "50%", "");
michael@0 1026 var v1v = cs.getPropertyValue(prop);
michael@0 1027 is(any_unit_to_num(v1v) * 2, a + b,
michael@0 1028 "computed value before transition for " + prop + ": '" +
michael@0 1029 v1v + "' should be halfway " +
michael@0 1030 "between '" + av + "' + and '" + bv + "'.");
michael@0 1031 div.style.setProperty("transition-property", prop, "");
michael@0 1032 div.style.setProperty(prop, "200px", "");
michael@0 1033 var v2v = cs.getPropertyValue(prop);
michael@0 1034 is(any_unit_to_num(v2v) * 8, 5*a + 3*b + 4*c,
michael@0 1035 "interpolation between length and percent for " + prop + ": '"
michael@0 1036 + v2v + "'");
michael@0 1037
michael@0 1038 div.style.setProperty("transition-property", "none", "");
michael@0 1039 div.style.setProperty(prop, "calc(25% + 100px)", "");
michael@0 1040 v1v = cs.getPropertyValue(prop);
michael@0 1041 is(any_unit_to_num(v1v) * 4, b + 4*c,
michael@0 1042 "computed value before transition for " + prop + ": '" + v1v + "'");
michael@0 1043 div.style.setProperty("transition-property", prop, "");
michael@0 1044 div.style.setProperty(prop, "75%", "");
michael@0 1045 v2v = cs.getPropertyValue(prop);
michael@0 1046 is(any_unit_to_num(v2v) * 8, 5*a + 3*b + 6*c,
michael@0 1047 "interpolation between calc() and percent for " + prop + ": '" +
michael@0 1048 v2v + "'");
michael@0 1049
michael@0 1050 div.style.setProperty("transition-property", "none", "");
michael@0 1051 div.style.setProperty(prop, "150px", "");
michael@0 1052 v1v = cs.getPropertyValue(prop);
michael@0 1053 is(any_unit_to_num(v1v) * 2, c * 3,
michael@0 1054 "computed value before transition for " + prop + ": '" + v1v + "'");
michael@0 1055 div.style.setProperty("transition-property", prop, "");
michael@0 1056 div.style.setProperty(prop, "calc(50% + 50px)", "");
michael@0 1057 v2v = cs.getPropertyValue(prop);
michael@0 1058 is(any_unit_to_num(v2v) * 8, 7 * a + b + 10*c,
michael@0 1059 "interpolation between length and calc() for " + prop + ": '" +
michael@0 1060 v2v + "'");
michael@0 1061
michael@0 1062 check_distance(prop, "50%", "calc(37.5% + 50px)", "200px");
michael@0 1063 check_distance(prop, "calc(25% + 100px)", "calc(37.5% + 75px)",
michael@0 1064 "75%");
michael@0 1065 check_distance(prop, "150px", "calc(125px + 12.5%)",
michael@0 1066 "calc(50% + 50px)");
michael@0 1067 }
michael@0 1068
michael@0 1069 function test_color_transition(prop) {
michael@0 1070 div.style.setProperty("transition-property", "none", "");
michael@0 1071 div.style.setProperty(prop, "rgb(255, 28, 0)", "");
michael@0 1072 is(cs.getPropertyValue(prop), "rgb(255, 28, 0)",
michael@0 1073 "color-valued property " + prop + ": computed value before transition");
michael@0 1074 div.style.setProperty("transition-property", prop, "");
michael@0 1075 div.style.setProperty(prop, "rgb(75, 84, 128)", "");
michael@0 1076 is(cs.getPropertyValue(prop), "rgb(210, 42, 32)",
michael@0 1077 "color-valued property " + prop + ": interpolation of colors");
michael@0 1078
michael@0 1079 div.style.setProperty("transition-property", "none", "");
michael@0 1080 div.style.setProperty(prop, "rgb(128, 64, 0)", "");
michael@0 1081 (prop == "color" ? div.parentNode : div).style.
michael@0 1082 setProperty("color", "rgb(0, 0, 128)", "");
michael@0 1083 is(cs.getPropertyValue(prop), "rgb(128, 64, 0)",
michael@0 1084 "color-valued property " + prop + ": computed value before transition");
michael@0 1085 div.style.setProperty("transition-property", prop, "");
michael@0 1086 div.style.setProperty(prop, "currentColor", "");
michael@0 1087 is(cs.getPropertyValue(prop), "rgb(96, 48, 32)",
michael@0 1088 "color-valued property " + prop + ": interpolation of currentColor");
michael@0 1089
michael@0 1090 check_distance(prop, "rgb(255, 28, 0)", "rgb(210, 42, 32)",
michael@0 1091 "rgb(75, 84, 128)");
michael@0 1092 check_distance(prop, "rgb(128, 64, 0)", "rgb(96, 48, 32)", "currentColor");
michael@0 1093
michael@0 1094 (prop == "color" ? div.parentNode : div).style.removeProperty("color");
michael@0 1095
michael@0 1096 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1097 div.style.setProperty("transition-property", "none", "");
michael@0 1098 div.style.setProperty(prop, "rgb(0, 255, 0)", "");
michael@0 1099 var vals = cs.getPropertyValue(prop).match(/rgb\(([^, ]*), ([^, ]*), ([^, ]*)\)/);
michael@0 1100 is(vals.length, 4,
michael@0 1101 "color-valued property " + prop + ": flush before clamping test (length)");
michael@0 1102 is(vals[1], "0",
michael@0 1103 "color-valued property " + prop + ": flush before clamping test (red)");
michael@0 1104 is(vals[2], "255",
michael@0 1105 "color-valued property " + prop + ": flush before clamping test (green)");
michael@0 1106 is(vals[3], "0",
michael@0 1107 "color-valued property " + prop + ": flush before clamping test (blue)");
michael@0 1108 div.style.setProperty("transition-property", prop, "");
michael@0 1109 div.style.setProperty(prop, "rgb(255, 0, 128)", "");
michael@0 1110 // FIXME: Once we support non-sRGB colors, these tests will need fixing.
michael@0 1111 vals = cs.getPropertyValue(prop).match(/rgb\(([^, ]*), ([^, ]*), ([^, ]*)\)/);
michael@0 1112 is(vals.length, 4,
michael@0 1113 "color-valued property " + prop + ": clamping of negatives (length)");
michael@0 1114 is(vals[1], "0",
michael@0 1115 "color-valued property " + prop + ": clamping of negatives (red)");
michael@0 1116 is(vals[2], "255",
michael@0 1117 "color-valued property " + prop + ": clamping of above-range (green)");
michael@0 1118 is(vals[3], "0",
michael@0 1119 "color-valued property " + prop + ": clamping of negatives (blue)");
michael@0 1120 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1121 }
michael@0 1122
michael@0 1123 function test_border_color_transition(prop) {
michael@0 1124 div.style.setProperty("transition-property", "none", "");
michael@0 1125 div.style.setProperty(prop, "rgb(128, 64, 0)", "");
michael@0 1126 div.style.setProperty("color", "rgb(0, 0, 128)", "");
michael@0 1127 is(cs.getPropertyValue(prop), "rgb(128, 64, 0)",
michael@0 1128 "color-valued property " + prop + ": computed value before transition");
michael@0 1129 div.style.setProperty("transition-property", prop, "");
michael@0 1130 div.style.removeProperty(prop);
michael@0 1131 is(cs.getPropertyValue(prop), "rgb(96, 48, 32)",
michael@0 1132 "color-valued property " + prop + ": interpolation of initial value");
michael@0 1133
michael@0 1134 check_distance(prop, "rgb(128, 64, 0)", "rgb(96, 48, 32)", "initial");
michael@0 1135
michael@0 1136 div.style.removeProperty("color");
michael@0 1137 }
michael@0 1138
michael@0 1139 function filter_function_list_equals(computedValStr, expectedList)
michael@0 1140 {
michael@0 1141 // Check simple case "none"
michael@0 1142 if (computedValStr == "none" && computedValStr == expectedList[0]) {
michael@0 1143 return true;
michael@0 1144 }
michael@0 1145
michael@0 1146 // The regular expression does not filter out the last parenthesis.
michael@0 1147 // Remove last character for now.
michael@0 1148 is(computedValStr.substring(computedValStr.length - 1, computedValStr.length),
michael@0 1149 ')', "Check if last character is close-paren");
michael@0 1150 computedValStr = computedValStr.substring(0, computedValStr.length - 1);
michael@0 1151
michael@0 1152 var reg = /\)*\s*(blur|brightness|contrast|grayscale|hue\-rotate|invert|opacity|saturate|sepia|drop\-shadow|url)\(/
michael@0 1153 var matches = computedValStr.split(reg);
michael@0 1154 // First item must be empty. All other items are of functionName, functionValue.
michael@0 1155 if (!matches || matches.shift() != "") {
michael@0 1156 ok(false, "computed style of 'filter' isn't in the format we expect");
michael@0 1157 return false;
michael@0 1158 }
michael@0 1159
michael@0 1160 // Odd items are the function name, even items the function value.
michael@0 1161 if (!matches.length || matches.length % 2 ||
michael@0 1162 expectedList.length != matches.length) {
michael@0 1163 ok(false, "computed style of 'filter' isn't in the format we expect");
michael@0 1164 return false;
michael@0 1165 }
michael@0 1166 for (var i = 0; i < matches.length; i += 2) {
michael@0 1167 var functionName = matches[i];
michael@0 1168 var functionValue = matches[i+1];
michael@0 1169 var expected = expectedList[i+1]
michael@0 1170 var tolerance = 0;
michael@0 1171 // Check if we have the expected function.
michael@0 1172 if (functionName != expectedList[i]) {
michael@0 1173 return false;
michael@0 1174 }
michael@0 1175 if (functionName == "blur") {
michael@0 1176 // Last two characters must be "px".
michael@0 1177 if (functionValue.search("px") != functionValue.length - 2) {
michael@0 1178 return false;
michael@0 1179 }
michael@0 1180 functionValue = functionValue.substring(0, functionValue.length - 2);
michael@0 1181 } else if (functionName == "hue-rotate") {
michael@0 1182 // Last two characters must be "rad".
michael@0 1183 if (functionValue.search("rad") != functionValue.length - 3) {
michael@0 1184 return false;
michael@0 1185 }
michael@0 1186 tolerance = 0.001;
michael@0 1187 functionValue = functionValue.substring(0, functionValue.length - 3);
michael@0 1188 } else if (functionName == "drop-shadow" || functionName == "url") {
michael@0 1189 if (functionValue != expected) {
michael@0 1190 return false;
michael@0 1191 }
michael@0 1192 continue;
michael@0 1193 }
michael@0 1194 // Check if string is not a number or difference is not in tolerance level.
michael@0 1195 if (isNaN(functionValue) ||
michael@0 1196 Math.abs(parseFloat(functionValue) - expected) > tolerance) {
michael@0 1197 return false;
michael@0 1198 }
michael@0 1199 }
michael@0 1200 return true;
michael@0 1201 }
michael@0 1202
michael@0 1203 function test_filter_transition(prop) {
michael@0 1204 if (!SpecialPowers.getBoolPref("layout.css.filters.enabled")) {
michael@0 1205 return;
michael@0 1206 }
michael@0 1207 for (var i in filterTests) {
michael@0 1208 var test = filterTests[i];
michael@0 1209 div.style.setProperty("transition-property", "none", "");
michael@0 1210 div.style.setProperty(prop, test.start, "");
michael@0 1211 cs.getPropertyValue(prop);
michael@0 1212 div.style.setProperty("transition-property", prop, "");
michael@0 1213 div.style.setProperty(prop, test.end, "");
michael@0 1214 var actual = cs.getPropertyValue(prop);
michael@0 1215 ok(filter_function_list_equals(actual, test.expected),
michael@0 1216 "Filter property is " + actual + " expected values of " +
michael@0 1217 test.expected);
michael@0 1218 }
michael@0 1219 }
michael@0 1220
michael@0 1221 function test_shadow_transition(prop) {
michael@0 1222 var spreadStr = (prop == "box-shadow") ? " 0px" : "";
michael@0 1223
michael@0 1224 div.style.setProperty("transition-property", "none", "");
michael@0 1225 div.style.setProperty(prop, "none", "");
michael@0 1226 is(cs.getPropertyValue(prop), "none",
michael@0 1227 "shadow-valued property " + prop + ": computed value before transition");
michael@0 1228 div.style.setProperty("transition-property", prop, "");
michael@0 1229 div.style.setProperty(prop, "4px 8px 3px red", "");
michael@0 1230 is(cs.getPropertyValue(prop), "rgba(255, 0, 0, 0.25) 1px 2px 0.75px" + spreadStr,
michael@0 1231 "shadow-valued property " + prop + ": interpolation of shadows");
michael@0 1232 check_distance(prop, "none", "rgba(255, 0, 0, 0.25) 1px 2px 0.75px",
michael@0 1233 "4px 8px 3px red");
michael@0 1234
michael@0 1235 div.style.setProperty("transition-property", "none", "");
michael@0 1236 div.style.setProperty(prop, "#038000 4px 4px, 2px 2px blue", "");
michael@0 1237 is(cs.getPropertyValue(prop), "rgb(3, 128, 0) 4px 4px 0px" + spreadStr + ", rgb(0, 0, 255) 2px 2px 0px" + spreadStr,
michael@0 1238 "shadow-valued property " + prop + ": computed value before transition");
michael@0 1239 div.style.setProperty("transition-property", prop, "");
michael@0 1240 div.style.setProperty(prop, "8px 8px 8px red", "");
michael@0 1241 is(cs.getPropertyValue(prop), "rgb(66, 96, 0) 5px 5px 2px" + spreadStr + ", rgba(0, 0, 255, 0.75) 1.5px 1.5px 0px" + spreadStr,
michael@0 1242 "shadow-valued property " + prop + ": interpolation of shadows");
michael@0 1243 check_distance(prop, "#038000 4px 4px, 2px 2px blue",
michael@0 1244 "rgb(66, 96, 0) 5px 5px 2px, rgba(0, 0, 255, 0.75) 1.5px 1.5px 0px",
michael@0 1245 "8px 8px 8px red");
michael@0 1246
michael@0 1247 if (prop == "box-shadow") {
michael@0 1248 div.style.setProperty(prop, "8px 8px 8px red inset", "");
michael@0 1249 is(cs.getPropertyValue(prop), "rgb(255, 0, 0) 8px 8px 8px 0px inset",
michael@0 1250 "shadow-valued property " + prop + ": non-interpolable cases");
michael@0 1251 div.style.setProperty(prop, "8px 8px 8px 8px red inset", "");
michael@0 1252 is(cs.getPropertyValue(prop), "rgb(255, 0, 0) 8px 8px 8px 2px inset",
michael@0 1253 "shadow-valued property " + prop + ": interpolation of spread");
michael@0 1254 // Leave in same state whether in the |if| or not.
michael@0 1255 div.style.setProperty(prop, "8px 8px 8px red", "");
michael@0 1256 is(cs.getPropertyValue(prop), "rgb(255, 0, 0) 8px 8px 8px 0px",
michael@0 1257 "shadow-valued property " + prop + ": non-interpolable cases");
michael@0 1258 check_distance(prop, "8px 8px 8px red inset",
michael@0 1259 "rgb(255, 0, 0) 8px 8px 8px 2px inset",
michael@0 1260 "8px 8px 8px 8px red inset");
michael@0 1261 }
michael@0 1262
michael@0 1263 var defaultColor = cs.getPropertyValue("color") + " ";
michael@0 1264 div.style.setProperty(prop, "2px 2px 2px", "");
michael@0 1265 is(cs.getPropertyValue(prop), defaultColor + "2px 2px 2px" + spreadStr,
michael@0 1266 "shadow-valued property " + prop + ": non-interpolable cases");
michael@0 1267 div.style.setProperty(prop, "6px 14px 10px", "");
michael@0 1268 is(cs.getPropertyValue(prop), defaultColor + "3px 5px 4px" + spreadStr,
michael@0 1269 "shadow-valued property " + prop + ": interpolation without color");
michael@0 1270 check_distance(prop, "2px 2px 2px", "3px 5px 4px", "6px 14px 10px");
michael@0 1271
michael@0 1272 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1273 div.style.setProperty("transition-property", "none", "");
michael@0 1274 div.style.setProperty(prop, "0px 0px 0px black", "");
michael@0 1275 is(cs.getPropertyValue(prop), "rgb(0, 0, 0) 0px 0px 0px" + spreadStr,
michael@0 1276 "shadow-valued property " + prop + ": flush before clamping test");
michael@0 1277 div.style.setProperty("transition-property", prop, "");
michael@0 1278 div.style.setProperty(prop, "10px 10px 10px black", "");
michael@0 1279 var vals = cs.getPropertyValue(prop).split(" ");
michael@0 1280 is(vals.length, 6 + (prop == "box-shadow"), "unexpected number of values");
michael@0 1281 is(vals.slice(0, 3).join(" "), "rgb(0, 0, 0)",
michael@0 1282 "shadow-valued property " + prop + " (color): clamping of negatives");
michael@0 1283 isnot(vals[3], "0px",
michael@0 1284 "shadow-valued property " + prop + " (x): clamping of negatives");
michael@0 1285 isnot(vals[4], "0px",
michael@0 1286 "shadow-valued property " + prop + " (y): clamping of negatives");
michael@0 1287 is(vals[5], "0px",
michael@0 1288 "shadow-valued property " + prop + " (radius): clamping of negatives");
michael@0 1289 if (prop == "box-shadow") {
michael@0 1290 div.style.setProperty("transition-property", "none", "");
michael@0 1291 div.style.setProperty(prop, "0px 0px 0px 0px black", "");
michael@0 1292 is(cs.getPropertyValue(prop), "rgb(0, 0, 0) 0px 0px 0px 0px",
michael@0 1293 "shadow-valued property " + prop + ": flush before clamping test");
michael@0 1294 div.style.setProperty("transition-property", prop, "");
michael@0 1295 div.style.setProperty(prop, "10px 10px 10px 10px black", "");
michael@0 1296 var vals = cs.getPropertyValue(prop).split(" ");
michael@0 1297 is(vals.length, 7, "unexpected number of values");
michael@0 1298 is(vals.slice(0, 3).join(" "), "rgb(0, 0, 0)",
michael@0 1299 "shadow-valued property " + prop + " (color): clamping of negatives");
michael@0 1300 isnot(vals[3], "0px",
michael@0 1301 "shadow-valued property " + prop + " (x): clamping of negatives");
michael@0 1302 isnot(vals[4], "0px",
michael@0 1303 "shadow-valued property " + prop + " (y): clamping of negatives");
michael@0 1304 is(vals[5], "0px",
michael@0 1305 "shadow-valued property " + prop + " (radius): clamping of negatives");
michael@0 1306 isnot(vals[6], "0px",
michael@0 1307 "shadow-valued property " + prop + " (spread): clamping of negatives");
michael@0 1308 }
michael@0 1309 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1310 }
michael@0 1311
michael@0 1312 function test_dasharray_transition(prop) {
michael@0 1313 div.style.setProperty("transition-property", "none", "");
michael@0 1314 div.style.setProperty(prop, "3", "");
michael@0 1315 is(cs.getPropertyValue(prop), "3",
michael@0 1316 "dasharray-valued property " + prop +
michael@0 1317 ": computed value before transition");
michael@0 1318 div.style.setProperty("transition-property", prop, "");
michael@0 1319 div.style.setProperty(prop, "15px", "");
michael@0 1320 is(cs.getPropertyValue(prop), "6",
michael@0 1321 "dasharray-valued property " + prop + ": interpolation of dasharray");
michael@0 1322 check_distance(prop, "3", "6", "15px");
michael@0 1323 div.style.setProperty(prop, "none", "");
michael@0 1324 is(cs.getPropertyValue(prop), "none",
michael@0 1325 "dasharray-valued property " + prop + ": non-interpolability of none");
michael@0 1326 div.style.setProperty(prop, "6,8px,4,4", "");
michael@0 1327 is(cs.getPropertyValue(prop), "6, 8px, 4, 4",
michael@0 1328 "dasharray-valued property " + prop +
michael@0 1329 ": computed value before transition");
michael@0 1330 div.style.setProperty(prop, "14, 12,16,16px", "");
michael@0 1331 is(cs.getPropertyValue(prop), "8, 9, 7, 7",
michael@0 1332 "dasharray-valued property " + prop + ": interpolation of dasharray");
michael@0 1333 check_distance(prop, "6,8px,4,4", "8,9,7,7", "14, 12,16,16px");
michael@0 1334 div.style.setProperty(prop, "none", "");
michael@0 1335 is(cs.getPropertyValue(prop), "none",
michael@0 1336 "dasharray-valued property " + prop + ": non-interpolability of none");
michael@0 1337 div.style.setProperty(prop, "8,16,4", "");
michael@0 1338 is(cs.getPropertyValue(prop), "8, 16, 4",
michael@0 1339 "dasharray-valued property " + prop +
michael@0 1340 ": computed value before transition");
michael@0 1341 div.style.setProperty(prop, "4,8,12,16", "");
michael@0 1342 is(cs.getPropertyValue(prop), "7, 14, 6, 10, 13, 5, 9, 16, 4, 8, 15, 7",
michael@0 1343 "dasharray-valued property " + prop + ": interpolation of dasharray");
michael@0 1344 check_distance(prop, "8,16,4", "7, 14, 6, 10, 13, 5, 9, 16, 4, 8, 15, 7",
michael@0 1345 "4,8,12,16");
michael@0 1346 div.style.setProperty(prop, "2,50%,6,10", "");
michael@0 1347 is(cs.getPropertyValue(prop), "2, 50%, 6, 10",
michael@0 1348 "dasharray-valued property " + prop + ": non-interpolability of mixed units");
michael@0 1349 div.style.setProperty(prop, "6,30%,2,2", "");
michael@0 1350 is(cs.getPropertyValue(prop), "3, 45%, 5, 8",
michael@0 1351 "dasharray-valued property " + prop + ": interpolation of dasharray");
michael@0 1352 check_distance(prop, "2,50%,6,10", "3, 45%, 5, 8", "6,30%,2,2");
michael@0 1353
michael@0 1354 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1355 div.style.setProperty("transition-property", "none", "");
michael@0 1356 div.style.setProperty(prop, "0,0%", "");
michael@0 1357 is(cs.getPropertyValue(prop), "0, 0%",
michael@0 1358 "dasharray-valued property " + prop + ": flush before clamping test");
michael@0 1359 div.style.setProperty("transition-property", prop, "");
michael@0 1360 div.style.setProperty(prop, "5, 25%", "");
michael@0 1361 is(cs.getPropertyValue(prop), "0, 0%",
michael@0 1362 "dasharray-valued property " + prop + ": clamping of negatives");
michael@0 1363 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1364 }
michael@0 1365
michael@0 1366 function test_radius_transition(prop) {
michael@0 1367 div.style.setProperty("transition-property", "none", "");
michael@0 1368
michael@0 1369 // FIXME: Test a square for now, since we haven't updated to the spec
michael@0 1370 // for vertical components being relative to the height.
michael@0 1371 // Note: We use powers of two here so the floating-point math comes out
michael@0 1372 // nicely.
michael@0 1373 div.style.setProperty("width", "256px", "");
michael@0 1374 div.style.setProperty("height", "256px", "");
michael@0 1375 div.style.setProperty("border", "none", "");
michael@0 1376 div.style.setProperty("padding", "0", "");
michael@0 1377
michael@0 1378 div.style.setProperty(prop, "3px", "");
michael@0 1379 is(cs.getPropertyValue(prop), "3px",
michael@0 1380 "radius-valued property " + prop +
michael@0 1381 ": computed value before transition");
michael@0 1382 div.style.setProperty("transition-property", prop, "");
michael@0 1383 div.style.setProperty(prop, "15px", "");
michael@0 1384 is(cs.getPropertyValue(prop), "6px",
michael@0 1385 "radius-valued property " + prop + ": interpolation of radius");
michael@0 1386 check_distance(prop, "3px", "6px", "15px");
michael@0 1387 div.style.setProperty("transition-property", "none", "");
michael@0 1388 div.style.setProperty(prop, "12.5%", "");
michael@0 1389 is(cs.getPropertyValue(prop), "32px",
michael@0 1390 "radius-valued property " + prop + ": computed value before transition");
michael@0 1391 div.style.setProperty("transition-property", prop, "");
michael@0 1392 div.style.setProperty(prop, "25%", "");
michael@0 1393 is(cs.getPropertyValue(prop), "40px",
michael@0 1394 "radius-valued property " + prop + ": interpolation of radius");
michael@0 1395 check_distance(prop, "12.5%", "15.625%", "25%");
michael@0 1396 div.style.setProperty("transition-property", "none", "");
michael@0 1397 div.style.setProperty(prop, "3px 8px", "");
michael@0 1398 is(cs.getPropertyValue(prop), "3px 8px",
michael@0 1399 "radius-valued property " + prop + ": computed value before transition");
michael@0 1400 div.style.setProperty("transition-property", prop, "");
michael@0 1401 div.style.setProperty(prop, "15px 12px", "");
michael@0 1402 is(cs.getPropertyValue(prop), "6px 9px",
michael@0 1403 "radius-valued property " + prop + ": interpolation of radius");
michael@0 1404 check_distance(prop, "3px 8px", "6px 9px", "15px 12px");
michael@0 1405 div.style.setProperty("transition-property", "none", "");
michael@0 1406 div.style.setProperty(prop, "12.5% 6.25%", "");
michael@0 1407 is(cs.getPropertyValue(prop), "32px 16px",
michael@0 1408 "radius-valued property " + prop + ": computed value before transition");
michael@0 1409 div.style.setProperty("transition-property", prop, "");
michael@0 1410 div.style.setProperty(prop, "25%", "");
michael@0 1411 is(cs.getPropertyValue(prop), "40px 28px",
michael@0 1412 "radius-valued property " + prop + ": interpolation of radius");
michael@0 1413 check_distance(prop, "12.5% 6.25%", "15.625% 10.9375%", "25%");
michael@0 1414 div.style.setProperty("transition-property", "none", "");
michael@0 1415 div.style.setProperty(prop, "6.25% 12.5%", "");
michael@0 1416 is(cs.getPropertyValue(prop), "16px 32px",
michael@0 1417 "radius-valued property " + prop + ": computed value before transition");
michael@0 1418 div.style.setProperty("transition-property", prop, "");
michael@0 1419 div.style.setProperty(prop, "64px 16px", "");
michael@0 1420 is(cs.getPropertyValue(prop), "28px",
michael@0 1421 "radius-valued property " + prop + ": interpolation of radius with mixed units");
michael@0 1422 check_distance(prop, "6.25% 12.5%",
michael@0 1423 "calc(4.6875% + 16px) calc(9.375% + 4px)",
michael@0 1424 "64px 16px");
michael@0 1425
michael@0 1426 div.style.setProperty("transition-property", "none", "");
michael@0 1427 div.style.setProperty(prop, "calc(5px) 10px", "");
michael@0 1428 is(cs.getPropertyValue(prop), "5px 10px",
michael@0 1429 "radius-valued property " + prop + ": computed value before transition");
michael@0 1430 div.style.setProperty("transition-property", prop, "");
michael@0 1431 div.style.setProperty(prop, "calc(25px) calc(50px)", "");
michael@0 1432 is(cs.getPropertyValue(prop), "10px 20px",
michael@0 1433 "radius-valued property " + prop + ": interpolation of radius with calc() units");
michael@0 1434
michael@0 1435 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1436 div.style.setProperty("transition-property", "none", "");
michael@0 1437 div.style.setProperty(prop, "0px 0px", "");
michael@0 1438 is(cs.getPropertyValue(prop), "0px",
michael@0 1439 "radius-valued property " + prop + ": flush before clamping test");
michael@0 1440 div.style.setProperty("transition-property", prop, "");
michael@0 1441 div.style.setProperty(prop, "10px 20px", "");
michael@0 1442 is(cs.getPropertyValue(prop), "0px",
michael@0 1443 "radius-valued property " + prop + ": clamping of negatives");
michael@0 1444 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1445
michael@0 1446 test_length_percent_calc_transition(prop);
michael@0 1447
michael@0 1448 div.style.removeProperty("width");
michael@0 1449 div.style.removeProperty("height");
michael@0 1450 div.style.removeProperty("border");
michael@0 1451 div.style.removeProperty("padding");
michael@0 1452 }
michael@0 1453
michael@0 1454 function test_integer_transition(prop) {
michael@0 1455 div.style.setProperty("transition-property", "none", "");
michael@0 1456 div.style.setProperty(prop, "4", "");
michael@0 1457 is(cs.getPropertyValue(prop), "4",
michael@0 1458 "integer-valued property " + prop + ": computed value before transition");
michael@0 1459 div.style.setProperty("transition-property", prop, "");
michael@0 1460 div.style.setProperty(prop, "-14", "");
michael@0 1461 is(cs.getPropertyValue(prop), "-1",
michael@0 1462 "integer-valued property " + prop + ": interpolation of integers");
michael@0 1463 check_distance(prop, "6", "1", "-14");
michael@0 1464
michael@0 1465 div.style.setProperty("transition-property", "none", "");
michael@0 1466 div.style.setProperty(prop, "-4", "");
michael@0 1467 is(cs.getPropertyValue(prop), "-4",
michael@0 1468 "integer-valued property " + prop + ": computed value before transition");
michael@0 1469 div.style.setProperty("transition-property", prop, "");
michael@0 1470 div.style.setProperty(prop, "8", "");
michael@0 1471 is(cs.getPropertyValue(prop), "-1",
michael@0 1472 "integer-valued property " + prop + ": interpolation of integers");
michael@0 1473 check_distance(prop, "-4", "-1", "8");
michael@0 1474
michael@0 1475 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1476 div.style.setProperty("transition-property", "none", "");
michael@0 1477 div.style.setProperty(prop, "0", "");
michael@0 1478 is(cs.getPropertyValue(prop), "0",
michael@0 1479 "integer-valued property " + prop + ": flush before clamping test");
michael@0 1480 div.style.setProperty("transition-property", prop, "");
michael@0 1481 div.style.setProperty(prop, "100", "");
michael@0 1482 isnot(cs.getPropertyValue(prop), "0",
michael@0 1483 "integer-valued property " + prop + ": clamping of negatives");
michael@0 1484 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1485 }
michael@0 1486
michael@0 1487 function test_font_stretch(prop) {
michael@0 1488 is(prop, "font-stretch", "only designed for one property");
michael@0 1489
michael@0 1490 div.style.setProperty("transition-property", "none", "");
michael@0 1491 div.style.setProperty(prop, "normal", "");
michael@0 1492 is(cs.getPropertyValue(prop), "normal",
michael@0 1493 "font-stretch property " + prop + ": computed value before transition");
michael@0 1494 div.style.setProperty("transition-property", prop, "");
michael@0 1495 div.style.setProperty(prop, "ultra-expanded", "");
michael@0 1496 is(cs.getPropertyValue(prop), "semi-expanded",
michael@0 1497 "font-stretch property " + prop + ": interpolation of font-stretches");
michael@0 1498 check_distance(prop, "normal", "semi-expanded", "ultra-expanded");
michael@0 1499 div.style.setProperty("transition-property", "none", "");
michael@0 1500 div.style.setProperty(prop, "expanded", "");
michael@0 1501 is(cs.getPropertyValue(prop), "expanded",
michael@0 1502 "font-stretch property " + prop + ": computed value before transition");
michael@0 1503 div.style.setProperty("transition-property", prop, "");
michael@0 1504 div.style.setProperty(prop, "extra-condensed", "");
michael@0 1505 is(cs.getPropertyValue(prop), "normal",
michael@0 1506 "font-stretch property " + prop + ": interpolation of font-stretches");
michael@0 1507 check_distance(prop, "expanded", "semi-expanded", "condensed");
michael@0 1508
michael@0 1509 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1510 div.style.setProperty("transition-property", "none", "");
michael@0 1511 div.style.setProperty(prop, "ultra-condensed", "");
michael@0 1512 is(cs.getPropertyValue(prop), "ultra-condensed",
michael@0 1513 "font-stretch property " + prop + ": flush before clamping test");
michael@0 1514 div.style.setProperty("transition-property", prop, "");
michael@0 1515 div.style.setProperty(prop, "ultra-expanded", "");
michael@0 1516 is(cs.getPropertyValue(prop), "ultra-condensed",
michael@0 1517 "font-stretch property " + prop + ": clamping of values");
michael@0 1518 div.style.setProperty("transition-property", "none", "");
michael@0 1519 div.style.setProperty(prop, "ultra-expanded", "");
michael@0 1520 is(cs.getPropertyValue(prop), "ultra-expanded",
michael@0 1521 "font-stretch property " + prop + ": flush before clamping test");
michael@0 1522 div.style.setProperty("transition-property", prop, "");
michael@0 1523 div.style.setProperty(prop, "ultra-condensed", "");
michael@0 1524 is(cs.getPropertyValue(prop), "ultra-expanded",
michael@0 1525 "font-stretch property " + prop + ": clamping of values");
michael@0 1526 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1527 }
michael@0 1528
michael@0 1529 function test_font_weight(prop) {
michael@0 1530 is(prop, "font-weight", "only designed for one property");
michael@0 1531
michael@0 1532 div.style.setProperty("transition-property", "none", "");
michael@0 1533 div.style.setProperty(prop, "normal", "");
michael@0 1534 is(cs.getPropertyValue(prop), "400",
michael@0 1535 "font-weight property " + prop + ": computed value before transition");
michael@0 1536 div.style.setProperty("transition-property", prop, "");
michael@0 1537 div.style.setProperty(prop, "900", "");
michael@0 1538 is(cs.getPropertyValue(prop), "500",
michael@0 1539 "font-weight property " + prop + ": interpolation of font-weights");
michael@0 1540 check_distance(prop, "400", "500", "800");
michael@0 1541
michael@0 1542 div.style.setProperty("transition-property", "none", "");
michael@0 1543 div.style.setProperty(prop, "900", "");
michael@0 1544 is(cs.getPropertyValue(prop), "900",
michael@0 1545 "font-weight property " + prop + ": computed value before transition");
michael@0 1546 div.style.setProperty("transition-property", prop, "");
michael@0 1547 div.style.setProperty(prop, "100", "");
michael@0 1548 is(cs.getPropertyValue(prop), "700",
michael@0 1549 "font-weight property " + prop + ": interpolation of font-weights");
michael@0 1550 check_distance(prop, "900", "700", "100");
michael@0 1551
michael@0 1552 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1553 div.style.setProperty("transition-property", "none", "");
michael@0 1554 div.style.setProperty(prop, "100", "");
michael@0 1555 is(cs.getPropertyValue(prop), "100",
michael@0 1556 "font-weight property " + prop + ": flush before clamping test");
michael@0 1557 div.style.setProperty("transition-property", prop, "");
michael@0 1558 div.style.setProperty(prop, "900", "");
michael@0 1559 is(cs.getPropertyValue(prop), "100",
michael@0 1560 "font-weight property " + prop + ": clamping of values");
michael@0 1561 div.style.setProperty("transition-property", "none", "");
michael@0 1562 div.style.setProperty(prop, "900", "");
michael@0 1563 is(cs.getPropertyValue(prop), "900",
michael@0 1564 "font-weight property " + prop + ": flush before clamping test");
michael@0 1565 div.style.setProperty("transition-property", prop, "");
michael@0 1566 div.style.setProperty(prop, "100", "");
michael@0 1567 is(cs.getPropertyValue(prop), "900",
michael@0 1568 "font-weight property " + prop + ": clamping of values");
michael@0 1569 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1570 }
michael@0 1571
michael@0 1572 function test_pos_integer_or_auto_transition(prop) {
michael@0 1573 div.style.setProperty("transition-property", "none", "");
michael@0 1574 div.style.setProperty(prop, "4", "");
michael@0 1575 is(cs.getPropertyValue(prop), "4",
michael@0 1576 "integer-valued property " + prop + ": computed value before transition");
michael@0 1577 div.style.setProperty("transition-property", prop, "");
michael@0 1578 div.style.setProperty(prop, "11", "");
michael@0 1579 is(cs.getPropertyValue(prop), "5",
michael@0 1580 "integer-valued property " + prop + ": interpolation of integers");
michael@0 1581 check_distance(prop, "4", "6", "12");
michael@0 1582 div.style.setProperty(prop, "auto", "");
michael@0 1583 is(cs.getPropertyValue(prop), "auto",
michael@0 1584 "integer-valued property " + prop + ": auto not interpolable");
michael@0 1585 div.style.setProperty(prop, "8", "");
michael@0 1586 is(cs.getPropertyValue(prop), "8",
michael@0 1587 "integer-valued property " + prop + ": computed value before transition");
michael@0 1588 div.style.setProperty(prop, "4", "");
michael@0 1589 is(cs.getPropertyValue(prop), "7",
michael@0 1590 "integer-valued property " + prop + ": interpolation of integers");
michael@0 1591 check_distance(prop, "8", "7", "4");
michael@0 1592 }
michael@0 1593
michael@0 1594 function test_integer_at_least_one_clamping(prop) {
michael@0 1595 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1596 div.style.setProperty("transition-property", "none", "");
michael@0 1597 div.style.setProperty(prop, "1", "");
michael@0 1598 is(cs.getPropertyValue(prop), "1",
michael@0 1599 "integer-valued property " + prop + ": flush before clamping test");
michael@0 1600 div.style.setProperty("transition-property", prop, "");
michael@0 1601 div.style.setProperty(prop, "5", "");
michael@0 1602 is(cs.getPropertyValue(prop), "1",
michael@0 1603 "integer-valued property " + prop + ": clamping of negatives");
michael@0 1604 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1605 }
michael@0 1606
michael@0 1607 function test_length_pair_transition(prop) {
michael@0 1608 div.style.setProperty("transition-property", "none", "");
michael@0 1609 div.style.setProperty(prop, "4px 6px", "");
michael@0 1610 is(cs.getPropertyValue(prop), "4px 6px",
michael@0 1611 "length-valued property " + prop + ": computed value before transition");
michael@0 1612 div.style.setProperty("transition-property", prop, "");
michael@0 1613 div.style.setProperty(prop, "12px 10px", "");
michael@0 1614 is(cs.getPropertyValue(prop), "6px 7px",
michael@0 1615 "length-valued property " + prop + ": interpolation of lengths");
michael@0 1616 check_distance(prop, "4px 6px", "6px 7px", "12px 10px");
michael@0 1617 }
michael@0 1618
michael@0 1619 function test_length_pair_transition_clamped(prop) {
michael@0 1620 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1621 div.style.setProperty("transition-property", "none", "");
michael@0 1622 div.style.setProperty(prop, "0px 0px", "");
michael@0 1623 is(cs.getPropertyValue(prop), "0px 0px",
michael@0 1624 "length-valued property " + prop + ": flush before clamping test");
michael@0 1625 div.style.setProperty("transition-property", prop, "");
michael@0 1626 div.style.setProperty(prop, "30px 50px", "");
michael@0 1627 is(cs.getPropertyValue(prop), "0px 0px",
michael@0 1628 "length-valued property " + prop + ": clamping of negatives");
michael@0 1629 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1630 }
michael@0 1631
michael@0 1632 function test_length_percent_pair_transition(prop) {
michael@0 1633 div.style.setProperty("transition-property", "none", "");
michael@0 1634 div.style.setProperty(prop, "4px 50%", "");
michael@0 1635 is(cs.getPropertyValue(prop), "4px 5px",
michael@0 1636 "length-valued property " + prop + ": computed value before transition");
michael@0 1637 div.style.setProperty("transition-property", prop, "");
michael@0 1638 div.style.setProperty(prop, "12px 70%", "");
michael@0 1639 is(cs.getPropertyValue(prop), "6px 5.5px",
michael@0 1640 "length-valued property " + prop + ": interpolation of lengths");
michael@0 1641 check_distance(prop, "4px 50%", "6px 55%", "12px 70%");
michael@0 1642 }
michael@0 1643
michael@0 1644 function test_length_percent_pair_clamped(prop) {
michael@0 1645 test_length_percent_pair_clamped_or_unclamped(prop, true);
michael@0 1646 }
michael@0 1647
michael@0 1648 function test_length_percent_pair_unclamped(prop) {
michael@0 1649 test_length_percent_pair_clamped_or_unclamped(prop, false);
michael@0 1650 }
michael@0 1651
michael@0 1652 function test_length_percent_pair_clamped_or_unclamped(prop, is_clamped) {
michael@0 1653 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1654 div.style.setProperty("transition-property", "none", "");
michael@0 1655 div.style.setProperty(prop, "0px 0%", "");
michael@0 1656 is(cs.getPropertyValue(prop), "0px 0px",
michael@0 1657 "length+percent-valued property " + prop + ": flush before clamping test");
michael@0 1658 div.style.setProperty("transition-property", prop, "");
michael@0 1659 div.style.setProperty(prop, "30px 25%", "");
michael@0 1660 (is_clamped ? is : isnot)(cs.getPropertyValue(prop), "0px 0px",
michael@0 1661 "length+percent-valued property " + prop + ": clamping of negatives");
michael@0 1662 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1663 }
michael@0 1664
michael@0 1665 function test_rect_transition(prop) {
michael@0 1666 div.style.setProperty("transition-property", "none", "");
michael@0 1667 div.style.setProperty(prop, "rect(4px, 16px, 12px, 6px)", "");
michael@0 1668 is(cs.getPropertyValue(prop), "rect(4px, 16px, 12px, 6px)",
michael@0 1669 "rect-valued property " + prop + ": computed value before transition");
michael@0 1670 div.style.setProperty("transition-property", prop, "");
michael@0 1671 div.style.setProperty(prop, "rect(0px, 4px, 4px, 2px)", "");
michael@0 1672 is(cs.getPropertyValue(prop), "rect(3px, 13px, 10px, 5px)",
michael@0 1673 "rect-valued property " + prop + ": interpolation of rects");
michael@0 1674 check_distance(prop, "rect(4px, 16px, 12px, 6px)",
michael@0 1675 "rect(3px, 13px, 10px, 5px)",
michael@0 1676 "rect(0px, 4px, 4px, 2px)");
michael@0 1677 if (prop == "clip") {
michael@0 1678 div.style.setProperty(prop, "rect(0px, 6px, 4px, auto)", "");
michael@0 1679 is(cs.getPropertyValue(prop), "rect(0px, 6px, 4px, auto)",
michael@0 1680 "rect-valued property " + prop + ": can't interpolate auto components");
michael@0 1681 div.style.setProperty(prop, "rect(0px, 6px, 4px, 2px)", "");
michael@0 1682 }
michael@0 1683 div.style.setProperty(prop, "auto", "");
michael@0 1684 is(cs.getPropertyValue(prop), "auto",
michael@0 1685 "rect-valued property " + prop + ": can't interpolate auto components");
michael@0 1686
michael@0 1687 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1688 div.style.setProperty("transition-property", "none", "");
michael@0 1689 div.style.setProperty(prop, "rect(-10px, 30px, 0px, 0px)", "");
michael@0 1690 var vals = cs.getPropertyValue(prop).match(/rect\(([^, ]*), ([^, ]*), ([^, ]*), ([^, ]*)\)/);
michael@0 1691 is(vals.length, 5,
michael@0 1692 "rect-valued property " + prop + ": flush before clamping test (length)");
michael@0 1693 is(vals[1], "-10px",
michael@0 1694 "rect-valued property " + prop + ": flush before clamping test (top)");
michael@0 1695 is(vals[2], "30px",
michael@0 1696 "rect-valued property " + prop + ": flush before clamping test (right)");
michael@0 1697 is(vals[3], "0px",
michael@0 1698 "rect-valued property " + prop + ": flush before clamping test (bottom)");
michael@0 1699 is(vals[4], "0px",
michael@0 1700 "rect-valued property " + prop + ": flush before clamping test (left)");
michael@0 1701 div.style.setProperty("transition-property", prop, "");
michael@0 1702 div.style.setProperty(prop, "rect(0px, 40px, 10px, 10px)", "");
michael@0 1703 vals = cs.getPropertyValue(prop).match(/rect\(([^, ]*), ([^, ]*), ([^, ]*), ([^, ]*)\)/);
michael@0 1704 is(vals.length, 5,
michael@0 1705 "rect-valued property " + prop + ": clamping of negatives (length)");
michael@0 1706 isnot(vals[1], "-10px",
michael@0 1707 "rect-valued property " + prop + ": clamping of negatives (top)");
michael@0 1708 isnot(vals[2], "30px",
michael@0 1709 "rect-valued property " + prop + ": clamping of negatives (right)");
michael@0 1710 isnot(vals[3], "0px",
michael@0 1711 "rect-valued property " + prop + ": clamping of negatives (bottom)");
michael@0 1712 isnot(vals[4], "0px",
michael@0 1713 "rect-valued property " + prop + ": clamping of negatives (left)");
michael@0 1714 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1715 }
michael@0 1716
michael@0 1717 function test_visibility_transition(prop) {
michael@0 1718 function do_test(from_value, to_value, interp_value) {
michael@0 1719 div.style.setProperty("transition-property", "none", "");
michael@0 1720 div.style.setProperty(prop, from_value, "");
michael@0 1721 is(cs.getPropertyValue(prop), from_value,
michael@0 1722 "visibility property " + prop + ": computed value before transition");
michael@0 1723 div.style.setProperty("transition-property", prop, "");
michael@0 1724 div.style.setProperty(prop, to_value, "");
michael@0 1725 is(cs.getPropertyValue(prop), interp_value,
michael@0 1726 "visibility property " + prop + ": interpolation of visibility");
michael@0 1727 }
michael@0 1728
michael@0 1729 do_test("visible", "hidden", "visible");
michael@0 1730 do_test("hidden", "visible", "visible");
michael@0 1731 do_test("hidden", "collapse", "collapse"); /* not interpolable */
michael@0 1732 do_test("collapse", "hidden", "hidden"); /* not interpolable */
michael@0 1733 do_test("visible", "collapse", "visible");
michael@0 1734 do_test("collapse", "visible", "visible");
michael@0 1735
michael@0 1736 isnot(get_distance(prop, "visible", "hidden"), 0,
michael@0 1737 "distance between visible and hidden should not be zero");
michael@0 1738 isnot(get_distance(prop, "visible", "collapse"), 0,
michael@0 1739 "distance between visible and collapse should not be zero");
michael@0 1740 is(get_distance(prop, "visible", "visible"), 0,
michael@0 1741 "distance between visible and visible should not be zero");
michael@0 1742 is(get_distance(prop, "hidden", "hidden"), 0,
michael@0 1743 "distance between hidden and hidden should not be zero");
michael@0 1744 is(get_distance(prop, "collapse", "collapse"), 0,
michael@0 1745 "distance between collapse and collapse should not be zero");
michael@0 1746
michael@0 1747 div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
michael@0 1748 function do_negative_test(from_value, to_value, interpolable) {
michael@0 1749 div.style.setProperty("transition-property", "none", "");
michael@0 1750 div.style.setProperty(prop, from_value, "");
michael@0 1751 is(cs.getPropertyValue(prop), from_value,
michael@0 1752 "visibility property " + prop + ": flush before clamping test");
michael@0 1753 div.style.setProperty("transition-property", prop, "");
michael@0 1754 div.style.setProperty(prop, to_value, "");
michael@0 1755 is(cs.getPropertyValue(prop), interpolable ? from_value : to_value,
michael@0 1756 "visibility property " + prop + ": clamping of negatives");
michael@0 1757 }
michael@0 1758 do_negative_test("visible", "hidden", true);
michael@0 1759 do_negative_test("hidden", "visible", true);
michael@0 1760 do_negative_test("hidden", "collapse", false);
michael@0 1761 do_negative_test("collapse", "hidden", false);
michael@0 1762 do_negative_test("visible", "collapse", true);
michael@0 1763 do_negative_test("collapse", "visible", true);
michael@0 1764
michael@0 1765 div.style.setProperty("transition-delay", "-3s", "");
michael@0 1766 div.style.setProperty("transition-timing-function", FUNC_OVERONE, "");
michael@0 1767
michael@0 1768 function do_overone_test(from_value, to_value) {
michael@0 1769 div.style.setProperty("transition-property", "none", "");
michael@0 1770 div.style.setProperty(prop, from_value, "");
michael@0 1771 is(cs.getPropertyValue(prop), from_value,
michael@0 1772 "visibility property " + prop + ": flush before clamping test");
michael@0 1773 div.style.setProperty("transition-property", prop, "");
michael@0 1774 div.style.setProperty(prop, to_value, "");
michael@0 1775 is(cs.getPropertyValue(prop), to_value,
michael@0 1776 "visibility property " + prop + ": clamping of over-ones");
michael@0 1777 }
michael@0 1778 do_overone_test("visible", "hidden");
michael@0 1779 do_overone_test("hidden", "visible");
michael@0 1780 do_overone_test("hidden", "collapse");
michael@0 1781 do_overone_test("collapse", "hidden");
michael@0 1782 do_overone_test("visible", "collapse");
michael@0 1783 do_overone_test("collapse", "visible");
michael@0 1784
michael@0 1785 div.style.setProperty("transition-delay", "-1s", "");
michael@0 1786 div.style.setProperty("transition-timing-function", "linear", "");
michael@0 1787 }
michael@0 1788
michael@0 1789 function test_background_size_transition(prop) {
michael@0 1790 div.style.setProperty("transition-property", "none", "");
michael@0 1791 div.style.setProperty(prop, "50% 80%", "");
michael@0 1792 is(cs.getPropertyValue(prop), "50% 80%",
michael@0 1793 "property " + prop + ": computed value before transition");
michael@0 1794 div.style.setProperty("transition-property", prop, "");
michael@0 1795 div.style.setProperty(prop, "100% 100%", "");
michael@0 1796 is(cs.getPropertyValue(prop), "62.5% 85%",
michael@0 1797 "property " + prop + ": interpolation of percents");
michael@0 1798 check_distance(prop, "50% 80%", "62.5% 85%", "100% 100%");
michael@0 1799 div.style.setProperty(prop, "contain", "");
michael@0 1800 is(cs.getPropertyValue(prop), "contain",
michael@0 1801 "property " + prop + ": can't interpolate 'contain'");
michael@0 1802 test_background_position_size_common(prop);
michael@0 1803 }
michael@0 1804
michael@0 1805 function test_background_position_transition(prop) {
michael@0 1806 div.style.setProperty("transition-property", "none", "");
michael@0 1807 div.style.setProperty(prop, "center 80%", "");
michael@0 1808 is(cs.getPropertyValue(prop), "50% 80%",
michael@0 1809 "property " + prop + ": computed value before transition");
michael@0 1810 div.style.setProperty("transition-property", prop, "");
michael@0 1811 div.style.setProperty(prop, "bottom right", "");
michael@0 1812 is(cs.getPropertyValue(prop), "62.5% 85%",
michael@0 1813 "property " + prop + ": interpolation of percents");
michael@0 1814 check_distance(prop, "center 80%", "62.5% 85%", "bottom right");
michael@0 1815 test_background_position_size_common(prop);
michael@0 1816 }
michael@0 1817
michael@0 1818 function test_background_position_size_common(prop) {
michael@0 1819 div.style.setProperty("transition-property", "none", "");
michael@0 1820 div.style.setProperty(prop, "40% 0%", "");
michael@0 1821 is(cs.getPropertyValue(prop), "40% 0%",
michael@0 1822 "property " + prop + ": computed value before transition");
michael@0 1823 div.style.setProperty("transition-property", prop, "");
michael@0 1824 div.style.setProperty(prop, "0% 0%", "");
michael@0 1825 is(cs.getPropertyValue(prop), "30% 0%",
michael@0 1826 "property " + prop + ": interpolation of percentages");
michael@0 1827 check_distance(prop, "40% 0%", "30% 0%", "0% 0%");
michael@0 1828
michael@0 1829 div.style.setProperty("transition-property", "none", "");
michael@0 1830 div.style.setProperty(prop, "0% 40%", "");
michael@0 1831 is(cs.getPropertyValue(prop), "0% 40%",
michael@0 1832 "property " + prop + ": computed value before transition");
michael@0 1833 div.style.setProperty("transition-property", prop, "");
michael@0 1834 div.style.setProperty(prop, "0% 0%", "");
michael@0 1835 is(cs.getPropertyValue(prop), "0% 30%",
michael@0 1836 "property " + prop + ": interpolation of percentages");
michael@0 1837 check_distance(prop, "0% 40%", "0% 30%", "0% 0%");
michael@0 1838
michael@0 1839 div.style.setProperty("transition-property", "none", "");
michael@0 1840 div.style.setProperty(prop, "10px 40px", "");
michael@0 1841 is(cs.getPropertyValue(prop), "10px 40px",
michael@0 1842 "property " + prop + ": computed value before transition");
michael@0 1843 div.style.setProperty("transition-property", prop, "");
michael@0 1844 div.style.setProperty(prop, "50px 0", "");
michael@0 1845 is(cs.getPropertyValue(prop), "20px 30px",
michael@0 1846 "property " + prop + ": interpolation of lengths");
michael@0 1847 check_distance(prop, "10px 40px", "20px 30px", "50px 0");
michael@0 1848 div.style.setProperty(prop, "10px 40px, 50px 50px, 30px 20px", "");
michael@0 1849 is(cs.getPropertyValue(prop), "10px 40px, 50px 50px, 30px 20px",
michael@0 1850 "property " + prop + ": computed value before transition");
michael@0 1851 div.style.setProperty(prop, "50px 20px, 70px 50px, 30px 40px", "");
michael@0 1852 is(cs.getPropertyValue(prop), "20px 35px, 55px 50px, 30px 25px",
michael@0 1853 "property " + prop + ": interpolation of lists of lengths");
michael@0 1854 check_distance(prop, "10px 40px, 50px 50px, 30px 20px",
michael@0 1855 "20px 35px, 55px 50px, 30px 25px",
michael@0 1856 "50px 20px, 70px 50px, 30px 40px");
michael@0 1857 div.style.setProperty(prop, "10px 40%, 50% 50px, 30% 20%, 5px 10px", "");
michael@0 1858 is(cs.getPropertyValue(prop), "10px 40%, 50% 50px, 30% 20%, 5px 10px",
michael@0 1859 "property " + prop + ": computed value before transition");
michael@0 1860 div.style.setProperty(prop, "50px 20%, 70% 50px, 30% 40%, 25px 50px", "");
michael@0 1861 is(cs.getPropertyValue(prop), "20px 35%, 55% 50px, 30% 25%, 10px 20px",
michael@0 1862 "property " + prop + ": interpolation of lists of lengths and percents");
michael@0 1863 check_distance(prop, "10px 40%, 50% 50px, 30% 20%, 5px 10px",
michael@0 1864 "20px 35%, 55% 50px, 30% 25%, 10px 20px",
michael@0 1865 "50px 20%, 70% 50px, 30% 40%, 25px 50px");
michael@0 1866 div.style.setProperty(prop, "20% 40%, 8px 12px", "");
michael@0 1867 is(cs.getPropertyValue(prop), "20% 40%, 8px 12px",
michael@0 1868 "property " + prop + ": computed value before transition");
michael@0 1869 div.style.setProperty(prop, "12px 20px, 40% 16%", "");
michael@0 1870 is(cs.getPropertyValue(prop), "calc(3px + 15%) calc(5px + 30%), calc(6px + 10%) calc(9px + 4%)",
michael@0 1871 "property " + prop + ": interpolation that computes to calc()");
michael@0 1872 check_distance(prop, "20% 40%, 8px 12px",
michael@0 1873 "calc(3px + 15%) calc(5px + 30%), calc(6px + 10%) calc(9px + 4%)",
michael@0 1874 "12px 20px, 40% 16%");
michael@0 1875 div.style.setProperty(prop, "calc(20% + 40px) calc(40px + 40%), 8px 12%, calc(20px + 12%) calc(24px + 8%)", "");
michael@0 1876 is(cs.getPropertyValue(prop), "calc(40px + 20%) calc(40px + 40%), 8px 12%, calc(20px + 12%) calc(24px + 8%)",
michael@0 1877 "property " + prop + ": computed value before transition");
michael@0 1878 div.style.setProperty(prop, "12px 20%, calc(20%) calc(16px + 60%), calc(8px + 20%) calc(40px + 16%)", "");
michael@0 1879 is(cs.getPropertyValue(prop), "calc(33px + 15%) calc(30px + 35%), calc(6px + 5%) calc(4px + 24%), calc(17px + 14%) calc(28px + 10%)",
michael@0 1880 "property " + prop + ": interpolation that computes to calc()");
michael@0 1881 check_distance(prop, "calc(20% + 40px) calc(40px + 40%), 8px 12%, calc(20px + 12%) calc(24px + 8%)",
michael@0 1882 "calc(33px + 15%) calc(30px + 35%), calc(6px + 5%) calc(4px + 24%), calc(17px + 14%) calc(28px + 10%)",
michael@0 1883 "12px 20%, calc(20%) calc(16px + 60%), calc(8px + 20%) calc(40px + 16%)");
michael@0 1884 }
michael@0 1885
michael@0 1886 function test_transform_transition(prop) {
michael@0 1887 is(prop, "transform", "Unexpected transform property! Test needs to be fixed");
michael@0 1888 var matrix_re = /^matrix\(([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*)\)$/;
michael@0 1889 for (var i in transformTests) {
michael@0 1890 var test = transformTests[i];
michael@0 1891 if (!("expected" in test)) {
michael@0 1892 var v = test.expected_uncomputed;
michael@0 1893 if (v.match(matrix_re) && !test.force_compute) {
michael@0 1894 test.expected = v;
michael@0 1895 } else {
michael@0 1896 test.expected = computeMatrix(v);
michael@0 1897 }
michael@0 1898 }
michael@0 1899 }
michael@0 1900
michael@0 1901 for (var i in transformTests) {
michael@0 1902 var test = transformTests[i];
michael@0 1903 div.style.setProperty("transition-property", "none", "");
michael@0 1904 div.style.setProperty(prop, test.start, "");
michael@0 1905 cs.getPropertyValue(prop);
michael@0 1906 div.style.setProperty("transition-property", prop, "");
michael@0 1907 div.style.setProperty(prop, test.end, "");
michael@0 1908 var actual = cs.getPropertyValue(prop);
michael@0 1909 if (!test.round_error_ok || actual == test.expected) {
michael@0 1910 // In most cases, we'll get an exact match, but in some cases
michael@0 1911 // there can be a small amount of rounding error.
michael@0 1912 is(actual, test.expected,
michael@0 1913 "interpolation of transitions: " + test.start + " to " + test.end);
michael@0 1914 } else {
michael@0 1915 function s(mat) {
michael@0 1916 return mat.match(matrix_re).slice(1,7);
michael@0 1917 }
michael@0 1918 var pass = true;
michael@0 1919 var actual_split = s(actual);
michael@0 1920 var expected_split = s(test.expected);
michael@0 1921 for (var i = 0; i < 6; ++i) {
michael@0 1922 // Allow differences of 1 at the sixth decimal place, and allow
michael@0 1923 // a drop extra for floating point error from the subtraction.
michael@0 1924 if (Math.abs(Number(actual_split[i]) - Number(expected_split[i])) >
michael@0 1925 0.0000011) {
michael@0 1926 pass = false;
michael@0 1927 }
michael@0 1928 }
michael@0 1929 ok(pass,
michael@0 1930 "interpolation of transitions: " + test.start + " to " + test.end +
michael@0 1931 ": " + actual + " should approximately equal " + test.expected);
michael@0 1932 }
michael@0 1933 }
michael@0 1934
michael@0 1935 // FIXME: should perhaps test that no clamping occurs
michael@0 1936
michael@0 1937 // These tests check the computed value 2/3 of the way through the transition
michael@0 1938 OMTAdiv.style.setProperty("transition-duration", "300s", "");
michael@0 1939 OMTAdiv.style.setProperty("transition-timing-function", "linear", "");
michael@0 1940 window.requestAnimationFrame(nextAsyncTransformTest);
michael@0 1941 }
michael@0 1942
michael@0 1943 function nextAsyncTransformTest()
michael@0 1944 {
michael@0 1945 var test = transformTests[transformTestIndex];
michael@0 1946
michael@0 1947 if (transformTestIndex >= transformTests.length) {
michael@0 1948 window.requestAnimationFrame(asyncOpacityTest);
michael@0 1949 return;
michael@0 1950 }
michael@0 1951
michael@0 1952 OMTAdiv.style.setProperty("transition-property", "none", "");
michael@0 1953 OMTAdiv.style.setProperty("transform", test.start, "");
michael@0 1954 OMTACs.getPropertyValue("transform");
michael@0 1955 OMTAdiv.style.setProperty("transition-property", "transform", "");
michael@0 1956 OMTAdiv.style.setProperty("transform", test.end, "");
michael@0 1957 OMTACs.getPropertyValue("transform");
michael@0 1958
michael@0 1959 window.requestAnimationFrame(checkAsyncTransformTest);
michael@0 1960 }
michael@0 1961
michael@0 1962 function checkAsyncTransformTest() {
michael@0 1963 function s(matrix) {
michael@0 1964 return matrix.replace(/^\w*\(/, '').replace(')','').split(/\s*,\s*/);
michael@0 1965 }
michael@0 1966 winUtils.advanceTimeAndRefresh(200000);
michael@0 1967 var test = transformTests[transformTestIndex];
michael@0 1968 var async_transform = winUtils.getOMTAOrComputedStyle(OMTAdiv, "transform");
michael@0 1969 var computed_transform = OMTACs.getPropertyValue("transform");
michael@0 1970 var async_split = s(async_transform);
michael@0 1971 var cs_split = s(computed_transform);
michael@0 1972 var pass = true;
michael@0 1973 for (var j = 0; j < 16; ++j) {
michael@0 1974 var epsilon = test.big_omta_round_error ? 0.1 : 0.0001;
michael@0 1975 if (Math.abs(Number(async_split[j]) - Number(cs_split[j])) > epsilon) {
michael@0 1976 pass = false;
michael@0 1977 }
michael@0 1978 }
michael@0 1979 ok(pass,
michael@0 1980 "interpolation of transitions: " + test.start + " to " + test.end +
michael@0 1981 ": OMTA - " + async_transform + ", computed style - " + computed_transform);
michael@0 1982 transformTestIndex++;
michael@0 1983 winUtils.restoreNormalRefresh();
michael@0 1984 window.requestAnimationFrame(nextAsyncTransformTest);
michael@0 1985 }
michael@0 1986
michael@0 1987 function asyncOpacityTest() {
michael@0 1988 OMTAdiv.style.setProperty("transition-property", "none", "");
michael@0 1989 OMTAdiv.style.setProperty("opacity", 0, "");
michael@0 1990 OMTACs.getPropertyValue("opacity");
michael@0 1991 OMTAdiv.style.setProperty("transition-property", "opacity", "");
michael@0 1992 OMTAdiv.style.setProperty("opacity", 1, "");
michael@0 1993 OMTACs.getPropertyValue("opacity");
michael@0 1994
michael@0 1995 window.requestAnimationFrame(checkAsyncOpacityTest);
michael@0 1996 }
michael@0 1997
michael@0 1998 function checkAsyncOpacityTest() {
michael@0 1999 winUtils.advanceTimeAndRefresh(200000);
michael@0 2000 var async_opacity = winUtils.getOMTAOrComputedStyle(OMTAdiv, "opacity");
michael@0 2001 var computed_opacity = OMTACs.getPropertyValue("opacity");
michael@0 2002 is(async_opacity, computed_opacity,
michael@0 2003 "Async animated opacity should match computed opacity");
michael@0 2004 winUtils.restoreNormalRefresh();
michael@0 2005 OMTAdiv.style.removeProperty("transition");
michael@0 2006 SimpleTest.finish();
michael@0 2007 }
michael@0 2008
michael@0 2009 </script>
michael@0 2010 </pre>
michael@0 2011 </body>
michael@0 2012 </html>

mercurial