223 lines
5.6 KiB
HTML
223 lines
5.6 KiB
HTML
<!doctype html>
|
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<script src="/tests/SimpleTest/WindowSnapshot.js"></script>
|
|
<!--
|
|
scrolling=no is just paranoia to ensure that we don't get invalidations
|
|
due to scrollbars
|
|
-->
|
|
<iframe scrolling="no" id="iframe"></iframe>
|
|
<script>
|
|
SimpleTest.waitForExplicitFinish();
|
|
|
|
// We hit an optimized path in WebRender that doesn't cause a repaint on the
|
|
// main thread:
|
|
//
|
|
// https://searchfox.org/mozilla-central/rev/b7f3977978922d44c7d92ae01c0d4cc2baca7bc2/layout/style/ImageLoader.cpp#553
|
|
//
|
|
// So our assertions and polling need to be a bit weaker on WR.
|
|
const kUsingWebRender = SpecialPowers.DOMWindowUtils.layerManagerType.startsWith("WebRender");
|
|
|
|
let iframe = document.getElementById("iframe");
|
|
let blankSnapshot;
|
|
|
|
async function assertAnimates(html, getExpectedRepaintedElement) {
|
|
const kExpectEqual = true;
|
|
const kNumRetries = kUsingWebRender ? 600 : 30;
|
|
|
|
info("testing: " + html);
|
|
|
|
{
|
|
let load = new Promise(resolve => {
|
|
iframe.addEventListener("load", resolve, { once: true });
|
|
});
|
|
iframe.srcdoc = html;
|
|
await load;
|
|
}
|
|
|
|
// This ensures the MozAfterPaint events come through as expected.
|
|
await SimpleTest.promiseFocus(iframe.contentWindow);
|
|
|
|
let initial = await snapshotWindow(iframe.contentWindow);
|
|
|
|
let repaintedElement = getExpectedRepaintedElement(iframe.contentDocument);
|
|
if (!kUsingWebRender) {
|
|
// Ensure the painted state is clear before we start polling.
|
|
SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement);
|
|
}
|
|
|
|
{
|
|
let [equal, s1 /* , s2, differentPixels, maxDiff */] = compareSnapshots(initial, blankSnapshot, kExpectEqual);
|
|
ok(!equal, "Initial snapshot shouldn't be blank");
|
|
info(s1);
|
|
}
|
|
|
|
let foundDifferent = false;
|
|
let foundInitialAgain = false;
|
|
for (let i = 0; i < kNumRetries; ++i) {
|
|
let current = await snapshotWindow(iframe.contentWindow);
|
|
let [equal, /* s1 */, s2 /* , differentPixels, maxDiff */ ] = compareSnapshots(initial, current, kExpectEqual);
|
|
if (!foundDifferent && !equal) {
|
|
ok(true, `Found different image after ${i} retries`);
|
|
ok(kUsingWebRender || SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement), "Should've repainted the expected element");
|
|
info(s2);
|
|
foundDifferent = true;
|
|
}
|
|
|
|
// Ensure that we go back to the initial state (animated1.gif) is an
|
|
// infinite gif.
|
|
if (foundDifferent && equal) {
|
|
ok(true, `Found same image again after ${i} retries`);
|
|
ok(kUsingWebRender || SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement), "Should've repainted the expected element");
|
|
foundInitialAgain = true;
|
|
break;
|
|
}
|
|
|
|
await new Promise(resolve => {
|
|
if (kUsingWebRender) {
|
|
requestAnimationFrame(() => {
|
|
requestAnimationFrame(resolve);
|
|
});
|
|
} else {
|
|
iframe.contentWindow.addEventListener("MozAfterPaint", resolve, { once: true });
|
|
}
|
|
});
|
|
}
|
|
|
|
ok(foundDifferent && foundInitialAgain, `Should've found a different snapshot and then an equal one, after ${kNumRetries} retries`);
|
|
}
|
|
|
|
const kTests = [
|
|
// Sanity test: background-image on a regular element.
|
|
{
|
|
html: `
|
|
<!doctype html>
|
|
<style>
|
|
div {
|
|
width: 100px;
|
|
height: 100px;
|
|
background-image: url(animated1.gif);
|
|
}
|
|
</style>
|
|
<div></div>
|
|
`,
|
|
element(doc) {
|
|
return doc.querySelector("div");
|
|
},
|
|
},
|
|
|
|
// bug 1627585: content: url()
|
|
{
|
|
html: `
|
|
<!doctype html>
|
|
<style>
|
|
div::before {
|
|
content: url(animated1.gif);
|
|
}
|
|
</style>
|
|
<div></div>
|
|
`,
|
|
element(doc) {
|
|
return doc.querySelector("div");
|
|
},
|
|
},
|
|
|
|
// bug 1627585: content: url() (on an element directly)
|
|
{
|
|
html: `
|
|
<!doctype html>
|
|
<style>
|
|
div {
|
|
content: url(animated1.gif);
|
|
}
|
|
</style>
|
|
<div></div>
|
|
`,
|
|
element(doc) {
|
|
return doc.querySelector("div");
|
|
},
|
|
},
|
|
|
|
// bug 1625571: background propagated to canvas.
|
|
{
|
|
html: `
|
|
<!doctype html>
|
|
<style>
|
|
body {
|
|
background-image: url(animated1.gif);
|
|
}
|
|
</style>
|
|
`,
|
|
element(doc) {
|
|
return doc.documentElement;
|
|
},
|
|
},
|
|
|
|
// bug 1719375: CSS animation in SVG image.
|
|
{
|
|
html: `
|
|
<!doctype html>
|
|
<style>
|
|
div {
|
|
width: 100px;
|
|
height: 100px;
|
|
background-image: url(animated1.svg);
|
|
}
|
|
</style>
|
|
<div></div>
|
|
`,
|
|
element(doc) {
|
|
return doc.querySelector("div");
|
|
},
|
|
},
|
|
|
|
// bug 1730834: stopped window.
|
|
{
|
|
html: `
|
|
<!doctype html>
|
|
<style>
|
|
div {
|
|
width: 100px;
|
|
height: 100px;
|
|
}
|
|
</style>
|
|
<body onload="window.stop(); document.querySelector('div').style.backgroundImage = 'url(animated1.gif)';">
|
|
<div></div>
|
|
</body>
|
|
`,
|
|
element(doc) {
|
|
return doc.querySelector("div");
|
|
},
|
|
},
|
|
|
|
// bug 1731138: Animated mask
|
|
{
|
|
html: `
|
|
<!doctype html>
|
|
<style>
|
|
div {
|
|
width: 100px;
|
|
height: 100px;
|
|
background-color: lime;
|
|
mask-clip: border-box;
|
|
mask-size: 100% 100%;
|
|
mask-image: url(animatedMask.gif);
|
|
}
|
|
</style>
|
|
<div></div>
|
|
`,
|
|
element(doc) {
|
|
return doc.querySelector("div");
|
|
},
|
|
},
|
|
];
|
|
|
|
onload = async function() {
|
|
// First snapshot the blank window.
|
|
blankSnapshot = await snapshotWindow(iframe.contentWindow);
|
|
|
|
for (let { html, element } of kTests)
|
|
await assertAnimates(html, element);
|
|
|
|
SimpleTest.finish();
|
|
}
|
|
</script>
|