| OLD | NEW | 
|---|
| 1 /* This is the helper function to run animation tests: | 1 /* This is the helper function to run animation tests: | 
| 2 | 2 | 
| 3 Test page requirements: | 3 Test page requirements: | 
| 4 - The body must contain an empty div with id "result" | 4 - The body must contain an empty div with id "result" | 
| 5 - Call this function directly from the <script> inside the test page | 5 - Call this function directly from the <script> inside the test page | 
| 6 | 6 | 
| 7 Function parameters: | 7 Function parameters: | 
| 8     expected [required]: an array of arrays defining a set of CSS properties tha
     t must have given values at specific times (see below) | 8     expected [required]: an array of arrays defining a set of CSS properties tha
     t must have given values at specific times (see below) | 
| 9     callbacks [optional]: a function to be executed immediately after animation 
     starts; | 9     callbacks [optional]: a function to be executed immediately after animation 
     starts; | 
| 10                           or, an object in the form {time: function} containing 
     functions to be | 10                           or, an object in the form {time: function} containing 
     functions to be | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 33     If the CSS property name is "webkitTransform.N", expected value must be a nu
     mber corresponding to the Nth element of the matrix | 33     If the CSS property name is "webkitTransform.N", expected value must be a nu
     mber corresponding to the Nth element of the matrix | 
| 34 | 34 | 
| 35 */ | 35 */ | 
| 36 | 36 | 
| 37 function isCloseEnough(actual, desired, tolerance) | 37 function isCloseEnough(actual, desired, tolerance) | 
| 38 { | 38 { | 
| 39     var diff = Math.abs(actual - desired); | 39     var diff = Math.abs(actual - desired); | 
| 40     return diff <= tolerance; | 40     return diff <= tolerance; | 
| 41 } | 41 } | 
| 42 | 42 | 
|  | 43 function roundNumber(num, decimalPlaces) | 
|  | 44 { | 
|  | 45   return Math.round(num * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPla
     ces); | 
|  | 46 } | 
|  | 47 | 
| 43 function matrixStringToArray(s) | 48 function matrixStringToArray(s) | 
| 44 { | 49 { | 
| 45     if (s == "none") | 50     if (s == "none") | 
| 46         return [ 1, 0, 0, 1, 0, 0 ]; | 51         return [ 1, 0, 0, 1, 0, 0 ]; | 
| 47     var m = s.split("("); | 52     var m = s.split("("); | 
| 48     m = m[1].split(")"); | 53     m = m[1].split(")"); | 
| 49     return m[0].split(","); | 54     return m[0].split(","); | 
| 50 } | 55 } | 
| 51 | 56 | 
| 52 function parseCrossFade(s) | 57 function parseCrossFade(s) | 
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 263 | 268 | 
| 264         if (comparePropertyValue(property, computedValue, expectedValue, toleran
     ce)) | 269         if (comparePropertyValue(property, computedValue, expectedValue, toleran
     ce)) | 
| 265             result += "PASS - \"" + property + "\" property for \"" + elementNam
     e + "\" element at " + time + | 270             result += "PASS - \"" + property + "\" property for \"" + elementNam
     e + "\" element at " + time + | 
| 266                             "s saw something close to: " + expectedValue + "<br>
     "; | 271                             "s saw something close to: " + expectedValue + "<br>
     "; | 
| 267         else | 272         else | 
| 268             result += "FAIL - \"" + property + "\" property for \"" + elementNam
     e + "\" element at " + time + | 273             result += "FAIL - \"" + property + "\" property for \"" + elementNam
     e + "\" element at " + time + | 
| 269                             "s expected: " + expectedValue + " but saw: " + comp
     utedValue + "<br>"; | 274                             "s expected: " + expectedValue + " but saw: " + comp
     utedValue + "<br>"; | 
