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(
+ "