Create reviewer/images.ts

This commit is contained in:
Henrik Giesel 2021-07-12 16:57:51 +02:00
parent 5cbb582d0b
commit ee1a1c35fb
2 changed files with 52 additions and 48 deletions

49
ts/reviewer/images.ts Normal file
View file

@ -0,0 +1,49 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
function injectPreloadLink(href: string, as: string): void {
const link = document.createElement("link");
link.rel = "preload";
link.href = href;
link.as = as;
document.head.appendChild(link);
}
export function allImagesLoaded(): Promise<void[]> {
return Promise.all(
Array.from(document.getElementsByTagName("img")).map(imageLoaded)
);
}
function imageLoaded(img: HTMLImageElement): Promise<void> {
return img.complete
? Promise.resolve()
: new Promise((resolve) => {
img.addEventListener("load", () => resolve());
img.addEventListener("error", () => resolve());
});
}
function clearPreloadLinks(): void {
document.head
.querySelectorAll("link[rel='preload']")
.forEach((link) => link.remove());
}
function extractImageSrcs(html: string): string[] {
const fragment = document.createRange().createContextualFragment(html);
const srcs = [...fragment.querySelectorAll("img[src]")].map(
(img) => (img as HTMLImageElement).src
);
return srcs;
}
export function preloadAnswerImages(qHtml: string, aHtml: string): void {
clearPreloadLinks();
const aSrcs = extractImageSrcs(aHtml);
if (aSrcs.length) {
const qSrcs = extractImageSrcs(qHtml);
const diff = aSrcs.filter((src) => !qSrcs.includes(src));
diff.forEach((src) => injectPreloadLink(src, "image"));
}
}

View file

@ -4,9 +4,11 @@
import "css-browser-selector/css_browser_selector";
import "jquery/dist/jquery";
import { bridgeCommand } from "lib/bridgecommand";
export { mutateNextCardStates } from "./answering";
import { bridgeCommand } from "lib/bridgecommand";
import { allImagesLoaded, preloadAnswerImages } from "./images";
declare const MathJax: any;
type Callback = () => void | Promise<void>;
@ -202,53 +204,6 @@ export function _emulateMobile(enabled: boolean): void {
}
}
function allImagesLoaded(): Promise<void[]> {
return Promise.all(
Array.from(document.getElementsByTagName("img")).map(imageLoaded)
);
}
function imageLoaded(img: HTMLImageElement): Promise<void> {
return img.complete
? Promise.resolve()
: new Promise((resolve) => {
img.addEventListener("load", () => resolve());
img.addEventListener("error", () => resolve());
});
}
function scrollToAnswer(): void {
document.getElementById("answer")?.scrollIntoView();
}
function injectPreloadLink(href: string, as: string): void {
const link = document.createElement("link");
link.rel = "preload";
link.href = href;
link.as = as;
document.head.appendChild(link);
}
function clearPreloadLinks(): void {
document.head
.querySelectorAll("link[rel='preload']")
.forEach((link) => link.remove());
}
function extractImageSrcs(html: string): string[] {
const fragment = document.createRange().createContextualFragment(html);
const srcs = [...fragment.querySelectorAll("img[src]")].map(
(img) => (img as HTMLImageElement).src
);
return srcs;
}
function preloadAnswerImages(qHtml: string, aHtml: string): void {
clearPreloadLinks();
const aSrcs = extractImageSrcs(aHtml);
if (aSrcs.length) {
const qSrcs = extractImageSrcs(qHtml);
const diff = aSrcs.filter((src) => !qSrcs.includes(src));
diff.forEach((src) => injectPreloadLink(src, "image"));
}
}