@formulaxjs/tinymce 0.1.2 → 0.2.1
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/README.md +48 -31
- package/README.zh-CN.md +48 -31
- package/dist/index.cjs +88 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.global.js +5092 -4425
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +75 -11
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
getFormulaLatexFromElement,
|
|
13
13
|
isFormulaElement,
|
|
14
14
|
replaceFormulaElement
|
|
15
|
-
} from "@formulaxjs/
|
|
15
|
+
} from "@formulaxjs/renderer";
|
|
16
16
|
function createTinyMceFormulaMarkup(latex, options = {}) {
|
|
17
17
|
return createFormulaMarkup(latex, {
|
|
18
18
|
...options,
|
|
@@ -85,12 +85,30 @@ function warnUnsupportedTinyMceVersion(tinymce) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
// src/plugin.ts
|
|
89
|
+
import { scheduleFormulaXEditorPreload } from "@formulaxjs/editor";
|
|
90
|
+
import { createKityFormulaRenderer } from "@formulaxjs/renderer-kity";
|
|
91
|
+
|
|
92
|
+
// src/modal.ts
|
|
93
|
+
import {
|
|
94
|
+
clearFormulaXPerfMarks,
|
|
95
|
+
markFormulaXPerf,
|
|
96
|
+
measureFormulaXPerf,
|
|
97
|
+
recordFormulaXPerfPoint,
|
|
98
|
+
renderFormulaXEditorLoadingState,
|
|
99
|
+
waitForFormulaXAnimationFrame
|
|
100
|
+
} from "@formulaxjs/editor";
|
|
101
|
+
|
|
88
102
|
// src/styles.ts
|
|
103
|
+
import {
|
|
104
|
+
ensureFormulaXBaseStyles
|
|
105
|
+
} from "@formulaxjs/renderer";
|
|
89
106
|
import {
|
|
90
107
|
ensureFormulaXModalStyles,
|
|
91
108
|
formulaXModalStyles
|
|
92
109
|
} from "@formulaxjs/editor";
|
|
93
110
|
function ensureTinyMceStyles(doc = document) {
|
|
111
|
+
ensureFormulaXBaseStyles(doc);
|
|
94
112
|
ensureFormulaXModalStyles(doc);
|
|
95
113
|
}
|
|
96
114
|
|
|
@@ -98,7 +116,6 @@ function ensureTinyMceStyles(doc = document) {
|
|
|
98
116
|
import {
|
|
99
117
|
mountFormulaXEditor
|
|
100
118
|
} from "@formulaxjs/editor";
|
|
101
|
-
import { serializeSvgForInsertion } from "@formulaxjs/renderer";
|
|
102
119
|
function mountFormulaXEditorInModal(root, input) {
|
|
103
120
|
const options = {
|
|
104
121
|
initialLatex: input.initialLatex,
|
|
@@ -114,6 +131,8 @@ function mountFormulaXEditorInModal(root, input) {
|
|
|
114
131
|
|
|
115
132
|
// src/modal.ts
|
|
116
133
|
function openFormulaXOverlayModal(input) {
|
|
134
|
+
recordFormulaXPerfPoint("fx:modal:open:start");
|
|
135
|
+
const modalOpenStart = markFormulaXPerf("fx:modal:open:start:scope");
|
|
117
136
|
ensureTinyMceStyles(document);
|
|
118
137
|
const { editor, target, options } = input;
|
|
119
138
|
const initialLatex = target ? getFormulaLatexFromElement(target, options.formulaAttributeName) : input.initialLatex ?? options.initialLatex ?? "";
|
|
@@ -141,17 +160,45 @@ function openFormulaXOverlayModal(input) {
|
|
|
141
160
|
`;
|
|
142
161
|
document.body.appendChild(root);
|
|
143
162
|
document.body.classList.add("fx-formula-modal-open");
|
|
163
|
+
const modalDomReadyMark = markFormulaXPerf("fx:modal:dom-ready");
|
|
164
|
+
measureFormulaXPerf("fx:modal:dom-ready", modalOpenStart, modalDomReadyMark);
|
|
165
|
+
clearFormulaXPerfMarks(modalDomReadyMark);
|
|
144
166
|
const host = root.querySelector(".fx-formula-editor-host");
|
|
145
167
|
if (!host) {
|
|
146
168
|
root.remove();
|
|
169
|
+
clearFormulaXPerfMarks(modalOpenStart);
|
|
147
170
|
throw new Error("[FormulaX] Modal editor host not found.");
|
|
148
171
|
}
|
|
149
|
-
|
|
172
|
+
renderFormulaXEditorLoadingState(host);
|
|
150
173
|
let closed = false;
|
|
174
|
+
let mounted = null;
|
|
175
|
+
const mountedPromise = waitForFormulaXAnimationFrame().then(() => {
|
|
176
|
+
if (closed) {
|
|
177
|
+
clearFormulaXPerfMarks(modalOpenStart);
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
const mountStartMark = markFormulaXPerf("fx:modal:editor-mount-start");
|
|
181
|
+
measureFormulaXPerf("fx:modal:editor-mount-start", modalOpenStart, mountStartMark);
|
|
182
|
+
clearFormulaXPerfMarks(mountStartMark);
|
|
183
|
+
const nextMounted = mountFormulaXEditorInModal(host, { initialLatex, options });
|
|
184
|
+
mounted = nextMounted;
|
|
185
|
+
const mountedMark = markFormulaXPerf("fx:modal:editor-mounted");
|
|
186
|
+
measureFormulaXPerf("fx:modal:editor-mounted", modalOpenStart, mountedMark);
|
|
187
|
+
clearFormulaXPerfMarks(mountedMark, modalOpenStart);
|
|
188
|
+
queueMicrotask(() => {
|
|
189
|
+
if (!closed) {
|
|
190
|
+
nextMounted.root.focus();
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
return nextMounted;
|
|
194
|
+
}).catch((error) => {
|
|
195
|
+
clearFormulaXPerfMarks(modalOpenStart);
|
|
196
|
+
throw error;
|
|
197
|
+
});
|
|
151
198
|
const close = () => {
|
|
152
199
|
if (closed) return;
|
|
153
200
|
closed = true;
|
|
154
|
-
mounted
|
|
201
|
+
mounted?.destroy();
|
|
155
202
|
root.removeEventListener("click", onClick);
|
|
156
203
|
document.removeEventListener("keydown", onKeydown, true);
|
|
157
204
|
root.remove();
|
|
@@ -159,8 +206,15 @@ function openFormulaXOverlayModal(input) {
|
|
|
159
206
|
editor.focus?.();
|
|
160
207
|
};
|
|
161
208
|
const submit = async () => {
|
|
162
|
-
const
|
|
163
|
-
|
|
209
|
+
const activeMounted = mounted ?? await mountedPromise;
|
|
210
|
+
if (!activeMounted) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const latex = await activeMounted.getLatex();
|
|
214
|
+
const renderHtml = latex.trim() ? (await options.renderer.renderLatex(latex, {
|
|
215
|
+
fontSize: options.editor.render?.fontsize ?? 40,
|
|
216
|
+
className: options.formulaClassName
|
|
217
|
+
})).html : void 0;
|
|
164
218
|
runEditorTransaction(editor, () => {
|
|
165
219
|
if (target) {
|
|
166
220
|
const next = replaceFormulaElement(target, latex, {
|
|
@@ -209,9 +263,6 @@ function openFormulaXOverlayModal(input) {
|
|
|
209
263
|
}
|
|
210
264
|
root.addEventListener("click", onClick);
|
|
211
265
|
document.addEventListener("keydown", onKeydown, true);
|
|
212
|
-
queueMicrotask(() => {
|
|
213
|
-
mounted.root.focus();
|
|
214
|
-
});
|
|
215
266
|
return { close };
|
|
216
267
|
}
|
|
217
268
|
function runEditorTransaction(editor, mutation) {
|
|
@@ -345,8 +396,13 @@ function resolveOptions(options = {}) {
|
|
|
345
396
|
cursorStyle: options.cursorStyle ?? "pointer",
|
|
346
397
|
formulaClassName: options.formulaClassName ?? "formulax-math",
|
|
347
398
|
formulaAttributeName: options.formulaAttributeName ?? "data-formulax-latex",
|
|
348
|
-
renderMode: options.renderMode ?? "text",
|
|
349
399
|
initialLatex: options.initialLatex ?? "",
|
|
400
|
+
renderer: options.renderer ?? createKityFormulaRenderer({
|
|
401
|
+
fontSize: options.editor?.render?.fontsize ?? 40,
|
|
402
|
+
height: options.editor?.height ?? "100%",
|
|
403
|
+
assets: options.editor?.assets ?? {}
|
|
404
|
+
}),
|
|
405
|
+
preload: options.preload ?? "idle",
|
|
350
406
|
modal: {
|
|
351
407
|
title: options.modal?.title ?? "FormulaX",
|
|
352
408
|
insertText: options.modal?.insertText ?? "Insert",
|
|
@@ -357,7 +413,6 @@ function resolveOptions(options = {}) {
|
|
|
357
413
|
closeOnBackdrop: options.modal?.closeOnBackdrop ?? true
|
|
358
414
|
},
|
|
359
415
|
editor: {
|
|
360
|
-
mode: "kity",
|
|
361
416
|
height: options.editor?.height ?? "100%",
|
|
362
417
|
autofocus: options.editor?.autofocus ?? true,
|
|
363
418
|
assets: options.editor?.assets ?? {},
|
|
@@ -377,6 +432,7 @@ function registerFormulaXTinyMcePlugin(tinymce, options = {}) {
|
|
|
377
432
|
resolved.pluginName,
|
|
378
433
|
function FormulaXTinyMcePlugin(editor) {
|
|
379
434
|
const compat = createTinyMceCompat(editor, tinymce);
|
|
435
|
+
let preloadCleanup = null;
|
|
380
436
|
editor.schema?.addValidElements?.(FORMULAX_SVG_VALID_ELEMENTS);
|
|
381
437
|
const open = (target) => {
|
|
382
438
|
const resolvedTarget = target ?? compat.getSelectedFormulaElement();
|
|
@@ -405,6 +461,10 @@ function registerFormulaXTinyMcePlugin(tinymce, options = {}) {
|
|
|
405
461
|
if (editorDoc) {
|
|
406
462
|
ensureTinyMceStyles(editorDoc);
|
|
407
463
|
}
|
|
464
|
+
preloadCleanup = scheduleFormulaXEditorPreload(
|
|
465
|
+
resolved.preload,
|
|
466
|
+
editor.getBody?.() ?? null
|
|
467
|
+
);
|
|
408
468
|
});
|
|
409
469
|
editor.on("dblclick", (event) => {
|
|
410
470
|
const formula = findFormulaElement(event.target);
|
|
@@ -420,6 +480,10 @@ function registerFormulaXTinyMcePlugin(tinymce, options = {}) {
|
|
|
420
480
|
e.preventDefault?.();
|
|
421
481
|
open(formula);
|
|
422
482
|
});
|
|
483
|
+
editor.on("remove", () => {
|
|
484
|
+
preloadCleanup?.();
|
|
485
|
+
preloadCleanup = null;
|
|
486
|
+
});
|
|
423
487
|
return void 0;
|
|
424
488
|
}
|
|
425
489
|
);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/markup.ts","../src/compat.ts","../src/styles.ts","../src/editor-host.ts","../src/modal.ts","../src/plugin.ts"],"sourcesContent":["import { parseLatex, serializeLatex, type FormulaDoc } from '@formulaxjs/core';\nimport {\n DEFAULT_FORMULA_ATTRIBUTE,\n DEFAULT_FORMULA_CLASS,\n FORMULA_FLAG_ATTRIBUTE,\n createFormulaElement,\n createFormulaMarkup,\n escapeAttribute,\n escapeHtml,\n findFormulaElement,\n getFormulaLatexFromElement,\n isFormulaElement,\n replaceFormulaElement,\n type CreateFormulaMarkupOptions,\n} from '@formulaxjs/editor';\n\nexport type { CreateFormulaMarkupOptions };\n\nexport function createTinyMceFormulaMarkup(\n latex: string,\n options: CreateFormulaMarkupOptions = {},\n): string {\n return createFormulaMarkup(latex, {\n ...options,\n extraAttributes: {\n ...options.extraAttributes,\n 'data-mce-contenteditable': 'false',\n },\n });\n}\n\r\nexport function parseTinyMceFormulaMarkup(latex: string): FormulaDoc {\r\n return parseLatex(latex);\r\n}\r\n\r\nexport function serializeTinyMceFormulaMarkup(\r\n doc: FormulaDoc,\r\n options: CreateFormulaMarkupOptions = {},\r\n): string {\r\n return createTinyMceFormulaMarkup(serializeLatex(doc), options);\r\n}\r\n\r\nexport function createTinyMceFormulaElement(\n ownerDocument: Document,\n latex: string,\n options: CreateFormulaMarkupOptions = {},\n): HTMLElement | null {\n return createFormulaElement(ownerDocument, latex, {\n ...options,\n extraAttributes: {\n ...options.extraAttributes,\n 'data-mce-contenteditable': 'false',\n },\n });\n}\n\nexport {\n DEFAULT_FORMULA_ATTRIBUTE,\n DEFAULT_FORMULA_CLASS,\n FORMULA_FLAG_ATTRIBUTE,\n escapeAttribute,\n escapeHtml,\n findFormulaElement,\n getFormulaLatexFromElement,\n isFormulaElement,\n replaceFormulaElement,\n};\n","import type { TinyMceEditorLike, TinyMceLike } from './types';\nimport { findFormulaElement } from './markup';\n\nexport interface TinyMceCompat {\n major: number;\n insertContent: (html: string) => void;\n dispatchEvent: (name: string, detail?: Record<string, unknown>) => void;\n getSelectedFormulaElement: () => HTMLElement | null;\n getEditorDocument: () => Document;\n getEditorWindow: () => Window;\n getEditorBody: () => HTMLElement | null;\n focus: () => void;\n}\n\nexport function getTinyMceMajorVersion(tinymce?: TinyMceLike): number {\n const raw = tinymce?.majorVersion;\n const major = typeof raw === 'string' ? Number.parseInt(raw, 10) : Number(raw);\n return Number.isFinite(major) ? major : 0;\n}\n\nexport function createTinyMceCompat(\n editor: TinyMceEditorLike,\n tinymce?: TinyMceLike,\n): TinyMceCompat {\n const major = getTinyMceMajorVersion(tinymce);\n\n return {\n major,\n\n insertContent(html: string): void {\n editor.insertContent(html);\n },\n\n dispatchEvent(name: string, detail?: Record<string, unknown>): void {\n if (typeof editor.dispatch === 'function') {\n editor.dispatch(name, detail);\n return;\n }\n\n if (typeof editor.fire === 'function') {\n editor.fire(name, detail);\n }\n },\n\n getSelectedFormulaElement(): HTMLElement | null {\n const node = editor.selection?.getNode?.();\n return findFormulaElement(node ?? null);\n },\n\n getEditorDocument(): Document {\n return editor.getDoc?.() ?? document;\n },\n\n getEditorWindow(): Window {\n return editor.getWin?.() ?? window;\n },\n\n getEditorBody(): HTMLElement | null {\n return editor.getBody?.() ?? null;\n },\n\n focus(): void {\n editor.focus?.();\n },\n };\n}\n\nexport function warnUnsupportedTinyMceVersion(tinymce?: TinyMceLike): void {\n const major = getTinyMceMajorVersion(tinymce);\n if (major > 0 && (major < 5 || major >= 9)) {\n console.warn(`[FormulaX] TinyMCE ${major} is not officially supported. Expected >=5 <9.`);\n }\n}\n","import {\n ensureFormulaXModalStyles,\n formulaXModalStyles,\n} from '@formulaxjs/editor';\n\nexport const tinymceStyles = formulaXModalStyles;\n\nexport function ensureTinyMceStyles(doc: Document = document): void {\n ensureFormulaXModalStyles(doc);\n}\n","import {\n mountFormulaXEditor,\n type FormulaXEditorOptions,\n} from '@formulaxjs/editor';\nimport { serializeSvgForInsertion } from '@formulaxjs/renderer';\nimport type { MountedFormulaXEditor, RequiredFormulaXTinyMceOptions } from './types';\n\nexport interface MountFormulaXEditorOptions {\n initialLatex?: string;\n options: RequiredFormulaXTinyMceOptions;\n}\n\nexport function mountFormulaXEditorInModal(\n root: HTMLElement,\n input: MountFormulaXEditorOptions,\n): MountedFormulaXEditor {\n const options: FormulaXEditorOptions = {\n initialLatex: input.initialLatex,\n height: input.options.editor.height ?? '100%',\n autofocus: input.options.editor.autofocus ?? true,\n assets: input.options.editor.assets,\n render: {\n fontsize: input.options.editor.render?.fontsize ?? 40,\n },\n };\n return mountFormulaXEditor(root, options);\n}\n\nexport { serializeSvgForInsertion };\n","import type { FormulaXModalOpenOptions, TinyMceEditorLike } from './types';\r\nimport { ensureTinyMceStyles } from './styles';\r\nimport { mountFormulaXEditorInModal } from './editor-host';\r\nimport {\r\n createTinyMceFormulaElement,\r\n createTinyMceFormulaMarkup,\r\n escapeAttribute,\r\n escapeHtml,\r\n getFormulaLatexFromElement,\r\n replaceFormulaElement,\r\n} from './markup';\r\n\r\nexport interface OpenFormulaXModalResult {\r\n close: () => void;\r\n}\r\n\r\nexport function openFormulaXOverlayModal(input: FormulaXModalOpenOptions): OpenFormulaXModalResult {\n ensureTinyMceStyles(document);\n\r\n const { editor, target, options } = input;\r\n const initialLatex = target\r\n ? getFormulaLatexFromElement(target, options.formulaAttributeName)\r\n : input.initialLatex ?? options.initialLatex ?? '';\r\n\r\n const root = document.createElement('div');\n root.className = 'fx-formula-modal-root';\n root.setAttribute('data-formulax-modal', 'true');\n\r\n const isUpdate = Boolean(target);\r\n const submitText = isUpdate ? options.modal.updateText : options.modal.insertText;\r\n const title = options.modal.title || (isUpdate ? 'Edit Formula' : 'Insert Formula');\r\n\r\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(title)}\">\n <header class=\"fx-formula-modal__header\">\n <h2 class=\"fx-formula-modal__title\">${escapeHtml(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(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 throw new Error('[FormulaX] Modal editor host not found.');\n }\r\n\r\n const mounted = mountFormulaXEditorInModal(host, { initialLatex, options });\r\n let closed = false;\r\n\r\n const close = (): void => {\r\n if (closed) return;\r\n closed = true;\r\n\r\n mounted.destroy();\r\n root.removeEventListener('click', onClick);\n document.removeEventListener('keydown', onKeydown, true);\n root.remove();\n document.body.classList.remove('fx-formula-modal-open');\n editor.focus?.();\n };\n\r\n const submit = async (): Promise<void> => {\r\n const latex = await mounted.getLatex();\r\n const renderHtml = mounted.getRenderHtml ? await mounted.getRenderHtml() : undefined;\r\n\r\n runEditorTransaction(editor, () => {\r\n if (target) {\n const next = replaceFormulaElement(target, latex, {\n attributeName: options.formulaAttributeName,\n className: options.formulaClassName,\n cursorStyle: options.cursorStyle,\n renderHtml,\n });\n if (next) {\n moveSelectionAfterNode(editor, next);\n }\n } else {\n insertFormulaElementIntoEditor(\n editor,\n latex,\n options.formulaAttributeName,\n options.formulaClassName,\n options.cursorStyle,\n renderHtml,\n );\n }\n\r\n notifyEditorChanged(editor);\r\n });\r\n\r\n close();\r\n };\r\n\r\n function onClick(event: MouseEvent): void {\r\n const action = (event.target as HTMLElement).closest<HTMLElement>('[data-action]')?.dataset.action;\r\n if (!action) return;\r\n\r\n if (action === 'submit') {\r\n void submit();\r\n return;\r\n }\r\n\r\n if (action === 'cancel' || action === 'close') {\r\n close();\r\n return;\r\n }\r\n\r\n if (action === 'backdrop' && options.modal.closeOnBackdrop) {\r\n close();\r\n }\r\n }\r\n\r\n function onKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'Escape') {\r\n event.preventDefault();\r\n close();\r\n }\r\n }\r\n\r\n root.addEventListener('click', onClick);\r\n document.addEventListener('keydown', onKeydown, true);\r\n\r\n queueMicrotask(() => {\r\n mounted.root.focus();\r\n });\r\n\r\n return { close };\r\n}\r\n\r\nfunction runEditorTransaction(editor: TinyMceEditorLike, mutation: () => void): void {\r\n if (typeof editor.undoManager?.transact === 'function') {\r\n editor.undoManager.transact(mutation);\r\n return;\r\n }\r\n\r\n mutation();\r\n editor.undoManager?.add?.();\r\n}\r\n\r\nfunction insertFormulaElementIntoEditor(\n editor: TinyMceEditorLike,\n latex: string,\n attributeName: string,\n className: string,\n cursorStyle: string,\n renderHtml?: string,\n): void {\n const editorDoc = editor.getDoc?.() ?? document;\n const next = createTinyMceFormulaElement(editorDoc, latex, {\n attributeName,\n className,\n cursorStyle,\n renderHtml,\n });\n\r\n if (next && insertNodeAtEditorSelection(editor, next)) {\r\n return;\r\n }\r\n\r\n insertFormulaElementWithPlaceholder(editor, latex, attributeName, className, cursorStyle, renderHtml);\n}\n\r\nfunction insertNodeAtEditorSelection(editor: TinyMceEditorLike, node: HTMLElement): boolean {\r\n const range = getEditorRange(editor);\r\n if (!range || !isRangeInsideEditor(editor, range)) {\r\n return false;\r\n }\r\n\r\n try {\r\n range.deleteContents();\r\n range.insertNode(node);\r\n moveSelectionAfterNode(editor, node);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nfunction getEditorRange(editor: TinyMceEditorLike): Range | null {\r\n try {\r\n return editor.selection?.getRng?.() ?? null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nfunction isRangeInsideEditor(editor: TinyMceEditorLike, range: Range): boolean {\r\n const editorDoc = editor.getDoc?.() ?? document;\r\n if (range.startContainer.ownerDocument !== editorDoc || range.endContainer.ownerDocument !== editorDoc) {\r\n return false;\r\n }\r\n\r\n const body = editor.getBody?.();\r\n if (!body) {\r\n return true;\r\n }\r\n\r\n return body.contains(getRangeContainerElement(range.startContainer))\r\n && body.contains(getRangeContainerElement(range.endContainer));\r\n}\r\n\r\nfunction getRangeContainerElement(node: Node): Node {\r\n return node.nodeType === 1 ? node : node.parentNode ?? node;\r\n}\r\n\r\nfunction moveSelectionAfterNode(editor: TinyMceEditorLike, node: HTMLElement): void {\r\n const doc = node.ownerDocument;\r\n const range = doc.createRange();\r\n range.setStartAfter(node);\r\n range.collapse(true);\r\n\r\n try {\r\n editor.selection?.setRng?.(range);\r\n editor.selection?.collapse?.(false);\r\n } catch {\r\n // Ignore selection restoration failures across TinyMCE versions.\r\n }\r\n}\r\n\r\nfunction insertFormulaElementWithPlaceholder(\n editor: TinyMceEditorLike,\n latex: string,\n attributeName: string,\n className: string,\n cursorStyle: string,\n renderHtml?: string,\n): void {\n const editorDoc = editor.getDoc?.() ?? document;\r\n const marker = `fx-pending-${Math.random().toString(36).slice(2, 10)}`;\r\n editor.insertContent(`<span data-formulax-pending=\"${escapeAttribute(marker)}\"></span>`);\r\n\r\n const placeholder = editorDoc.querySelector<HTMLElement>(`[data-formulax-pending=\"${marker}\"]`);\r\n if (!placeholder) {\r\n const html = createTinyMceFormulaMarkup(latex, {\n attributeName,\n className,\n cursorStyle,\n renderHtml,\n });\n editor.insertContent(html);\r\n return;\r\n }\r\n\r\n const next = createTinyMceFormulaElement(editorDoc, latex, {\n attributeName,\n className,\n cursorStyle,\n renderHtml,\n });\n\r\n if (!next) {\r\n placeholder.remove();\r\n return;\r\n }\r\n\r\n placeholder.replaceWith(next);\r\n moveSelectionAfterNode(editor, next);\r\n}\r\n\r\nfunction notifyEditorChanged(editor: TinyMceEditorLike): void {\r\n editor.nodeChanged?.();\r\n\r\n if (typeof editor.dispatch === 'function') {\r\n editor.dispatch('change');\r\n return;\r\n }\r\n\r\n editor.fire?.('change');\r\n}\r\n","import type {\n FormulaXTinyMceOptions,\n RequiredFormulaXTinyMceOptions,\n TinyMceEditorLike,\n TinyMceLike,\n} from './types';\nimport { createTinyMceCompat, warnUnsupportedTinyMceVersion } from './compat';\nimport { findFormulaElement } from './markup';\nimport { openFormulaXOverlayModal } from './modal';\nimport { ensureTinyMceStyles } from './styles';\n\nconst FORMULAX_SVG_VALID_ELEMENTS = [\n 'svg[class|style|id|xmlns|xmlns:xlink|version|width|height|viewbox|font-size|focusable|role|tabindex|contenteditable|data-formulax|data-formulax-latex|data-latex|aria-hidden|preserveaspectratio]',\n 'defs[id|class|style]',\n 'style[type|media]',\n 'g[id|class|style|transform|fill|stroke|stroke-width|stroke-linecap|stroke-linejoin|opacity|font-family|font-size|font-style|font-weight|data-type|data-flag|data-root]',\n 'path[id|class|style|d|fill|stroke|stroke-width|stroke-linecap|stroke-linejoin|opacity|transform|data-type|data-mce-style]',\n 'use[id|class|style|x|y|width|height|href|xlink:href|transform|fill|stroke|opacity]',\n 'text[id|class|style|x|y|dx|dy|fill|stroke|transform|font-family|font-size|font-style|font-weight|text-anchor|text-rendering|xml:space]',\n 'tspan[id|class|style|x|y|dx|dy|fill|stroke|transform|font-family|font-size|font-style|font-weight|text-anchor]',\n 'line[id|class|style|x1|y1|x2|y2|fill|stroke|stroke-width|stroke-linecap|opacity|transform]',\n 'rect[id|class|style|x|y|width|height|rx|ry|fill|stroke|stroke-width|opacity|transform]',\n 'circle[id|class|style|cx|cy|r|fill|stroke|stroke-width|opacity|transform]',\n 'ellipse[id|class|style|cx|cy|rx|ry|fill|stroke|stroke-width|opacity|transform]',\n 'polygon[id|class|style|points|fill|stroke|stroke-width|opacity|transform]',\n 'polyline[id|class|style|points|fill|stroke|stroke-width|opacity|transform]',\n].join(',');\n\nexport function resolveOptions(options: FormulaXTinyMceOptions = {}): RequiredFormulaXTinyMceOptions {\n return {\r\n pluginName: options.pluginName ?? 'formulax',\r\n buttonName: options.buttonName ?? 'formulax',\r\n menuItemName: options.menuItemName ?? 'formulax',\n toolbarText: options.toolbarText ?? 'FormulaX',\n tooltip: options.tooltip ?? 'Insert formula',\n cursorStyle: options.cursorStyle ?? 'pointer',\n formulaClassName: options.formulaClassName ?? 'formulax-math',\n formulaAttributeName: options.formulaAttributeName ?? 'data-formulax-latex',\n renderMode: options.renderMode ?? 'text',\n initialLatex: options.initialLatex ?? '',\r\n modal: {\r\n title: options.modal?.title ?? 'FormulaX',\r\n insertText: options.modal?.insertText ?? 'Insert',\r\n updateText: options.modal?.updateText ?? 'Update',\r\n cancelText: options.modal?.cancelText ?? 'Cancel',\r\n width: options.modal?.width ?? '1100px',\r\n height: options.modal?.height ?? 'auto',\r\n closeOnBackdrop: options.modal?.closeOnBackdrop ?? true,\r\n },\r\n editor: {\n mode: 'kity',\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 },\r\n };\r\n}\r\n\r\nexport function registerFormulaXTinyMcePlugin(\r\n tinymce: TinyMceLike,\r\n options: FormulaXTinyMceOptions = {},\r\n): void {\r\n if (!tinymce?.PluginManager?.add) {\r\n throw new Error('[FormulaX] Invalid TinyMCE instance: PluginManager.add is missing.');\r\n }\r\n\r\n warnUnsupportedTinyMceVersion(tinymce);\r\n const resolved = resolveOptions(options);\r\n\r\n tinymce.PluginManager.add(\n resolved.pluginName,\n function FormulaXTinyMcePlugin(editor: TinyMceEditorLike): undefined {\n const compat = createTinyMceCompat(editor, tinymce);\n editor.schema?.addValidElements?.(FORMULAX_SVG_VALID_ELEMENTS);\n\n const open = (target?: HTMLElement | null): void => {\n const resolvedTarget = target ?? compat.getSelectedFormulaElement();\n\n openFormulaXOverlayModal({\n editor,\n target: resolvedTarget,\r\n initialLatex: resolvedTarget ? undefined : resolved.initialLatex,\r\n options: resolved,\r\n });\r\n };\r\n\n editor.addCommand('FormulaXOpen', () => {\n open();\n });\n\r\n editor.ui?.registry?.addButton?.(resolved.buttonName, {\n text: resolved.toolbarText,\n tooltip: resolved.tooltip,\n onAction: () => editor.execCommand('FormulaXOpen'),\n });\n\r\n editor.ui?.registry?.addMenuItem?.(resolved.menuItemName, {\r\n text: resolved.toolbarText,\r\n onAction: () => editor.execCommand('FormulaXOpen'),\r\n });\r\n\n editor.on('init', () => {\n ensureTinyMceStyles(document);\n const editorDoc = editor.getDoc?.();\n if (editorDoc) {\n ensureTinyMceStyles(editorDoc);\n }\n });\n\r\n editor.on('dblclick', (event: unknown) => {\r\n const formula = findFormulaElement((event as MouseEvent).target as Node);\n if (!formula) return;\n (event as Event).preventDefault?.();\n open(formula);\n });\n\r\n editor.on('keydown', (event: unknown) => {\r\n const e = event as KeyboardEvent;\r\n if (e.key !== 'Enter' && e.key !== ' ') return;\n const formula = compat.getSelectedFormulaElement();\n if (!formula) return;\n e.preventDefault?.();\n open(formula);\n });\n\r\n return undefined;\r\n },\r\n );\r\n}\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/markup.ts","../src/compat.ts","../src/plugin.ts","../src/modal.ts","../src/styles.ts","../src/editor-host.ts"],"sourcesContent":["import { parseLatex, serializeLatex, type FormulaDoc } from '@formulaxjs/core';\nimport {\n DEFAULT_FORMULA_ATTRIBUTE,\n DEFAULT_FORMULA_CLASS,\n FORMULA_FLAG_ATTRIBUTE,\n createFormulaElement,\n createFormulaMarkup,\n escapeAttribute,\n escapeHtml,\n findFormulaElement,\n getFormulaLatexFromElement,\n isFormulaElement,\n replaceFormulaElement,\n type CreateFormulaMarkupOptions,\n} from '@formulaxjs/renderer';\n\nexport type { CreateFormulaMarkupOptions };\n\nexport function createTinyMceFormulaMarkup(\n latex: string,\n options: CreateFormulaMarkupOptions = {},\n): string {\n return createFormulaMarkup(latex, {\n ...options,\n extraAttributes: {\n ...options.extraAttributes,\n 'data-mce-contenteditable': 'false',\n },\n });\n}\n\r\nexport function parseTinyMceFormulaMarkup(latex: string): FormulaDoc {\r\n return parseLatex(latex);\r\n}\r\n\r\nexport function serializeTinyMceFormulaMarkup(\r\n doc: FormulaDoc,\r\n options: CreateFormulaMarkupOptions = {},\r\n): string {\r\n return createTinyMceFormulaMarkup(serializeLatex(doc), options);\r\n}\r\n\r\nexport function createTinyMceFormulaElement(\n ownerDocument: Document,\n latex: string,\n options: CreateFormulaMarkupOptions = {},\n): HTMLElement | null {\n return createFormulaElement(ownerDocument, latex, {\n ...options,\n extraAttributes: {\n ...options.extraAttributes,\n 'data-mce-contenteditable': 'false',\n },\n });\n}\n\nexport {\n DEFAULT_FORMULA_ATTRIBUTE,\n DEFAULT_FORMULA_CLASS,\n FORMULA_FLAG_ATTRIBUTE,\n escapeAttribute,\n escapeHtml,\n findFormulaElement,\n getFormulaLatexFromElement,\n isFormulaElement,\n replaceFormulaElement,\n};\n","import type { TinyMceEditorLike, TinyMceLike } from './types';\nimport { findFormulaElement } from './markup';\n\nexport interface TinyMceCompat {\n major: number;\n insertContent: (html: string) => void;\n dispatchEvent: (name: string, detail?: Record<string, unknown>) => void;\n getSelectedFormulaElement: () => HTMLElement | null;\n getEditorDocument: () => Document;\n getEditorWindow: () => Window;\n getEditorBody: () => HTMLElement | null;\n focus: () => void;\n}\n\nexport function getTinyMceMajorVersion(tinymce?: TinyMceLike): number {\n const raw = tinymce?.majorVersion;\n const major = typeof raw === 'string' ? Number.parseInt(raw, 10) : Number(raw);\n return Number.isFinite(major) ? major : 0;\n}\n\nexport function createTinyMceCompat(\n editor: TinyMceEditorLike,\n tinymce?: TinyMceLike,\n): TinyMceCompat {\n const major = getTinyMceMajorVersion(tinymce);\n\n return {\n major,\n\n insertContent(html: string): void {\n editor.insertContent(html);\n },\n\n dispatchEvent(name: string, detail?: Record<string, unknown>): void {\n if (typeof editor.dispatch === 'function') {\n editor.dispatch(name, detail);\n return;\n }\n\n if (typeof editor.fire === 'function') {\n editor.fire(name, detail);\n }\n },\n\n getSelectedFormulaElement(): HTMLElement | null {\n const node = editor.selection?.getNode?.();\n return findFormulaElement(node ?? null);\n },\n\n getEditorDocument(): Document {\n return editor.getDoc?.() ?? document;\n },\n\n getEditorWindow(): Window {\n return editor.getWin?.() ?? window;\n },\n\n getEditorBody(): HTMLElement | null {\n return editor.getBody?.() ?? null;\n },\n\n focus(): void {\n editor.focus?.();\n },\n };\n}\n\nexport function warnUnsupportedTinyMceVersion(tinymce?: TinyMceLike): void {\n const major = getTinyMceMajorVersion(tinymce);\n if (major > 0 && (major < 5 || major >= 9)) {\n console.warn(`[FormulaX] TinyMCE ${major} is not officially supported. Expected >=5 <9.`);\n }\n}\n","import type {\n FormulaXTinyMceOptions,\n RequiredFormulaXTinyMceOptions,\n TinyMceEditorLike,\n TinyMceLike,\n} from './types';\nimport { scheduleFormulaXEditorPreload } from '@formulaxjs/editor';\nimport { createKityFormulaRenderer } from '@formulaxjs/renderer-kity';\nimport { createTinyMceCompat, warnUnsupportedTinyMceVersion } from './compat';\nimport { findFormulaElement } from './markup';\nimport { openFormulaXOverlayModal } from './modal';\nimport { ensureTinyMceStyles } from './styles';\n\nconst FORMULAX_SVG_VALID_ELEMENTS = [\n 'svg[class|style|id|xmlns|xmlns:xlink|version|width|height|viewbox|font-size|focusable|role|tabindex|contenteditable|data-formulax|data-formulax-latex|data-latex|aria-hidden|preserveaspectratio]',\n 'defs[id|class|style]',\n 'style[type|media]',\n 'g[id|class|style|transform|fill|stroke|stroke-width|stroke-linecap|stroke-linejoin|opacity|font-family|font-size|font-style|font-weight|data-type|data-flag|data-root]',\n 'path[id|class|style|d|fill|stroke|stroke-width|stroke-linecap|stroke-linejoin|opacity|transform|data-type|data-mce-style]',\n 'use[id|class|style|x|y|width|height|href|xlink:href|transform|fill|stroke|opacity]',\n 'text[id|class|style|x|y|dx|dy|fill|stroke|transform|font-family|font-size|font-style|font-weight|text-anchor|text-rendering|xml:space]',\n 'tspan[id|class|style|x|y|dx|dy|fill|stroke|transform|font-family|font-size|font-style|font-weight|text-anchor]',\n 'line[id|class|style|x1|y1|x2|y2|fill|stroke|stroke-width|stroke-linecap|opacity|transform]',\n 'rect[id|class|style|x|y|width|height|rx|ry|fill|stroke|stroke-width|opacity|transform]',\n 'circle[id|class|style|cx|cy|r|fill|stroke|stroke-width|opacity|transform]',\n 'ellipse[id|class|style|cx|cy|rx|ry|fill|stroke|stroke-width|opacity|transform]',\n 'polygon[id|class|style|points|fill|stroke|stroke-width|opacity|transform]',\n 'polyline[id|class|style|points|fill|stroke|stroke-width|opacity|transform]',\n].join(',');\n\nexport function resolveOptions(options: FormulaXTinyMceOptions = {}): RequiredFormulaXTinyMceOptions {\n return {\r\n pluginName: options.pluginName ?? 'formulax',\r\n buttonName: options.buttonName ?? 'formulax',\r\n menuItemName: options.menuItemName ?? 'formulax',\n toolbarText: options.toolbarText ?? 'FormulaX',\n tooltip: options.tooltip ?? 'Insert formula',\n cursorStyle: options.cursorStyle ?? 'pointer',\n formulaClassName: options.formulaClassName ?? 'formulax-math',\n formulaAttributeName: options.formulaAttributeName ?? 'data-formulax-latex',\n initialLatex: options.initialLatex ?? '',\n renderer: options.renderer ?? createKityFormulaRenderer({\n fontSize: options.editor?.render?.fontsize ?? 40,\n height: options.editor?.height ?? '100%',\n assets: options.editor?.assets ?? {},\n }),\n preload: options.preload ?? 'idle',\n modal: {\n title: options.modal?.title ?? 'FormulaX',\n insertText: options.modal?.insertText ?? 'Insert',\n updateText: options.modal?.updateText ?? 'Update',\n cancelText: options.modal?.cancelText ?? 'Cancel',\n width: options.modal?.width ?? '1100px',\r\n height: options.modal?.height ?? 'auto',\r\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 },\r\n };\r\n}\r\n\r\nexport function registerFormulaXTinyMcePlugin(\r\n tinymce: TinyMceLike,\r\n options: FormulaXTinyMceOptions = {},\r\n): void {\r\n if (!tinymce?.PluginManager?.add) {\r\n throw new Error('[FormulaX] Invalid TinyMCE instance: PluginManager.add is missing.');\r\n }\r\n\r\n warnUnsupportedTinyMceVersion(tinymce);\r\n const resolved = resolveOptions(options);\r\n\r\n tinymce.PluginManager.add(\n resolved.pluginName,\n function FormulaXTinyMcePlugin(editor: TinyMceEditorLike): undefined {\n const compat = createTinyMceCompat(editor, tinymce);\n let preloadCleanup: (() => void) | null = null;\n editor.schema?.addValidElements?.(FORMULAX_SVG_VALID_ELEMENTS);\n\n const open = (target?: HTMLElement | null): void => {\n const resolvedTarget = target ?? compat.getSelectedFormulaElement();\n\n openFormulaXOverlayModal({\n editor,\n target: resolvedTarget,\r\n initialLatex: resolvedTarget ? undefined : resolved.initialLatex,\r\n options: resolved,\r\n });\r\n };\r\n\n editor.addCommand('FormulaXOpen', () => {\n open();\n });\n\r\n editor.ui?.registry?.addButton?.(resolved.buttonName, {\n text: resolved.toolbarText,\n tooltip: resolved.tooltip,\n onAction: () => editor.execCommand('FormulaXOpen'),\n });\n\r\n editor.ui?.registry?.addMenuItem?.(resolved.menuItemName, {\r\n text: resolved.toolbarText,\r\n onAction: () => editor.execCommand('FormulaXOpen'),\r\n });\r\n\n editor.on('init', () => {\n ensureTinyMceStyles(document);\n const editorDoc = editor.getDoc?.();\n if (editorDoc) {\n ensureTinyMceStyles(editorDoc);\n }\n\n preloadCleanup = scheduleFormulaXEditorPreload(\n resolved.preload,\n editor.getBody?.() ?? null,\n );\n });\n\r\n editor.on('dblclick', (event: unknown) => {\r\n const formula = findFormulaElement((event as MouseEvent).target as Node);\n if (!formula) return;\n (event as Event).preventDefault?.();\n open(formula);\n });\n\r\n editor.on('keydown', (event: unknown) => {\n const e = event as KeyboardEvent;\n if (e.key !== 'Enter' && e.key !== ' ') return;\n const formula = compat.getSelectedFormulaElement();\n if (!formula) return;\n e.preventDefault?.();\n open(formula);\n });\n\n editor.on('remove', () => {\n preloadCleanup?.();\n preloadCleanup = null;\n });\n\n return undefined;\n },\n );\r\n}\r\n","import type { FormulaXModalOpenOptions, TinyMceEditorLike } from './types';\nimport {\n clearFormulaXPerfMarks,\n markFormulaXPerf,\n measureFormulaXPerf,\n recordFormulaXPerfPoint,\n renderFormulaXEditorLoadingState,\n waitForFormulaXAnimationFrame,\n} from '@formulaxjs/editor';\nimport { ensureTinyMceStyles } from './styles';\nimport { mountFormulaXEditorInModal } from './editor-host';\nimport {\r\n createTinyMceFormulaElement,\r\n createTinyMceFormulaMarkup,\r\n escapeAttribute,\r\n escapeHtml,\r\n getFormulaLatexFromElement,\r\n replaceFormulaElement,\r\n} from './markup';\r\n\r\nexport interface OpenFormulaXModalResult {\r\n close: () => void;\r\n}\r\n\r\nexport function openFormulaXOverlayModal(input: FormulaXModalOpenOptions): OpenFormulaXModalResult {\n recordFormulaXPerfPoint('fx:modal:open:start');\n const modalOpenStart = markFormulaXPerf('fx:modal:open:start:scope');\n ensureTinyMceStyles(document);\n\r\n const { editor, target, options } = input;\r\n const initialLatex = target\r\n ? getFormulaLatexFromElement(target, options.formulaAttributeName)\r\n : input.initialLatex ?? options.initialLatex ?? '';\r\n\r\n const root = document.createElement('div');\n root.className = 'fx-formula-modal-root';\n root.setAttribute('data-formulax-modal', 'true');\n\r\n const isUpdate = Boolean(target);\r\n const submitText = isUpdate ? options.modal.updateText : options.modal.insertText;\r\n const title = options.modal.title || (isUpdate ? 'Edit Formula' : 'Insert Formula');\r\n\r\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(title)}\">\n <header class=\"fx-formula-modal__header\">\n <h2 class=\"fx-formula-modal__title\">${escapeHtml(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(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 const modalDomReadyMark = markFormulaXPerf('fx:modal:dom-ready');\n measureFormulaXPerf('fx:modal:dom-ready', modalOpenStart, modalDomReadyMark);\n clearFormulaXPerfMarks(modalDomReadyMark);\n\n const host = root.querySelector<HTMLElement>('.fx-formula-editor-host');\n if (!host) {\n root.remove();\n clearFormulaXPerfMarks(modalOpenStart);\n throw new Error('[FormulaX] Modal editor host not found.');\n }\n\n renderFormulaXEditorLoadingState(host);\n let closed = false;\n let mounted: ReturnType<typeof mountFormulaXEditorInModal> | null = null;\n\n const mountedPromise = waitForFormulaXAnimationFrame()\n .then(() => {\n if (closed) {\n clearFormulaXPerfMarks(modalOpenStart);\n return null;\n }\n\n const mountStartMark = markFormulaXPerf('fx:modal:editor-mount-start');\n measureFormulaXPerf('fx:modal:editor-mount-start', modalOpenStart, mountStartMark);\n clearFormulaXPerfMarks(mountStartMark);\n\n const nextMounted = mountFormulaXEditorInModal(host, { initialLatex, options });\n mounted = nextMounted;\n\n const mountedMark = markFormulaXPerf('fx:modal:editor-mounted');\n measureFormulaXPerf('fx:modal:editor-mounted', modalOpenStart, mountedMark);\n clearFormulaXPerfMarks(mountedMark, modalOpenStart);\n\n queueMicrotask(() => {\n if (!closed) {\n nextMounted.root.focus();\n }\n });\n\n return nextMounted;\n })\n .catch((error) => {\n clearFormulaXPerfMarks(modalOpenStart);\n throw error;\n });\n\n const close = (): void => {\n if (closed) return;\n closed = true;\n\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 editor.focus?.();\n };\n\n const submit = async (): Promise<void> => {\n const activeMounted = mounted ?? await mountedPromise;\n if (!activeMounted) {\n return;\n }\n\n const latex = await activeMounted.getLatex();\n const renderHtml = latex.trim()\n ? (await options.renderer.renderLatex(latex, {\n fontSize: options.editor.render?.fontsize ?? 40,\n className: options.formulaClassName,\n })).html\n : undefined;\n\r\n runEditorTransaction(editor, () => {\r\n if (target) {\n const next = replaceFormulaElement(target, latex, {\n attributeName: options.formulaAttributeName,\n className: options.formulaClassName,\n cursorStyle: options.cursorStyle,\n renderHtml,\n });\n if (next) {\n moveSelectionAfterNode(editor, next);\n }\n } else {\n insertFormulaElementIntoEditor(\n editor,\n latex,\n options.formulaAttributeName,\n options.formulaClassName,\n options.cursorStyle,\n renderHtml,\n );\n }\n\r\n notifyEditorChanged(editor);\r\n });\r\n\r\n close();\r\n };\r\n\r\n function onClick(event: MouseEvent): void {\r\n const action = (event.target as HTMLElement).closest<HTMLElement>('[data-action]')?.dataset.action;\r\n if (!action) return;\r\n\r\n if (action === 'submit') {\r\n void submit();\r\n return;\r\n }\r\n\r\n if (action === 'cancel' || action === 'close') {\r\n close();\r\n return;\r\n }\r\n\r\n if (action === 'backdrop' && options.modal.closeOnBackdrop) {\r\n close();\r\n }\r\n }\r\n\r\n function onKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'Escape') {\r\n event.preventDefault();\r\n close();\r\n }\r\n }\r\n\n root.addEventListener('click', onClick);\n document.addEventListener('keydown', onKeydown, true);\n\n return { close };\n}\n\r\nfunction runEditorTransaction(editor: TinyMceEditorLike, mutation: () => void): void {\r\n if (typeof editor.undoManager?.transact === 'function') {\r\n editor.undoManager.transact(mutation);\r\n return;\r\n }\r\n\r\n mutation();\r\n editor.undoManager?.add?.();\r\n}\r\n\r\nfunction insertFormulaElementIntoEditor(\n editor: TinyMceEditorLike,\n latex: string,\n attributeName: string,\n className: string,\n cursorStyle: string,\n renderHtml?: string,\n): void {\n const editorDoc = editor.getDoc?.() ?? document;\n const next = createTinyMceFormulaElement(editorDoc, latex, {\n attributeName,\n className,\n cursorStyle,\n renderHtml,\n });\n\r\n if (next && insertNodeAtEditorSelection(editor, next)) {\r\n return;\r\n }\r\n\r\n insertFormulaElementWithPlaceholder(editor, latex, attributeName, className, cursorStyle, renderHtml);\n}\n\r\nfunction insertNodeAtEditorSelection(editor: TinyMceEditorLike, node: HTMLElement): boolean {\r\n const range = getEditorRange(editor);\r\n if (!range || !isRangeInsideEditor(editor, range)) {\r\n return false;\r\n }\r\n\r\n try {\r\n range.deleteContents();\r\n range.insertNode(node);\r\n moveSelectionAfterNode(editor, node);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nfunction getEditorRange(editor: TinyMceEditorLike): Range | null {\r\n try {\r\n return editor.selection?.getRng?.() ?? null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nfunction isRangeInsideEditor(editor: TinyMceEditorLike, range: Range): boolean {\r\n const editorDoc = editor.getDoc?.() ?? document;\r\n if (range.startContainer.ownerDocument !== editorDoc || range.endContainer.ownerDocument !== editorDoc) {\r\n return false;\r\n }\r\n\r\n const body = editor.getBody?.();\r\n if (!body) {\r\n return true;\r\n }\r\n\r\n return body.contains(getRangeContainerElement(range.startContainer))\r\n && body.contains(getRangeContainerElement(range.endContainer));\r\n}\r\n\r\nfunction getRangeContainerElement(node: Node): Node {\r\n return node.nodeType === 1 ? node : node.parentNode ?? node;\r\n}\r\n\r\nfunction moveSelectionAfterNode(editor: TinyMceEditorLike, node: HTMLElement): void {\r\n const doc = node.ownerDocument;\r\n const range = doc.createRange();\r\n range.setStartAfter(node);\r\n range.collapse(true);\r\n\r\n try {\r\n editor.selection?.setRng?.(range);\r\n editor.selection?.collapse?.(false);\r\n } catch {\r\n // Ignore selection restoration failures across TinyMCE versions.\r\n }\r\n}\r\n\r\nfunction insertFormulaElementWithPlaceholder(\n editor: TinyMceEditorLike,\n latex: string,\n attributeName: string,\n className: string,\n cursorStyle: string,\n renderHtml?: string,\n): void {\n const editorDoc = editor.getDoc?.() ?? document;\r\n const marker = `fx-pending-${Math.random().toString(36).slice(2, 10)}`;\r\n editor.insertContent(`<span data-formulax-pending=\"${escapeAttribute(marker)}\"></span>`);\r\n\r\n const placeholder = editorDoc.querySelector<HTMLElement>(`[data-formulax-pending=\"${marker}\"]`);\r\n if (!placeholder) {\r\n const html = createTinyMceFormulaMarkup(latex, {\n attributeName,\n className,\n cursorStyle,\n renderHtml,\n });\n editor.insertContent(html);\r\n return;\r\n }\r\n\r\n const next = createTinyMceFormulaElement(editorDoc, latex, {\n attributeName,\n className,\n cursorStyle,\n renderHtml,\n });\n\r\n if (!next) {\r\n placeholder.remove();\r\n return;\r\n }\r\n\r\n placeholder.replaceWith(next);\r\n moveSelectionAfterNode(editor, next);\r\n}\r\n\r\nfunction notifyEditorChanged(editor: TinyMceEditorLike): void {\r\n editor.nodeChanged?.();\r\n\r\n if (typeof editor.dispatch === 'function') {\r\n editor.dispatch('change');\r\n return;\r\n }\r\n\r\n editor.fire?.('change');\r\n}\r\n","import {\n ensureFormulaXBaseStyles,\n} from '@formulaxjs/renderer';\nimport {\n ensureFormulaXModalStyles,\n formulaXModalStyles,\n} from '@formulaxjs/editor';\n\nexport const tinymceStyles = formulaXModalStyles;\n\nexport function ensureTinyMceStyles(doc: Document = document): void {\n ensureFormulaXBaseStyles(doc);\n ensureFormulaXModalStyles(doc);\n}\n","import {\n mountFormulaXEditor,\n type FormulaXEditorOptions,\n} from '@formulaxjs/editor';\nimport type { MountedFormulaXEditor, RequiredFormulaXTinyMceOptions } from './types';\n\nexport interface MountFormulaXEditorOptions {\n initialLatex?: string;\n options: RequiredFormulaXTinyMceOptions;\n}\n\nexport function mountFormulaXEditorInModal(\n root: HTMLElement,\n input: MountFormulaXEditorOptions,\n): MountedFormulaXEditor {\n const options: FormulaXEditorOptions = {\n initialLatex: input.initialLatex,\n height: input.options.editor.height ?? '100%',\n autofocus: input.options.editor.autofocus ?? true,\n assets: input.options.editor.assets,\n render: {\n fontsize: input.options.editor.render?.fontsize ?? 40,\n },\n };\n return mountFormulaXEditor(root, options);\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formulaxjs/tinymce",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@formulaxjs/core": "0.1.0",
|
|
34
|
-
"@formulaxjs/
|
|
35
|
-
"@formulaxjs/renderer": "0.1
|
|
36
|
-
"@formulaxjs/editor": "0.
|
|
34
|
+
"@formulaxjs/renderer": "0.2.0",
|
|
35
|
+
"@formulaxjs/renderer-kity": "0.2.1",
|
|
36
|
+
"@formulaxjs/editor": "0.3.1"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"tinymce": ">=5 <9"
|