Merge pull request #19617 from overleaf/dp-tooltip-alignment

Always render math preview tooltip at start of math content

GitOrigin-RevId: b0af7aa3c0920b2a9b9930f27a580018de1d2f52
This commit is contained in:
David 2024-07-26 11:52:57 +01:00 committed by Copybot
parent afd965c04b
commit 72c7b946ed
2 changed files with 26 additions and 12 deletions

View file

@ -14,6 +14,7 @@ import {
import { loadMathJax } from '../../mathjax/load-mathjax'
import { descendantsOfNodeWithType } from '../utils/tree-query'
import {
MathContainer,
mathAncestorNode,
parseMathContainer,
} from '../utils/tree-operations/math'
@ -92,12 +93,13 @@ function buildTooltips(state: EditorState): readonly Tooltip[] {
for (const range of state.selection.ranges) {
if (range.empty) {
const pos = range.from
const content = buildTooltipContent(state, pos)
if (content) {
const mathContainer = getMathContainer(state, range.from)
const content = buildTooltipContent(state, mathContainer)
if (content && mathContainer) {
const tooltip: Tooltip = {
pos,
pos: mathContainer.pos,
above: true,
strictSide: true,
arrow: false,
create() {
const dom = document.createElement('div')
@ -116,18 +118,21 @@ function buildTooltips(state: EditorState): readonly Tooltip[] {
return tooltips
}
const buildTooltipContent = (
state: EditorState,
pos: number
): HTMLDivElement | null => {
// if anywhere inside Math, render the whole Math content
const getMathContainer = (state: EditorState, pos: number) => {
// if anywhere inside Math, find the whole Math node
const ancestorNode = mathAncestorNode(state, pos)
if (!ancestorNode) return null
const [node] = descendantsOfNodeWithType(ancestorNode, 'Math', 'Math')
if (!node) return null
const math = parseMathContainer(state, node, ancestorNode)
return parseMathContainer(state, node, ancestorNode)
}
const buildTooltipContent = (
state: EditorState,
math: MathContainer | null
): HTMLDivElement | null => {
if (!math || !math.content.length) return null
const element = document.createElement('div')

View file

@ -3,6 +3,13 @@ import { EditorState } from '@codemirror/state'
import { SyntaxNode, SyntaxNodeRef } from '@lezer/common'
import { ancestorNodeOfType } from './ancestors'
export type MathContainer = {
content: string
displayMode: boolean
passToMathJax: boolean
pos: number
}
export const mathAncestorNode = (state: EditorState, pos: number) =>
ancestorNodeOfType(state, pos, '$MathContainer') ||
ancestorNodeOfType(state, pos, 'EquationEnvironment') ||
@ -13,7 +20,7 @@ export const parseMathContainer = (
state: EditorState,
nodeRef: SyntaxNodeRef,
ancestorNode: SyntaxNode
) => {
): MathContainer | null => {
// the content of the Math element, without braces
const innerContent = state.doc.sliceString(nodeRef.from, nodeRef.to).trim()
@ -24,6 +31,7 @@ export const parseMathContainer = (
let content = innerContent
let displayMode = false
let passToMathJax = true
let pos = nodeRef.from
if (ancestorNode.type.is('$Environment')) {
const environmentName = getEnvironmentName(ancestorNode, state)
@ -37,6 +45,7 @@ export const parseMathContainer = (
content = state.doc
.sliceString(ancestorNode.from, ancestorNode.to)
.trim()
pos = ancestorNode.from
}
if (environmentName !== 'math') {
@ -52,5 +61,5 @@ export const parseMathContainer = (
}
}
return { content, displayMode, passToMathJax }
return { content, displayMode, passToMathJax, pos }
}