From af12756980d32f73dc8b608ff1b27409b6ea8f87 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 5 Jul 2021 12:45:44 +0200 Subject: [PATCH 01/16] Move reviewer to ts/reviewer --- qt/aqt/data/web/css/BUILD.bazel | 9 + qt/aqt/data/web/js/BUILD.bazel | 6 +- qt/aqt/data/web/js/reviewer.ts | 240 ----------------- qt/aqt/reviewer.py | 6 +- ts/editor/BUILD.bazel | 1 + ts/reviewer/BUILD.bazel | 20 +- ts/reviewer/index.ts | 244 +++++++++++++++++- ts/reviewer/index_wrapper.ts | 8 + .../web/css => ts/reviewer}/reviewer.scss | 0 9 files changed, 279 insertions(+), 255 deletions(-) delete mode 100644 qt/aqt/data/web/js/reviewer.ts create mode 100644 ts/reviewer/index_wrapper.ts rename {qt/aqt/data/web/css => ts/reviewer}/reviewer.scss (100%) diff --git a/qt/aqt/data/web/css/BUILD.bazel b/qt/aqt/data/web/css/BUILD.bazel index e29acf7ed..6ac2deb4c 100644 --- a/qt/aqt/data/web/css/BUILD.bazel +++ b/qt/aqt/data/web/css/BUILD.bazel @@ -26,11 +26,20 @@ copy_files_into_group( package = "//ts/editor", ) +copy_files_into_group( + name = "reviewer", + srcs = [ + "reviewer.css", + ], + package = "//ts/reviewer", +) + filegroup( name = "css", srcs = [ "css_local", "editor", + "reviewer", ], visibility = ["//qt:__subpackages__"], ) diff --git a/qt/aqt/data/web/js/BUILD.bazel b/qt/aqt/data/web/js/BUILD.bazel index 20db65237..c46de6f84 100644 --- a/qt/aqt/data/web/js/BUILD.bazel +++ b/qt/aqt/data/web/js/BUILD.bazel @@ -38,9 +38,9 @@ copy_files_into_group( ) copy_files_into_group( - name = "reviewer_extras", + name = "reviewer", srcs = [ - "reviewer_extras.js", + "reviewer.js", ], package = "//ts/reviewer", ) @@ -50,8 +50,8 @@ filegroup( srcs = [ "aqt_es5", "editor", + "reviewer", "mathjax.js", - "reviewer_extras", "//qt/aqt/data/web/js/vendor", ], visibility = ["//qt:__subpackages__"], diff --git a/qt/aqt/data/web/js/reviewer.ts b/qt/aqt/data/web/js/reviewer.ts deleted file mode 100644 index 92fb7ee2a..000000000 --- a/qt/aqt/data/web/js/reviewer.ts +++ /dev/null @@ -1,240 +0,0 @@ -/* Copyright: Ankitects Pty Ltd and contributors - * License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */ - -declare var MathJax: any; - -type Callback = () => void | Promise; - -var ankiPlatform = "desktop"; -var typeans: HTMLElement | undefined; -var _updatingQueue: Promise = Promise.resolve(); - -var onUpdateHook: Array; -var onShownHook: Array; - -function _runHook(arr: Array): Promise { - const promises = []; - - for (let i = 0; i < arr.length; i++) { - promises.push(arr[i]()); - } - - return Promise.all(promises); -} - -function _queueAction(action: Callback): void { - _updatingQueue = _updatingQueue.then(action); -} - -function setInnerHTML(element: Element, html: string): void { - for (const oldVideo of element.getElementsByTagName("video")) { - oldVideo.pause(); - - while (oldVideo.firstChild) { - oldVideo.removeChild(oldVideo.firstChild); - } - - oldVideo.load(); - } - - element.innerHTML = html; - - for (const oldScript of element.getElementsByTagName("script")) { - const newScript = document.createElement("script"); - - for (const attribute of oldScript.attributes) { - newScript.setAttribute(attribute.name, attribute.value); - } - - newScript.appendChild(document.createTextNode(oldScript.innerHTML)); - oldScript.parentNode.replaceChild(newScript, oldScript); - } -} - -async function _updateQA( - html: string, - _unusused: unknown, - onupdate: Callback, - onshown: Callback -): Promise { - onUpdateHook = [onupdate]; - onShownHook = [onshown]; - - const qa = document.getElementById("qa")!; - const renderError = - (kind: string) => - (error: Error): void => { - const errorMessage = String(error).substring(0, 2000); - const errorStack = String(error.stack).substring(0, 2000); - qa.innerHTML = - `Invalid ${kind} on card: ${errorMessage}\n${errorStack}`.replace( - /\n/g, - "
" - ); - }; - - // hide current card - qa.style.opacity = "0"; - - // update card - try { - setInnerHTML(qa, html); - } catch (error) { - renderError("HTML")(error); - } - - await _runHook(onUpdateHook); - - // wait for mathjax to ready - await MathJax.startup.promise - .then(() => { - // clear MathJax buffers from previous typesets - MathJax.typesetClear(); - - return MathJax.typesetPromise([qa]); - }) - .catch(renderError("MathJax")); - - // and reveal card when processing is done - qa.style.opacity = "1"; - await _runHook(onShownHook); -} - -function _showQuestion(q: string, a: string, bodyclass: string): void { - _queueAction(() => - _updateQA( - q, - null, - function () { - // return to top of window - window.scrollTo(0, 0); - - document.body.className = bodyclass; - }, - function () { - // focus typing area if visible - typeans = document.getElementById("typeans"); - if (typeans) { - typeans.focus(); - } - // preload images - allImagesLoaded().then(() => preloadAnswerImages(q, a)); - } - ) - ); -} - -function _showAnswer(a: string, bodyclass: string): void { - _queueAction(() => - _updateQA( - a, - null, - function () { - if (bodyclass) { - // when previewing - document.body.className = bodyclass; - } - - // avoid scrolling to the answer until images load - allImagesLoaded().then(scrollToAnswer); - }, - function () {} - ) - ); -} - -const _flagColours = { - 1: "#e25252", - 2: "#ffb347", - 3: "#54c414", - 4: "#578cff", - 5: "#ff82ee", - 6: "#00d1b5", - 7: "#9649dd", -}; - -function _drawFlag(flag: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7): void { - const elem = document.getElementById("_flag"); - if (flag === 0) { - elem.setAttribute("hidden", ""); - return; - } - elem.removeAttribute("hidden"); - elem.style.color = _flagColours[flag]; -} - -function _drawMark(mark: boolean): void { - const elem = document.getElementById("_mark"); - if (!mark) { - elem.setAttribute("hidden", ""); - } else { - elem.removeAttribute("hidden"); - } -} - -function _typeAnsPress(): void { - const code = (window.event as KeyboardEvent).code; - if (["Enter", "NumpadEnter"].includes(code)) { - pycmd("ans"); - } -} - -function _emulateMobile(enabled: boolean): void { - const list = document.documentElement.classList; - if (enabled) { - list.add("mobile"); - } else { - list.remove("mobile"); - } -} - -function allImagesLoaded(): Promise { - return Promise.all( - Array.from(document.getElementsByTagName("img")).map(imageLoaded) - ); -} - -function imageLoaded(img: HTMLImageElement): Promise { - 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")); - } -} diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index fa540c55b..f598740db 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -288,12 +288,8 @@ class Reviewer: self.revHtml(), css=["css/reviewer.css"], js=[ - "js/vendor/jquery.min.js", - "js/vendor/css_browser_selector.min.js", - "js/mathjax.js", - "js/vendor/mathjax/tex-chtml.js", + "js/vendor/protobuf.min.js", "js/reviewer.js", - "js/reviewer_extras.js", ], context=self, ) diff --git a/ts/editor/BUILD.bazel b/ts/editor/BUILD.bazel index 15946689b..278acdf5e 100644 --- a/ts/editor/BUILD.bazel +++ b/ts/editor/BUILD.bazel @@ -33,6 +33,7 @@ compile_sass( visibility = ["//visibility:public"], deps = [ "//ts/sass:scrollbar_lib", + "//ts/sass/codemirror", ], ) diff --git a/ts/reviewer/BUILD.bazel b/ts/reviewer/BUILD.bazel index 76bec83ff..798268bae 100644 --- a/ts/reviewer/BUILD.bazel +++ b/ts/reviewer/BUILD.bazel @@ -5,6 +5,16 @@ load("//ts/svelte:svelte.bzl", "svelte", "svelte_check") load("//ts:esbuild.bzl", "esbuild") load("//ts:compile_sass.bzl", "compile_sass") +compile_sass( + srcs = [ + "reviewer.scss", + ], + group = "reviewer_scss", + visibility = ["//visibility:public"], + deps = [], +) + + ts_library( name = "lib", srcs = glob(["*.ts"]), @@ -12,12 +22,18 @@ ts_library( ) esbuild( - name = "reviewer_extras", + name = "reviewer", + srcs = [ + "//ts:protobuf-shim.js", + ], args = [ "--resolve-extensions=.mjs,.js", "--log-level=warning", ], - entry_point = "index.ts", + entry_point = "index_wrapper.ts", + external = [ + "protobufjs/light", + ], visibility = ["//visibility:public"], deps = [ ":lib", diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index ebe6a96fb..aa060a7d4 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -1,9 +1,243 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -// This is a temporary extra file we load separately from reviewer.ts. Once -// reviewer.ts has been migrated into ts/, the code here can be merged into -// it. +import { bridgeCommand } from "lib/bridgecommand"; +export { mutateNextCardStates } from "./answering"; -import { mutateNextCardStates } from "./answering"; -globalThis.anki = { ...globalThis.anki, mutateNextCardStates }; +declare const MathJax: any; + +type Callback = () => void | Promise; + +export const ankiPlatform = "desktop"; +export let typeans: HTMLElement | undefined; +let _updatingQueue: Promise = Promise.resolve(); + +export const onUpdateHook: Array = []; +export const onShownHook: Array = []; + +function _runHook(arr: Array): Promise { + const promises: (Promise | void)[] = []; + + for (let i = 0; i < arr.length; i++) { + promises.push(arr[i]()); + } + + return Promise.all(promises); +} + +function _queueAction(action: Callback): void { + _updatingQueue = _updatingQueue.then(action); +} + +function setInnerHTML(element: Element, html: string): void { + for (const oldVideo of element.getElementsByTagName("video")) { + oldVideo.pause(); + + while (oldVideo.firstChild) { + oldVideo.removeChild(oldVideo.firstChild); + } + + oldVideo.load(); + } + + element.innerHTML = html; + + for (const oldScript of element.getElementsByTagName("script")) { + const newScript = document.createElement("script"); + + for (const attribute of oldScript.attributes) { + newScript.setAttribute(attribute.name, attribute.value); + } + + newScript.appendChild(document.createTextNode(oldScript.innerHTML)); + oldScript.parentNode!.replaceChild(newScript, oldScript); + } +} + +async function _updateQA( + html: string, + _unusused: unknown, + onupdate: Callback, + onshown: Callback +): Promise { + onUpdateHook.splice(0, Infinity, onupdate); + onShownHook.splice(0, Infinity, onshown); + + const qa = document.getElementById("qa")!; + const renderError = + (kind: string) => + (error: Error): void => { + const errorMessage = String(error).substring(0, 2000); + const errorStack = String(error.stack).substring(0, 2000); + qa.innerHTML = + `Invalid ${kind} on card: ${errorMessage}\n${errorStack}`.replace( + /\n/g, + "
" + ); + }; + + // hide current card + qa.style.opacity = "0"; + + // update card + try { + setInnerHTML(qa, html); + } catch (error) { + renderError("HTML")(error); + } + + await _runHook(onUpdateHook); + + // wait for mathjax to ready + await MathJax.startup.promise + .then(() => { + // clear MathJax buffers from previous typesets + MathJax.typesetClear(); + + return MathJax.typesetPromise([qa]); + }) + .catch(renderError("MathJax")); + + // and reveal card when processing is done + qa.style.opacity = "1"; + await _runHook(onShownHook); +} + +export function _showQuestion(q: string, a: string, bodyclass: string): void { + _queueAction(() => + _updateQA( + q, + null, + function () { + // return to top of window + window.scrollTo(0, 0); + + document.body.className = bodyclass; + }, + function () { + // focus typing area if visible + typeans = document.getElementById("typeans") as HTMLElement; + if (typeans) { + typeans.focus(); + } + // preload images + allImagesLoaded().then(() => preloadAnswerImages(q, a)); + } + ) + ); +} + +export function _showAnswer(a: string, bodyclass: string): void { + _queueAction(() => + _updateQA( + a, + null, + function () { + if (bodyclass) { + // when previewing + document.body.className = bodyclass; + } + + // avoid scrolling to the answer until images load + allImagesLoaded().then(scrollToAnswer); + }, + function () {} + ) + ); +} + +const _flagColours = { + 1: "#e25252", + 2: "#ffb347", + 3: "#54c414", + 4: "#578cff", + 5: "#ff82ee", + 6: "#00d1b5", + 7: "#9649dd", +}; + +export function _drawFlag(flag: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7): void { + const elem = document.getElementById("_flag")!; + if (flag === 0) { + elem.setAttribute("hidden", ""); + return; + } + elem.removeAttribute("hidden"); + elem.style.color = _flagColours[flag]; +} + +export function _drawMark(mark: boolean): void { + const elem = document.getElementById("_mark")!; + if (!mark) { + elem.setAttribute("hidden", ""); + } else { + elem.removeAttribute("hidden"); + } +} + +export function _typeAnsPress(): void { + const code = (window.event as KeyboardEvent).code; + if (["Enter", "NumpadEnter"].includes(code)) { + bridgeCommand("ans"); + } +} + +export function _emulateMobile(enabled: boolean): void { + const list = document.documentElement.classList; + if (enabled) { + list.add("mobile"); + } else { + list.remove("mobile"); + } +} + +function allImagesLoaded(): Promise { + return Promise.all( + Array.from(document.getElementsByTagName("img")).map(imageLoaded) + ); +} + +function imageLoaded(img: HTMLImageElement): Promise { + 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")); + } +} diff --git a/ts/reviewer/index_wrapper.ts b/ts/reviewer/index_wrapper.ts new file mode 100644 index 000000000..13b2ec606 --- /dev/null +++ b/ts/reviewer/index_wrapper.ts @@ -0,0 +1,8 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html + +// extend the global namespace with our exports - not sure if there's a better way with esbuild +import * as globals from "./index"; +for (const key in globals) { + window[key] = globals[key]; +} diff --git a/qt/aqt/data/web/css/reviewer.scss b/ts/reviewer/reviewer.scss similarity index 100% rename from qt/aqt/data/web/css/reviewer.scss rename to ts/reviewer/reviewer.scss From afa8f8a6f0af83e062aa6d8e1132c0e9a1d408a2 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 12 Jul 2021 15:00:36 +0200 Subject: [PATCH 02/16] Export getTypedAnswer --- qt/aqt/reviewer.py | 2 +- ts/reviewer/index.ts | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index f598740db..a670495ad 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -694,7 +694,7 @@ class Reviewer: return s def _getTypedAnswer(self) -> None: - self.web.evalWithCallback("typeans ? typeans.value : null", self._onTypedAnswer) + self.web.evalWithCallback("getTypedAnswer();", self._onTypedAnswer) def _onTypedAnswer(self, val: None) -> None: self.typedAnswer = val or "" diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index aa060a7d4..45159af4d 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -8,13 +8,16 @@ declare const MathJax: any; type Callback = () => void | Promise; -export const ankiPlatform = "desktop"; -export let typeans: HTMLElement | undefined; -let _updatingQueue: Promise = Promise.resolve(); - export const onUpdateHook: Array = []; export const onShownHook: Array = []; +export const ankiPlatform = "desktop"; +let typeans: HTMLInputElement | undefined; + +export function getTypedAnswer(): string | null { + return typeans?.value ?? null; +} + function _runHook(arr: Array): Promise { const promises: (Promise | void)[] = []; @@ -25,6 +28,8 @@ function _runHook(arr: Array): Promise { return Promise.all(promises); } +let _updatingQueue: Promise = Promise.resolve(); + function _queueAction(action: Callback): void { _updatingQueue = _updatingQueue.then(action); } @@ -60,8 +65,11 @@ async function _updateQA( onupdate: Callback, onshown: Callback ): Promise { - onUpdateHook.splice(0, Infinity, onupdate); - onShownHook.splice(0, Infinity, onshown); + onUpdateHook.length = 0; + onUpdateHook.push(onupdate); + + onShownHook.length = 0; + onShownHook.push(onshown); const qa = document.getElementById("qa")!; const renderError = @@ -116,7 +124,7 @@ export function _showQuestion(q: string, a: string, bodyclass: string): void { }, function () { // focus typing area if visible - typeans = document.getElementById("typeans") as HTMLElement; + typeans = document.getElementById("typeans") as HTMLInputElement; if (typeans) { typeans.focus(); } From f203562c58320eb6caaafa33abba2bbc95916f64 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 12 Jul 2021 15:26:28 +0200 Subject: [PATCH 03/16] Include protobuf in clayout and browser (p)reviewer --- qt/aqt/browser/previewer.py | 1 + qt/aqt/clayout.py | 1 + 2 files changed, 2 insertions(+) diff --git a/qt/aqt/browser/previewer.py b/qt/aqt/browser/previewer.py index 693cd2279..b18512267 100644 --- a/qt/aqt/browser/previewer.py +++ b/qt/aqt/browser/previewer.py @@ -129,6 +129,7 @@ class Previewer(QDialog): "js/vendor/css_browser_selector.min.js", "js/mathjax.js", "js/vendor/mathjax/tex-chtml.js", + "js/vendor/protobuf.min.js", "js/reviewer.js", ] self._web.stdHtml( diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py index 4c69299e1..0f2077bc2 100644 --- a/qt/aqt/clayout.py +++ b/qt/aqt/clayout.py @@ -335,6 +335,7 @@ class CardLayout(QDialog): "js/vendor/css_browser_selector.min.js", "js/mathjax.js", "js/vendor/mathjax/tex-chtml.js", + "js/vendor/protobuf.min.js", "js/reviewer.js", ] self.preview_web.stdHtml( From 68ac505d8198286702cbc429b1d2298b505f944d Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 12 Jul 2021 16:04:27 +0200 Subject: [PATCH 04/16] Include css-browser-selector via ts/reviewer --- qt/aqt/browser/previewer.py | 1 - qt/aqt/clayout.py | 1 - ts/reviewer/BUILD.bazel | 10 +++++++--- ts/reviewer/index.ts | 2 ++ 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/qt/aqt/browser/previewer.py b/qt/aqt/browser/previewer.py index b18512267..02fbe35af 100644 --- a/qt/aqt/browser/previewer.py +++ b/qt/aqt/browser/previewer.py @@ -126,7 +126,6 @@ class Previewer(QDialog): def _setup_web_view(self) -> None: jsinc = [ "js/vendor/jquery.min.js", - "js/vendor/css_browser_selector.min.js", "js/mathjax.js", "js/vendor/mathjax/tex-chtml.js", "js/vendor/protobuf.min.js", diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py index 0f2077bc2..f951f8e4d 100644 --- a/qt/aqt/clayout.py +++ b/qt/aqt/clayout.py @@ -332,7 +332,6 @@ class CardLayout(QDialog): jsinc = [ "js/vendor/jquery.min.js", - "js/vendor/css_browser_selector.min.js", "js/mathjax.js", "js/vendor/mathjax/tex-chtml.js", "js/vendor/protobuf.min.js", diff --git a/ts/reviewer/BUILD.bazel b/ts/reviewer/BUILD.bazel index 798268bae..e90e5f6c1 100644 --- a/ts/reviewer/BUILD.bazel +++ b/ts/reviewer/BUILD.bazel @@ -16,9 +16,13 @@ compile_sass( ts_library( - name = "lib", + name = "reviewer_ts", srcs = glob(["*.ts"]), - deps = ["//ts/lib"], + deps = [ + "//ts/lib", + "//ts/lib:backend_proto", + "@npm//css-browser-selector", + ], ) esbuild( @@ -36,7 +40,7 @@ esbuild( ], visibility = ["//visibility:public"], deps = [ - ":lib", + ":reviewer_ts", "//ts/lib", "@npm//protobufjs", ], diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index 45159af4d..52a8e46d8 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -1,6 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +import "css-browser-selector/css_browser_selector"; + import { bridgeCommand } from "lib/bridgecommand"; export { mutateNextCardStates } from "./answering"; From 5cbb582d0b62259aceb25ddd62e133b6a4cf62c1 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 12 Jul 2021 16:49:32 +0200 Subject: [PATCH 05/16] Export jquery via ts/reviewer --- qt/aqt/browser/previewer.py | 1 - qt/aqt/clayout.py | 1 - ts/reviewer/BUILD.bazel | 1 + ts/reviewer/index.ts | 1 + 4 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qt/aqt/browser/previewer.py b/qt/aqt/browser/previewer.py index 02fbe35af..cd21fd4c2 100644 --- a/qt/aqt/browser/previewer.py +++ b/qt/aqt/browser/previewer.py @@ -125,7 +125,6 @@ class Previewer(QDialog): def _setup_web_view(self) -> None: jsinc = [ - "js/vendor/jquery.min.js", "js/mathjax.js", "js/vendor/mathjax/tex-chtml.js", "js/vendor/protobuf.min.js", diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py index f951f8e4d..b6ce650d2 100644 --- a/qt/aqt/clayout.py +++ b/qt/aqt/clayout.py @@ -331,7 +331,6 @@ class CardLayout(QDialog): qconnect(pform.preview_settings.clicked, self.on_preview_settings) jsinc = [ - "js/vendor/jquery.min.js", "js/mathjax.js", "js/vendor/mathjax/tex-chtml.js", "js/vendor/protobuf.min.js", diff --git a/ts/reviewer/BUILD.bazel b/ts/reviewer/BUILD.bazel index e90e5f6c1..972034642 100644 --- a/ts/reviewer/BUILD.bazel +++ b/ts/reviewer/BUILD.bazel @@ -22,6 +22,7 @@ ts_library( "//ts/lib", "//ts/lib:backend_proto", "@npm//css-browser-selector", + "@npm//jquery", ], ) diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index 52a8e46d8..3735c497d 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -2,6 +2,7 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import "css-browser-selector/css_browser_selector"; +import "jquery/dist/jquery"; import { bridgeCommand } from "lib/bridgecommand"; export { mutateNextCardStates } from "./answering"; From ee1a1c35fb20caadbc6ab457e1d72bf66c8d564a Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 12 Jul 2021 16:57:51 +0200 Subject: [PATCH 06/16] Create reviewer/images.ts --- ts/reviewer/images.ts | 49 +++++++++++++++++++++++++++++++++++++++++ ts/reviewer/index.ts | 51 +++---------------------------------------- 2 files changed, 52 insertions(+), 48 deletions(-) create mode 100644 ts/reviewer/images.ts diff --git a/ts/reviewer/images.ts b/ts/reviewer/images.ts new file mode 100644 index 000000000..d98635cf1 --- /dev/null +++ b/ts/reviewer/images.ts @@ -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 { + return Promise.all( + Array.from(document.getElementsByTagName("img")).map(imageLoaded) + ); +} + +function imageLoaded(img: HTMLImageElement): Promise { + 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")); + } +} diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index 3735c497d..20577d1ff 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -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; @@ -202,53 +204,6 @@ export function _emulateMobile(enabled: boolean): void { } } -function allImagesLoaded(): Promise { - return Promise.all( - Array.from(document.getElementsByTagName("img")).map(imageLoaded) - ); -} - -function imageLoaded(img: HTMLImageElement): Promise { - 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")); - } -} From c016f0c8d0b371b8613b2a7133027c7b324d96ec Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 12 Jul 2021 17:11:14 +0200 Subject: [PATCH 07/16] Simplify some reviewer code --- ts/reviewer/index.ts | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index 20577d1ff..178511126 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -140,6 +140,10 @@ export function _showQuestion(q: string, a: string, bodyclass: string): void { ); } +function scrollToAnswer(): void { + document.getElementById("answer")?.scrollIntoView(); +} + export function _showAnswer(a: string, bodyclass: string): void { _queueAction(() => _updateQA( @@ -159,33 +163,14 @@ export function _showAnswer(a: string, bodyclass: string): void { ); } -const _flagColours = { - 1: "#e25252", - 2: "#ffb347", - 3: "#54c414", - 4: "#578cff", - 5: "#ff82ee", - 6: "#00d1b5", - 7: "#9649dd", -}; - export function _drawFlag(flag: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7): void { const elem = document.getElementById("_flag")!; - if (flag === 0) { - elem.setAttribute("hidden", ""); - return; - } - elem.removeAttribute("hidden"); - elem.style.color = _flagColours[flag]; + elem.toggleAttribute("hidden", flag === 0); + elem.style.color = `var(--flag${flag}-fg)`; } export function _drawMark(mark: boolean): void { - const elem = document.getElementById("_mark")!; - if (!mark) { - elem.setAttribute("hidden", ""); - } else { - elem.removeAttribute("hidden"); - } + document.getElementById("_mark")!.toggleAttribute("hidden", !mark); } export function _typeAnsPress(): void { @@ -196,14 +181,5 @@ export function _typeAnsPress(): void { } export function _emulateMobile(enabled: boolean): void { - const list = document.documentElement.classList; - if (enabled) { - list.add("mobile"); - } else { - list.remove("mobile"); - } -} - -function scrollToAnswer(): void { - document.getElementById("answer")?.scrollIntoView(); + document.documentElement.classList.toggle("mobile", enabled); } From 05771b75984f78c1e28556967c43d664c72f4234 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 12 Jul 2021 22:10:40 +0200 Subject: [PATCH 08/16] Include MathJax over ts/reviewer --- qt/aqt/browser/previewer.py | 11 +++---- qt/aqt/clayout.py | 11 +++---- ts/licenses.json | 57 +++++++++++++++++++++++++++++++++++++ ts/package.json | 1 + ts/reviewer/BUILD.bazel | 2 ++ ts/reviewer/index.ts | 38 ++++++++----------------- ts/reviewer/mathjax.ts | 34 ++++++++++++++++++++++ ts/yarn.lock | 49 +++++++++++++++++++++++++++++++ 8 files changed, 163 insertions(+), 40 deletions(-) create mode 100644 ts/reviewer/mathjax.ts diff --git a/qt/aqt/browser/previewer.py b/qt/aqt/browser/previewer.py index cd21fd4c2..ec4b9cff0 100644 --- a/qt/aqt/browser/previewer.py +++ b/qt/aqt/browser/previewer.py @@ -124,16 +124,13 @@ class Previewer(QDialog): self._close_callback() def _setup_web_view(self) -> None: - jsinc = [ - "js/mathjax.js", - "js/vendor/mathjax/tex-chtml.js", - "js/vendor/protobuf.min.js", - "js/reviewer.js", - ] self._web.stdHtml( self.mw.reviewer.revHtml(), css=["css/reviewer.css"], - js=jsinc, + js=[ + "js/vendor/protobuf.min.js", + "js/reviewer.js", + ], context=self, ) self._web.set_bridge_command(self._on_bridge_cmd, self) diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py index b6ce650d2..cbf602675 100644 --- a/qt/aqt/clayout.py +++ b/qt/aqt/clayout.py @@ -330,16 +330,13 @@ class CardLayout(QDialog): ) qconnect(pform.preview_settings.clicked, self.on_preview_settings) - jsinc = [ - "js/mathjax.js", - "js/vendor/mathjax/tex-chtml.js", - "js/vendor/protobuf.min.js", - "js/reviewer.js", - ] self.preview_web.stdHtml( self.mw.reviewer.revHtml(), css=["css/reviewer.css"], - js=jsinc, + js=[ + "js/vendor/protobuf.min.js", + "js/reviewer.js", + ], context=self, ) self.preview_web.set_bridge_command(self._on_bridge_cmd, self) diff --git a/ts/licenses.json b/ts/licenses.json index 2f177c860..fdee3fc47 100644 --- a/ts/licenses.json +++ b/ts/licenses.json @@ -164,6 +164,14 @@ "path": "node_modules/commander", "licenseFile": "node_modules/commander/LICENSE" }, + "commander@8.0.0": { + "licenses": "MIT", + "repository": "https://github.com/tj/commander.js", + "publisher": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "path": "node_modules/speech-rule-engine/node_modules/commander", + "licenseFile": "node_modules/speech-rule-engine/node_modules/commander/LICENSE" + }, "css-browser-selector@0.6.5": { "licenses": "CC-BY-SA-2.5", "repository": "https://github.com/verbatim/css_browser_selector", @@ -426,6 +434,14 @@ "path": "node_modules/delaunator", "licenseFile": "node_modules/delaunator/LICENSE" }, + "esm@3.2.25": { + "licenses": "MIT", + "repository": "https://github.com/standard-things/esm", + "publisher": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "path": "node_modules/esm", + "licenseFile": "node_modules/esm/LICENSE" + }, "iconv-lite@0.6.3": { "licenses": "MIT", "repository": "https://github.com/ashtuchkin/iconv-lite", @@ -489,12 +505,31 @@ "path": "node_modules/marked", "licenseFile": "node_modules/marked/LICENSE.md" }, + "mathjax-full@3.2.0": { + "licenses": "Apache-2.0", + "repository": "https://github.com/mathjax/Mathjax-src", + "path": "node_modules/mathjax-full", + "licenseFile": "node_modules/mathjax-full/LICENSE" + }, "mathjax@3.1.4": { "licenses": "Apache-2.0", "repository": "https://github.com/mathjax/MathJax", "path": "node_modules/mathjax", "licenseFile": "node_modules/mathjax/LICENSE" }, + "mhchemparser@4.1.1": { + "licenses": "Apache-2.0", + "repository": "https://github.com/mhchem/mhchemParser", + "publisher": "Martin Hensel", + "path": "node_modules/mhchemparser", + "licenseFile": "node_modules/mhchemparser/LICENSE.txt" + }, + "mj-context-menu@0.6.1": { + "licenses": "Apache-2.0", + "repository": "https://github.com/zorkow/context-menu", + "path": "node_modules/mj-context-menu", + "licenseFile": "node_modules/mj-context-menu/README.md" + }, "protobufjs@6.11.2": { "licenses": "BSD-3-Clause", "repository": "https://github.com/protobufjs/protobuf.js", @@ -526,6 +561,28 @@ "url": "https://github.com/ChALkeR", "path": "node_modules/safer-buffer", "licenseFile": "node_modules/safer-buffer/LICENSE" + }, + "speech-rule-engine@3.3.3": { + "licenses": "Apache-2.0", + "repository": "https://github.com/zorkow/speech-rule-engine", + "path": "node_modules/speech-rule-engine", + "licenseFile": "node_modules/speech-rule-engine/LICENSE" + }, + "wicked-good-xpath@1.3.0": { + "licenses": "MIT", + "repository": "https://github.com/google/wicked-good-xpath", + "publisher": "Google Inc.", + "path": "node_modules/wicked-good-xpath", + "licenseFile": "node_modules/wicked-good-xpath/LICENSE" + }, + "xmldom-sre@0.1.31": { + "licenses": "MIT*", + "repository": "https://github.com/zorkow/xmldom", + "publisher": "jindw", + "email": "jindw@xidea.org", + "url": "http://www.xidea.org", + "path": "node_modules/xmldom-sre", + "licenseFile": "node_modules/xmldom-sre/LICENSE" } } diff --git a/ts/package.json b/ts/package.json index 1b68e2934..24722dcfc 100644 --- a/ts/package.json +++ b/ts/package.json @@ -72,6 +72,7 @@ "lodash-es": "^4.17.21", "marked": "=2.0.5", "mathjax": "^3.1.2", + "mathjax-full": "^3.2.0", "protobufjs": "^6.10.2" }, "resolutions": { diff --git a/ts/reviewer/BUILD.bazel b/ts/reviewer/BUILD.bazel index 972034642..d68a5b531 100644 --- a/ts/reviewer/BUILD.bazel +++ b/ts/reviewer/BUILD.bazel @@ -21,6 +21,7 @@ ts_library( deps = [ "//ts/lib", "//ts/lib:backend_proto", + "@npm//mathjax-full", "@npm//css-browser-selector", "@npm//jquery", ], @@ -42,6 +43,7 @@ esbuild( visibility = ["//visibility:public"], deps = [ ":reviewer_ts", + "@npm//mathjax-full", "//ts/lib", "@npm//protobufjs", ], diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index 178511126..5deec6525 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -8,8 +8,7 @@ export { mutateNextCardStates } from "./answering"; import { bridgeCommand } from "lib/bridgecommand"; import { allImagesLoaded, preloadAnswerImages } from "./images"; - -declare const MathJax: any; +import { convertMathJax } from "./mathjax"; type Callback = () => void | Promise; @@ -64,6 +63,15 @@ function setInnerHTML(element: Element, html: string): void { } } +function renderError(error: Error): string { + const errorMessage = String(error).substring(0, 2000); + const errorStack = String(error.stack).substring(0, 2000); + return `
Error while rendering card: ${errorMessage}\n${errorStack}
`.replace( + /\n/g, + "
" + ); +} + async function _updateQA( html: string, _unusused: unknown, @@ -77,40 +85,18 @@ async function _updateQA( onShownHook.push(onshown); const qa = document.getElementById("qa")!; - const renderError = - (kind: string) => - (error: Error): void => { - const errorMessage = String(error).substring(0, 2000); - const errorStack = String(error.stack).substring(0, 2000); - qa.innerHTML = - `Invalid ${kind} on card: ${errorMessage}\n${errorStack}`.replace( - /\n/g, - "
" - ); - }; // hide current card qa.style.opacity = "0"; - // update card try { - setInnerHTML(qa, html); + setInnerHTML(qa, convertMathJax(html)); } catch (error) { - renderError("HTML")(error); + setInnerHTML(qa, renderError(error)); } await _runHook(onUpdateHook); - // wait for mathjax to ready - await MathJax.startup.promise - .then(() => { - // clear MathJax buffers from previous typesets - MathJax.typesetClear(); - - return MathJax.typesetPromise([qa]); - }) - .catch(renderError("MathJax")); - // and reveal card when processing is done qa.style.opacity = "1"; await _runHook(onShownHook); diff --git a/ts/reviewer/mathjax.ts b/ts/reviewer/mathjax.ts new file mode 100644 index 000000000..f7f7546b6 --- /dev/null +++ b/ts/reviewer/mathjax.ts @@ -0,0 +1,34 @@ +import { mathjax } from "mathjax-full/js/mathjax"; +import { TeX } from "mathjax-full/js/input/tex"; +import { CHTML } from "mathjax-full/js/output/chtml"; +import { HTMLAdaptor } from "mathjax-full/js/adaptors/HTMLAdaptor"; +import { RegisterHTMLHandler } from "mathjax-full/js/handlers/html"; + +import { AllPackages } from "mathjax-full/js/input/tex/AllPackages.js"; +import "mathjax-full/js/util/entities/all"; + +const adaptor = new HTMLAdaptor(window as any); +RegisterHTMLHandler(adaptor); + +const texOptions = { + displayMath: [["\\[", "\\]"]], + processRefs: false, + processEnvironments: false, + processEscapes: false, + packages: AllPackages, +}; + +export function convertMathJax(input: string): string { + const tex = new TeX(texOptions); + const chtml = new CHTML({ + fontURL: "/_anki/js/vendor/mathjax/output/chtml/fonts/woff-v2", + }); + + const html = mathjax.document(input, { InputJax: tex, OutputJax: chtml }); + html.render(); + + return ( + adaptor.innerHTML(adaptor.head(html.document)) + + adaptor.innerHTML(adaptor.body(html.document)) + ); +} diff --git a/ts/yarn.lock b/ts/yarn.lock index fc5719c20..5688ef636 100644 --- a/ts/yarn.lock +++ b/ts/yarn.lock @@ -1596,6 +1596,11 @@ commander@7: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +commander@>=7.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.0.0.tgz#1da2139548caef59bd23e66d18908dfb54b02258" + integrity sha512-Xvf85aAtu6v22+E5hfVoLHqyul/jyxh91zvqk/ioJTQuJR7Z78n7H558vMPKanPSRgIEeZemT92I2g9Y8LPbSQ== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -2154,6 +2159,11 @@ eslint@^7.24.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" +esm@^3.2.25: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + espree@^7.3.0, espree@^7.3.1: version "7.3.1" resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" @@ -3356,6 +3366,16 @@ marked@=2.0.5, marked@^2.0.3: resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.5.tgz#2d15c759b9497b0e7b5b57f4c2edabe1002ef9e7" integrity sha512-yfCEUXmKhBPLOzEC7c+tc4XZdIeTdGoRCZakFMkCxodr7wDXqoapIME4wjcpBPJLNyUnKJ3e8rb8wlAgnLnaDw== +mathjax-full@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/mathjax-full/-/mathjax-full-3.2.0.tgz#e53269842a943d4df10502937518991268996c5c" + integrity sha512-D2EBNvUG+mJyhn+M1C858k0f2Fc4KxXvbEX2WCMXroV10212JwfYqaBJ336ECBSz5X9L5LRoamxb7AJtg3KaJA== + dependencies: + esm "^3.2.25" + mhchemparser "^4.1.0" + mj-context-menu "^0.6.1" + speech-rule-engine "^3.3.3" + mathjax@^3.1.2: version "3.1.4" resolved "https://registry.yarnpkg.com/mathjax/-/mathjax-3.1.4.tgz#4e8932d12845c0abae8b7f1976ea98cb505e8420" @@ -3376,6 +3396,11 @@ merge2@^1.3.0: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +mhchemparser@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/mhchemparser/-/mhchemparser-4.1.1.tgz#a2142fdab37a02ec8d1b48a445059287790becd5" + integrity sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA== + micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" @@ -3418,6 +3443,11 @@ minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +mj-context-menu@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/mj-context-menu/-/mj-context-menu-0.6.1.tgz#a043c5282bf7e1cf3821de07b13525ca6f85aa69" + integrity sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA== + mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -4094,6 +4124,15 @@ spdx-satisfies@^5.0.0: spdx-expression-parse "^3.0.0" spdx-ranges "^2.0.0" +speech-rule-engine@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/speech-rule-engine/-/speech-rule-engine-3.3.3.tgz#781ed03cbcf3279f94d1d80241025ea954c6d571" + integrity sha512-0exWw+0XauLjat+f/aFeo5T8SiDsO1JtwpY3qgJE4cWt+yL/Stl0WP4VNDWdh7lzGkubUD9lWP4J1ASnORXfyQ== + dependencies: + commander ">=7.0.0" + wicked-good-xpath "^1.3.0" + xmldom-sre "^0.1.31" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -4505,6 +4544,11 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +wicked-good-xpath@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz#81b0e95e8650e49c94b22298fff8686b5553cf6c" + integrity sha1-gbDpXoZQ5JyUsiKY//hoa1VTz2w= + word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -4554,6 +4598,11 @@ xmlcreate@^2.0.3: resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.3.tgz#df9ecd518fd3890ab3548e1b811d040614993497" integrity sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ== +xmldom-sre@^0.1.31: + version "0.1.31" + resolved "https://registry.yarnpkg.com/xmldom-sre/-/xmldom-sre-0.1.31.tgz#10860d5bab2c603144597d04bf2c4980e98067f4" + integrity sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" From d6393ba9960eed1e6aca04751a948525645d0dad Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Mon, 12 Jul 2021 22:23:40 +0200 Subject: [PATCH 09/16] Do not set opacity to 0 in reviewer --- ts/reviewer/index.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index 5deec6525..abb96a661 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -86,19 +86,14 @@ async function _updateQA( const qa = document.getElementById("qa")!; - // hide current card - qa.style.opacity = "0"; - try { setInnerHTML(qa, convertMathJax(html)); } catch (error) { setInnerHTML(qa, renderError(error)); } + /* TODO redunancy */ await _runHook(onUpdateHook); - - // and reveal card when processing is done - qa.style.opacity = "1"; await _runHook(onShownHook); } From ddf3adfc8ebc2cdb3e452b270cacb69afe50caa4 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Tue, 13 Jul 2021 00:14:01 +0200 Subject: [PATCH 10/16] Remove protobuf important from reiewer (no longer necessary (?)) --- qt/aqt/browser/previewer.py | 5 +---- qt/aqt/clayout.py | 5 +---- qt/aqt/reviewer.py | 5 +---- ts/editor/BUILD.bazel | 4 ++-- ts/reviewer/BUILD.bazel | 8 +------- 5 files changed, 6 insertions(+), 21 deletions(-) diff --git a/qt/aqt/browser/previewer.py b/qt/aqt/browser/previewer.py index ec4b9cff0..7421141c2 100644 --- a/qt/aqt/browser/previewer.py +++ b/qt/aqt/browser/previewer.py @@ -127,10 +127,7 @@ class Previewer(QDialog): self._web.stdHtml( self.mw.reviewer.revHtml(), css=["css/reviewer.css"], - js=[ - "js/vendor/protobuf.min.js", - "js/reviewer.js", - ], + js=["js/reviewer.js"], context=self, ) self._web.set_bridge_command(self._on_bridge_cmd, self) diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py index cbf602675..0a3fea9b4 100644 --- a/qt/aqt/clayout.py +++ b/qt/aqt/clayout.py @@ -333,10 +333,7 @@ class CardLayout(QDialog): self.preview_web.stdHtml( self.mw.reviewer.revHtml(), css=["css/reviewer.css"], - js=[ - "js/vendor/protobuf.min.js", - "js/reviewer.js", - ], + js=["js/reviewer.js"], context=self, ) self.preview_web.set_bridge_command(self._on_bridge_cmd, self) diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index a670495ad..e2ceced7d 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -287,10 +287,7 @@ class Reviewer: self.web.stdHtml( self.revHtml(), css=["css/reviewer.css"], - js=[ - "js/vendor/protobuf.min.js", - "js/reviewer.js", - ], + js=["js/reviewer.js"], context=self, ) # show answer / ease buttons diff --git a/ts/editor/BUILD.bazel b/ts/editor/BUILD.bazel index 278acdf5e..18221bd9e 100644 --- a/ts/editor/BUILD.bazel +++ b/ts/editor/BUILD.bazel @@ -133,10 +133,10 @@ esbuild( output_css = "editor.css", visibility = ["//visibility:public"], deps = [ - "base_css", - "bootstrap-icons", "editor_ts", + "base_css", "local_css", + "bootstrap-icons", "mdi-icons", "svelte_components", "//ts/components", diff --git a/ts/reviewer/BUILD.bazel b/ts/reviewer/BUILD.bazel index d68a5b531..228dd078b 100644 --- a/ts/reviewer/BUILD.bazel +++ b/ts/reviewer/BUILD.bazel @@ -29,22 +29,16 @@ ts_library( esbuild( name = "reviewer", - srcs = [ - "//ts:protobuf-shim.js", - ], args = [ "--resolve-extensions=.mjs,.js", "--log-level=warning", ], entry_point = "index_wrapper.ts", - external = [ - "protobufjs/light", - ], visibility = ["//visibility:public"], deps = [ ":reviewer_ts", - "@npm//mathjax-full", "//ts/lib", + "//ts/lib:backend_proto", "@npm//protobufjs", ], ) From ac3577455d3536a5452a6d79c358d585e2f0c6ba Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Tue, 13 Jul 2021 00:23:46 +0200 Subject: [PATCH 11/16] Satisfy eslint --- ts/reviewer/index.ts | 6 +++++- ts/reviewer/mathjax.ts | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index abb96a661..88ab8f3e0 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -1,6 +1,10 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +/* eslint +@typescript-eslint/no-non-null-assertion: "off", + */ + import "css-browser-selector/css_browser_selector"; import "jquery/dist/jquery"; @@ -139,7 +143,7 @@ export function _showAnswer(a: string, bodyclass: string): void { // avoid scrolling to the answer until images load allImagesLoaded().then(scrollToAnswer); }, - function () {} + function () {/* noop */} ) ); } diff --git a/ts/reviewer/mathjax.ts b/ts/reviewer/mathjax.ts index f7f7546b6..7fcbcfcbf 100644 --- a/ts/reviewer/mathjax.ts +++ b/ts/reviewer/mathjax.ts @@ -7,7 +7,8 @@ import { RegisterHTMLHandler } from "mathjax-full/js/handlers/html"; import { AllPackages } from "mathjax-full/js/input/tex/AllPackages.js"; import "mathjax-full/js/util/entities/all"; -const adaptor = new HTMLAdaptor(window as any); +// @ts-expect-error Minor interface mismatch: document.documentElement.nodeValue might be null +const adaptor = new HTMLAdaptor(window); RegisterHTMLHandler(adaptor); const texOptions = { From d41530f4ccdcdfb750d140a1439fa30ce2a43467 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Tue, 13 Jul 2021 00:30:20 +0200 Subject: [PATCH 12/16] Satisfy formatter --- ts/reviewer/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index 88ab8f3e0..d51eefbbf 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -143,7 +143,9 @@ export function _showAnswer(a: string, bodyclass: string): void { // avoid scrolling to the answer until images load allImagesLoaded().then(scrollToAnswer); }, - function () {/* noop */} + function () { + /* noop */ + } ) ); } From a616d0dfbc5a32bc00b67872a399ab9931582c16 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Tue, 13 Jul 2021 00:33:55 +0200 Subject: [PATCH 13/16] Add copyright header --- ts/reviewer/mathjax.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ts/reviewer/mathjax.ts b/ts/reviewer/mathjax.ts index 7fcbcfcbf..58e9d91ab 100644 --- a/ts/reviewer/mathjax.ts +++ b/ts/reviewer/mathjax.ts @@ -1,3 +1,6 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html + import { mathjax } from "mathjax-full/js/mathjax"; import { TeX } from "mathjax-full/js/input/tex"; import { CHTML } from "mathjax-full/js/output/chtml"; From 272f2f7d1a383add2ca99682bf89b3d184a2350c Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Fri, 16 Jul 2021 16:33:12 +0200 Subject: [PATCH 14/16] Revert to MathJax through script tag --- qt/aqt/browser/previewer.py | 6 +++- qt/aqt/clayout.py | 6 +++- qt/aqt/reviewer.py | 6 +++- ts/licenses.json | 57 ------------------------------------- ts/package.json | 1 - ts/reviewer/BUILD.bazel | 1 - ts/reviewer/index.ts | 36 +++++++++++++++-------- ts/reviewer/mathjax.ts | 38 ------------------------- ts/yarn.lock | 49 ------------------------------- 9 files changed, 39 insertions(+), 161 deletions(-) delete mode 100644 ts/reviewer/mathjax.ts diff --git a/qt/aqt/browser/previewer.py b/qt/aqt/browser/previewer.py index 7421141c2..b7b57f21b 100644 --- a/qt/aqt/browser/previewer.py +++ b/qt/aqt/browser/previewer.py @@ -127,7 +127,11 @@ class Previewer(QDialog): self._web.stdHtml( self.mw.reviewer.revHtml(), css=["css/reviewer.css"], - js=["js/reviewer.js"], + js=[ + "js/mathjax.js", + "js/vendor/mathjax/tex-chtml.js", + "js/reviewer.js", + ], context=self, ) self._web.set_bridge_command(self._on_bridge_cmd, self) diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py index 0a3fea9b4..20319cc3c 100644 --- a/qt/aqt/clayout.py +++ b/qt/aqt/clayout.py @@ -333,7 +333,11 @@ class CardLayout(QDialog): self.preview_web.stdHtml( self.mw.reviewer.revHtml(), css=["css/reviewer.css"], - js=["js/reviewer.js"], + js=[ + "js/mathjax.js", + "js/vendor/mathjax/tex-chtml.js", + "js/reviewer.js", + ], context=self, ) self.preview_web.set_bridge_command(self._on_bridge_cmd, self) diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index e2ceced7d..49cc3fe21 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -287,7 +287,11 @@ class Reviewer: self.web.stdHtml( self.revHtml(), css=["css/reviewer.css"], - js=["js/reviewer.js"], + js=[ + "js/mathjax.js", + "js/vendor/mathjax/tex-chtml.js", + "js/reviewer.js", + ], context=self, ) # show answer / ease buttons diff --git a/ts/licenses.json b/ts/licenses.json index fdee3fc47..2f177c860 100644 --- a/ts/licenses.json +++ b/ts/licenses.json @@ -164,14 +164,6 @@ "path": "node_modules/commander", "licenseFile": "node_modules/commander/LICENSE" }, - "commander@8.0.0": { - "licenses": "MIT", - "repository": "https://github.com/tj/commander.js", - "publisher": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "path": "node_modules/speech-rule-engine/node_modules/commander", - "licenseFile": "node_modules/speech-rule-engine/node_modules/commander/LICENSE" - }, "css-browser-selector@0.6.5": { "licenses": "CC-BY-SA-2.5", "repository": "https://github.com/verbatim/css_browser_selector", @@ -434,14 +426,6 @@ "path": "node_modules/delaunator", "licenseFile": "node_modules/delaunator/LICENSE" }, - "esm@3.2.25": { - "licenses": "MIT", - "repository": "https://github.com/standard-things/esm", - "publisher": "John-David Dalton", - "email": "john.david.dalton@gmail.com", - "path": "node_modules/esm", - "licenseFile": "node_modules/esm/LICENSE" - }, "iconv-lite@0.6.3": { "licenses": "MIT", "repository": "https://github.com/ashtuchkin/iconv-lite", @@ -505,31 +489,12 @@ "path": "node_modules/marked", "licenseFile": "node_modules/marked/LICENSE.md" }, - "mathjax-full@3.2.0": { - "licenses": "Apache-2.0", - "repository": "https://github.com/mathjax/Mathjax-src", - "path": "node_modules/mathjax-full", - "licenseFile": "node_modules/mathjax-full/LICENSE" - }, "mathjax@3.1.4": { "licenses": "Apache-2.0", "repository": "https://github.com/mathjax/MathJax", "path": "node_modules/mathjax", "licenseFile": "node_modules/mathjax/LICENSE" }, - "mhchemparser@4.1.1": { - "licenses": "Apache-2.0", - "repository": "https://github.com/mhchem/mhchemParser", - "publisher": "Martin Hensel", - "path": "node_modules/mhchemparser", - "licenseFile": "node_modules/mhchemparser/LICENSE.txt" - }, - "mj-context-menu@0.6.1": { - "licenses": "Apache-2.0", - "repository": "https://github.com/zorkow/context-menu", - "path": "node_modules/mj-context-menu", - "licenseFile": "node_modules/mj-context-menu/README.md" - }, "protobufjs@6.11.2": { "licenses": "BSD-3-Clause", "repository": "https://github.com/protobufjs/protobuf.js", @@ -561,28 +526,6 @@ "url": "https://github.com/ChALkeR", "path": "node_modules/safer-buffer", "licenseFile": "node_modules/safer-buffer/LICENSE" - }, - "speech-rule-engine@3.3.3": { - "licenses": "Apache-2.0", - "repository": "https://github.com/zorkow/speech-rule-engine", - "path": "node_modules/speech-rule-engine", - "licenseFile": "node_modules/speech-rule-engine/LICENSE" - }, - "wicked-good-xpath@1.3.0": { - "licenses": "MIT", - "repository": "https://github.com/google/wicked-good-xpath", - "publisher": "Google Inc.", - "path": "node_modules/wicked-good-xpath", - "licenseFile": "node_modules/wicked-good-xpath/LICENSE" - }, - "xmldom-sre@0.1.31": { - "licenses": "MIT*", - "repository": "https://github.com/zorkow/xmldom", - "publisher": "jindw", - "email": "jindw@xidea.org", - "url": "http://www.xidea.org", - "path": "node_modules/xmldom-sre", - "licenseFile": "node_modules/xmldom-sre/LICENSE" } } diff --git a/ts/package.json b/ts/package.json index 24722dcfc..1b68e2934 100644 --- a/ts/package.json +++ b/ts/package.json @@ -72,7 +72,6 @@ "lodash-es": "^4.17.21", "marked": "=2.0.5", "mathjax": "^3.1.2", - "mathjax-full": "^3.2.0", "protobufjs": "^6.10.2" }, "resolutions": { diff --git a/ts/reviewer/BUILD.bazel b/ts/reviewer/BUILD.bazel index 228dd078b..ebc3b79f0 100644 --- a/ts/reviewer/BUILD.bazel +++ b/ts/reviewer/BUILD.bazel @@ -21,7 +21,6 @@ ts_library( deps = [ "//ts/lib", "//ts/lib:backend_proto", - "@npm//mathjax-full", "@npm//css-browser-selector", "@npm//jquery", ], diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index d51eefbbf..297318221 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -12,7 +12,7 @@ export { mutateNextCardStates } from "./answering"; import { bridgeCommand } from "lib/bridgecommand"; import { allImagesLoaded, preloadAnswerImages } from "./images"; -import { convertMathJax } from "./mathjax"; +declare const MathJax: any; type Callback = () => void | Promise; @@ -67,14 +67,16 @@ function setInnerHTML(element: Element, html: string): void { } } -function renderError(error: Error): string { - const errorMessage = String(error).substring(0, 2000); - const errorStack = String(error.stack).substring(0, 2000); - return `
Error while rendering card: ${errorMessage}\n${errorStack}
`.replace( - /\n/g, - "
" - ); -} +const renderError = + (type: string) => + (error: Error): string => { + const errorMessage = String(error).substring(0, 2000); + const errorStack = String(error.stack).substring(0, 2000); + return `
Invalid ${type} on card: ${errorMessage}\n${errorStack}
`.replace( + /\n/g, + "
" + ); + }; async function _updateQA( html: string, @@ -91,13 +93,23 @@ async function _updateQA( const qa = document.getElementById("qa")!; try { - setInnerHTML(qa, convertMathJax(html)); + setInnerHTML(qa, html); } catch (error) { - setInnerHTML(qa, renderError(error)); + setInnerHTML(qa, renderError("html")(error)); } - /* TODO redunancy */ await _runHook(onUpdateHook); + + // wait for mathjax to ready + await MathJax.startup.promise + .then(() => { + // clear MathJax buffers from previous typesets + MathJax.typesetClear(); + + return MathJax.typesetPromise([qa]); + }) + .catch(renderError("MathJax")); + await _runHook(onShownHook); } diff --git a/ts/reviewer/mathjax.ts b/ts/reviewer/mathjax.ts deleted file mode 100644 index 58e9d91ab..000000000 --- a/ts/reviewer/mathjax.ts +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright: Ankitects Pty Ltd and contributors -// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html - -import { mathjax } from "mathjax-full/js/mathjax"; -import { TeX } from "mathjax-full/js/input/tex"; -import { CHTML } from "mathjax-full/js/output/chtml"; -import { HTMLAdaptor } from "mathjax-full/js/adaptors/HTMLAdaptor"; -import { RegisterHTMLHandler } from "mathjax-full/js/handlers/html"; - -import { AllPackages } from "mathjax-full/js/input/tex/AllPackages.js"; -import "mathjax-full/js/util/entities/all"; - -// @ts-expect-error Minor interface mismatch: document.documentElement.nodeValue might be null -const adaptor = new HTMLAdaptor(window); -RegisterHTMLHandler(adaptor); - -const texOptions = { - displayMath: [["\\[", "\\]"]], - processRefs: false, - processEnvironments: false, - processEscapes: false, - packages: AllPackages, -}; - -export function convertMathJax(input: string): string { - const tex = new TeX(texOptions); - const chtml = new CHTML({ - fontURL: "/_anki/js/vendor/mathjax/output/chtml/fonts/woff-v2", - }); - - const html = mathjax.document(input, { InputJax: tex, OutputJax: chtml }); - html.render(); - - return ( - adaptor.innerHTML(adaptor.head(html.document)) + - adaptor.innerHTML(adaptor.body(html.document)) - ); -} diff --git a/ts/yarn.lock b/ts/yarn.lock index 5688ef636..fc5719c20 100644 --- a/ts/yarn.lock +++ b/ts/yarn.lock @@ -1596,11 +1596,6 @@ commander@7: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== -commander@>=7.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.0.0.tgz#1da2139548caef59bd23e66d18908dfb54b02258" - integrity sha512-Xvf85aAtu6v22+E5hfVoLHqyul/jyxh91zvqk/ioJTQuJR7Z78n7H558vMPKanPSRgIEeZemT92I2g9Y8LPbSQ== - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -2159,11 +2154,6 @@ eslint@^7.24.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" -esm@^3.2.25: - version "3.2.25" - resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" - integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== - espree@^7.3.0, espree@^7.3.1: version "7.3.1" resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" @@ -3366,16 +3356,6 @@ marked@=2.0.5, marked@^2.0.3: resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.5.tgz#2d15c759b9497b0e7b5b57f4c2edabe1002ef9e7" integrity sha512-yfCEUXmKhBPLOzEC7c+tc4XZdIeTdGoRCZakFMkCxodr7wDXqoapIME4wjcpBPJLNyUnKJ3e8rb8wlAgnLnaDw== -mathjax-full@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/mathjax-full/-/mathjax-full-3.2.0.tgz#e53269842a943d4df10502937518991268996c5c" - integrity sha512-D2EBNvUG+mJyhn+M1C858k0f2Fc4KxXvbEX2WCMXroV10212JwfYqaBJ336ECBSz5X9L5LRoamxb7AJtg3KaJA== - dependencies: - esm "^3.2.25" - mhchemparser "^4.1.0" - mj-context-menu "^0.6.1" - speech-rule-engine "^3.3.3" - mathjax@^3.1.2: version "3.1.4" resolved "https://registry.yarnpkg.com/mathjax/-/mathjax-3.1.4.tgz#4e8932d12845c0abae8b7f1976ea98cb505e8420" @@ -3396,11 +3376,6 @@ merge2@^1.3.0: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -mhchemparser@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/mhchemparser/-/mhchemparser-4.1.1.tgz#a2142fdab37a02ec8d1b48a445059287790becd5" - integrity sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA== - micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" @@ -3443,11 +3418,6 @@ minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -mj-context-menu@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/mj-context-menu/-/mj-context-menu-0.6.1.tgz#a043c5282bf7e1cf3821de07b13525ca6f85aa69" - integrity sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA== - mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -4124,15 +4094,6 @@ spdx-satisfies@^5.0.0: spdx-expression-parse "^3.0.0" spdx-ranges "^2.0.0" -speech-rule-engine@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/speech-rule-engine/-/speech-rule-engine-3.3.3.tgz#781ed03cbcf3279f94d1d80241025ea954c6d571" - integrity sha512-0exWw+0XauLjat+f/aFeo5T8SiDsO1JtwpY3qgJE4cWt+yL/Stl0WP4VNDWdh7lzGkubUD9lWP4J1ASnORXfyQ== - dependencies: - commander ">=7.0.0" - wicked-good-xpath "^1.3.0" - xmldom-sre "^0.1.31" - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -4544,11 +4505,6 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wicked-good-xpath@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz#81b0e95e8650e49c94b22298fff8686b5553cf6c" - integrity sha1-gbDpXoZQ5JyUsiKY//hoa1VTz2w= - word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -4598,11 +4554,6 @@ xmlcreate@^2.0.3: resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.3.tgz#df9ecd518fd3890ab3548e1b811d040614993497" integrity sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ== -xmldom-sre@^0.1.31: - version "0.1.31" - resolved "https://registry.yarnpkg.com/xmldom-sre/-/xmldom-sre-0.1.31.tgz#10860d5bab2c603144597d04bf2c4980e98067f4" - integrity sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" From f52df75bc2bcaa2c0ca7d35ea21a9178e11e1989 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Fri, 16 Jul 2021 17:26:04 +0200 Subject: [PATCH 15/16] Add back opacity change --- ts/reviewer/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index 297318221..7119ded42 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -92,6 +92,8 @@ async function _updateQA( const qa = document.getElementById("qa")!; + qa.style.opacity = "0"; + try { setInnerHTML(qa, html); } catch (error) { @@ -110,6 +112,8 @@ async function _updateQA( }) .catch(renderError("MathJax")); + qa.style.opacity = "1"; + await _runHook(onShownHook); } From 1c1181b9e0c4da5d781535fd60275e2c3a1f1f47 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Fri, 16 Jul 2021 17:28:31 +0200 Subject: [PATCH 16/16] Allow any in reviewer/index.ts --- ts/reviewer/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index 7119ded42..334f9f988 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -3,6 +3,7 @@ /* eslint @typescript-eslint/no-non-null-assertion: "off", +@typescript-eslint/no-explicit-any: "off", */ import "css-browser-selector/css_browser_selector";