| 270     } | 275     } | 
| 271 } | 276 } | 
| 272 | 277 | 
|  | 278 function compareRGB(rgb, expected, tolerance) | 
|  | 279 { | 
|  | 280     return (isCloseEnough(parseInt(rgb[0]), expected[0], tolerance) && | 
|  | 281             isCloseEnough(parseInt(rgb[1]), expected[1], tolerance) && | 
|  | 282             isCloseEnough(parseInt(rgb[2]), expected[2], tolerance)); | 
|  | 283 } | 
|  | 284 | 
|  | 285 function parseCrossFade(s) | 
|  | 286 { | 
|  | 287     var matches = s.match("-webkit-cross-fade\\((.*)\\s*,\\s*(.*)\\s*,\\s*(.*)\\
     )"); | 
|  | 288 | 
|  | 289     if (!matches) | 
|  | 290         return null; | 
|  | 291 | 
|  | 292     return {"from": matches[1], "to": matches[2], "percent": parseFloat(matches[
     3])} | 
|  | 293 } | 
|  | 294 | 
|  | 295 function checkExpectedTransitionValue(expected, index) | 
|  | 296 { | 
|  | 297     expected[index].shift(); | 
|  | 298     var time = expected[index][0]; | 
|  | 299     var elementId = expected[index][1]; | 
|  | 300     var property = expected[index][2]; | 
|  | 301     var expectedValue = expected[index][3]; | 
|  | 302     var tolerance = expected[index][4]; | 
|  | 303     var postCompletionCallback = expected[index][5]; | 
|  | 304 | 
|  | 305     var computedValue; | 
|  | 306     var pass = false; | 
|  | 307     var transformRegExp = /^-webkit-transform(\.\d+)?$/; | 
|  | 308     if (transformRegExp.test(property)) { | 
|  | 309         computedValue = window.getComputedStyle(document.getElementById(elementI
     d)).webkitTransform; | 
|  | 310         if (typeof expectedValue == "string") | 
|  | 311             pass = (computedValue == expectedValue); | 
|  | 312         else if (typeof expectedValue == "number") { | 
|  | 313             var m = computedValue.split("("); | 
|  | 314             var m = m[1].split(","); | 
|  | 315             pass = isCloseEnough(parseFloat(m[parseInt(property.substring(18))])
     , expectedValue, tolerance); | 
|  | 316         } else { | 
|  | 317             var m = computedValue.split("("); | 
|  | 318             var m = m[1].split(","); | 
|  | 319             for (i = 0; i < expectedValue.length; ++i) { | 
|  | 320                 pass = isCloseEnough(parseFloat(m[i]), expectedValue[i], toleran
     ce); | 
|  | 321                 if (!pass) | 
|  | 322                     break; | 
|  | 323             } | 
|  | 324         } | 
|  | 325     } else if (property == "fill" || property == "stroke") { | 
|  | 326         computedValue = window.getComputedStyle(document.getElementById(elementI
     d)).getPropertyCSSValue(property).rgbColor; | 
|  | 327         if (compareRGB([computedValue.red.cssText, computedValue.green.cssText, 
     computedValue.blue.cssText], expectedValue, tolerance)) | 
|  | 328             pass = true; | 
|  | 329         else { | 
|  | 330             // We failed. Make sure computed value is something we can read in t
     he error message | 
|  | 331             computedValue = window.getComputedStyle(document.getElementById(elem
     entId)).getPropertyCSSValue(property).cssText; | 
|  | 332         } | 
|  | 333     } else if (property == "stop-color" || property == "flood-color" || property
      == "lighting-color") { | 
|  | 334         computedValue = window.getComputedStyle(document.getElementById(elementI
     d)).getPropertyCSSValue(property); | 
|  | 335         // The computedValue cssText is rgb(num, num, num) | 
|  | 336         var components = computedValue.cssText.split("(")[1].split(")")[0].split
     (","); | 
|  | 337         if (compareRGB(components, expectedValue, tolerance)) | 
|  | 338             pass = true; | 
|  | 339         else { | 
|  | 340             // We failed. Make sure computed value is something we can read in t
     he error message | 
|  | 341             computedValue = computedValue.cssText; | 
|  | 342         } | 
|  | 343     } else if (property == "lineHeight") { | 
|  | 344         computedValue = parseInt(window.getComputedStyle(document.getElementById
     (elementId)).lineHeight); | 
|  | 345         pass = isCloseEnough(computedValue, expectedValue, tolerance); | 
|  | 346     } else if (property == "background-image" | 
|  | 347                || property == "border-image-source" | 
|  | 348                || property == "border-image" | 
|  | 349                || property == "list-style-image" | 
|  | 350                || property == "-webkit-mask-image" | 
|  | 351                || property == "-webkit-mask-box-image") { | 
|  | 352         if (property == "border-image" || property == "-webkit-mask-image" || pr
     operty == "-webkit-mask-box-image") | 
|  | 353             property += "-source"; | 
|  | 354 | 
|  | 355         computedValue = window.getComputedStyle(document.getElementById(elementI
     d)).getPropertyCSSValue(property).cssText; | 
|  | 356         computedCrossFade = parseCrossFade(computedValue); | 
|  | 357 | 
|  | 358         if (!computedCrossFade) { | 
|  | 359             pass = false; | 
|  | 360         } else { | 
|  | 361             pass = isCloseEnough(computedCrossFade.percent, expectedValue, toler
     ance); | 
|  | 362         } | 
|  | 363     } else { | 
|  | 364         var computedStyle = window.getComputedStyle(document.getElementById(elem
     entId)).getPropertyCSSValue(property); | 
|  | 365         if (computedStyle.cssValueType == CSSValue.CSS_VALUE_LIST) { | 
|  | 366             var values = []; | 
|  | 367             for (var i = 0; i < computedStyle.length; ++i) { | 
|  | 368                 switch (computedStyle[i].cssValueType) { | 
|  | 369                   case CSSValue.CSS_PRIMITIVE_VALUE: | 
|  | 370                     values.push(computedStyle[i].getFloatValue(CSSPrimitiveValue
     .CSS_NUMBER)); | 
|  | 371                     break; | 
|  | 372                   case CSSValue.CSS_CUSTOM: | 
|  | 373                     // arbitrarily pick shadow-x and shadow-y | 
|  | 374                     if (property == 'box-shadow' || property == 'text-shadow') { | 
|  | 375                       var text = computedStyle[i].cssText; | 
|  | 376                       // Shadow cssText looks like "rgb(0, 0, 255) 0px -3px 10px
      0px" | 
|  | 377                       var shadowPositionRegExp = /\)\s*(-?\d+)px\s*(-?\d+)px/; | 
|  | 378                       var match = shadowPositionRegExp.exec(text); | 
|  | 379                       var shadowXY = [parseInt(match[1]), parseInt(match[2])]; | 
|  | 380                       values.push(shadowXY[0]); | 
|  | 381                       values.push(shadowXY[1]); | 
|  | 382                     } else | 
|  | 383                       values.push(computedStyle[i].cssText); | 
|  | 384                     break; | 
|  | 385                 } | 
|  | 386             } | 
|  | 387             computedValue = values.join(','); | 
|  | 388             pass = true; | 
|  | 389             for (var i = 0; i < values.length; ++i) | 
|  | 390                 pass &= isCloseEnough(values[i], expectedValue[i], tolerance); | 
|  | 391         } else if (computedStyle.cssValueType == CSSValue.CSS_PRIMITIVE_VALUE) { | 
|  | 392             switch (computedStyle.primitiveType) { | 
|  | 393                 case CSSPrimitiveValue.CSS_STRING: | 
|  | 394                 case CSSPrimitiveValue.CSS_IDENT: | 
|  | 395                     computedValue = computedStyle.getStringValue(); | 
|  | 396                     pass = computedValue == expectedValue; | 
|  | 397                     break; | 
|  | 398                 case CSSPrimitiveValue.CSS_RGBCOLOR: | 
|  | 399                     var rgbColor = computedStyle.getRGBColorValue(); | 
|  | 400                     computedValue = [rgbColor.red.getFloatValue(CSSPrimitiveValu
     e.CSS_NUMBER), | 
|  | 401                                      rgbColor.green.getFloatValue(CSSPrimitiveVa
     lue.CSS_NUMBER), | 
|  | 402                                      rgbColor.blue.getFloatValue(CSSPrimitiveVal
     ue.CSS_NUMBER)]; // alpha is not exposed to JS | 
|  | 403                     pass = true; | 
|  | 404                     for (var i = 0; i < 3; ++i) | 
|  | 405                         pass &= isCloseEnough(computedValue[i], expectedValue[i]
     , tolerance); | 
|  | 406                     break; | 
|  | 407                 case CSSPrimitiveValue.CSS_RECT: | 
|  | 408                     computedValue = computedStyle.getRectValue(); | 
|  | 409                     computedValue = [computedValue.top.getFloatValue(CSSPrimitiv
     eValue.CSS_NUMBER), | 
|  | 410                                      computedValue.right.getFloatValue(CSSPrimit
     iveValue.CSS_NUMBER), | 
|  | 411                                      computedValue.bottom.getFloatValue(CSSPrimi
     tiveValue.CSS_NUMBER), | 
|  | 412                                      computedValue.left.getFloatValue(CSSPrimiti
     veValue.CSS_NUMBER)]; | 
|  | 413                      pass = true; | 
|  | 414                      for (var i = 0; i < 4; ++i) | 
|  | 415                          pass &= isCloseEnough(computedValue[i], expectedValue[i
     ], tolerance); | 
|  | 416                     break; | 
|  | 417                 case CSSPrimitiveValue.CSS_PERCENTAGE: | 
|  | 418                     computedValue = parseFloat(computedStyle.cssText); | 
|  | 419                     pass = isCloseEnough(computedValue, expectedValue, tolerance
     ); | 
|  | 420                     break; | 
|  | 421                 default: | 
|  | 422                     computedValue = computedStyle.getFloatValue(CSSPrimitiveValu
     e.CSS_NUMBER); | 
|  | 423                     pass = isCloseEnough(computedValue, expectedValue, tolerance
     ); | 
|  | 424             } | 
|  | 425         } | 
|  | 426     } | 
|  | 427 | 
|  | 428     if (pass) | 
|  | 429         result += "PASS - \"" + property + "\" property for \"" + elementId + "\
     " element at " + time + "s saw something close to: " + expectedValue + "<br>"; | 
