@formulaxjs/tiptap 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -64,7 +64,7 @@ function openFormulaXTiptapModal(input) {
64
64
  root.remove();
65
65
  return Promise.reject(new Error("[FormulaX] Tiptap modal host not found."));
66
66
  }
67
- const mounted = (0, import_editor.mountFormulaXKityEditor)(host, {
67
+ const mounted = (0, import_editor.mountFormulaXEditor)(host, {
68
68
  initialLatex: input.initialLatex,
69
69
  height: input.options.editor.height,
70
70
  autofocus: input.options.editor.autofocus,
@@ -415,7 +415,7 @@ function renderFormulaSvgMarkup(latex, options) {
415
415
  host.style.pointerEvents = "none";
416
416
  host.setAttribute("aria-hidden", "true");
417
417
  document.body.appendChild(host);
418
- const mounted = (0, import_editor2.mountFormulaXKityEditor)(host, {
418
+ const mounted = (0, import_editor2.mountFormulaXEditor)(host, {
419
419
  initialLatex: latex,
420
420
  height: options.editor.height,
421
421
  autofocus: false,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/modal.ts"],"sourcesContent":["import { Node } from '@tiptap/core';\nimport { parseLatex, serializeLatex, type FormulaDoc } from '@formulaxjs/core';\nimport {\n createFormulaElement,\n DEFAULT_FORMULA_ATTRIBUTE,\n DEFAULT_FORMULA_CLASS,\n ensureFormulaXModalStyles,\n getFormulaLatexFromElement,\n mountFormulaXKityEditor,\n} from '@formulaxjs/editor';\nimport { openFormulaXTiptapModal } from './modal';\nimport type { FormulaXPayload, FormulaXTiptapOptions, RequiredFormulaXTiptapOptions } from './types';\n\nexport interface FormulaXNodeAttributes {\n latex: string;\n}\n\nexport const FORMULAX_NODE_NAME = 'formulaX';\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n formulaX: {\n openFormulaX: () => ReturnType;\n };\n }\n}\n\nexport function resolveOptions(options: FormulaXTiptapOptions = {}): RequiredFormulaXTiptapOptions {\n return {\n name: options.name ?? FORMULAX_NODE_NAME,\n formulaClassName: options.formulaClassName ?? DEFAULT_FORMULA_CLASS,\n formulaAttributeName: options.formulaAttributeName ?? DEFAULT_FORMULA_ATTRIBUTE,\n cursorStyle: options.cursorStyle ?? 'pointer',\n initialLatex: options.initialLatex ?? '',\n modal: {\n title: options.modal?.title ?? 'FormulaX Editor',\n insertText: options.modal?.insertText ?? 'Insert',\n updateText: options.modal?.updateText ?? 'Update',\n cancelText: options.modal?.cancelText ?? 'Cancel',\n closeOnBackdrop: options.modal?.closeOnBackdrop ?? true,\n },\n editor: {\n height: options.editor?.height ?? '100%',\n autofocus: options.editor?.autofocus ?? true,\n assets: options.editor?.assets ?? {},\n render: {\n fontsize: options.editor?.render?.fontsize ?? 40,\n },\n },\n };\n}\n\nfunction warnDuplicateNodeName(extension: {\n name: string;\n editor?: { extensionManager?: { extensions?: Array<{ name?: string }> } };\n}) {\n const extensions = extension.editor?.extensionManager?.extensions ?? [];\n const duplicates = extensions.filter((item) => item?.name === extension.name);\n\n if (duplicates.length > 1) {\n console.warn(\n `[FormulaX] TipTap node name \"${extension.name}\" is already registered. ` +\n 'Pass a unique \"name\" option to avoid schema collisions.',\n );\n }\n}\n\nfunction createFormulaXNodeConfig(options: RequiredFormulaXTiptapOptions): any {\n return {\n name: options.name,\n group: 'inline',\n inline: true,\n atom: true,\n selectable: true,\n addOptions() {\n return options;\n },\n onCreate() {\n warnDuplicateNodeName(this);\n\n if (typeof document !== 'undefined') {\n ensureFormulaXModalStyles(document);\n }\n },\n addAttributes() {\n return {\n latex: {\n default: '',\n },\n };\n },\n parseHTML() {\n return [{\n tag: 'span[data-formulax]',\n getAttrs: (element: Node | string) => {\n if (!(element instanceof HTMLElement)) {\n return false;\n }\n\n return {\n latex: getFormulaLatexFromElement(element, this.options.formulaAttributeName),\n };\n },\n }];\n },\n renderHTML({ node }: { node: { attrs: FormulaXNodeAttributes } }) {\n if (typeof document === 'undefined') {\n return [\n 'span',\n {\n 'data-formulax': 'true',\n [this.options.formulaAttributeName]: node.attrs.latex,\n 'data-latex': node.attrs.latex,\n },\n node.attrs.latex || '\\\\square',\n ] as const;\n }\n\n return createFormulaDomElement(document, node.attrs, this.options);\n },\n addCommands() {\n return {\n openFormulaX: () => () => {\n const selectedFormula = getSelectedFormula(this.editor, this.name);\n const initialLatex = selectedFormula?.attrs.latex ?? this.options.initialLatex;\n\n void openFormulaXTiptapModal({\n initialLatex,\n isUpdate: Boolean(selectedFormula),\n options: this.options,\n }).then((payload) => {\n if (!payload) {\n return;\n }\n\n applyFormulaPayload(this.editor, payload, selectedFormula, this.name);\n this.editor.commands.focus();\n });\n\n return true;\n },\n };\n },\n addKeyboardShortcuts() {\n return {\n Enter: () => {\n if (!getSelectedFormula(this.editor, this.name)) {\n return false;\n }\n\n return this.editor.commands.openFormulaX();\n },\n Space: () => {\n if (!getSelectedFormula(this.editor, this.name)) {\n return false;\n }\n\n return this.editor.commands.openFormulaX();\n },\n };\n },\n addNodeView() {\n return ({ editor, getPos, node }: {\n editor: { commands: { openFormulaX: () => boolean; setNodeSelection?: (position: number) => boolean } };\n getPos: () => number;\n node: { attrs: FormulaXNodeAttributes };\n }) => {\n const dom = createFormulaDomElement(document, node.attrs, this.options) ?? document.createElement('span');\n dom.classList.add('formulax-math--interactive');\n void renderFormulaIntoElement(dom, node.attrs, this.options);\n\n const selectNode = (): void => {\n const position = getPos();\n if (typeof position !== 'number') {\n return;\n }\n\n editor.commands.setNodeSelection?.(position);\n };\n\n dom.addEventListener('click', (event) => {\n event.preventDefault();\n selectNode();\n });\n\n dom.addEventListener('dblclick', (event) => {\n event.preventDefault();\n event.stopPropagation();\n selectNode();\n editor.commands.openFormulaX();\n });\n\n return {\n dom,\n update: (updatedNode: { attrs: FormulaXNodeAttributes; type: { name: string } }) => {\n if (updatedNode.type.name !== this.name) {\n return false;\n }\n\n syncFormulaDomElement(dom, updatedNode.attrs, this.options);\n void renderFormulaIntoElement(dom, updatedNode.attrs, this.options);\n return true;\n },\n selectNode: () => {\n dom.classList.add('ProseMirror-selectednode');\n },\n deselectNode: () => {\n dom.classList.remove('ProseMirror-selectednode');\n },\n };\n };\n },\n };\n}\n\nexport interface TiptapNodeFactory {\n create: typeof Node.create;\n}\n\nexport function createFormulaXNode(\n nodeFactory: TiptapNodeFactory = Node,\n options?: FormulaXTiptapOptions,\n) {\n return nodeFactory.create(createFormulaXNodeConfig(resolveOptions(options))) as any;\n}\n\nexport const FormulaXNode = createFormulaXNode();\n\nexport const createFormulaXPayload = (latex: string): FormulaDoc => parseLatex(latex);\n\nexport const serializeFormulaXPayload = (doc: FormulaDoc): string => serializeLatex(doc);\n\nfunction applyFormulaPayload(\n editor: {\n chain: () => {\n focus: () => {\n deleteRange: (range: { from: number; to: number }) => { run: () => boolean };\n insertContent: (content: unknown) => { run: () => boolean };\n insertContentAt: (range: { from: number; to: number }, content: unknown) => { run: () => boolean };\n };\n };\n },\n payload: FormulaXPayload,\n selectedFormula: SelectedFormula | null,\n nodeName: string,\n): void {\n const latex = payload.latex.trim();\n\n if (selectedFormula) {\n if (!latex) {\n editor.chain().focus().deleteRange({\n from: selectedFormula.from,\n to: selectedFormula.to,\n }).run();\n return;\n }\n\n editor.chain().focus().insertContentAt(\n {\n from: selectedFormula.from,\n to: selectedFormula.to,\n },\n createFormulaNodeContent(payload, nodeName),\n ).run();\n return;\n }\n\n if (!latex) {\n return;\n }\n\n editor.chain().focus().insertContent(createFormulaNodeContent(payload, nodeName)).run();\n}\n\ninterface SelectedFormula {\n from: number;\n to: number;\n attrs: FormulaXNodeAttributes;\n}\n\nfunction getSelectedFormula(editor: {\n state: {\n selection: {\n from: number;\n to: number;\n node?: { type?: { name?: string }; attrs?: FormulaXNodeAttributes };\n };\n };\n}, nodeName: string): SelectedFormula | null {\n const { selection } = editor.state;\n const node = selection.node;\n\n if (node?.type?.name !== nodeName) {\n return null;\n }\n\n return {\n from: selection.from,\n to: selection.to,\n attrs: {\n latex: node.attrs?.latex ?? '',\n },\n };\n}\n\nfunction createFormulaNodeContent(\n payload: FormulaXPayload,\n nodeName = FORMULAX_NODE_NAME,\n): {\n type: string;\n attrs: FormulaXNodeAttributes;\n} {\n return {\n type: nodeName,\n attrs: {\n latex: payload.latex,\n },\n };\n}\n\nfunction createFormulaDomElement(\n ownerDocument: Document,\n attrs: FormulaXNodeAttributes,\n options: RequiredFormulaXTiptapOptions,\n): HTMLElement | null {\n return createFormulaElement(ownerDocument, attrs.latex, {\n attributeName: options.formulaAttributeName,\n className: options.formulaClassName,\n cursorStyle: options.cursorStyle,\n });\n}\n\nfunction syncFormulaDomElement(\n dom: HTMLElement,\n attrs: FormulaXNodeAttributes,\n options: RequiredFormulaXTiptapOptions,\n): void {\n const next = createFormulaDomElement(dom.ownerDocument ?? document, attrs, options);\n if (!next) {\n return;\n }\n\n dom.replaceChildren(...Array.from(next.childNodes));\n Array.from(dom.attributes).forEach((attribute) => {\n if (attribute.name === 'class') {\n return;\n }\n\n dom.removeAttribute(attribute.name);\n });\n\n Array.from(next.attributes).forEach((attribute) => {\n dom.setAttribute(attribute.name, attribute.value);\n });\n}\n\nconst formulaRenderCache = new Map<string, Promise<string>>();\n\nasync function renderFormulaIntoElement(\n dom: HTMLElement,\n attrs: FormulaXNodeAttributes,\n options: RequiredFormulaXTiptapOptions,\n): Promise<void> {\n const latex = attrs.latex.trim();\n const renderToken = `${latex}::${Date.now()}::${Math.random().toString(36).slice(2, 8)}`;\n dom.dataset.renderToken = renderToken;\n\n if (!latex) {\n const placeholder = dom.querySelector<HTMLElement>(`.${options.formulaClassName}__render`);\n if (placeholder) {\n placeholder.textContent = '\\\\square';\n }\n return;\n }\n\n try {\n const markup = await renderFormulaSvgMarkup(latex, options);\n if (dom.dataset.renderToken !== renderToken) {\n return;\n }\n\n dom.innerHTML = markup;\n } catch (error) {\n if (dom.dataset.renderToken !== renderToken) {\n return;\n }\n\n console.error('[FormulaX] Failed to render Tiptap formula node:', error);\n const placeholder = dom.querySelector<HTMLElement>(`.${options.formulaClassName}__render`);\n if (placeholder) {\n placeholder.textContent = latex;\n }\n }\n}\n\nfunction renderFormulaSvgMarkup(\n latex: string,\n options: RequiredFormulaXTiptapOptions,\n): Promise<string> {\n const cached = formulaRenderCache.get(latex);\n if (cached) {\n return cached;\n }\n\n const pending = (async () => {\n const host = document.createElement('div');\n host.style.position = 'fixed';\n host.style.left = '-100000px';\n host.style.top = '0';\n host.style.width = '1px';\n host.style.height = '1px';\n host.style.opacity = '0';\n host.style.pointerEvents = 'none';\n host.setAttribute('aria-hidden', 'true');\n document.body.appendChild(host);\n\n const mounted = mountFormulaXKityEditor(host, {\n initialLatex: latex,\n height: options.editor.height,\n autofocus: false,\n assets: options.editor.assets,\n render: {\n fontsize: options.editor.render.fontsize,\n },\n });\n\n try {\n return await mounted.getRenderHtml();\n } finally {\n mounted.destroy();\n host.remove();\n }\n })();\n\n formulaRenderCache.set(latex, pending);\n pending.catch(() => {\n if (formulaRenderCache.get(latex) === pending) {\n formulaRenderCache.delete(latex);\n }\n });\n return pending;\n}\n\nexport type { FormulaXPayload, FormulaXTiptapOptions, RequiredFormulaXTiptapOptions } from './types';\nexport { openFormulaXTiptapModal } from './modal';\n","import {\n ensureFormulaXModalStyles,\n escapeAttribute,\n escapeHtml,\n mountFormulaXKityEditor,\n} from '@formulaxjs/editor';\nimport type { FormulaXPayload, RequiredFormulaXTiptapOptions } from './types';\n\nexport interface OpenFormulaXTiptapModalInput {\n initialLatex: string;\n isUpdate: boolean;\n options: RequiredFormulaXTiptapOptions;\n}\n\nexport function openFormulaXTiptapModal(\n input: OpenFormulaXTiptapModalInput,\n): Promise<FormulaXPayload | null> {\n ensureFormulaXModalStyles(document);\n\n const root = document.createElement('div');\n root.className = 'fx-formula-modal-root';\n root.setAttribute('data-formulax-modal', 'true');\n\n const submitText = input.isUpdate ? input.options.modal.updateText : input.options.modal.insertText;\n\n root.innerHTML = `\n <div class=\"fx-formula-modal-backdrop\" data-action=\"backdrop\"></div>\n <div class=\"fx-formula-modal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"${escapeAttribute(input.options.modal.title)}\">\n <header class=\"fx-formula-modal__header\">\n <h2 class=\"fx-formula-modal__title\">${escapeHtml(input.options.modal.title)}</h2>\n <button class=\"fx-formula-modal__close\" type=\"button\" data-action=\"close\" aria-label=\"Close\">×</button>\n </header>\n <section class=\"fx-formula-modal__body\">\n <div class=\"fx-formula-editor-host\"></div>\n </section>\n <footer class=\"fx-formula-modal__footer\">\n <button class=\"fx-formula-modal__button\" type=\"button\" data-action=\"cancel\">${escapeHtml(input.options.modal.cancelText)}</button>\n <button class=\"fx-formula-modal__button fx-formula-modal__button--primary\" type=\"button\" data-action=\"submit\">${escapeHtml(submitText)}</button>\n </footer>\n </div>\n `;\n\n document.body.appendChild(root);\n document.body.classList.add('fx-formula-modal-open');\n\n const host = root.querySelector<HTMLElement>('.fx-formula-editor-host');\n if (!host) {\n root.remove();\n return Promise.reject(new Error('[FormulaX] Tiptap modal host not found.'));\n }\n\n const mounted = mountFormulaXKityEditor(host, {\n initialLatex: input.initialLatex,\n height: input.options.editor.height,\n autofocus: input.options.editor.autofocus,\n assets: input.options.editor.assets,\n render: {\n fontsize: input.options.editor.render.fontsize,\n },\n });\n let closed = false;\n\n return new Promise((resolve) => {\n const close = (payload: FormulaXPayload | null): void => {\n if (closed) {\n return;\n }\n\n closed = true;\n mounted.destroy();\n root.removeEventListener('click', onClick);\n document.removeEventListener('keydown', onKeydown, true);\n root.remove();\n document.body.classList.remove('fx-formula-modal-open');\n resolve(payload);\n };\n\n const submit = async (): Promise<void> => {\n try {\n const latex = await mounted.getLatex();\n close({ latex });\n } catch (error) {\n host.innerHTML = `\n <div class=\"fx-formula-editor-error\">\n Failed to read FormulaX editor content.\n <pre>${escapeHtml(error instanceof Error ? error.message : String(error))}</pre>\n </div>\n `;\n }\n };\n\n function onClick(event: MouseEvent): void {\n const action = (event.target as HTMLElement).closest<HTMLElement>('[data-action]')?.dataset.action;\n if (!action) {\n return;\n }\n\n if (action === 'submit') {\n void submit();\n return;\n }\n\n if (action === 'cancel' || action === 'close') {\n close(null);\n return;\n }\n\n if (action === 'backdrop' && input.options.modal.closeOnBackdrop) {\n close(null);\n }\n }\n\n function onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.preventDefault();\n close(null);\n }\n }\n\n root.addEventListener('click', onClick);\n document.addEventListener('keydown', onKeydown, true);\n\n queueMicrotask(() => {\n mounted.root.focus();\n });\n });\n}\n"],"mappings":"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","names":["import_core","import_editor"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/modal.ts"],"sourcesContent":["import { Node } from '@tiptap/core';\nimport { parseLatex, serializeLatex, type FormulaDoc } from '@formulaxjs/core';\nimport {\n createFormulaElement,\n DEFAULT_FORMULA_ATTRIBUTE,\n DEFAULT_FORMULA_CLASS,\n ensureFormulaXModalStyles,\n getFormulaLatexFromElement,\n mountFormulaXEditor,\n} from '@formulaxjs/editor';\nimport { openFormulaXTiptapModal } from './modal';\nimport type { FormulaXPayload, FormulaXTiptapOptions, RequiredFormulaXTiptapOptions } from './types';\n\nexport interface FormulaXNodeAttributes {\n latex: string;\n}\n\nexport const FORMULAX_NODE_NAME = 'formulaX';\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n formulaX: {\n openFormulaX: () => ReturnType;\n };\n }\n}\n\nexport function resolveOptions(options: FormulaXTiptapOptions = {}): RequiredFormulaXTiptapOptions {\n return {\n name: options.name ?? FORMULAX_NODE_NAME,\n formulaClassName: options.formulaClassName ?? DEFAULT_FORMULA_CLASS,\n formulaAttributeName: options.formulaAttributeName ?? DEFAULT_FORMULA_ATTRIBUTE,\n cursorStyle: options.cursorStyle ?? 'pointer',\n initialLatex: options.initialLatex ?? '',\n modal: {\n title: options.modal?.title ?? 'FormulaX Editor',\n insertText: options.modal?.insertText ?? 'Insert',\n updateText: options.modal?.updateText ?? 'Update',\n cancelText: options.modal?.cancelText ?? 'Cancel',\n closeOnBackdrop: options.modal?.closeOnBackdrop ?? true,\n },\n editor: {\n height: options.editor?.height ?? '100%',\n autofocus: options.editor?.autofocus ?? true,\n assets: options.editor?.assets ?? {},\n render: {\n fontsize: options.editor?.render?.fontsize ?? 40,\n },\n },\n };\n}\n\nfunction warnDuplicateNodeName(extension: {\n name: string;\n editor?: { extensionManager?: { extensions?: Array<{ name?: string }> } };\n}) {\n const extensions = extension.editor?.extensionManager?.extensions ?? [];\n const duplicates = extensions.filter((item) => item?.name === extension.name);\n\n if (duplicates.length > 1) {\n console.warn(\n `[FormulaX] TipTap node name \"${extension.name}\" is already registered. ` +\n 'Pass a unique \"name\" option to avoid schema collisions.',\n );\n }\n}\n\nfunction createFormulaXNodeConfig(options: RequiredFormulaXTiptapOptions): any {\n return {\n name: options.name,\n group: 'inline',\n inline: true,\n atom: true,\n selectable: true,\n addOptions() {\n return options;\n },\n onCreate() {\n warnDuplicateNodeName(this);\n\n if (typeof document !== 'undefined') {\n ensureFormulaXModalStyles(document);\n }\n },\n addAttributes() {\n return {\n latex: {\n default: '',\n },\n };\n },\n parseHTML() {\n return [{\n tag: 'span[data-formulax]',\n getAttrs: (element: Node | string) => {\n if (!(element instanceof HTMLElement)) {\n return false;\n }\n\n return {\n latex: getFormulaLatexFromElement(element, this.options.formulaAttributeName),\n };\n },\n }];\n },\n renderHTML({ node }: { node: { attrs: FormulaXNodeAttributes } }) {\n if (typeof document === 'undefined') {\n return [\n 'span',\n {\n 'data-formulax': 'true',\n [this.options.formulaAttributeName]: node.attrs.latex,\n 'data-latex': node.attrs.latex,\n },\n node.attrs.latex || '\\\\square',\n ] as const;\n }\n\n return createFormulaDomElement(document, node.attrs, this.options);\n },\n addCommands() {\n return {\n openFormulaX: () => () => {\n const selectedFormula = getSelectedFormula(this.editor, this.name);\n const initialLatex = selectedFormula?.attrs.latex ?? this.options.initialLatex;\n\n void openFormulaXTiptapModal({\n initialLatex,\n isUpdate: Boolean(selectedFormula),\n options: this.options,\n }).then((payload) => {\n if (!payload) {\n return;\n }\n\n applyFormulaPayload(this.editor, payload, selectedFormula, this.name);\n this.editor.commands.focus();\n });\n\n return true;\n },\n };\n },\n addKeyboardShortcuts() {\n return {\n Enter: () => {\n if (!getSelectedFormula(this.editor, this.name)) {\n return false;\n }\n\n return this.editor.commands.openFormulaX();\n },\n Space: () => {\n if (!getSelectedFormula(this.editor, this.name)) {\n return false;\n }\n\n return this.editor.commands.openFormulaX();\n },\n };\n },\n addNodeView() {\n return ({ editor, getPos, node }: {\n editor: { commands: { openFormulaX: () => boolean; setNodeSelection?: (position: number) => boolean } };\n getPos: () => number;\n node: { attrs: FormulaXNodeAttributes };\n }) => {\n const dom = createFormulaDomElement(document, node.attrs, this.options) ?? document.createElement('span');\n dom.classList.add('formulax-math--interactive');\n void renderFormulaIntoElement(dom, node.attrs, this.options);\n\n const selectNode = (): void => {\n const position = getPos();\n if (typeof position !== 'number') {\n return;\n }\n\n editor.commands.setNodeSelection?.(position);\n };\n\n dom.addEventListener('click', (event) => {\n event.preventDefault();\n selectNode();\n });\n\n dom.addEventListener('dblclick', (event) => {\n event.preventDefault();\n event.stopPropagation();\n selectNode();\n editor.commands.openFormulaX();\n });\n\n return {\n dom,\n update: (updatedNode: { attrs: FormulaXNodeAttributes; type: { name: string } }) => {\n if (updatedNode.type.name !== this.name) {\n return false;\n }\n\n syncFormulaDomElement(dom, updatedNode.attrs, this.options);\n void renderFormulaIntoElement(dom, updatedNode.attrs, this.options);\n return true;\n },\n selectNode: () => {\n dom.classList.add('ProseMirror-selectednode');\n },\n deselectNode: () => {\n dom.classList.remove('ProseMirror-selectednode');\n },\n };\n };\n },\n };\n}\n\nexport interface TiptapNodeFactory {\n create: typeof Node.create;\n}\n\nexport function createFormulaXNode(\n nodeFactory: TiptapNodeFactory = Node,\n options?: FormulaXTiptapOptions,\n) {\n return nodeFactory.create(createFormulaXNodeConfig(resolveOptions(options))) as any;\n}\n\nexport const FormulaXNode = createFormulaXNode();\n\nexport const createFormulaXPayload = (latex: string): FormulaDoc => parseLatex(latex);\n\nexport const serializeFormulaXPayload = (doc: FormulaDoc): string => serializeLatex(doc);\n\nfunction applyFormulaPayload(\n editor: {\n chain: () => {\n focus: () => {\n deleteRange: (range: { from: number; to: number }) => { run: () => boolean };\n insertContent: (content: unknown) => { run: () => boolean };\n insertContentAt: (range: { from: number; to: number }, content: unknown) => { run: () => boolean };\n };\n };\n },\n payload: FormulaXPayload,\n selectedFormula: SelectedFormula | null,\n nodeName: string,\n): void {\n const latex = payload.latex.trim();\n\n if (selectedFormula) {\n if (!latex) {\n editor.chain().focus().deleteRange({\n from: selectedFormula.from,\n to: selectedFormula.to,\n }).run();\n return;\n }\n\n editor.chain().focus().insertContentAt(\n {\n from: selectedFormula.from,\n to: selectedFormula.to,\n },\n createFormulaNodeContent(payload, nodeName),\n ).run();\n return;\n }\n\n if (!latex) {\n return;\n }\n\n editor.chain().focus().insertContent(createFormulaNodeContent(payload, nodeName)).run();\n}\n\ninterface SelectedFormula {\n from: number;\n to: number;\n attrs: FormulaXNodeAttributes;\n}\n\nfunction getSelectedFormula(editor: {\n state: {\n selection: {\n from: number;\n to: number;\n node?: { type?: { name?: string }; attrs?: FormulaXNodeAttributes };\n };\n };\n}, nodeName: string): SelectedFormula | null {\n const { selection } = editor.state;\n const node = selection.node;\n\n if (node?.type?.name !== nodeName) {\n return null;\n }\n\n return {\n from: selection.from,\n to: selection.to,\n attrs: {\n latex: node.attrs?.latex ?? '',\n },\n };\n}\n\nfunction createFormulaNodeContent(\n payload: FormulaXPayload,\n nodeName = FORMULAX_NODE_NAME,\n): {\n type: string;\n attrs: FormulaXNodeAttributes;\n} {\n return {\n type: nodeName,\n attrs: {\n latex: payload.latex,\n },\n };\n}\n\nfunction createFormulaDomElement(\n ownerDocument: Document,\n attrs: FormulaXNodeAttributes,\n options: RequiredFormulaXTiptapOptions,\n): HTMLElement | null {\n return createFormulaElement(ownerDocument, attrs.latex, {\n attributeName: options.formulaAttributeName,\n className: options.formulaClassName,\n cursorStyle: options.cursorStyle,\n });\n}\n\nfunction syncFormulaDomElement(\n dom: HTMLElement,\n attrs: FormulaXNodeAttributes,\n options: RequiredFormulaXTiptapOptions,\n): void {\n const next = createFormulaDomElement(dom.ownerDocument ?? document, attrs, options);\n if (!next) {\n return;\n }\n\n dom.replaceChildren(...Array.from(next.childNodes));\n Array.from(dom.attributes).forEach((attribute) => {\n if (attribute.name === 'class') {\n return;\n }\n\n dom.removeAttribute(attribute.name);\n });\n\n Array.from(next.attributes).forEach((attribute) => {\n dom.setAttribute(attribute.name, attribute.value);\n });\n}\n\nconst formulaRenderCache = new Map<string, Promise<string>>();\n\nasync function renderFormulaIntoElement(\n dom: HTMLElement,\n attrs: FormulaXNodeAttributes,\n options: RequiredFormulaXTiptapOptions,\n): Promise<void> {\n const latex = attrs.latex.trim();\n const renderToken = `${latex}::${Date.now()}::${Math.random().toString(36).slice(2, 8)}`;\n dom.dataset.renderToken = renderToken;\n\n if (!latex) {\n const placeholder = dom.querySelector<HTMLElement>(`.${options.formulaClassName}__render`);\n if (placeholder) {\n placeholder.textContent = '\\\\square';\n }\n return;\n }\n\n try {\n const markup = await renderFormulaSvgMarkup(latex, options);\n if (dom.dataset.renderToken !== renderToken) {\n return;\n }\n\n dom.innerHTML = markup;\n } catch (error) {\n if (dom.dataset.renderToken !== renderToken) {\n return;\n }\n\n console.error('[FormulaX] Failed to render Tiptap formula node:', error);\n const placeholder = dom.querySelector<HTMLElement>(`.${options.formulaClassName}__render`);\n if (placeholder) {\n placeholder.textContent = latex;\n }\n }\n}\n\nfunction renderFormulaSvgMarkup(\n latex: string,\n options: RequiredFormulaXTiptapOptions,\n): Promise<string> {\n const cached = formulaRenderCache.get(latex);\n if (cached) {\n return cached;\n }\n\n const pending = (async () => {\n const host = document.createElement('div');\n host.style.position = 'fixed';\n host.style.left = '-100000px';\n host.style.top = '0';\n host.style.width = '1px';\n host.style.height = '1px';\n host.style.opacity = '0';\n host.style.pointerEvents = 'none';\n host.setAttribute('aria-hidden', 'true');\n document.body.appendChild(host);\n\n const mounted = mountFormulaXEditor(host, {\n initialLatex: latex,\n height: options.editor.height,\n autofocus: false,\n assets: options.editor.assets,\n render: {\n fontsize: options.editor.render.fontsize,\n },\n });\n\n try {\n return await mounted.getRenderHtml();\n } finally {\n mounted.destroy();\n host.remove();\n }\n })();\n\n formulaRenderCache.set(latex, pending);\n pending.catch(() => {\n if (formulaRenderCache.get(latex) === pending) {\n formulaRenderCache.delete(latex);\n }\n });\n return pending;\n}\n\nexport type { FormulaXPayload, FormulaXTiptapOptions, RequiredFormulaXTiptapOptions } from './types';\nexport { openFormulaXTiptapModal } from './modal';\n","import {\n ensureFormulaXModalStyles,\n escapeAttribute,\n escapeHtml,\n mountFormulaXEditor,\n} from '@formulaxjs/editor';\nimport type { FormulaXPayload, RequiredFormulaXTiptapOptions } from './types';\n\nexport interface OpenFormulaXTiptapModalInput {\n initialLatex: string;\n isUpdate: boolean;\n options: RequiredFormulaXTiptapOptions;\n}\n\nexport function openFormulaXTiptapModal(\n input: OpenFormulaXTiptapModalInput,\n): Promise<FormulaXPayload | null> {\n ensureFormulaXModalStyles(document);\n\n const root = document.createElement('div');\n root.className = 'fx-formula-modal-root';\n root.setAttribute('data-formulax-modal', 'true');\n\n const submitText = input.isUpdate ? input.options.modal.updateText : input.options.modal.insertText;\n\n root.innerHTML = `\n <div class=\"fx-formula-modal-backdrop\" data-action=\"backdrop\"></div>\n <div class=\"fx-formula-modal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"${escapeAttribute(input.options.modal.title)}\">\n <header class=\"fx-formula-modal__header\">\n <h2 class=\"fx-formula-modal__title\">${escapeHtml(input.options.modal.title)}</h2>\n <button class=\"fx-formula-modal__close\" type=\"button\" data-action=\"close\" aria-label=\"Close\">×</button>\n </header>\n <section class=\"fx-formula-modal__body\">\n <div class=\"fx-formula-editor-host\"></div>\n </section>\n <footer class=\"fx-formula-modal__footer\">\n <button class=\"fx-formula-modal__button\" type=\"button\" data-action=\"cancel\">${escapeHtml(input.options.modal.cancelText)}</button>\n <button class=\"fx-formula-modal__button fx-formula-modal__button--primary\" type=\"button\" data-action=\"submit\">${escapeHtml(submitText)}</button>\n </footer>\n </div>\n `;\n\n document.body.appendChild(root);\n document.body.classList.add('fx-formula-modal-open');\n\n const host = root.querySelector<HTMLElement>('.fx-formula-editor-host');\n if (!host) {\n root.remove();\n return Promise.reject(new Error('[FormulaX] Tiptap modal host not found.'));\n }\n\n const mounted = mountFormulaXEditor(host, {\n initialLatex: input.initialLatex,\n height: input.options.editor.height,\n autofocus: input.options.editor.autofocus,\n assets: input.options.editor.assets,\n render: {\n fontsize: input.options.editor.render.fontsize,\n },\n });\n let closed = false;\n\n return new Promise((resolve) => {\n const close = (payload: FormulaXPayload | null): void => {\n if (closed) {\n return;\n }\n\n closed = true;\n mounted.destroy();\n root.removeEventListener('click', onClick);\n document.removeEventListener('keydown', onKeydown, true);\n root.remove();\n document.body.classList.remove('fx-formula-modal-open');\n resolve(payload);\n };\n\n const submit = async (): Promise<void> => {\n try {\n const latex = await mounted.getLatex();\n close({ latex });\n } catch (error) {\n host.innerHTML = `\n <div class=\"fx-formula-editor-error\">\n Failed to read FormulaX editor content.\n <pre>${escapeHtml(error instanceof Error ? error.message : String(error))}</pre>\n </div>\n `;\n }\n };\n\n function onClick(event: MouseEvent): void {\n const action = (event.target as HTMLElement).closest<HTMLElement>('[data-action]')?.dataset.action;\n if (!action) {\n return;\n }\n\n if (action === 'submit') {\n void submit();\n return;\n }\n\n if (action === 'cancel' || action === 'close') {\n close(null);\n return;\n }\n\n if (action === 'backdrop' && input.options.modal.closeOnBackdrop) {\n close(null);\n }\n }\n\n function onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.preventDefault();\n close(null);\n }\n }\n\n root.addEventListener('click', onClick);\n document.addEventListener('keydown', onKeydown, true);\n\n queueMicrotask(() => {\n mounted.root.focus();\n });\n });\n}\n"],"mappings":"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","names":["import_core","import_editor"]}
@@ -4012,7 +4012,7 @@ var FormulaX = (() => {
4012
4012
  }
4013
4013
  });
4014
4014
 
4015
- // ../kity-runtime/dist/chunk-EKIJQ64F.js
4015
+ // ../kity-runtime/dist/chunk-53JBJHMR.js
4016
4016
  function getLegacyEventId(target) {
4017
4017
  return target.__kfeEventId ?? target.__kfe_eid;
4018
4018
  }
@@ -4157,23 +4157,7 @@ var FormulaX = (() => {
4157
4157
  return node.classList;
4158
4158
  }
4159
4159
  function createLegacyUiUtils() {
4160
- return {
4161
- ele: createElement,
4162
- getRectBox,
4163
- on(target, type, fn) {
4164
- addEvent(target, type, fn);
4165
- return this;
4166
- },
4167
- delegate(target, selector, type, fn) {
4168
- delegateEvent(target, selector, type, fn);
4169
- return this;
4170
- },
4171
- publish(topic, ...args) {
4172
- publish(topic, ...args);
4173
- },
4174
- subscribe,
4175
- getClassList
4176
- };
4160
+ return legacyUiUtils;
4177
4161
  }
4178
4162
  function setToolbarAssetUrls(assets) {
4179
4163
  toolbarAssetFileMap = {
@@ -4189,9 +4173,9 @@ var FormulaX = (() => {
4189
4173
  }
4190
4174
  throw new Error(`Missing Kity toolbar asset URL for "${normalizedFileName}".`);
4191
4175
  }
4192
- var legacyBoxType, legacyKfEvent, eventListenerStore, eventId, beforeResult, eventHandler, legacyEventListener, utils, utils_default, legacyBaseUtils, legacyEleType, legacyGroupType, replacementMap, legacyInputFilter, legacyItemType, legacyKfExtDef, legacySysconf, legacyUiDef, topicPool, legacyOtherPosition, toolbarAssetFileMap;
4193
- var init_chunk_EKIJQ64F = __esm({
4194
- "../kity-runtime/dist/chunk-EKIJQ64F.js"() {
4176
+ var legacyBoxType, legacyKfEvent, eventListenerStore, eventId, beforeResult, eventHandler, legacyEventListener, utils, utils_default, legacyBaseUtils, legacyEleType, legacyGroupType, replacementMap, legacyInputFilter, legacyItemType, legacyKfExtDef, legacySysconf, legacyUiDef, topicPool, legacyUiUtils, legacyOtherPosition, toolbarAssetFileMap;
4177
+ var init_chunk_53JBJHMR = __esm({
4178
+ "../kity-runtime/dist/chunk-53JBJHMR.js"() {
4195
4179
  "use strict";
4196
4180
  init_lodash();
4197
4181
  init_lodash();
@@ -4391,6 +4375,23 @@ var FormulaX = (() => {
4391
4375
  }
4392
4376
  };
4393
4377
  topicPool = /* @__PURE__ */ new Map();
4378
+ legacyUiUtils = {
4379
+ ele: createElement,
4380
+ getRectBox,
4381
+ on(target, type, fn) {
4382
+ addEvent(target, type, fn);
4383
+ return this;
4384
+ },
4385
+ delegate(target, selector, type, fn) {
4386
+ delegateEvent(target, selector, type, fn);
4387
+ return this;
4388
+ },
4389
+ publish(topic, ...args) {
4390
+ publish(topic, ...args);
4391
+ },
4392
+ subscribe,
4393
+ getClassList
4394
+ };
4394
4395
  legacyOtherPosition = {
4395
4396
  "x=\\frac {-b\\pm\\sqrt {b^2-4ac}}{2a}": {
4396
4397
  "pos": {
@@ -14245,11 +14246,11 @@ var FormulaX = (() => {
14245
14246
  }
14246
14247
  });
14247
14248
 
14248
- // ../kity-runtime/dist/start-GQH6XUBI.js
14249
- var start_GQH6XUBI_exports = {};
14250
- __export(start_GQH6XUBI_exports, {
14249
+ // ../kity-runtime/dist/start-2M6472FZ.js
14250
+ var start_2M6472FZ_exports = {};
14251
+ __export(start_2M6472FZ_exports, {
14251
14252
  Factory: () => factory_default,
14252
- KFEditor: () => editor_default2,
14253
+ KFEditor: () => editor_default,
14253
14254
  default: () => start_default,
14254
14255
  installKityEditorStart: () => installKityEditorStart
14255
14256
  });
@@ -14960,27 +14961,27 @@ var FormulaX = (() => {
14960
14961
  function installKityEditorStart(target = window) {
14961
14962
  const runtimeTarget = target;
14962
14963
  if (!installed3) {
14963
- editor_default2.registerComponents("ui", ui_default);
14964
- editor_default2.registerComponents("parser", parser_default);
14965
- editor_default2.registerComponents("render", render_default);
14966
- editor_default2.registerComponents("position", position_default);
14967
- editor_default2.registerComponents("syntax", syntax_default);
14968
- editor_default2.registerComponents("control", controller_default);
14969
- editor_default2.registerComponents("print", printer_default);
14964
+ editor_default.registerComponents("ui", ui_default);
14965
+ editor_default.registerComponents("parser", parser_default);
14966
+ editor_default.registerComponents("render", render_default);
14967
+ editor_default.registerComponents("position", position_default);
14968
+ editor_default.registerComponents("syntax", syntax_default);
14969
+ editor_default.registerComponents("control", controller_default);
14970
+ editor_default.registerComponents("print", printer_default);
14970
14971
  installed3 = true;
14971
14972
  }
14972
14973
  runtimeTarget.kf = runtimeTarget.kf ?? {};
14973
14974
  runtimeTarget.kf.EditorFactory = factory_default;
14974
14975
  return {
14975
- KFEditor: editor_default2,
14976
+ KFEditor: editor_default,
14976
14977
  Factory: factory_default
14977
14978
  };
14978
14979
  }
14979
- var defaultOptions, components, kity, kf, KFEditor, editor_default2, EditorWrapper, factory, factory_default, PREFIX, LIST_OFFSET, DEFAULT_OPTIONS2, $$, kity2, Button, button_default, PREFIX2, $$2, kity3, List, list_default, kity4, $$3, PREFIX3, BOX_TYPE, ITEM_TYPE, SCROLL_STEP, BoxItem, Box, box_default, PREFIX4, PANEL_HEIGHT, $$4, kity5, Area, area_default, PREFIX5, $$5, kity6, Delimiter, delimiter_default, $$6, kity7, DrapdownBox, dropdown_box_default, UiImpl, ui_impl_default, $$7, kity8, Toolbar, toolbar_default, SCROLLBAR_DEF, SCROLLBAR_CONF, CLASS_PREFIX, kity9, Scrollbar, scrollbar_default, UNICODE_SYMBOLS, STYLE_FONT_MAP, UI_ELE_TYPE, BOX_TYPE2, OTHER_POSITION, config, toolbar_config_default, $$8, VIEW_STATE, DEFAULT_EDIT_AREA_HEIGHT, kity10, UIComponent, ui_default, kity11, kf2, PlaceholderOperator, kf_ext_placeholder_operator_default, kity12, kf3, BaseCompoundExpression, PlaceholderExpression, kf_ext_placeholder_expression_default, kf4, kf_ext_extension_default, legacyVirtualGroupMap, vgroup_def_default, CURSOR_CHAR, ROOT_P_TEXT, COMBINATION_NAME, PID_PREFIX, pidSeed, kity13, kf5, BaseComponent, Parser, parser_default, DEFAULT_OPTIONS22, kity14, kf6, BaseComponent2, RenderComponent, render_default, kity15, PositionComponent, position_default, kity16, DeleteComponent, syntax_delete_default, kity17, MoveComponent, syntax_move_default, CURSOR_CHAR2, kity18, SyntaxComponent, syntax_default, KEY_CODE, kity19, InputComponent, input_default, kity20, LocationComponent, location_default, MAX_DISTANCE, kity21, SelectionComponent, selection_default, kity22, ListenerComponent, listener_default, kity23, ControllerComponent, controller_default, kity24, Printer, printer_default, installed3, start_default;
14980
- var init_start_GQH6XUBI = __esm({
14981
- "../kity-runtime/dist/start-GQH6XUBI.js"() {
14980
+ var defaultOptions, components, kity, kf, KFEditor, editor_default, EditorWrapper, factory, factory_default, PREFIX, LIST_OFFSET, DEFAULT_OPTIONS2, $$, kity2, Button, button_default, PREFIX2, $$2, kity3, List, list_default, kity4, $$3, PREFIX3, BOX_TYPE, ITEM_TYPE, SCROLL_STEP, BoxItem, Box, box_default, PREFIX4, PANEL_HEIGHT, $$4, kity5, Area, area_default, PREFIX5, $$5, kity6, Delimiter, delimiter_default, $$6, kity7, DrapdownBox, dropdown_box_default, UiImpl, ui_impl_default, $$7, kity8, Toolbar, toolbar_default, SCROLLBAR_DEF, SCROLLBAR_CONF, CLASS_PREFIX, kity9, Scrollbar, scrollbar_default, UNICODE_SYMBOLS, STYLE_FONT_MAP, UI_ELE_TYPE, BOX_TYPE2, OTHER_POSITION, config, toolbar_config_default, $$8, VIEW_STATE, DEFAULT_EDIT_AREA_HEIGHT, kity10, UIComponent, ui_default, kity11, kf2, PlaceholderOperator, kf_ext_placeholder_operator_default, kity12, kf3, BaseCompoundExpression, PlaceholderExpression, kf_ext_placeholder_expression_default, kf4, kf_ext_extension_default, legacyVirtualGroupMap, vgroup_def_default, CURSOR_CHAR, ROOT_P_TEXT, COMBINATION_NAME, PID_PREFIX, pidSeed, kity13, kf5, BaseComponent, Parser, parser_default, DEFAULT_OPTIONS22, kity14, kf6, BaseComponent2, RenderComponent, render_default, kity15, PositionComponent, position_default, kity16, DeleteComponent, syntax_delete_default, kity17, MoveComponent, syntax_move_default, CURSOR_CHAR2, kity18, SyntaxComponent, syntax_default, KEY_CODE, kity19, InputComponent, input_default, kity20, LocationComponent, location_default, MAX_DISTANCE, kity21, SelectionComponent, selection_default, kity22, ListenerComponent, listener_default, kity23, ControllerComponent, controller_default, kity24, Printer, printer_default, installed3, start_default;
14981
+ var init_start_2M6472FZ = __esm({
14982
+ "../kity-runtime/dist/start-2M6472FZ.js"() {
14982
14983
  "use strict";
14983
- init_chunk_EKIJQ64F();
14984
+ init_chunk_53JBJHMR();
14984
14985
  defaultOptions = {
14985
14986
  formula: {
14986
14987
  fontsize: 50,
@@ -15087,12 +15088,12 @@ var FormulaX = (() => {
15087
15088
  components[name] = component;
15088
15089
  }
15089
15090
  });
15090
- editor_default2 = KFEditor;
15091
+ editor_default = KFEditor;
15091
15092
  EditorWrapper = class {
15092
15093
  callbacks = [];
15093
15094
  editor;
15094
15095
  constructor(container, options) {
15095
- this.editor = new editor_default2(container, options);
15096
+ this.editor = new editor_default(container, options);
15096
15097
  this.editor.ready(() => {
15097
15098
  this.trigger();
15098
15099
  });
@@ -26798,12 +26799,10 @@ var FormulaX = (() => {
26798
26799
  var serializeLatex = (document2) => serializeNode(document2);
26799
26800
 
26800
26801
  // ../kity-runtime/dist/index.js
26801
- init_chunk_EKIJQ64F();
26802
-
26803
- // ../kity-assets/dist/index.js
26802
+ init_chunk_53JBJHMR();
26804
26803
  var btn_default = "./btn-5DANP6JY.png";
26805
26804
  var other_default = "./other-OMWJFGL5.png";
26806
- var editor_default = "./editor-JT5KLVXX.css?url";
26805
+ var editor_default2 = "./editor-JT5KLVXX.css?url";
26807
26806
  var KF_AMS_BB_default = "./KF_AMS_BB-5QF7FUSO.woff";
26808
26807
  var KF_AMS_CAL_default = "./KF_AMS_CAL-NXRNLAZN.woff";
26809
26808
  var KF_AMS_FRAK_default = "./KF_AMS_FRAK-CO33WWN4.woff";
@@ -26821,15 +26820,13 @@ var FormulaX = (() => {
26821
26820
  other: other_default
26822
26821
  };
26823
26822
  var kityStyleAssets = {
26824
- editor: editor_default
26823
+ editor: editor_default2
26825
26824
  };
26826
26825
  var kityAssetManifest = {
26827
26826
  fonts: kityFontAssets,
26828
26827
  toolbar: kityToolbarAssets,
26829
26828
  styles: kityStyleAssets
26830
26829
  };
26831
-
26832
- // ../kity-runtime/dist/index.js
26833
26830
  var legacyCharPosition = {
26834
26831
  "\\pm": {
26835
26832
  "x": 5,
@@ -30287,7 +30284,7 @@ var FormulaX = (() => {
30287
30284
  kity: runtimeWindow.kity,
30288
30285
  otherPosition: legacyOtherPosition,
30289
30286
  uiDef: legacyUiDef,
30290
- uiUtils: createLegacyUiUtils()
30287
+ uiUtils: legacyUiUtils
30291
30288
  };
30292
30289
  }
30293
30290
  async function ensureKityRuntime() {
@@ -30304,7 +30301,7 @@ var FormulaX = (() => {
30304
30301
  const { installLegacyParserRuntime: installLegacyParserRuntime2 } = await Promise.resolve().then(() => (init_install_HKCG5NWK(), install_HKCG5NWK_exports));
30305
30302
  installLegacyParserRuntime2(runtimeWindow);
30306
30303
  installLegacyRuntime(runtimeWindow);
30307
- const { installKityEditorStart: installKityEditorStart2 } = await Promise.resolve().then(() => (init_start_GQH6XUBI(), start_GQH6XUBI_exports));
30304
+ const { installKityEditorStart: installKityEditorStart2 } = await Promise.resolve().then(() => (init_start_2M6472FZ(), start_2M6472FZ_exports));
30308
30305
  installKityEditorStart2(runtimeWindow);
30309
30306
  })();
30310
30307
  return runtimePromise;
@@ -30711,7 +30708,7 @@ var FormulaX = (() => {
30711
30708
  style.textContent = formulaXModalStyles;
30712
30709
  doc2.head.appendChild(style);
30713
30710
  }
30714
- function mountFormulaXKityEditor(root2, options = {}) {
30711
+ function mountFormulaXEditor(root2, options = {}) {
30715
30712
  let destroyed = false;
30716
30713
  let latestLatex = options.initialLatex ?? "";
30717
30714
  let handle = null;
@@ -31151,7 +31148,7 @@ var FormulaX = (() => {
31151
31148
  root2.remove();
31152
31149
  return Promise.reject(new Error("[FormulaX] Tiptap modal host not found."));
31153
31150
  }
31154
- const mounted = mountFormulaXKityEditor(host, {
31151
+ const mounted = mountFormulaXEditor(host, {
31155
31152
  initialLatex: input.initialLatex,
31156
31153
  height: input.options.editor.height,
31157
31154
  autofocus: input.options.editor.autofocus,
@@ -31502,7 +31499,7 @@ var FormulaX = (() => {
31502
31499
  host.style.pointerEvents = "none";
31503
31500
  host.setAttribute("aria-hidden", "true");
31504
31501
  document.body.appendChild(host);
31505
- const mounted = mountFormulaXKityEditor(host, {
31502
+ const mounted = mountFormulaXEditor(host, {
31506
31503
  initialLatex: latex,
31507
31504
  height: options.editor.height,
31508
31505
  autofocus: false,