From 1465d3a8481498fc7a00b9bca3c8027b97a3020d Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Wed, 4 Aug 2021 04:21:35 +0200 Subject: [PATCH] Survive to Codable and back --- .../{MathjaxBlock.svelte => Mathjax.svelte} | 5 +- ts/editable/editable.ts | 16 +++++- ts/editable/mathjax-components.ts | 57 ++++++++++++++++--- 3 files changed, 65 insertions(+), 13 deletions(-) rename ts/editable/{MathjaxBlock.svelte => Mathjax.svelte} (55%) diff --git a/ts/editable/MathjaxBlock.svelte b/ts/editable/Mathjax.svelte similarity index 55% rename from ts/editable/MathjaxBlock.svelte rename to ts/editable/Mathjax.svelte index 0ff5f6a5f..e2304db39 100644 --- a/ts/editable/MathjaxBlock.svelte +++ b/ts/editable/Mathjax.svelte @@ -6,7 +6,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import { convertMathjax } from "./mathjax"; export let mathjax: string; - $: converted = convertMathjax(`\\(${mathjax}\\)`); + export let type: "inline" | "block" | "chemistry"; + + $: delimiters = type === "inline" ? ["\\[", "\\]"] : ["\\(", "\\)"]; + $: converted = convertMathjax(`${delimiters[0]}${mathjax}${delimiters[1]}`); {@html converted} diff --git a/ts/editable/editable.ts b/ts/editable/editable.ts index 57ce5c7ce..e817cb47d 100644 --- a/ts/editable/editable.ts +++ b/ts/editable/editable.ts @@ -25,6 +25,8 @@ function containsInlineContent(element: Element): boolean { return true; } +const components = ["anki-mathjax-block", "anki-mathjax-inline"]; + export class Editable extends HTMLElement { set fieldHTML(content: string) { this.innerHTML = content; @@ -35,9 +37,17 @@ export class Editable extends HTMLElement { } get fieldHTML(): string { - return containsInlineContent(this) && this.innerHTML.endsWith("
") - ? this.innerHTML.slice(0, -4) // trim trailing
- : this.innerHTML; + const clone = this.cloneNode(true) as Element; + + for (const component of components) { + for (const element of clone.getElementsByTagName(component)) { + (element as any).undecorate(); + } + } + + return containsInlineContent(clone) && this.innerHTML.endsWith("
") + ? clone.innerHTML.slice(0, -4) // trim trailing
+ : clone.innerHTML; } connectedCallback(): void { diff --git a/ts/editable/mathjax-components.ts b/ts/editable/mathjax-components.ts index 7ed48f1bf..dc5b3a64f 100644 --- a/ts/editable/mathjax-components.ts +++ b/ts/editable/mathjax-components.ts @@ -1,35 +1,74 @@ -import MathjaxBlock_svelte from "./MathjaxBlock.svelte"; +import Mathjax_svelte from "./Mathjax.svelte"; -class MathjaxBlock extends HTMLElement { +class MathjaxInline extends HTMLElement { connectedCallback() { + this.decorate(); + } + + decorate(): void { this.contentEditable = "false"; const mathjax = (this.dataset.mathjax = this.innerText); + const type = "inline"; this.innerHTML = ""; - new MathjaxBlock_svelte({ + new Mathjax_svelte({ target: this, - props: { mathjax }, + props: { mathjax, type }, }); } + + undecorate(): void { + this.removeAttribute("contentEditable"); + this.innerHTML = this.dataset.mathjax ?? ""; + delete this.dataset.mathjax; + } +} + +customElements.define("anki-mathjax-inline", MathjaxInline); + +class MathjaxBlock extends HTMLElement { + connectedCallback() { + this.decorate(); + } + + decorate(): void { + this.contentEditable = "false"; + + const mathjax = (this.dataset.mathjax = this.innerText); + const type = "block"; + this.innerHTML = ""; + + new Mathjax_svelte({ + target: this, + props: { mathjax, type }, + }); + } + + undecorate(): void { + this.removeAttribute("contentEditable"); + this.innerHTML = this.dataset.mathjax ?? ""; + delete this.dataset.mathjax; + } } -// customElements.define("anki-mathjax-inline", MathjaxInline); customElements.define("anki-mathjax-block", MathjaxBlock); +// TODO mathjax regex will prob. fail at double quotes const mathjaxInlineTagPattern = - /(.*?)<\/anki-mathjax-inline>/gsu; -const mathjaxBlockTagPattern = /(.*?)<\/anki-mathjax-block>/gsu; + /]*?data-mathjax="(.*?)"[^>]*?>.*?<\/anki-mathjax-inline>/gsu; +const mathjaxBlockTagPattern = + /]*?data-mathjax="(.*?)"[^>]*?>.*?<\/anki-mathjax-block>/gsu; export function toMathjaxDelimiters(html: string): string { return html .replace( mathjaxInlineTagPattern, - (_match: string, text: string) => `\(${text}\)` + (_match: string, text: string) => `\\(${text}\\)` ) .replace( mathjaxBlockTagPattern, - (_match: string, text: string) => `\[${text}\]` + (_match: string, text: string) => `\\[${text}\\]` ); }