diff --git a/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/math.ts b/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/math.ts index b82f966a3f..a4bd95afdb 100644 --- a/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/math.ts +++ b/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/math.ts @@ -1,5 +1,5 @@ import { EditorView, WidgetType } from '@codemirror/view' -import { loadMathJax } from '../../../../mathjax/load-mathjax' +import { loadMathJax } from '@/features/mathjax/load-mathjax' import { placeSelectionInsideBlock } from '../selection' export class MathWidget extends WidgetType { @@ -17,15 +17,21 @@ export class MathWidget extends WidgetType { this.destroyed = false const element = document.createElement(this.displayMode ? 'div' : 'span') element.classList.add('ol-cm-math') + element.style.height = this.estimatedHeight + 'px' if (this.displayMode) { element.addEventListener('mouseup', event => { event.preventDefault() view.dispatch(placeSelectionInsideBlock(view, event as MouseEvent)) }) } - this.renderMath(element).catch(() => { - element.classList.add('ol-cm-math-error') - }) + this.renderMath(element) + .catch(() => { + element.classList.add('ol-cm-math-error') + }) + .finally(() => { + view.requestMeasure() + }) + return element } @@ -39,10 +45,14 @@ export class MathWidget extends WidgetType { updateDOM(element: HTMLElement, view: EditorView) { this.destroyed = false - this.renderMath(element).catch(() => { - element.classList.add('ol-cm-math-error') - }) - view.requestMeasure() + this.renderMath(element) + .catch(() => { + element.classList.add('ol-cm-math-error') + }) + .finally(() => { + view.requestMeasure() + }) + return true } @@ -65,6 +75,10 @@ export class MathWidget extends WidgetType { this.destroyed = true } + get estimatedHeight() { + return this.math.split('\n').length * 40 + } + coordsAt(element: HTMLElement) { return element.getBoundingClientRect() } @@ -72,21 +86,30 @@ export class MathWidget extends WidgetType { async renderMath(element: HTMLElement) { const MathJax = await loadMathJax() - if (!this.destroyed) { - MathJax.texReset([0]) // equation numbering is disabled, but this is still needed - if (this.preamble) { - try { - await MathJax.tex2svgPromise(this.preamble) - } catch { - // ignore errors thrown during parsing command definitions - } - } - const math = await MathJax.tex2svgPromise(this.math, { - ...MathJax.getMetricsFor(element), - display: this.displayMode, - }) - element.textContent = '' - element.append(math) + // abandon if the widget has been destroyed + if (this.destroyed) { + return } + + MathJax.texReset([0]) // equation numbering is disabled, but this is still needed + if (this.preamble) { + try { + await MathJax.tex2svgPromise(this.preamble) + } catch { + // ignore errors thrown during parsing command definitions + } + } + + // abandon if the element has been removed from the DOM + if (!element.isConnected) { + return + } + + const math = await MathJax.tex2svgPromise(this.math, { + ...MathJax.getMetricsFor(element, this.displayMode), + display: this.displayMode, + }) + element.replaceChildren(math) + element.style.height = 'auto' } }