Preload images to be displayed on answer side

This commit is contained in:
hikaru-y 2021-07-02 05:45:19 +09:00
parent 3581ee8f95
commit 9782d39ced
3 changed files with 50 additions and 4 deletions

View File

@ -171,6 +171,7 @@ class Previewer(QDialog):
return
c = self.card()
func = "_showQuestion"
ans_txt = ""
if not c:
txt = tr.qt_misc_please_select_1_card()
bodyclass = ""
@ -188,10 +189,11 @@ class Previewer(QDialog):
# need to force reload even if answer
txt = c.question(reload=True)
ans_txt = c.answer()
if self._state == "answer":
func = "_showAnswer"
txt = c.answer()
txt = ans_txt
txt = re.sub(r"\[\[type:[^]]+\]\]", "", txt)
bodyclass = theme_manager.body_classes_for_card_ord(c.ord)
@ -218,7 +220,14 @@ class Previewer(QDialog):
txt = self.mw.prepare_card_text_for_display(txt)
txt = gui_hooks.card_will_show(txt, c, f"preview{self._state.capitalize()}")
self._last_state = self._state_and_mod()
self._web.eval(f"{func}({json.dumps(txt)},'{bodyclass}');")
js: str
if self._state == "question":
ans_txt = self.mw.col.media.escape_media_filenames(ans_txt)
js = f"{func}({json.dumps(txt)}, {json.dumps(ans_txt)}, '{bodyclass}');"
else:
js = f"{func}({json.dumps(txt)}, '{bodyclass}');"
self._web.eval(js)
self._card_changed = False
def _on_show_both_sides(self, toggle: bool) -> None:

View File

@ -100,7 +100,7 @@ async function _updateQA(
await _runHook(onShownHook);
}
function _showQuestion(q: string, bodyclass: string): void {
function _showQuestion(q: string, a: string, bodyclass: string): void {
_queueAction(() =>
_updateQA(
q,
@ -117,6 +117,8 @@ function _showQuestion(q: string, bodyclass: string): void {
if (typeans) {
typeans.focus();
}
// preload images
allImagesLoaded().then(() => preloadAnswerImages(q, a));
}
)
);
@ -203,3 +205,35 @@ function imageLoaded(img: HTMLImageElement): Promise<void> {
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"));
}
}

View File

@ -339,8 +339,11 @@ class Reviewer:
self._run_state_mutation_hook()
bodyclass = theme_manager.body_classes_for_card_ord(c.ord)
a = self.mw.col.media.escape_media_filenames(c.answer())
self.web.eval(f"_showQuestion({json.dumps(q)},'{bodyclass}');")
self.web.eval(
f"_showQuestion({json.dumps(q)}, {json.dumps(a)}, '{bodyclass}');"
)
self._update_flag_icon()
self._update_mark_icon()
self._showAnswerButton()