gecko-dev/layout/style/test/test_restyles_in_smil_animation.html
Hiroyuki Ikezoe ee7fe17000 Bug 1275142 - Don't create animate SVG along with its parent element at the same time. r=birtles
If we create an animate SVG along with its parent, in rare cases,
the animation does not start in the first frame, i.e, it's the frame
that the animated element and its parent element are created. In such
cases, restyle for the animation is not observed in the first frame.
To avoid it, we need to create parent element in the first place,
then, append an animated element into the parent in the next frame.

MozReview-Commit-ID: 3GPDxX4cmkQ

--HG--
extra : rebase_source : 5cfa60deb3661df443ffd07c8e39d50752ab47f8
2016-06-27 10:57:27 +09:00

104 lines
2.9 KiB
HTML

<!doctype html>
<head>
<meta charset=utf-8>
<title>Tests restyles in smil animation</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/SpawnTask.js"></script>
<script src="/tests/SimpleTest/paint_listener.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
</head>
<body>
<div id="target-div">
<svg>
<rect id="svg-rect" width="100%" height="100%" fill="lime"/>
</svg>
</div>
<script>
"use strict";
function waitForAnimationFrames(frameCount) {
return new Promise(function(resolve, reject) {
function handleFrame() {
if (--frameCount <= 0) {
resolve();
} else {
window.requestAnimationFrame(handleFrame); // wait another frame
}
}
window.requestAnimationFrame(handleFrame);
});
}
function observeStyling(frameCount) {
var Ci = SpecialPowers.Ci;
var docShell =
SpecialPowers.wrap(window).QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
docShell.recordProfileTimelineMarkers = true;
docShell.popProfileTimelineMarkers();
return new Promise(function(resolve) {
return waitForAnimationFrames(frameCount).then(function() {
var markers = docShell.popProfileTimelineMarkers();
docShell.recordProfileTimelineMarkers = false;
var stylingMarkers = markers.filter(function(marker, index) {
return marker.restyleHint == "eRestyle_SVGAttrAnimations";
});
resolve(stylingMarkers);
});
});
}
function ensureElementRemoval(aElement) {
return new Promise(function(resolve) {
aElement.remove();
waitForAllPaintsFlushed(resolve);
});
}
function waitForPaintFlushed() {
return new Promise(function(resolve) {
waitForAllPaintsFlushed(resolve);
});
}
SimpleTest.waitForExplicitFinish();
add_task(function* smil_is_in_display_none_subtree() {
yield waitForPaintFlushed();
var animate =
document.createElementNS("http://www.w3.org/2000/svg", "animate");
animate.setAttribute("attributeType", "XML");
animate.setAttribute("attributeName", "fill");
animate.setAttribute("values", "red;lime");
animate.setAttribute("dur", "1s");
animate.setAttribute("repeatCount", "indefinite");
document.getElementById("svg-rect").appendChild(animate);
yield waitForPaintFlushed();
var displayMarkers = yield observeStyling(5);
is(displayMarkers.length, 5, "should restyle in every frame");
var div = document.getElementById("target-div");
div.style.display = "none";
getComputedStyle(div).display;
var displayNoneMarkers = yield observeStyling(5);
is(displayNoneMarkers.length, 0, "should never restyle if display:none");
div.style.display = "";
getComputedStyle(div).display;
var displayAgainMarkers = yield observeStyling(5);
is(displayAgainMarkers.length, 5, "should restyle again");
yield ensureElementRemoval(animate);
});
</script>
</body>