|  | 430     else | 
|  | 431         result += "FAIL - \"" + property + "\" property for \"" + elementId + "\
     " element at " + time + "s expected: " + expectedValue + " but saw: " + computed
     Value + "<br>"; | 
|  | 432 | 
|  | 433     if (postCompletionCallback) | 
|  | 434       result += postCompletionCallback(); | 
|  | 435 } | 
|  | 436 | 
| 273 | 437 | 
| 274 function getPropertyValue(property, elementId, iframeId) | 438 function getPropertyValue(property, elementId, iframeId) | 
| 275 { | 439 { | 
| 276     var computedValue; | 440     var computedValue; | 
| 277     var element; | 441     var element; | 
| 278     if (iframeId) | 442     if (iframeId) | 
| 279         element = document.getElementById(iframeId).contentDocument.getElementBy
     Id(elementId); | 443         element = document.getElementById(iframeId).contentDocument.getElementBy
     Id(elementId); | 
| 280     else | 444     else | 
| 281         element = document.getElementById(elementId); | 445         element = document.getElementById(elementId); | 
| 282 | 446 | 
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 395     if (hasPauseAnimationAPI) | 559     if (hasPauseAnimationAPI) | 
| 396         runChecksWithPauseAPI(checks); | 560         runChecksWithPauseAPI(checks); | 
| 397     else | 561     else | 
| 398         runChecksWithRAF(checks); | 562         runChecksWithRAF(checks); | 
| 399 } | 563 } | 
| 400 | 564 | 
| 401 var useResultElement = false; | 565 var useResultElement = false; | 
| 402 var result = ""; | 566 var result = ""; | 
| 403 var hasPauseAnimationAPI; | 567 var hasPauseAnimationAPI; | 
| 404 var animStartTime; | 568 var animStartTime; | 
|  | 569 var isTransitionsTest = false; | 
|  | 570 | 
|  | 571 var usePauseAPI = true; | 
|  | 572 var dontUsePauseAPI = false; | 
|  | 573 var shouldBeTransitioning = 'should-be-transitioning'; | 
|  | 574 var shouldNotBeTransitioning = 'should-not-be-transitioning'; | 
| 405 | 575 | 
| 406 // FIXME: remove deprecatedEvent, disablePauseAnimationAPI and doPixelTest | 576 // FIXME: remove deprecatedEvent, disablePauseAnimationAPI and doPixelTest | 
| 407 function runAnimationTest(expected, callbacks, deprecatedEvent, disablePauseAnim
     ationAPI, doPixelTest) | 577 function runAnimationTest(expected, callbacks, deprecatedEvent, disablePauseAnim
     ationAPI, doPixelTest) | 
