Răsfoiți Sursa

Use estimated height of math widget (#20359)

GitOrigin-RevId: b412e429b26ae51c83f84b855084b36a0015838d
Alf Eaton 2 ani în urmă
părinte
comite
26af3e1ecf

+ 45 - 22
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
-        }
+    // 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
       }
-      const math = await MathJax.tex2svgPromise(this.math, {
-        ...MathJax.getMetricsFor(element),
-        display: this.displayMode,
-      })
-      element.textContent = ''
-      element.append(math)
     }
+
+    // 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'
   }
 }