diff --git a/ts/editable/Mathjax.svelte b/ts/editable/Mathjax.svelte index 3642ef27c..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 --> void = () => { + /* noop */ + }; + + function onImageResize(): void { + if (activeImage) { + errorMessage = activeImage.title; + updateSelection().then(() => dropdownApi.update()); + } + } + + $: if (activeImage) { + activeImage.addEventListener("resize", onImageResize); + + const lastImage = activeImage; + removeEventListener = () => + lastImage.removeEventListener("resize", onImageResize); + } else { + removeEventListener(); + } + const resizeObserver = new ResizeObserver(async () => { if (activeImage) { await updateSelection(); @@ -36,21 +57,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html return image.closest("anki-mathjax")! as HTMLElement; } - function onEditorUpdate(event: CustomEvent) { + function onEditorUpdate(event: CustomEvent): void { + /* this updates the image in Mathjax.svelte */ getComponent(activeImage!).dataset.mathjax = event.detail.mathjax; - - let selectionResolve: (value: void) => void; - const afterSelectionUpdate = new Promise((resolve) => { - selectionResolve = resolve; - }); - - setTimeout(async () => { - errorMessage = activeImage!.title; - await updateSelection(); - selectionResolve(); - }); - - return afterSelectionUpdate; } @@ -60,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} />
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(); } } 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( + "