2021-07-12 16:57:51 +02:00
|
|
|
// Copyright: Ankitects Pty Ltd and contributors
|
|
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
|
2023-05-10 05:26:02 +02:00
|
|
|
const template = document.createElement("template");
|
2021-07-12 16:57:51 +02:00
|
|
|
|
|
|
|
export function allImagesLoaded(): Promise<void[]> {
|
|
|
|
return Promise.all(
|
2021-10-19 01:06:00 +02:00
|
|
|
Array.from(document.getElementsByTagName("img")).map(imageLoaded),
|
2021-07-12 16:57:51 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function imageLoaded(img: HTMLImageElement): Promise<void> {
|
|
|
|
return img.complete
|
|
|
|
? Promise.resolve()
|
|
|
|
: new Promise((resolve) => {
|
2022-11-28 00:33:04 +01:00
|
|
|
img.addEventListener("load", () => resolve());
|
|
|
|
img.addEventListener("error", () => resolve());
|
|
|
|
});
|
2021-07-12 16:57:51 +02:00
|
|
|
}
|
|
|
|
|
2023-05-10 05:26:02 +02:00
|
|
|
function extractImageSrcs(fragment: DocumentFragment): string[] {
|
2021-07-12 16:57:51 +02:00
|
|
|
const srcs = [...fragment.querySelectorAll("img[src]")].map(
|
2021-10-19 01:06:00 +02:00
|
|
|
(img) => (img as HTMLImageElement).src,
|
2021-07-12 16:57:51 +02:00
|
|
|
);
|
|
|
|
return srcs;
|
|
|
|
}
|
|
|
|
|
2023-05-10 05:26:02 +02:00
|
|
|
function createImage(src: string): HTMLImageElement {
|
|
|
|
const img = new Image();
|
|
|
|
img.src = src;
|
|
|
|
return img;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function preloadAnswerImages(html: string): void {
|
|
|
|
template.innerHTML = html;
|
|
|
|
extractImageSrcs(template.content).forEach(createImage);
|
2021-07-12 16:57:51 +02:00
|
|
|
}
|
2022-11-04 01:07:51 +01:00
|
|
|
|
2023-05-10 05:26:02 +02:00
|
|
|
/** Prevent flickering & layout shift on image load */
|
|
|
|
export function preloadImages(fragment: DocumentFragment): Promise<void>[] {
|
|
|
|
return extractImageSrcs(fragment).map(createImage).map(imageLoaded);
|
2022-11-04 01:07:51 +01:00
|
|
|
}
|