Merge pull request #1271 from hikaru-y/preload-images

Preload answer images
This commit is contained in:
Damien Elmes 2021-07-04 15:50:55 +10:00 committed by GitHub
commit 209a646d63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 4 deletions

View File

@ -171,6 +171,7 @@ class Previewer(QDialog):
return return
c = self.card() c = self.card()
func = "_showQuestion" func = "_showQuestion"
ans_txt = ""
if not c: if not c:
txt = tr.qt_misc_please_select_1_card() txt = tr.qt_misc_please_select_1_card()
bodyclass = "" bodyclass = ""
@ -188,10 +189,11 @@ class Previewer(QDialog):
# need to force reload even if answer # need to force reload even if answer
txt = c.question(reload=True) txt = c.question(reload=True)
ans_txt = c.answer()
if self._state == "answer": if self._state == "answer":
func = "_showAnswer" func = "_showAnswer"
txt = c.answer() txt = ans_txt
txt = re.sub(r"\[\[type:[^]]+\]\]", "", txt) txt = re.sub(r"\[\[type:[^]]+\]\]", "", txt)
bodyclass = theme_manager.body_classes_for_card_ord(c.ord) 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 = self.mw.prepare_card_text_for_display(txt)
txt = gui_hooks.card_will_show(txt, c, f"preview{self._state.capitalize()}") txt = gui_hooks.card_will_show(txt, c, f"preview{self._state.capitalize()}")
self._last_state = self._state_and_mod() 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 self._card_changed = False
def _on_show_both_sides(self, toggle: bool) -> None: def _on_show_both_sides(self, toggle: bool) -> None:

View File

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

@ -338,8 +338,11 @@ class Reviewer:
self._run_state_mutation_hook() self._run_state_mutation_hook()
bodyclass = theme_manager.body_classes_for_card_ord(c.ord) 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_flag_icon()
self._update_mark_icon() self._update_mark_icon()
self._showAnswerButton() self._showAnswerButton()