diff options
Diffstat (limited to 'dom/base/test/file_domwindowutils_animation.html')
-rw-r--r-- | dom/base/test/file_domwindowutils_animation.html | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/dom/base/test/file_domwindowutils_animation.html b/dom/base/test/file_domwindowutils_animation.html new file mode 100644 index 0000000000..dfcc8fc05c --- /dev/null +++ b/dom/base/test/file_domwindowutils_animation.html @@ -0,0 +1,217 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title>DOMWindowUtils test with animation</title> + <script src="/tests/SimpleTest/paint_listener.js"></script> + <script src="/tests/dom/animation/test/testcommon.js"></script> +</head> +<body> +<script type="application/javascript"> + +const SimpleTest = window.opener.SimpleTest; +const utils = SpecialPowers.getDOMWindowUtils(window); +const next = window.opener.next; +const is = window.opener.is; +const ok = window.opener.ok; + +function addStyle(rules) { + const extraStyle = document.createElement("style"); + document.head.appendChild(extraStyle); + rules.forEach(rule => { + extraStyle.sheet.insertRule(rule, extraStyle.sheet.cssRules.length); + }); +} + +function deleteStyle() { + document.head.querySelector("style").remove(); +} + + +function test_getUnanimatedComputedStyle() { + [ + { + property: "opacity", + keyframes: [1, 0], + expectedInitialStyle: "1", + expectedDuringTransitionStyle: "0", + isDiscrete: false, + }, + { + property: "clear", + keyframes: ["left", "inline-end"], + expectedInitialStyle: "none", + expectedDuringTransitionStyle: "inline-end", + isDiscrete: true, + }, + ].forEach(testcase => { + const { property, keyframes, expectedInitialStyle, + expectedDuringTransitionStyle, isDiscrete } = testcase; + + [null, "unset", "initial", "inherit"].forEach(initialStyle => { + const scriptAnimation = target => { + return target.animate({ [property]: keyframes }, 1000); + } + checkUnanimatedComputedStyle(property, initialStyle, null, + expectedInitialStyle, expectedInitialStyle, + scriptAnimation, "script animation"); + + const cssAnimationStyle = `@keyframes cssanimation {` + + ` from { ${property}: ${ keyframes[0] }; }` + + ` to { ${property}: ${ keyframes[1] }; } }`; + addStyle([cssAnimationStyle]); + const cssAnimation = target => { + target.style.animation = "cssanimation 1s"; + return target.getAnimations()[0]; + } + checkUnanimatedComputedStyle(property, initialStyle, null, + expectedInitialStyle, expectedInitialStyle, + cssAnimation, "CSS Animations"); + deleteStyle(); + + // We don't support discrete animations for CSS Transitions yet. + // (bug 1320854) + if (!isDiscrete) { + const cssTransition = target => { + target.style[property] = keyframes[0]; + target.style.transition = + `${ property } 1s`; + window.getComputedStyle(target)[property]; + target.style[property] = keyframes[1]; + return target.getAnimations()[0]; + } + checkUnanimatedComputedStyle(property, initialStyle, null, + expectedInitialStyle, + expectedDuringTransitionStyle, + cssTransition, "CSS Transitions"); + } + + addStyle([cssAnimationStyle, + ".pseudo::before { content: '' }", + ".animation::before { animation: cssanimation 1s }"]); + const pseudoAnimation = target => { + target.classList.add("animation"); + return target.getAnimations({ subtree: true })[0]; + } + checkUnanimatedComputedStyle(property, initialStyle, "::before", + expectedInitialStyle, expectedInitialStyle, + pseudoAnimation, "Animation at pseudo"); + deleteStyle(); + }); + }); + + const div = document.createElement("div"); + document.body.appendChild(div); + + SimpleTest.doesThrow( + () => utils.getUnanimatedComputedStyle(div, null, "background", utils.FLUSH_NONE), + "NS_ERROR_INVALID_ARG", + "Shorthand property should throw"); + + SimpleTest.doesThrow( + () => utils.getUnanimatedComputedStyle(div, null, "invalid", utils.FLUSH_NONE), + "NS_ERROR_INVALID_ARG", + "Invalid property should throw"); + + SimpleTest.doesThrow( + () => utils.getUnanimatedComputedStyle(null, null, "opacity", utils.FLUSH_NONE), + "NS_ERROR_INVALID_ARG", + "Null element should throw"); + + SimpleTest.doesThrow( + () => utils.getUnanimatedComputedStyle(div, null, "opacity", utils.FLUSH_LAYOUT), + "NS_ERROR_INVALID_ARG", + "FLUSH_LAYOUT option should throw"); + + SimpleTest.doesThrow( + () => utils.getUnanimatedComputedStyle(div, null, "opacity", utils.FLUSH_DISPLAY), + "NS_ERROR_INVALID_ARG", + "FLUSH_DISPLAY option should throw"); + + SimpleTest.doesThrow( + () => utils.getUnanimatedComputedStyle(div, "::before", "opacity", utils.FLUSH_NONE), + "NS_ERROR_FAILURE", + "Non-existent pseudo should throw"); + + // Flush styles since getUnanimatedComputedStyle flushes pending styles even + // with FLUSH_NONE option if the element hasn't yet styled. + getComputedStyle(div).opacity; + + div.style.opacity = "0"; + is(utils.getUnanimatedComputedStyle(div, null, "opacity", utils.FLUSH_NONE), + "1", + "getUnanimatedComputedStyle with FLUSH_NONE should not flush pending styles"); + + is(utils.getUnanimatedComputedStyle(div, null, "opacity", utils.FLUSH_STYLE), + "0", + "getUnanimatedComputedStyle with FLUSH_STYLE should flush pending styles"); + + div.remove(); + + test_needsFlushWithThrottledAnimations(); +} + +function checkUnanimatedComputedStyle(property, initialStyle, pseudoType, + expectedBeforeAnimation, + expectedDuringAnimation, + animate, animationType) { + const div = document.createElement("div"); + document.body.appendChild(div); + + if (initialStyle) { + div.style[property] = initialStyle; + } + if (pseudoType) { + div.classList.add("pseudo"); + } + + is(utils.getUnanimatedComputedStyle(div, pseudoType, property, utils.FLUSH_STYLE), + expectedBeforeAnimation, + `'${ property }' property with '${ initialStyle }' style ` + + `should be '${ expectedBeforeAnimation }' ` + + `before animating by ${ animationType }`); + + const animation = animate(div); + animation.currentTime = 500; + is(utils.getUnanimatedComputedStyle(div, pseudoType, property, utils.FLUSH_STYLE), + expectedDuringAnimation, + `'${ property }' property with '${ initialStyle }' style ` + + `should be '${ expectedDuringAnimation }' ` + + `even while animating by ${ animationType }`); + + div.remove(); +} + +function test_needsFlushWithThrottledAnimations() { + const div = document.createElement("div"); + div.style = "width: 100px; height: 100px; background-color: blue;"; + document.body.appendChild(div); + + const animation = div.animate({ opacity: [ 0, 1 ] }, + { duration: 100000, iterations: Infinity }); + waitForAnimationReadyToRestyle(animation).then(() => { + ok(SpecialPowers.wrap(animation).isRunningOnCompositor, + "Opacity animation should run on the compositor"); + + // FIXME! Bug 1442861: We should make sure needsFlush() returns true + // before flusing layout. + //ok(utils.needsFlush(SpecialPowers.Ci.nsIDOMWindowUtils.FLUSH_STYLE), + // "needsFlush should return true if there is an animation on the compositor"); + + // Flush layout. + document.documentElement.getBoundingClientRect(); + + ok(!utils.needsFlush(SpecialPowers.Ci.nsIDOMWindowUtils.FLUSH_STYLE), + "needsFlush should return false after flushing layout"); + + div.remove(); + next(); + window.close(); + }); +} + +window.addEventListener("load", test_getUnanimatedComputedStyle); + +</script> +</body> +</html> |