@formulaxjs/tiptap 0.1.0

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 ADDED
@@ -0,0 +1,440 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ FORMULAX_NODE_NAME: () => FORMULAX_NODE_NAME,
24
+ FormulaXNode: () => FormulaXNode,
25
+ createFormulaXNode: () => createFormulaXNode,
26
+ createFormulaXPayload: () => createFormulaXPayload,
27
+ openFormulaXTiptapModal: () => openFormulaXTiptapModal,
28
+ resolveOptions: () => resolveOptions,
29
+ serializeFormulaXPayload: () => serializeFormulaXPayload
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+ var import_core = require("@tiptap/core");
33
+ var import_core2 = require("@formulaxjs/core");
34
+ var import_editor2 = require("@formulaxjs/editor");
35
+
36
+ // src/modal.ts
37
+ var import_editor = require("@formulaxjs/editor");
38
+ function openFormulaXTiptapModal(input) {
39
+ (0, import_editor.ensureFormulaXModalStyles)(document);
40
+ const root = document.createElement("div");
41
+ root.className = "fx-formula-modal-root";
42
+ root.setAttribute("data-formulax-modal", "true");
43
+ const submitText = input.isUpdate ? input.options.modal.updateText : input.options.modal.insertText;
44
+ root.innerHTML = `
45
+ <div class="fx-formula-modal-backdrop" data-action="backdrop"></div>
46
+ <div class="fx-formula-modal" role="dialog" aria-modal="true" aria-label="${(0, import_editor.escapeAttribute)(input.options.modal.title)}">
47
+ <header class="fx-formula-modal__header">
48
+ <h2 class="fx-formula-modal__title">${(0, import_editor.escapeHtml)(input.options.modal.title)}</h2>
49
+ <button class="fx-formula-modal__close" type="button" data-action="close" aria-label="Close">\xD7</button>
50
+ </header>
51
+ <section class="fx-formula-modal__body">
52
+ <div class="fx-formula-editor-host"></div>
53
+ </section>
54
+ <footer class="fx-formula-modal__footer">
55
+ <button class="fx-formula-modal__button" type="button" data-action="cancel">${(0, import_editor.escapeHtml)(input.options.modal.cancelText)}</button>
56
+ <button class="fx-formula-modal__button fx-formula-modal__button--primary" type="button" data-action="submit">${(0, import_editor.escapeHtml)(submitText)}</button>
57
+ </footer>
58
+ </div>
59
+ `;
60
+ document.body.appendChild(root);
61
+ document.body.classList.add("fx-formula-modal-open");
62
+ const host = root.querySelector(".fx-formula-editor-host");
63
+ if (!host) {
64
+ root.remove();
65
+ return Promise.reject(new Error("[FormulaX] Tiptap modal host not found."));
66
+ }
67
+ const mounted = (0, import_editor.mountFormulaXKityEditor)(host, {
68
+ initialLatex: input.initialLatex,
69
+ height: input.options.editor.height,
70
+ autofocus: input.options.editor.autofocus,
71
+ assets: input.options.editor.assets,
72
+ render: {
73
+ fontsize: input.options.editor.render.fontsize
74
+ }
75
+ });
76
+ let closed = false;
77
+ return new Promise((resolve) => {
78
+ const close = (payload) => {
79
+ if (closed) {
80
+ return;
81
+ }
82
+ closed = true;
83
+ mounted.destroy();
84
+ root.removeEventListener("click", onClick);
85
+ document.removeEventListener("keydown", onKeydown, true);
86
+ root.remove();
87
+ document.body.classList.remove("fx-formula-modal-open");
88
+ resolve(payload);
89
+ };
90
+ const submit = async () => {
91
+ try {
92
+ const latex = await mounted.getLatex();
93
+ close({ latex });
94
+ } catch (error) {
95
+ host.innerHTML = `
96
+ <div class="fx-formula-editor-error">
97
+ Failed to read FormulaX editor content.
98
+ <pre>${(0, import_editor.escapeHtml)(error instanceof Error ? error.message : String(error))}</pre>
99
+ </div>
100
+ `;
101
+ }
102
+ };
103
+ function onClick(event) {
104
+ const action = event.target.closest("[data-action]")?.dataset.action;
105
+ if (!action) {
106
+ return;
107
+ }
108
+ if (action === "submit") {
109
+ void submit();
110
+ return;
111
+ }
112
+ if (action === "cancel" || action === "close") {
113
+ close(null);
114
+ return;
115
+ }
116
+ if (action === "backdrop" && input.options.modal.closeOnBackdrop) {
117
+ close(null);
118
+ }
119
+ }
120
+ function onKeydown(event) {
121
+ if (event.key === "Escape") {
122
+ event.preventDefault();
123
+ close(null);
124
+ }
125
+ }
126
+ root.addEventListener("click", onClick);
127
+ document.addEventListener("keydown", onKeydown, true);
128
+ queueMicrotask(() => {
129
+ mounted.root.focus();
130
+ });
131
+ });
132
+ }
133
+
134
+ // src/index.ts
135
+ var FORMULAX_NODE_NAME = "formulaX";
136
+ function resolveOptions(options = {}) {
137
+ return {
138
+ formulaClassName: options.formulaClassName ?? import_editor2.DEFAULT_FORMULA_CLASS,
139
+ formulaAttributeName: options.formulaAttributeName ?? import_editor2.DEFAULT_FORMULA_ATTRIBUTE,
140
+ cursorStyle: options.cursorStyle ?? "pointer",
141
+ initialLatex: options.initialLatex ?? "",
142
+ modal: {
143
+ title: options.modal?.title ?? "FormulaX Editor",
144
+ insertText: options.modal?.insertText ?? "Insert",
145
+ updateText: options.modal?.updateText ?? "Update",
146
+ cancelText: options.modal?.cancelText ?? "Cancel",
147
+ closeOnBackdrop: options.modal?.closeOnBackdrop ?? true
148
+ },
149
+ editor: {
150
+ height: options.editor?.height ?? "100%",
151
+ autofocus: options.editor?.autofocus ?? true,
152
+ assets: options.editor?.assets ?? {},
153
+ render: {
154
+ fontsize: options.editor?.render?.fontsize ?? 40
155
+ }
156
+ }
157
+ };
158
+ }
159
+ var formulaXNodeConfig = {
160
+ name: FORMULAX_NODE_NAME,
161
+ group: "inline",
162
+ inline: true,
163
+ atom: true,
164
+ selectable: true,
165
+ addOptions() {
166
+ return resolveOptions();
167
+ },
168
+ onCreate() {
169
+ if (typeof document !== "undefined") {
170
+ (0, import_editor2.ensureFormulaXModalStyles)(document);
171
+ }
172
+ },
173
+ addAttributes() {
174
+ return {
175
+ latex: {
176
+ default: ""
177
+ }
178
+ };
179
+ },
180
+ parseHTML() {
181
+ return [{
182
+ tag: "span[data-formulax]",
183
+ getAttrs: (element) => {
184
+ if (!(element instanceof HTMLElement)) {
185
+ return false;
186
+ }
187
+ return {
188
+ latex: (0, import_editor2.getFormulaLatexFromElement)(element, this.options.formulaAttributeName)
189
+ };
190
+ }
191
+ }];
192
+ },
193
+ renderHTML({ node }) {
194
+ if (typeof document === "undefined") {
195
+ return [
196
+ "span",
197
+ {
198
+ "data-formulax": "true",
199
+ [this.options.formulaAttributeName]: node.attrs.latex,
200
+ "data-latex": node.attrs.latex
201
+ },
202
+ node.attrs.latex || "\\square"
203
+ ];
204
+ }
205
+ return createFormulaDomElement(document, node.attrs, this.options);
206
+ },
207
+ addCommands() {
208
+ return {
209
+ openFormulaX: () => () => {
210
+ const selectedFormula = getSelectedFormula(this.editor);
211
+ const initialLatex = selectedFormula?.attrs.latex ?? this.options.initialLatex;
212
+ void openFormulaXTiptapModal({
213
+ initialLatex,
214
+ isUpdate: Boolean(selectedFormula),
215
+ options: this.options
216
+ }).then((payload) => {
217
+ if (!payload) {
218
+ return;
219
+ }
220
+ applyFormulaPayload(this.editor, payload, selectedFormula);
221
+ this.editor.commands.focus();
222
+ });
223
+ return true;
224
+ }
225
+ };
226
+ },
227
+ addKeyboardShortcuts() {
228
+ return {
229
+ Enter: () => {
230
+ if (!getSelectedFormula(this.editor)) {
231
+ return false;
232
+ }
233
+ return this.editor.commands.openFormulaX();
234
+ },
235
+ Space: () => {
236
+ if (!getSelectedFormula(this.editor)) {
237
+ return false;
238
+ }
239
+ return this.editor.commands.openFormulaX();
240
+ }
241
+ };
242
+ },
243
+ addNodeView() {
244
+ return ({ editor, getPos, node }) => {
245
+ const dom = createFormulaDomElement(document, node.attrs, this.options) ?? document.createElement("span");
246
+ dom.classList.add("formulax-math--interactive");
247
+ void renderFormulaIntoElement(dom, node.attrs, this.options);
248
+ const selectNode = () => {
249
+ const position = getPos();
250
+ if (typeof position !== "number") {
251
+ return;
252
+ }
253
+ editor.commands.setNodeSelection?.(position);
254
+ };
255
+ dom.addEventListener("click", (event) => {
256
+ event.preventDefault();
257
+ selectNode();
258
+ });
259
+ dom.addEventListener("dblclick", (event) => {
260
+ event.preventDefault();
261
+ event.stopPropagation();
262
+ selectNode();
263
+ editor.commands.openFormulaX();
264
+ });
265
+ return {
266
+ dom,
267
+ update: (updatedNode) => {
268
+ if (updatedNode.type.name !== FORMULAX_NODE_NAME) {
269
+ return false;
270
+ }
271
+ syncFormulaDomElement(dom, updatedNode.attrs, this.options);
272
+ void renderFormulaIntoElement(dom, updatedNode.attrs, this.options);
273
+ return true;
274
+ },
275
+ selectNode: () => {
276
+ dom.classList.add("ProseMirror-selectednode");
277
+ },
278
+ deselectNode: () => {
279
+ dom.classList.remove("ProseMirror-selectednode");
280
+ }
281
+ };
282
+ };
283
+ }
284
+ };
285
+ function createFormulaXNode(nodeFactory = import_core.Node, options) {
286
+ const extension = nodeFactory.create(formulaXNodeConfig);
287
+ return options ? extension.configure(options) : extension;
288
+ }
289
+ var FormulaXNode = createFormulaXNode();
290
+ var createFormulaXPayload = (latex) => (0, import_core2.parseLatex)(latex);
291
+ var serializeFormulaXPayload = (doc) => (0, import_core2.serializeLatex)(doc);
292
+ function applyFormulaPayload(editor, payload, selectedFormula) {
293
+ const latex = payload.latex.trim();
294
+ if (selectedFormula) {
295
+ if (!latex) {
296
+ editor.chain().focus().deleteRange({
297
+ from: selectedFormula.from,
298
+ to: selectedFormula.to
299
+ }).run();
300
+ return;
301
+ }
302
+ editor.chain().focus().insertContentAt(
303
+ {
304
+ from: selectedFormula.from,
305
+ to: selectedFormula.to
306
+ },
307
+ createFormulaNodeContent(payload)
308
+ ).run();
309
+ return;
310
+ }
311
+ if (!latex) {
312
+ return;
313
+ }
314
+ editor.chain().focus().insertContent(createFormulaNodeContent(payload)).run();
315
+ }
316
+ function getSelectedFormula(editor) {
317
+ const { selection } = editor.state;
318
+ const node = selection.node;
319
+ if (node?.type?.name !== FORMULAX_NODE_NAME) {
320
+ return null;
321
+ }
322
+ return {
323
+ from: selection.from,
324
+ to: selection.to,
325
+ attrs: {
326
+ latex: node.attrs?.latex ?? ""
327
+ }
328
+ };
329
+ }
330
+ function createFormulaNodeContent(payload) {
331
+ return {
332
+ type: FORMULAX_NODE_NAME,
333
+ attrs: {
334
+ latex: payload.latex
335
+ }
336
+ };
337
+ }
338
+ function createFormulaDomElement(ownerDocument, attrs, options) {
339
+ return (0, import_editor2.createFormulaElement)(ownerDocument, attrs.latex, {
340
+ attributeName: options.formulaAttributeName,
341
+ className: options.formulaClassName,
342
+ cursorStyle: options.cursorStyle
343
+ });
344
+ }
345
+ function syncFormulaDomElement(dom, attrs, options) {
346
+ const next = createFormulaDomElement(dom.ownerDocument ?? document, attrs, options);
347
+ if (!next) {
348
+ return;
349
+ }
350
+ dom.replaceChildren(...Array.from(next.childNodes));
351
+ Array.from(dom.attributes).forEach((attribute) => {
352
+ if (attribute.name === "class") {
353
+ return;
354
+ }
355
+ dom.removeAttribute(attribute.name);
356
+ });
357
+ Array.from(next.attributes).forEach((attribute) => {
358
+ dom.setAttribute(attribute.name, attribute.value);
359
+ });
360
+ }
361
+ var formulaRenderCache = /* @__PURE__ */ new Map();
362
+ async function renderFormulaIntoElement(dom, attrs, options) {
363
+ const latex = attrs.latex.trim();
364
+ const renderToken = `${latex}::${Date.now()}::${Math.random().toString(36).slice(2, 8)}`;
365
+ dom.dataset.renderToken = renderToken;
366
+ if (!latex) {
367
+ const placeholder = dom.querySelector(`.${options.formulaClassName}__render`);
368
+ if (placeholder) {
369
+ placeholder.textContent = "\\square";
370
+ }
371
+ return;
372
+ }
373
+ try {
374
+ const markup = await renderFormulaSvgMarkup(latex, options);
375
+ if (dom.dataset.renderToken !== renderToken) {
376
+ return;
377
+ }
378
+ dom.innerHTML = markup;
379
+ } catch (error) {
380
+ if (dom.dataset.renderToken !== renderToken) {
381
+ return;
382
+ }
383
+ console.error("[FormulaX] Failed to render Tiptap formula node:", error);
384
+ const placeholder = dom.querySelector(`.${options.formulaClassName}__render`);
385
+ if (placeholder) {
386
+ placeholder.textContent = latex;
387
+ }
388
+ }
389
+ }
390
+ function renderFormulaSvgMarkup(latex, options) {
391
+ const cached = formulaRenderCache.get(latex);
392
+ if (cached) {
393
+ return cached;
394
+ }
395
+ const pending = (async () => {
396
+ const host = document.createElement("div");
397
+ host.style.position = "fixed";
398
+ host.style.left = "-100000px";
399
+ host.style.top = "0";
400
+ host.style.width = "1px";
401
+ host.style.height = "1px";
402
+ host.style.opacity = "0";
403
+ host.style.pointerEvents = "none";
404
+ host.setAttribute("aria-hidden", "true");
405
+ document.body.appendChild(host);
406
+ const mounted = (0, import_editor2.mountFormulaXKityEditor)(host, {
407
+ initialLatex: latex,
408
+ height: options.editor.height,
409
+ autofocus: false,
410
+ assets: options.editor.assets,
411
+ render: {
412
+ fontsize: options.editor.render.fontsize
413
+ }
414
+ });
415
+ try {
416
+ return await mounted.getRenderHtml();
417
+ } finally {
418
+ mounted.destroy();
419
+ host.remove();
420
+ }
421
+ })();
422
+ formulaRenderCache.set(latex, pending);
423
+ pending.catch(() => {
424
+ if (formulaRenderCache.get(latex) === pending) {
425
+ formulaRenderCache.delete(latex);
426
+ }
427
+ });
428
+ return pending;
429
+ }
430
+ // Annotate the CommonJS export names for ESM import in node:
431
+ 0 && (module.exports = {
432
+ FORMULAX_NODE_NAME,
433
+ FormulaXNode,
434
+ createFormulaXNode,
435
+ createFormulaXPayload,
436
+ openFormulaXTiptapModal,
437
+ resolveOptions,
438
+ serializeFormulaXPayload
439
+ });
440
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +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 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\nconst formulaXNodeConfig: any = {\n name: FORMULAX_NODE_NAME,\n group: 'inline',\n inline: true,\n atom: true,\n selectable: true,\n addOptions() {\n return resolveOptions();\n },\n onCreate() {\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);\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);\n this.editor.commands.focus();\n });\n\n return true;\n },\n };\n },\n addKeyboardShortcuts() {\n return {\n Enter: () => {\n if (!getSelectedFormula(this.editor)) {\n return false;\n }\n\n return this.editor.commands.openFormulaX();\n },\n Space: () => {\n if (!getSelectedFormula(this.editor)) {\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 !== FORMULAX_NODE_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\nexport interface TiptapNodeFactory {\n create: typeof Node.create;\n}\n\nexport function createFormulaXNode(\n nodeFactory: TiptapNodeFactory = Node,\n options?: FormulaXTiptapOptions,\n) {\n const extension = nodeFactory.create(formulaXNodeConfig) as any;\n return options ? extension.configure(options) : extension;\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): 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),\n ).run();\n return;\n }\n\n if (!latex) {\n return;\n }\n\n editor.chain().focus().insertContent(createFormulaNodeContent(payload)).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}): SelectedFormula | null {\n const { selection } = editor.state;\n const node = selection.node;\n\n if (node?.type?.name !== FORMULAX_NODE_NAME) {\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(payload: FormulaXPayload): {\n type: string;\n attrs: FormulaXNodeAttributes;\n} {\n return {\n type: FORMULAX_NODE_NAME,\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"]}