Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /html/semantics/embedded-content/the-img-element/update-the-image-data/lazy-out-of-band-load.html - WPT Dashboard Interop Dashboard
<!doctype html>
<title>Lazy loaded image doesn't get loaded eagerly, or get image data, after another image gets loaded with the same source</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<div style="height: 1000vh"></div>
<div id="below-viewport"></div>
<script>
// The lazy image's load is never triggered, so it stays at step 25 of update the
// image data and its current request's state stays unavailable. That means no
// load or error event, and also no image data: the state only becomes partially
// or completely available via step 27, which is reached by fetching, or via step
// 7, which also fires a load event.
async function run_test(prop, image, placement, t) {
let value = `${image.path}?lazy-out-of-band-load-` + Math.random();
let lazy = document.createElement("img")
lazy[prop] = value;
lazy.loading = "lazy";
lazy.addEventListener("error", t.unreached_func("error: should never try to load"));
lazy.addEventListener("load", t.unreached_func("load: should never try to load"));
if (placement == "display-none") {
lazy.style.display = "none";
document.body.appendChild(lazy);
} else {
document.getElementById("below-viewport").appendChild(lazy);
}
await new Promise(r => t.step_timeout(r, 100));
assert_equals(lazy.naturalWidth, 0, "lazy image starts out deferred with no natural width");
// now load another image with the same src, but not lazy.
let img = document.createElement("img");
img[prop] = value;
await new Promise(r => {
img.addEventListener("load", r, { once: true });
img.addEventListener("error", r, { once: true });
document.body.appendChild(img);
});
// Without this the image data assertions below would also pass if nothing
// loaded at all.
if (image.loads)
assert_greater_than(img.naturalWidth, 0, "out of band image has a natural width");
// Wait a bit to make sure we don't get a broken load.
await new Promise(r => t.step_timeout(r, 100));
assert_false(lazy.complete, "lazy image is not complete");
assert_equals(lazy.naturalWidth, 0, "lazy image has no natural width");
assert_equals(lazy.naturalHeight, 0, "lazy image has no natural height");
}
const images = [
{ path: "/images/green.png", loads: true },
{ path: "/images/not-found", loads: false },
];
for (let prop of ["src", "srcset"]) {
for (let image of images) {
for (let placement of ["display-none", "below-viewport"]) {
promise_test(t => run_test(prop, image, placement, t),
`${prop} = ${image.path}, ${placement}`);
}
}
}
</script>