| 408 { | 578 { | 
| 409     if (disablePauseAnimationAPI) | 579     if (disablePauseAnimationAPI) | 
| 410         result += 'Warning this test is running in real-time and may be flaky.<b
     r>'; | 580         result += 'Warning this test is running in real-time and may be flaky.<b
     r>'; | 
| 411     if (deprecatedEvent) | 581     if (deprecatedEvent) | 
| 412         throw 'Event argument is deprecated!'; | 582         throw 'Event argument is deprecated!'; | 
| 413     if (!expected) | 583     if (!expected) | 
| 414         throw "Expected results are missing!"; | 584         throw "Expected results are missing!"; | 
| 415 | 585 | 
| 416     hasPauseAnimationAPI = 'internals' in window; | 586     hasPauseAnimationAPI = 'internals' in window; | 
| 417     if (disablePauseAnimationAPI) | 587     if (disablePauseAnimationAPI) | 
| 418         hasPauseAnimationAPI = false; | 588         hasPauseAnimationAPI = false; | 
| 419 | 589 | 
| 420     var checks = {}; | 590     var checks = {}; | 
|  | 591     var trigger = function() {}; | 
| 421 | 592 | 
| 422     if (typeof callbacks == 'function') | 593     if (isTransitionsTest) { | 
|  | 594         var transitionTrigger = callbacks; | 
|  | 595         callbacks = null; | 
|  | 596         trigger = function() { | 
|  | 597             transitionTrigger(); | 
|  | 598             document.body.offsetTop | 
|  | 599             if (window.testRunner) | 
|  | 600                 testRunner.display(); | 
|  | 601         }; | 
|  | 602     } | 
|  | 603 | 
|  | 604     if (typeof callbacks == 'function') { | 
| 423         checks[0] = [callbacks]; | 605         checks[0] = [callbacks]; | 
| 424     else for (var time in callbacks) { | 606     } else for (var time in callbacks) { | 
| 425         timeMs = Math.round(time * 1000); | 607         timeMs = Math.round(time * 1000); | 
| 426         checks[timeMs] = [callbacks[time]]; | 608         checks[timeMs] = [callbacks[time]]; | 
| 427     } | 609     } | 
| 428 | 610 | 
| 429     for (var i = 0; i < expected.length; i++) { | 611     for (var i = 0; i < expected.length; i++) { | 
| 430         var expectation = expected[i]; | 612         var expectation = expected[i]; | 
| 431         var timeMs = Math.round(expectation[1] * 1000); | 613         var timeMs = Math.round(expectation[1] * 1000); | 
| 432         if (!checks[timeMs]) | 614         if (!checks[timeMs]) | 
| 433             checks[timeMs] = []; | 615             checks[timeMs] = []; | 
| 434         checks[timeMs].push(checkExpectedValue.bind(null, expected, i)); | 616         if (isTransitionsTest) | 
|  | 617             checks[timeMs].push(checkExpectedTransitionValue.bind(null, expected
     , i)); | 
|  | 618         else | 
|  | 619             checks[timeMs].push(checkExpectedValue.bind(null, expected, i)); | 
| 435     } | 620     } | 
| 436 | 621 | 
| 437     var doPixelTest = Boolean(doPixelTest); | 622     var doPixelTest = Boolean(doPixelTest); | 
| 438     useResultElement = doPixelTest; | 623     useResultElement = doPixelTest; | 
| 439 | 624 | 
| 440     if (window.testRunner) { | 625     if (window.testRunner) { | 
| 441         testRunner.dumpAsText(doPixelTest); | 626         testRunner.dumpAsText(doPixelTest); | 
| 442         testRunner.waitUntilDone(); | 627         testRunner.waitUntilDone(); | 
| 443     } | 628     } | 
| 444 | 629 | 
| 445     var started = false; | 630     var started = false; | 
| 446     document.addEventListener('webkitAnimationStart', function() { | 631     var target = isTransitionsTest ? window : document; | 
|  | 632     var event = isTransitionsTest ? 'load' : 'webkitAnimationStart'; | 
|  | 633     target.addEventListener(event, function() { | 
| 447         if (!started) { | 634         if (!started) { | 
| 448             started = true; | 635             started = true; | 
|  | 636             trigger(); | 
| 449             animStartTime = performance.now(); | 637             animStartTime = performance.now(); | 
| 450             // delay to give hardware animations a chance to start | 638             // delay to give hardware animations a chance to start | 
| 451             setTimeout(function() { | 639             setTimeout(function() { | 
| 452                 startTest(checks); | 640                 startTest(checks); | 
| 453             }, 0); | 641             }, 0); | 
| 454         } | 642         } | 
| 455     }, false); | 643     }, false); | 
| 456 } | 644 } | 
|  | 645 | 
|  | 646 /* This is the helper function to run transition tests: | 
|  | 647 | 
|  | 648 Test page requirements: | 
|  | 649 - The body must contain an empty div with id "result" | 
|  | 650 - Call this function directly from the <script> inside the test page | 
|  | 651 | 
|  | 652 Function parameters: | 
|  | 653     expected [required]: an array of arrays defining a set of CSS properties tha
     t must have given values at specific times (see below) | 
|  | 654     callback [optional]: a function to be executed just before the test starts (
     none by default) | 
|  | 655 | 
|  | 656     Each sub-array must contain these items in this order: | 
|  | 657     - the time in seconds at which to snapshot the CSS property | 
|  | 658     - the id of the element on which to get the CSS property value | 
|  | 659     - the name of the CSS property to get [1] | 
|  | 660     - the expected value for the CSS property | 
|  | 661     - the tolerance to use when comparing the effective CSS property value with 
     its expected value | 
|  | 662 | 
|  | 663     [1] If the CSS property name is "-webkit-transform", expected value must be 
     an array of 1 or more numbers corresponding to the matrix elements, | 
|  | 664     or a string which will be compared directly (useful if the expected value is
      "none") | 
|  | 665     If the CSS property name is "-webkit-transform.N", expected value must be a 
     number corresponding to the Nth element of the matrix | 
|  | 666 | 
|  | 667 */ | 
|  | 668 function runTransitionTest(expected, callback, usePauseAPI, doPixelTest) { | 
|  | 669     expected = expected.map(function(expectation) { expectation.unshift(null); r
     eturn expectation; }); | 
|  | 670     isTransitionsTest = true; | 
|  | 671     runAnimationTest(expected, callback, undefined, !usePauseAPI, doPixelTest); | 
|  | 672 } | 
| OLD | NEW | 
|---|