From a1dde7c9662d693de0640504531fd35602543d88 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Thu, 16 Sep 2021 14:31:20 +0200 Subject: [PATCH 1/6] Wrap Mathjax compilation into try/catch --- ts/editable/mathjax.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/ts/editable/mathjax.ts b/ts/editable/mathjax.ts index b21c43301..1471a3c15 100644 --- a/ts/editable/mathjax.ts +++ b/ts/editable/mathjax.ts @@ -36,19 +36,25 @@ export function convertMathjax( return getEmptyIcon(style); } - const output = globalThis.MathJax.tex2svg(input); - const svg = output.children[0]; + let output: Element; + try { + output = globalThis.MathJax.tex2svg(input); + } catch (e) { + return ["Mathjax Error", String(e)]; + } - if (svg.viewBox.baseVal.height === 16) { + const svg = output.children[0] as SVGElement; + + if ((svg as any).viewBox.baseVal.height === 16) { return getEmptyIcon(style); } let title = ""; if (svg.innerHTML.includes("data-mjx-error")) { - svg.querySelector("rect").setAttribute("fill", "yellow"); - svg.querySelector("text").setAttribute("color", "red"); - title = svg.querySelector("title").innerHTML; + svg.querySelector("rect")?.setAttribute("fill", "yellow"); + svg.querySelector("text")?.setAttribute("color", "red"); + title = svg.querySelector("title")?.innerHTML ?? ""; } else { svg.insertBefore(style, svg.children[0]); } From c30ba6a3f650b1041b80cec68e2e6c394b7593b8 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Thu, 16 Sep 2021 14:47:05 +0200 Subject: [PATCH 2/6] Add ChangeTimer.prototype.fireImmediately so Mathjax is saved when exiting editor prematurely --- ts/editor/MathjaxHandleEditor.svelte | 7 ++++++- ts/editor/change-timer.ts | 17 ++++++++++++++++- ts/editor/saving.ts | 5 ++--- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/ts/editor/MathjaxHandleEditor.svelte b/ts/editor/MathjaxHandleEditor.svelte index 6dccbfe71..35568b8f8 100644 --- a/ts/editor/MathjaxHandleEditor.svelte +++ b/ts/editor/MathjaxHandleEditor.svelte @@ -16,6 +16,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html let codeMirror: CodeMirror.EditorFromTextArea; const changeTimer = new ChangeTimer(); + const dispatch = createEventDispatcher(); function onInput() { changeTimer.schedule( @@ -24,12 +25,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html ); } + function onBlur() { + changeTimer.fireImmediately(); + } + function openCodemirror(textarea: HTMLTextAreaElement): void { codeMirror = CodeMirror.fromTextArea(textarea, codeMirrorOptions); codeMirror.on("change", onInput); + codeMirror.on("blur", onBlur); } - const dispatch = createEventDispatcher(); let textarea: HTMLTextAreaElement; onMount(() => { diff --git a/ts/editor/change-timer.ts b/ts/editor/change-timer.ts index 1849c33f0..9c48ee718 100644 --- a/ts/editor/change-timer.ts +++ b/ts/editor/change-timer.ts @@ -3,10 +3,16 @@ export class ChangeTimer { private value: number | null = null; + private action: (() => void) | null = null; + + constructor() { + this.fireImmediately = this.fireImmediately.bind(this); + } schedule(action: () => void, delay: number): void { this.clear(); - this.value = setTimeout(action, delay); + this.action = action; + this.value = setTimeout(this.fireImmediately, delay); } clear(): void { @@ -15,4 +21,13 @@ export class ChangeTimer { this.value = null; } } + + fireImmediately(): void { + if (this.action) { + this.action(); + this.action = null; + } + + this.clear(); + } } diff --git a/ts/editor/saving.ts b/ts/editor/saving.ts index ebb70e7bd..e00c6e839 100644 --- a/ts/editor/saving.ts +++ b/ts/editor/saving.ts @@ -29,12 +29,11 @@ export function saveNow(keepFocus: boolean): void { return; } - saveFieldTimer.clear(); - if (keepFocus) { - saveField(currentField, "key"); + saveFieldTimer.fireImmediately(); } else { // triggers onBlur, which saves + saveFieldTimer.clear(); currentField.blur(); } } From 88fd31a099a9f5c1273766e27cb271ce383369b4 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Fri, 17 Sep 2021 20:12:11 +0200 Subject: [PATCH 3/6] Ugly fix: do not execute moveCursorPastPostfix when front includes "anki-mathjax" --- ts/lib/wrap.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ts/lib/wrap.ts b/ts/lib/wrap.ts index 7f97c7c1b..18cc0916a 100644 --- a/ts/lib/wrap.ts +++ b/ts/lib/wrap.ts @@ -38,7 +38,12 @@ export function wrapInternal( document.execCommand("inserthtml", false, new_); } - if (!span.innerHTML) { + if ( + !span.innerHTML && + /* ugly solution: treat differently than other wraps */ !front.includes( + " Date: Fri, 17 Sep 2021 20:54:37 +0200 Subject: [PATCH 4/6] Fix missizing of HandleSelection when first moving from empty to Mathjax --- ts/editable/Mathjax.svelte | 18 +++++++++++++----- ts/editor/MathjaxHandle.svelte | 19 +++++++++++-------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/ts/editable/Mathjax.svelte b/ts/editable/Mathjax.svelte index 3642ef27c..ccf442f12 100644 --- a/ts/editable/Mathjax.svelte +++ b/ts/editable/Mathjax.svelte @@ -3,7 +3,7 @@ Copyright: Ankitects Pty Ltd and contributors License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html --> void) => (): void => { + errorMessage = activeImage!.title; + updateSelection().then(resolve); + }; + function onEditorUpdate(event: CustomEvent): Promise { let selectionResolve: (value: void) => void; - const afterSelectionUpdate = new Promise((resolve) => { + const afterSelectionUpdate = new Promise((resolve: (value: void) => void) => { selectionResolve = resolve; }); - setTimeout(async () => { - errorMessage = activeImage!.title; - await updateSelection(); - selectionResolve(); - }); + const imageResize = onImageResize(selectionResolve!); + + activeImage!.addEventListener("resize", imageResize, { once: true }); + /* this updates the image in Mathjax.svelte */ + getComponent(activeImage!).dataset.mathjax = event.detail.mathjax; return afterSelectionUpdate; } From 51c0cedaf5a7f5c13b32b8865730569d9fa1b13c Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Fri, 17 Sep 2021 21:23:04 +0200 Subject: [PATCH 5/6] Make HandleSelection perfectly size when first activating --- ts/editable/Mathjax.svelte | 5 ++-- ts/editor/MathjaxHandle.svelte | 44 ++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/ts/editable/Mathjax.svelte b/ts/editable/Mathjax.svelte index ccf442f12..0f3a3385f 100644 --- a/ts/editable/Mathjax.svelte +++ b/ts/editable/Mathjax.svelte @@ -3,7 +3,7 @@ Copyright: Ankitects Pty Ltd and contributors License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html --> @@ -63,7 +69,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html autoClose={false} distance={4} let:createDropdown - let:dropdownObject > {#if activeImage} { - await onEditorUpdate(event); - dropdownObject.update(); - }} + on:update={onEditorUpdate} />
From 3f1da036153a9f16cae8d75217c38350533ceffa Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Fri, 17 Sep 2021 21:30:32 +0200 Subject: [PATCH 6/6] Allow for explicit any --- ts/editable/mathjax.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ts/editable/mathjax.ts b/ts/editable/mathjax.ts index 1471a3c15..739b45f43 100644 --- a/ts/editable/mathjax.ts +++ b/ts/editable/mathjax.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-explicit-any: "off", + */ + import { mathIcon } from "./icons"; const parser = new DOMParser();