diff --git a/ts/editable/editable.ts b/ts/editable/editable.ts index 187bb3ca1..f05f7b922 100644 --- a/ts/editable/editable.ts +++ b/ts/editable/editable.ts @@ -50,9 +50,12 @@ export class Editable extends HTMLElement { } } - return containsInlineContent(clone) && this.innerHTML.endsWith("
") - ? clone.innerHTML.slice(0, -4) // trim trailing
- : clone.innerHTML; + const result = + containsInlineContent(clone) && clone.innerHTML.endsWith("
") + ? clone.innerHTML.slice(0, -4) // trim trailing
+ : clone.innerHTML; + + return result; } connectedCallback(): void { diff --git a/ts/editable/mathjax-component.ts b/ts/editable/mathjax-component.ts index f72a93278..150743c4d 100644 --- a/ts/editable/mathjax-component.ts +++ b/ts/editable/mathjax-component.ts @@ -1,9 +1,49 @@ import "mathjax/es5/tex-svg-full"; +import { nodeIsElement } from "lib/dom"; import Mathjax_svelte from "./Mathjax.svelte"; +function moveNodesInsertedBeforeEndToAfterEnd(element: Element): () => void { + const allowedChildNodes = element.childNodes.length; + + const observer = new MutationObserver(() => { + for (const node of [...element.childNodes].slice(allowedChildNodes)) { + element.removeChild(node); + + let referenceNode: Node; + + if (nodeIsElement(node)) { + referenceNode = element.insertAdjacentElement("afterend", node)!; + } else { + element.insertAdjacentText("afterend", (node as Text).wholeText); + referenceNode = element.nextSibling!; + } + + if (!referenceNode) { + continue; + } + + const range = document.createRange(); + range.setStartAfter(referenceNode); + range.collapse(false); + + const selection = document.getSelection()!; + selection.removeAllRanges(); + selection.addRange(range); + } + }); + + observer.observe(element, { characterData: true, subtree: true }); + return () => observer.disconnect(); +} + class Mathjax extends HTMLElement { block: boolean = false; + disconnect: () => void = () => {}; + + constructor() { + super(); + } static get observedAttributes(): string[] { return ["block"]; @@ -11,6 +51,11 @@ class Mathjax extends HTMLElement { connectedCallback(): void { this.decorate(); + this.disconnect = moveNodesInsertedBeforeEndToAfterEnd(this); + } + + disconnectedCallback(): void { + this.disconnect(); } attributeChangedCallback(_name: string, _old: string, newValue: string): void { @@ -41,17 +86,18 @@ class Mathjax extends HTMLElement { customElements.define("anki-mathjax", Mathjax); -// TODO mathjax regex will prob. fail at double quotes const mathjaxTagPattern = /]*?block="(.*?)")?[^>]*?>(.*?)<\/anki-mathjax>/gsu; export function toMathjaxDelimiters(html: string): string { return html.replace( mathjaxTagPattern, - (_match: string, block: string | undefined, text: string) => - typeof block === "string" && block !== "false" + (_match: string, block: string | undefined, text: string) => { + console.log("delim", _match, block, "text", text); + return typeof block === "string" && block !== "false" ? `\\[${text}\\]` - : `\\(${text}\\)` + : `\\(${text}\\)`; + } ); } @@ -62,11 +108,14 @@ export function toMathjaxTags(html: string): string { return html .replace( mathjaxBlockDelimiterPattern, - (_match: string, text: string) => - `${text}` + (_match: string, text: string) => ( + console.log(text), `${text}` + ) ) .replace( mathjaxInlineDelimiterPattern, - (_match: string, text: string) => `${text}` + (_match: string, text: string) => ( + console.log(text), `${text}` + ) ); }