Use estimated height of math widget (#20359)

GitOrigin-RevId: b412e429b26ae51c83f84b855084b36a0015838d
This commit is contained in:
Alf Eaton 2024-09-12 09:39:55 +01:00 committed by Copybot
parent d93bd9d4c8
commit 26af3e1ecf

View file

@ -1,5 +1,5 @@
import { EditorView, WidgetType } from '@codemirror/view' import { EditorView, WidgetType } from '@codemirror/view'
import { loadMathJax } from '../../../../mathjax/load-mathjax' import { loadMathJax } from '@/features/mathjax/load-mathjax'
import { placeSelectionInsideBlock } from '../selection' import { placeSelectionInsideBlock } from '../selection'
export class MathWidget extends WidgetType { export class MathWidget extends WidgetType {
@ -17,15 +17,21 @@ export class MathWidget extends WidgetType {
this.destroyed = false this.destroyed = false
const element = document.createElement(this.displayMode ? 'div' : 'span') const element = document.createElement(this.displayMode ? 'div' : 'span')
element.classList.add('ol-cm-math') element.classList.add('ol-cm-math')
element.style.height = this.estimatedHeight + 'px'
if (this.displayMode) { if (this.displayMode) {
element.addEventListener('mouseup', event => { element.addEventListener('mouseup', event => {
event.preventDefault() event.preventDefault()
view.dispatch(placeSelectionInsideBlock(view, event as MouseEvent)) view.dispatch(placeSelectionInsideBlock(view, event as MouseEvent))
}) })
} }
this.renderMath(element).catch(() => { this.renderMath(element)
element.classList.add('ol-cm-math-error') .catch(() => {
}) element.classList.add('ol-cm-math-error')
})
.finally(() => {
view.requestMeasure()
})
return element return element
} }
@ -39,10 +45,14 @@ export class MathWidget extends WidgetType {
updateDOM(element: HTMLElement, view: EditorView) { updateDOM(element: HTMLElement, view: EditorView) {
this.destroyed = false this.destroyed = false
this.renderMath(element).catch(() => { this.renderMath(element)
element.classList.add('ol-cm-math-error') .catch(() => {
}) element.classList.add('ol-cm-math-error')
view.requestMeasure() })
.finally(() => {
view.requestMeasure()
})
return true return true
} }
@ -65,6 +75,10 @@ export class MathWidget extends WidgetType {
this.destroyed = true this.destroyed = true
} }
get estimatedHeight() {
return this.math.split('\n').length * 40
}
coordsAt(element: HTMLElement) { coordsAt(element: HTMLElement) {
return element.getBoundingClientRect() return element.getBoundingClientRect()
} }
@ -72,21 +86,30 @@ export class MathWidget extends WidgetType {
async renderMath(element: HTMLElement) { async renderMath(element: HTMLElement) {
const MathJax = await loadMathJax() const MathJax = await loadMathJax()
if (!this.destroyed) { // abandon if the widget has been destroyed
MathJax.texReset([0]) // equation numbering is disabled, but this is still needed if (this.destroyed) {
if (this.preamble) { return
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)
} }
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'
} }
} }