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