зеркало из https://github.com/mozilla/gecko-dev.git
218 строки
7.5 KiB
HTML
218 строки
7.5 KiB
HTML
<!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>
|