--- a/dom/animation/test/css-animations/file_keyframeeffect-getframes.html
+++ b/dom/animation/test/css-animations/file_keyframeeffect-getframes.html
@@ -10,18 +10,18 @@
}
@keyframes anim-only-timing {
from { animation-timing-function: linear; }
to { }
}
@keyframes anim-only-non-animatable {
- from { display: none; }
- to { display: inline; }
+ from { animation-duration: 3s; }
+ to { animation-duration: 5s; }
}
@keyframes anim-simple {
from { color: black; }
to { color: white; }
}
@keyframes anim-simple-three {
@@ -54,16 +54,23 @@
@keyframes anim-omit-from {
to { color: blue; }
}
@keyframes anim-omit-from-to {
50% { color: blue; }
}
+@keyframes anim-partially-omit-to {
+ from { margin-top: 50px;
+ margin-bottom: 100px; }
+ to { margin-top: 150px !important; /* ignored */
+ margin-bottom: 200px; }
+}
+
@keyframes anim-different-props {
from { color: black; margin-top: 8px; }
25% { color: blue; }
75% { margin-top: 12px; }
to { color: white; margin-top: 16px }
}
@keyframes anim-different-props-and-easing {
@@ -95,31 +102,57 @@
from { margin-top: 0px; animation-timing-function: steps(1, end); }
from { margin-right: 0px; animation-timing-function: step-end; }
from { margin-bottom: 0px; animation-timing-function: steps(1); }
50% { margin-top: 10px; animation-timing-function: step-end; }
50% { margin-right: 10px; animation-timing-function: step-end; }
50% { margin-bottom: 10px; animation-timing-function: step-end; }
to { margin-top: 20px; margin-right: 20px; margin-bottom: 20px; }
}
+
+@keyframes anim-overriding {
+ from { padding-top: 50px }
+ 50%, from { padding-top: 30px } /* wins: 0% */
+ 75%, 85%, 50% { padding-top: 20px } /* wins: 75%, 50% */
+ 100%, 85% { padding-top: 70px } /* wins: 100% */
+ 85.1% { padding-top: 60px } /* wins: 85.1% */
+ 85% { padding-top: 30px } /* wins: 85% */
+}
+
+@keyframes anim-filter {
+ to { filter: blur(5px) sepia(60%) saturate(30%); }
+}
+
+@keyframes anim-text-shadow {
+ to { text-shadow: none; }
+}
+
+@keyframes anim-background-size {
+ to { background-size: 50%, 6px, contain }
+}
</style>
<body>
<script>
"use strict";
function getFrames(e) {
return e.getAnimations()[0].effect.getFrames();
}
function assert_frames_equal(a, b, name) {
assert_equals(Object.keys(a).sort().toString(),
Object.keys(b).sort().toString(),
"properties on " + name);
for (var p in a) {
- assert_equals(a[p], b[p], "value for '" + p + "' on " + name);
+ if (p === 'offset' || p === 'computedOffset') {
+ assert_approx_equals(a[p], b[p], 0.00001,
+ "value for '" + p + "' on " + name);
+ } else {
+ assert_equals(a[p], b[p], "value for '" + p + "' on " + name);
+ }
}
}
// animation-timing-function values to test with, where the value
// is exactly the same as its serialization, sorted by the order
// getFrames() will group frames with the same easing function
// together (by nsTimingFunction::Compare).
const kTimingFunctionValues = [
@@ -137,17 +170,16 @@ const kTimingFunctionValues = [
"steps(2)",
"steps(2, end)",
"cubic-bezier(0, 0, 1, 1)",
"cubic-bezier(0, 0.25, 0.75, 1)",
];
test(function(t) {
var div = addDiv(t);
- var frames;
div.style.animation = 'anim-empty 100s';
assert_equals(getFrames(div).length, 0,
"number of frames with empty @keyframes");
div.style.animation = 'anim-empty-frames 100s';
assert_equals(getFrames(div).length, 0,
"number of frames when @keyframes has empty keyframes");
@@ -168,20 +200,18 @@ test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-simple 100s';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
- { offset: 0, computedOffset: 0, easing: "ease",
- color: "rgb(0, 0, 0)" },
- { offset: 1, computedOffset: 1, easing: "linear",
- color: "rgb(255, 255, 255)" },
+ { offset: 0, computedOffset: 0, easing: "ease", color: "black" },
+ { offset: 1, computedOffset: 1, easing: "ease", color: "white" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for a simple ' +
'animation');
@@ -190,17 +220,17 @@ test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-simple-three 100s ' + easing;
var frames = getFrames(div);
assert_equals(frames.length, 3, "number of frames");
for (var i = 0; i < frames.length; i++) {
- assert_equals(frames[i].easing, i == frames.length - 1 ? "linear" : easing,
+ assert_equals(frames[i].easing, easing,
"value for 'easing' on ComputedKeyframe #" + i);
}
});
}, 'KeyframeEffectReadOnly.getFrames() returns frames with expected easing ' +
'values, when the easing comes from animation-timing-function on the ' +
'element');
test(function(t) {
@@ -209,52 +239,52 @@ test(function(t) {
div.style.animation = 'anim-simple-timing 100s';
var frames = getFrames(div);
assert_equals(frames.length, 3, "number of frames");
assert_equals(frames[0].easing, "linear",
"value of 'easing' on ComputedKeyframe #0");
assert_equals(frames[1].easing, "ease-in-out",
"value of 'easing' on ComputedKeyframe #1");
- assert_equals(frames[2].easing, "linear",
+ assert_equals(frames[2].easing, "step-end",
"value of 'easing' on ComputedKeyframe #2");
}, 'KeyframeEffectReadOnly.getFrames() returns frames with expected easing ' +
'values, when the easing is specified on each keyframe');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-simple-timing-some 100s step-start';
var frames = getFrames(div);
assert_equals(frames.length, 3, "number of frames");
assert_equals(frames[0].easing, "linear",
"value of 'easing' on ComputedKeyframe #0");
assert_equals(frames[1].easing, "step-start",
"value of 'easing' on ComputedKeyframe #1");
- assert_equals(frames[2].easing, "linear",
+ assert_equals(frames[2].easing, "step-start",
"value of 'easing' on ComputedKeyframe #2");
}, 'KeyframeEffectReadOnly.getFrames() returns frames with expected easing ' +
'values, when the easing is specified on some keyframes');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-simple-shorthand 100s';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease",
- marginTop: "8px", marginRight: "8px",
- marginBottom: "8px", marginLeft: "8px" },
- { offset: 1, computedOffset: 1, easing: "linear",
- marginTop: "16px", marginRight: "16px",
- marginBottom: "16px", marginLeft: "16px" },
+ marginBottom: "8px", marginLeft: "8px",
+ marginRight: "8px", marginTop: "8px" },
+ { offset: 1, computedOffset: 1, easing: "ease",
+ marginBottom: "16px", marginLeft: "16px",
+ marginRight: "16px", marginTop: "16px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for a simple ' +
'animation that specifies a single shorthand property');
@@ -263,19 +293,18 @@ test(function(t) {
div.style.animation = 'anim-omit-to 100s';
div.style.color = 'white';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
- { offset: 0, computedOffset: 0, easing: "ease",
- color: "rgb(0, 0, 255)" },
- { offset: 1, computedOffset: 1, easing: "linear",
+ { offset: 0, computedOffset: 0, easing: "ease", color: "blue" },
+ { offset: 1, computedOffset: 1, easing: "ease",
color: "rgb(255, 255, 255)" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with a 0% keyframe and no 100% keyframe');
@@ -287,18 +316,17 @@ test(function(t) {
div.style.color = 'white';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease",
color: "rgb(255, 255, 255)" },
- { offset: 1, computedOffset: 1, easing: "linear",
- color: "rgb(0, 0, 255)" },
+ { offset: 1, computedOffset: 1, easing: "ease", color: "blue" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with a 100% keyframe and no 0% keyframe');
@@ -307,47 +335,69 @@ test(function(t) {
div.style.animation = 'anim-omit-from-to 100s';
div.style.color = 'white';
var frames = getFrames(div);
assert_equals(frames.length, 3, "number of frames");
var expected = [
- { offset: 0, computedOffset: 0, easing: "ease",
+ { offset: 0, computedOffset: 0, easing: "ease",
color: "rgb(255, 255, 255)" },
- { offset: 0.5, computedOffset: 0.5, easing: "ease",
- color: "rgb(0, 0, 255)" },
- { offset: 1, computedOffset: 1, easing: "linear",
+ { offset: 0.5, computedOffset: 0.5, easing: "ease", color: "blue" },
+ { offset: 1, computedOffset: 1, easing: "ease",
color: "rgb(255, 255, 255)" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with no 0% or 100% keyframe but with a 50% keyframe');
test(function(t) {
var div = addDiv(t);
+ div.style.animation = 'anim-partially-omit-to 100s';
+ div.style.marginTop = '250px';
+ var frames = getFrames(div);
+
+ assert_equals(frames.length, 2, "number of frames");
+
+ var expected = [
+ { offset: 0, computedOffset: 0, easing: "ease",
+ marginTop: '50px', marginBottom: '100px' },
+ { offset: 1, computedOffset: 1, easing: "ease",
+ marginTop: '250px', marginBottom: '200px' },
+ ];
+
+ for (var i = 0; i < frames.length; i++) {
+ assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
+ }
+}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
+ 'animation with a partially complete 100% keyframe (because the ' +
+ '!important rule is ignored)');
+
+test(function(t) {
+ var div = addDiv(t);
+
div.style.animation = 'anim-different-props 100s';
var frames = getFrames(div);
assert_equals(frames.length, 4, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease",
- color: "rgb(0, 0, 0)", marginTop: "8px" },
+ color: "black", marginTop: "8px" },
{ offset: 0.25, computedOffset: 0.25, easing: "ease",
- color: "rgb(0, 0, 255)" },
+ color: "blue" },
{ offset: 0.75, computedOffset: 0.75, easing: "ease",
marginTop: "12px" },
- { offset: 1, computedOffset: 1, easing: "linear",
- color: "rgb(255, 255, 255)", marginTop: "16px" },
+ { offset: 1, computedOffset: 1, easing: "ease",
+ color: "white", marginTop: "16px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with different properties on different keyframes, all ' +
'with the same easing function');
@@ -357,23 +407,23 @@ test(function(t) {
div.style.animation = 'anim-different-props-and-easing 100s';
var frames = getFrames(div);
assert_equals(frames.length, 4, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "linear",
- color: "rgb(0, 0, 0)", marginTop: "8px" },
+ color: "black", marginTop: "8px" },
{ offset: 0.25, computedOffset: 0.25, easing: "step-end",
- color: "rgb(0, 0, 255)" },
+ color: "blue" },
{ offset: 0.75, computedOffset: 0.75, easing: "ease-in",
marginTop: "12px" },
- { offset: 1, computedOffset: 1, easing: "linear",
- color: "rgb(255, 255, 255)", marginTop: "16px" },
+ { offset: 1, computedOffset: 1, easing: "ease",
+ color: "white", marginTop: "16px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with different properties on different keyframes, with ' +
'a different easing function on each');
@@ -383,19 +433,19 @@ test(function(t) {
div.style.animation = 'anim-merge-offset 100s';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease",
- color: "rgb(0, 0, 0)", marginTop: "8px" },
- { offset: 1, computedOffset: 1, easing: "linear",
- color: "rgb(255, 255, 255)", marginTop: "16px" },
+ color: "black", marginTop: "8px" },
+ { offset: 1, computedOffset: 1, easing: "ease",
+ color: "white", marginTop: "16px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with multiple keyframes for the same time, and all with ' +
'the same easing function');
@@ -404,22 +454,22 @@ test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-merge-offset-and-easing 100s';
var frames = getFrames(div);
assert_equals(frames.length, 3, "number of frames");
var expected = [
+ { offset: 0, computedOffset: 0, easing: "step-end",
+ color: "black", fontSize: "16px" },
{ offset: 0, computedOffset: 0, easing: "linear",
marginTop: "8px", paddingLeft: "2px" },
- { offset: 0, computedOffset: 0, easing: "step-end",
- color: "rgb(0, 0, 0)", fontSize: "16px" },
- { offset: 1, computedOffset: 1, easing: "linear",
- color: "rgb(255, 255, 255)", fontSize: "32px", marginTop: "16px",
+ { offset: 1, computedOffset: 1, easing: "ease",
+ color: "white", fontSize: "32px", marginTop: "16px",
paddingLeft: "4px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with multiple keyframes for the same time and with ' +
@@ -429,30 +479,146 @@ test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-no-merge-equiv-easing 100s';
var frames = getFrames(div);
assert_equals(frames.length, 5, "number of frames");
var expected = [
+ { offset: 0, computedOffset: 0, easing: "steps(1, end)",
+ marginTop: "0px" },
{ offset: 0, computedOffset: 0, easing: "step-end",
marginRight: "0px" },
{ offset: 0, computedOffset: 0, easing: "steps(1)",
marginBottom: "0px" },
- { offset: 0, computedOffset: 0, easing: "steps(1, end)",
- marginTop: "0px" },
{ offset: 0.5, computedOffset: 0.5, easing: "step-end",
marginTop: "10px", marginRight: "10px", marginBottom: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear",
+ { offset: 1, computedOffset: 1, easing: "ease",
marginTop: "20px", marginRight: "20px", marginBottom: "20px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with multiple keyframes for the same time and with ' +
'different but equivalent easing functions');
+test(function(t) {
+ var div = addDiv(t);
+
+ div.style.animation = 'anim-overriding 100s';
+ var frames = getFrames(div);
+
+ assert_equals(frames.length, 6, "number of frames");
+
+ var expected = [
+ { offset: 0, computedOffset: 0, easing: "ease",
+ paddingTop: "30px" },
+ { offset: 0.5, computedOffset: 0.5, easing: "ease",
+ paddingTop: "20px" },
+ { offset: 0.75, computedOffset: 0.75, easing: "ease",
+ paddingTop: "20px" },
+ { offset: 0.85, computedOffset: 0.85, easing: "ease",
+ paddingTop: "30px" },
+ { offset: 0.851, computedOffset: 0.851, easing: "ease",
+ paddingTop: "60px" },
+ { offset: 1, computedOffset: 1, easing: "ease",
+ paddingTop: "70px" },
+ ];
+
+ for (var i = 0; i < frames.length; i++) {
+ assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
+ }
+}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for ' +
+ 'overlapping keyframes');
+
+// Gecko-specific test case: We are specifically concerned here that the
+// computed value for filter, "none", is correctly represented.
+
+test(function(t) {
+ var div = addDiv(t);
+
+ div.style.animation = 'anim-filter 100s';
+ var frames = getFrames(div);
+
+ assert_equals(frames.length, 2, "number of frames");
+
+ var expected = [
+ { offset: 0, computedOffset: 0, easing: "ease",
+ filter: "none" },
+ { offset: 1, computedOffset: 1, easing: "ease",
+ filter: "blur(5px) sepia(60%) saturate(30%)" },
+ ];
+
+ for (var i = 0; i < frames.length; i++) {
+ assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
+ }
+}, 'KeyframeEffectReadOnly.getFrames() returns expected values for ' +
+ 'animations with filter properties and missing keyframes');
+
+// Gecko-specific test case: We are specifically concerned here that the
+// computed value for text-shadow and a "none" specified on a keyframe
+// are correctly represented.
+
+test(function(t) {
+ var div = addDiv(t);
+
+ div.style.textShadow = '1px 1px 2px black, 0 0 16px blue, 0 0 3.2px blue';
+ div.style.animation = 'anim-text-shadow 100s';
+ var frames = getFrames(div);
+
+ assert_equals(frames.length, 2, "number of frames");
+
+ var expected = [
+ { offset: 0, computedOffset: 0, easing: "ease",
+ textShadow: "1px 1px 2px 0px rgb(0, 0, 0),"
+ + " 0px 0px 16px 0px rgb(0, 0, 255),"
+ + " 0px 0px 3.2px 0px rgb(0, 0, 255)" },
+ { offset: 1, computedOffset: 1, easing: "ease", textShadow: "none" },
+ ];
+
+ for (var i = 0; i < frames.length; i++) {
+ assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
+ }
+}, 'KeyframeEffectReadOnly.getFrames() returns expected values for ' +
+ 'animations with text-shadow properties and missing keyframes');
+
+// Gecko-specific test case: We are specifically concerned here that the
+// initial value for background-size and the specified list are correctly
+// represented.
+
+test(function(t) {
+ var div = addDiv(t);
+
+ div.style.animation = 'anim-background-size 100s';
+ var frames = getFrames(div);
+
+ assert_equals(frames.length, 2, "number of frames");
+
+ var expected = [
+ { offset: 0, computedOffset: 0, easing: "ease",
+ backgroundSize: "auto auto" },
+ { offset: 1, computedOffset: 1, easing: "ease",
+ backgroundSize: "50% auto, 6px auto, contain" },
+ ];
+
+ for (var i = 0; i < frames.length; i++) {
+ assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
+ }
+
+ // Test inheriting a background-size value
+
+ expected[0].backgroundSize = div.style.backgroundSize =
+ "30px auto, 40% auto, auto auto";
+ frames = getFrames(div);
+
+ for (var i = 0; i < frames.length; i++) {
+ assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i
+ + " after updating current style");
+ }
+}, 'KeyframeEffectReadOnly.getFrames() returns expected values for ' +
+ 'animations with background-size properties and missing keyframes');
+
done();
</script>
</body>