summaryrefslogtreecommitdiffstats
path: root/dom/base/test/file_domwindowutils_animation.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/base/test/file_domwindowutils_animation.html217
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>