@formulaxjs/tinymce 0.1.1 → 0.2.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/README.md CHANGED
@@ -4,7 +4,7 @@ English | [简体中文](./README.zh-CN.md)
4
4
 
5
5
  TinyMCE integration adapter for FormulaX.
6
6
 
7
- `@formulaxjs/tinymce` registers FormulaX as a TinyMCE plugin and provides a modal-based formula editing experience for inserting and updating formulas inside TinyMCE content.
7
+ `@formulaxjs/tinymce` registers FormulaX as a TinyMCE plugin and provides a modal-based formula editing experience for inserting and updating formulas inside TinyMCE content.
8
8
 
9
9
  > Status: experimental. Public APIs may change before the first stable release.
10
10
 
@@ -14,12 +14,14 @@ TinyMCE integration adapter for FormulaX.
14
14
  - FormulaX toolbar button and menu item support
15
15
  - `FormulaXOpen` TinyMCE command for programmatic opening
16
16
  - Insert and update formulas as non-editable inline nodes
17
- - Double-click, Enter, and Space editing interactions for existing formulas
18
- - TinyMCE compatibility layer for versions `>=5 <9`
19
- - LaTeX persistence through `data-formulax-latex`
20
- - Markup helpers for creating, parsing, serializing, finding, and replacing formula elements
21
-
22
- ## Compatibility
17
+ - Double-click, Enter, and Space editing interactions for existing formulas
18
+ - TinyMCE compatibility layer for versions `>=5 <9`
19
+ - LaTeX persistence through `data-formulax-latex`
20
+ - Markup helpers for creating, parsing, serializing, finding, and replacing formula elements
21
+ - Default read-only rendering through `@formulaxjs/renderer-kity`
22
+ - Optional runtime preload before the first modal open
23
+
24
+ ## Compatibility
23
25
 
24
26
  The package declares TinyMCE as an optional peer dependency:
25
27
 
@@ -60,15 +62,14 @@ import { registerFormulaXTinyMcePlugin } from '@formulaxjs/tinymce';
60
62
  registerFormulaXTinyMcePlugin(tinymce, {
61
63
  toolbarText: 'FormulaX',
62
64
  tooltip: 'Insert or edit formula',
63
- modal: {
64
- title: 'FormulaX Editor',
65
- },
66
- editor: {
67
- mode: 'kity',
68
- height: '100%',
69
- autofocus: true,
70
- render: { fontsize: 40 },
71
- },
65
+ modal: {
66
+ title: 'FormulaX Editor',
67
+ },
68
+ editor: {
69
+ height: '100%',
70
+ autofocus: true,
71
+ render: { fontsize: 40 },
72
+ },
72
73
  });
73
74
 
74
75
  await tinymce.init({
@@ -146,7 +147,23 @@ A generated formula node stores the source LaTeX in `data-formulax-latex` and is
146
147
  ></span>
147
148
  ```
148
149
 
149
- The exact generated markup is internal and may evolve. Consumers should rely on the exported helper functions where possible.
150
+ The exact generated markup is internal and may evolve. Consumers should rely on the exported helper functions where possible.
151
+
152
+ ## Custom renderer
153
+
154
+ The adapter accepts a `renderer` option. By default it uses `createKityFormulaRenderer()` from `@formulaxjs/renderer-kity`.
155
+
156
+ ```ts
157
+ import tinymce from 'tinymce';
158
+ import { registerFormulaXTinyMcePlugin } from '@formulaxjs/tinymce';
159
+ import { createKityFormulaRenderer } from '@formulaxjs/renderer-kity';
160
+
161
+ registerFormulaXTinyMcePlugin(tinymce, {
162
+ renderer: createKityFormulaRenderer({
163
+ fontSize: 44,
164
+ }),
165
+ });
166
+ ```
150
167
 
151
168
  ## Options
152
169
 
@@ -160,11 +177,12 @@ interface FormulaXTinyMceOptions {
160
177
  cursorStyle?: string;
161
178
  formulaClassName?: string;
162
179
  formulaAttributeName?: string;
163
- renderMode?: 'text' | 'html';
164
- initialLatex?: string;
165
- modal?: FormulaXModalOptions;
166
- editor?: FormulaXEditorOptions;
167
- }
180
+ renderer?: FormulaRenderer;
181
+ preload?: FormulaXEditorPreloadMode;
182
+ initialLatex?: string;
183
+ modal?: FormulaXModalOptions;
184
+ editor?: FormulaXEditorOptions;
185
+ }
168
186
  ```
169
187
 
170
188
  | Option | Default | Description |
@@ -176,11 +194,12 @@ interface FormulaXTinyMceOptions {
176
194
  | `tooltip` | `Insert formula` | Toolbar button tooltip. |
177
195
  | `cursorStyle` | `pointer` | Cursor style applied to generated formula nodes. |
178
196
  | `formulaClassName` | `formulax-math` | CSS class used by generated formula nodes. |
179
- | `formulaAttributeName` | `data-formulax-latex` | Attribute used to persist source LaTeX. |
180
- | `renderMode` | `text` | Experimental render mode option. |
181
- | `initialLatex` | empty string | Initial LaTeX when inserting a new formula. |
182
- | `modal` | see below | Modal labels, dimensions, and closing behavior. |
183
- | `editor` | see below | Embedded FormulaX editor options. |
197
+ | `formulaAttributeName` | `data-formulax-latex` | Attribute used to persist source LaTeX. |
198
+ | `renderer` | `createKityFormulaRenderer()` | Renderer used when the plugin needs runtime formula HTML. |
199
+ | `preload` | `idle` | Preloads the FormulaX runtime on browser idle, on host hover/focus, or never. |
200
+ | `initialLatex` | empty string | Initial LaTeX when inserting a new formula. |
201
+ | `modal` | see below | Modal labels, dimensions, and closing behavior. |
202
+ | `editor` | see below | Embedded FormulaX editor options. |
184
203
 
185
204
  ### Modal options
186
205
 
@@ -198,11 +217,10 @@ interface FormulaXTinyMceOptions {
198
217
 
199
218
  | Option | Default | Description |
200
219
  | --- | --- | --- |
201
- | `mode` | `kity` | Formula editor runtime mode. |
202
- | `height` | `100%` | Embedded editor height. |
203
- | `autofocus` | `true` | Whether the embedded editor should autofocus. |
204
- | `assets` | `{}` | Optional Kity runtime asset overrides. |
205
- | `render.fontsize` | `40` | Formula render font size. |
220
+ | `height` | `100%` | Embedded editor height. |
221
+ | `autofocus` | `true` | Whether the embedded editor should autofocus. |
222
+ | `assets` | `{}` | Optional Kity runtime asset overrides. |
223
+ | `render.fontsize` | `40` | Formula render font size. |
206
224
 
207
225
  ## Exported API
208
226
 
package/README.zh-CN.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  FormulaX 的 TinyMCE 集成适配器。
6
6
 
7
- `@formulaxjs/tinymce` 会将 FormulaX 注册为 TinyMCE 插件,并提供基于弹窗的公式编辑体验,用于在 TinyMCE 内容中插入和更新公式。
7
+ `@formulaxjs/tinymce` 会将 FormulaX 注册为 TinyMCE 插件,并提供基于弹窗的公式编辑体验,用于在 TinyMCE 内容中插入和更新公式。
8
8
 
9
9
  > 状态:实验阶段。在首个稳定版本发布前,公共 API 仍可能调整。
10
10
 
@@ -14,10 +14,12 @@ FormulaX 的 TinyMCE 集成适配器。
14
14
  - 支持 FormulaX 工具栏按钮和菜单项
15
15
  - 提供 `FormulaXOpen` TinyMCE 命令,便于代码中主动打开公式编辑器
16
16
  - 将公式作为不可直接编辑的 inline 节点插入和更新
17
- - 支持双击、Enter、Space 编辑已有公式
18
- - 面向 TinyMCE `>=5 <9` 的兼容层
19
- - 通过 `data-formulax-latex` 持久化 LaTeX 源内容
20
- - 提供创建、解析、序列化、查找和替换公式元素的 markup 工具函数
17
+ - 支持双击、Enter、Space 编辑已有公式
18
+ - 面向 TinyMCE `>=5 <9` 的兼容层
19
+ - 通过 `data-formulax-latex` 持久化 LaTeX 源内容
20
+ - 提供创建、解析、序列化、查找和替换公式元素的 markup 工具函数
21
+ - 默认通过 `@formulaxjs/renderer-kity` 完成只读渲染
22
+ - 支持在首次打开弹窗前预加载 runtime
21
23
 
22
24
  ## 兼容性
23
25
 
@@ -60,15 +62,14 @@ import { registerFormulaXTinyMcePlugin } from '@formulaxjs/tinymce';
60
62
  registerFormulaXTinyMcePlugin(tinymce, {
61
63
  toolbarText: 'FormulaX',
62
64
  tooltip: '插入或编辑公式',
63
- modal: {
64
- title: 'FormulaX 公式编辑器',
65
- },
66
- editor: {
67
- mode: 'kity',
68
- height: '100%',
69
- autofocus: true,
70
- render: { fontsize: 40 },
71
- },
65
+ modal: {
66
+ title: 'FormulaX 公式编辑器',
67
+ },
68
+ editor: {
69
+ height: '100%',
70
+ autofocus: true,
71
+ render: { fontsize: 40 },
72
+ },
72
73
  });
73
74
 
74
75
  await tinymce.init({
@@ -134,19 +135,35 @@ if (isFormulaElement(element)) {
134
135
 
135
136
  生成的公式节点会将 LaTeX 源内容保存在 `data-formulax-latex` 中,并通过 `data-formulax="true"` 标记:
136
137
 
137
- ```html
138
- <span
139
- class="formulax-math"
140
- data-formulax="true"
141
- data-formulax-latex="\\sqrt{x}"
142
- data-latex="\\sqrt{x}"
143
- contenteditable="false"
144
- data-mce-contenteditable="false"
145
- style="cursor: pointer"
146
- ></span>
147
- ```
138
+ ```html
139
+ <span
140
+ class="formulax-math"
141
+ data-formulax="true"
142
+ data-formulax-latex="\\sqrt{x}"
143
+ data-latex="\\sqrt{x}"
144
+ contenteditable="false"
145
+ data-mce-contenteditable="false"
146
+ style="cursor: pointer"
147
+ ></span>
148
+ ```
148
149
 
149
- 具体生成的 HTML 结构属于内部实现,后续可能演进。业务侧应优先依赖导出的工具函数。
150
+ 具体生成的 HTML 结构属于内部实现,后续可能演进。业务侧应优先依赖导出的工具函数。
151
+
152
+ ## 自定义 renderer
153
+
154
+ 该适配器支持 `renderer` 配置项。默认值是来自 `@formulaxjs/renderer-kity` 的 `createKityFormulaRenderer()`。
155
+
156
+ ```ts
157
+ import tinymce from 'tinymce';
158
+ import { registerFormulaXTinyMcePlugin } from '@formulaxjs/tinymce';
159
+ import { createKityFormulaRenderer } from '@formulaxjs/renderer-kity';
160
+
161
+ registerFormulaXTinyMcePlugin(tinymce, {
162
+ renderer: createKityFormulaRenderer({
163
+ fontSize: 44,
164
+ }),
165
+ });
166
+ ```
150
167
 
151
168
  ## 配置项
152
169
 
@@ -160,27 +177,29 @@ interface FormulaXTinyMceOptions {
160
177
  cursorStyle?: string;
161
178
  formulaClassName?: string;
162
179
  formulaAttributeName?: string;
163
- renderMode?: 'text' | 'html';
164
- initialLatex?: string;
165
- modal?: FormulaXModalOptions;
166
- editor?: FormulaXEditorOptions;
167
- }
180
+ renderer?: FormulaRenderer;
181
+ preload?: FormulaXEditorPreloadMode;
182
+ initialLatex?: string;
183
+ modal?: FormulaXModalOptions;
184
+ editor?: FormulaXEditorOptions;
185
+ }
168
186
  ```
169
187
 
170
188
  | 配置项 | 默认值 | 说明 |
171
189
  | --- | --- | --- |
172
190
  | `pluginName` | `formulax` | 通过 `tinymce.PluginManager.add` 注册的 TinyMCE 插件名。 |
173
191
  | `buttonName` | `formulax` | 工具栏按钮名。 |
174
- | `menuItemName` | `formulax` | 菜单项名。 |
175
- | `toolbarText` | `FormulaX` | 工具栏按钮和菜单项显示文本。 |
176
- | `tooltip` | `Insert formula` | 工具栏按钮 tooltip。 |
192
+ | `menuItemName` | `formulax` | 菜单项名。 |
193
+ | `toolbarText` | `FormulaX` | 工具栏按钮和菜单项显示文本。 |
194
+ | `tooltip` | `Insert formula` | 工具栏按钮 tooltip。 |
177
195
  | `cursorStyle` | `pointer` | 应用于生成公式节点的鼠标光标样式。 |
178
196
  | `formulaClassName` | `formulax-math` | 生成的公式节点 CSS class。 |
179
- | `formulaAttributeName` | `data-formulax-latex` | 用于保存 LaTeX 源内容的属性。 |
180
- | `renderMode` | `text` | 实验性的渲染模式配置。 |
181
- | `initialLatex` | 空字符串 | 插入新公式时的初始 LaTeX。 |
182
- | `modal` | 见下方 | 弹窗标题、按钮文本、尺寸和关闭行为。 |
183
- | `editor` | 见下方 | 内嵌 FormulaX 编辑器配置。 |
197
+ | `formulaAttributeName` | `data-formulax-latex` | 用于保存 LaTeX 源内容的属性。 |
198
+ | `renderer` | `createKityFormulaRenderer()` | 插件在需要运行时公式 HTML 时使用的 renderer。 |
199
+ | `preload` | `idle` | 控制在浏览器空闲时、宿主 hover/focus 时,或完全不预加载 FormulaX runtime。 |
200
+ | `initialLatex` | 空字符串 | 插入新公式时的初始 LaTeX。 |
201
+ | `modal` | 见下方 | 弹窗标题、按钮文本、尺寸和关闭行为。 |
202
+ | `editor` | 见下方 | 内嵌 FormulaX 编辑器配置。 |
184
203
 
185
204
  ### Modal 配置
186
205
 
@@ -198,11 +217,10 @@ interface FormulaXTinyMceOptions {
198
217
 
199
218
  | 配置项 | 默认值 | 说明 |
200
219
  | --- | --- | --- |
201
- | `mode` | `kity` | 公式编辑器运行时模式。 |
202
- | `height` | `100%` | 内嵌编辑器高度。 |
203
- | `autofocus` | `true` | 内嵌编辑器是否自动聚焦。 |
204
- | `assets` | `{}` | 可选的 Kity runtime 资源覆盖配置。 |
205
- | `render.fontsize` | `40` | 公式渲染字号。 |
220
+ | `height` | `100%` | 内嵌编辑器高度。 |
221
+ | `autofocus` | `true` | 内嵌编辑器是否自动聚焦。 |
222
+ | `assets` | `{}` | 可选的 Kity runtime 资源覆盖配置。 |
223
+ | `render.fontsize` | `40` | 公式渲染字号。 |
206
224
 
207
225
  ## 导出 API
208
226
 
package/dist/index.cjs CHANGED
@@ -20,19 +20,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- DEFAULT_FORMULA_ATTRIBUTE: () => import_editor.DEFAULT_FORMULA_ATTRIBUTE,
24
- DEFAULT_FORMULA_CLASS: () => import_editor.DEFAULT_FORMULA_CLASS,
25
- FORMULA_FLAG_ATTRIBUTE: () => import_editor.FORMULA_FLAG_ATTRIBUTE,
23
+ DEFAULT_FORMULA_ATTRIBUTE: () => import_renderer.DEFAULT_FORMULA_ATTRIBUTE,
24
+ DEFAULT_FORMULA_CLASS: () => import_renderer.DEFAULT_FORMULA_CLASS,
25
+ FORMULA_FLAG_ATTRIBUTE: () => import_renderer.FORMULA_FLAG_ATTRIBUTE,
26
26
  createTinyMceCompat: () => createTinyMceCompat,
27
27
  createTinyMceFormulaMarkup: () => createTinyMceFormulaMarkup,
28
- findFormulaElement: () => import_editor.findFormulaElement,
29
- getFormulaLatexFromElement: () => import_editor.getFormulaLatexFromElement,
28
+ findFormulaElement: () => import_renderer.findFormulaElement,
29
+ getFormulaLatexFromElement: () => import_renderer.getFormulaLatexFromElement,
30
30
  getTinyMceMajorVersion: () => getTinyMceMajorVersion,
31
- isFormulaElement: () => import_editor.isFormulaElement,
31
+ isFormulaElement: () => import_renderer.isFormulaElement,
32
32
  openFormulaXOverlayModal: () => openFormulaXOverlayModal,
33
33
  parseTinyMceFormulaMarkup: () => parseTinyMceFormulaMarkup,
34
34
  registerFormulaXTinyMcePlugin: () => registerFormulaXTinyMcePlugin,
35
- replaceFormulaElement: () => import_editor.replaceFormulaElement,
35
+ replaceFormulaElement: () => import_renderer.replaceFormulaElement,
36
36
  resolveOptions: () => resolveOptions,
37
37
  serializeTinyMceFormulaMarkup: () => serializeTinyMceFormulaMarkup,
38
38
  warnUnsupportedTinyMceVersion: () => warnUnsupportedTinyMceVersion
@@ -41,9 +41,9 @@ module.exports = __toCommonJS(index_exports);
41
41
 
42
42
  // src/markup.ts
43
43
  var import_core = require("@formulaxjs/core");
44
- var import_editor = require("@formulaxjs/editor");
44
+ var import_renderer = require("@formulaxjs/renderer");
45
45
  function createTinyMceFormulaMarkup(latex, options = {}) {
46
- return (0, import_editor.createFormulaMarkup)(latex, {
46
+ return (0, import_renderer.createFormulaMarkup)(latex, {
47
47
  ...options,
48
48
  extraAttributes: {
49
49
  ...options.extraAttributes,
@@ -58,7 +58,7 @@ function serializeTinyMceFormulaMarkup(doc, options = {}) {
58
58
  return createTinyMceFormulaMarkup((0, import_core.serializeLatex)(doc), options);
59
59
  }
60
60
  function createTinyMceFormulaElement(ownerDocument, latex, options = {}) {
61
- return (0, import_editor.createFormulaElement)(ownerDocument, latex, {
61
+ return (0, import_renderer.createFormulaElement)(ownerDocument, latex, {
62
62
  ...options,
63
63
  extraAttributes: {
64
64
  ...options.extraAttributes,
@@ -91,7 +91,7 @@ function createTinyMceCompat(editor, tinymce) {
91
91
  },
92
92
  getSelectedFormulaElement() {
93
93
  const node = editor.selection?.getNode?.();
94
- return (0, import_editor.findFormulaElement)(node ?? null);
94
+ return (0, import_renderer.findFormulaElement)(node ?? null);
95
95
  },
96
96
  getEditorDocument() {
97
97
  return editor.getDoc?.() ?? document;
@@ -114,15 +114,23 @@ function warnUnsupportedTinyMceVersion(tinymce) {
114
114
  }
115
115
  }
116
116
 
117
+ // src/plugin.ts
118
+ var import_editor4 = require("@formulaxjs/editor");
119
+ var import_renderer_kity = require("@formulaxjs/renderer-kity");
120
+
121
+ // src/modal.ts
122
+ var import_editor3 = require("@formulaxjs/editor");
123
+
117
124
  // src/styles.ts
118
- var import_editor2 = require("@formulaxjs/editor");
125
+ var import_renderer2 = require("@formulaxjs/renderer");
126
+ var import_editor = require("@formulaxjs/editor");
119
127
  function ensureTinyMceStyles(doc = document) {
120
- (0, import_editor2.ensureFormulaXModalStyles)(doc);
128
+ (0, import_renderer2.ensureFormulaXBaseStyles)(doc);
129
+ (0, import_editor.ensureFormulaXModalStyles)(doc);
121
130
  }
122
131
 
123
132
  // src/editor-host.ts
124
- var import_editor3 = require("@formulaxjs/editor");
125
- var import_renderer = require("@formulaxjs/renderer");
133
+ var import_editor2 = require("@formulaxjs/editor");
126
134
  function mountFormulaXEditorInModal(root, input) {
127
135
  const options = {
128
136
  initialLatex: input.initialLatex,
@@ -133,14 +141,16 @@ function mountFormulaXEditorInModal(root, input) {
133
141
  fontsize: input.options.editor.render?.fontsize ?? 40
134
142
  }
135
143
  };
136
- return (0, import_editor3.mountFormulaXKityEditor)(root, options);
144
+ return (0, import_editor2.mountFormulaXEditor)(root, options);
137
145
  }
138
146
 
139
147
  // src/modal.ts
140
148
  function openFormulaXOverlayModal(input) {
149
+ (0, import_editor3.recordFormulaXPerfPoint)("fx:modal:open:start");
150
+ const modalOpenStart = (0, import_editor3.markFormulaXPerf)("fx:modal:open:start:scope");
141
151
  ensureTinyMceStyles(document);
142
152
  const { editor, target, options } = input;
143
- const initialLatex = target ? (0, import_editor.getFormulaLatexFromElement)(target, options.formulaAttributeName) : input.initialLatex ?? options.initialLatex ?? "";
153
+ const initialLatex = target ? (0, import_renderer.getFormulaLatexFromElement)(target, options.formulaAttributeName) : input.initialLatex ?? options.initialLatex ?? "";
144
154
  const root = document.createElement("div");
145
155
  root.className = "fx-formula-modal-root";
146
156
  root.setAttribute("data-formulax-modal", "true");
@@ -149,33 +159,61 @@ function openFormulaXOverlayModal(input) {
149
159
  const title = options.modal.title || (isUpdate ? "Edit Formula" : "Insert Formula");
150
160
  root.innerHTML = `
151
161
  <div class="fx-formula-modal-backdrop" data-action="backdrop"></div>
152
- <div class="fx-formula-modal" role="dialog" aria-modal="true" aria-label="${(0, import_editor.escapeAttribute)(title)}">
162
+ <div class="fx-formula-modal" role="dialog" aria-modal="true" aria-label="${(0, import_renderer.escapeAttribute)(title)}">
153
163
  <header class="fx-formula-modal__header">
154
- <h2 class="fx-formula-modal__title">${(0, import_editor.escapeHtml)(title)}</h2>
164
+ <h2 class="fx-formula-modal__title">${(0, import_renderer.escapeHtml)(title)}</h2>
155
165
  <button class="fx-formula-modal__close" type="button" data-action="close" aria-label="Close">\xD7</button>
156
166
  </header>
157
167
  <section class="fx-formula-modal__body">
158
168
  <div class="fx-formula-editor-host"></div>
159
169
  </section>
160
170
  <footer class="fx-formula-modal__footer">
161
- <button class="fx-formula-modal__button" type="button" data-action="cancel">${(0, import_editor.escapeHtml)(options.modal.cancelText)}</button>
162
- <button class="fx-formula-modal__button fx-formula-modal__button--primary" type="button" data-action="submit">${(0, import_editor.escapeHtml)(submitText)}</button>
171
+ <button class="fx-formula-modal__button" type="button" data-action="cancel">${(0, import_renderer.escapeHtml)(options.modal.cancelText)}</button>
172
+ <button class="fx-formula-modal__button fx-formula-modal__button--primary" type="button" data-action="submit">${(0, import_renderer.escapeHtml)(submitText)}</button>
163
173
  </footer>
164
174
  </div>
165
175
  `;
166
176
  document.body.appendChild(root);
167
177
  document.body.classList.add("fx-formula-modal-open");
178
+ const modalDomReadyMark = (0, import_editor3.markFormulaXPerf)("fx:modal:dom-ready");
179
+ (0, import_editor3.measureFormulaXPerf)("fx:modal:dom-ready", modalOpenStart, modalDomReadyMark);
180
+ (0, import_editor3.clearFormulaXPerfMarks)(modalDomReadyMark);
168
181
  const host = root.querySelector(".fx-formula-editor-host");
169
182
  if (!host) {
170
183
  root.remove();
184
+ (0, import_editor3.clearFormulaXPerfMarks)(modalOpenStart);
171
185
  throw new Error("[FormulaX] Modal editor host not found.");
172
186
  }
173
- const mounted = mountFormulaXEditorInModal(host, { initialLatex, options });
187
+ (0, import_editor3.renderFormulaXEditorLoadingState)(host);
174
188
  let closed = false;
189
+ let mounted = null;
190
+ const mountedPromise = (0, import_editor3.waitForFormulaXAnimationFrame)().then(() => {
191
+ if (closed) {
192
+ (0, import_editor3.clearFormulaXPerfMarks)(modalOpenStart);
193
+ return null;
194
+ }
195
+ const mountStartMark = (0, import_editor3.markFormulaXPerf)("fx:modal:editor-mount-start");
196
+ (0, import_editor3.measureFormulaXPerf)("fx:modal:editor-mount-start", modalOpenStart, mountStartMark);
197
+ (0, import_editor3.clearFormulaXPerfMarks)(mountStartMark);
198
+ const nextMounted = mountFormulaXEditorInModal(host, { initialLatex, options });
199
+ mounted = nextMounted;
200
+ const mountedMark = (0, import_editor3.markFormulaXPerf)("fx:modal:editor-mounted");
201
+ (0, import_editor3.measureFormulaXPerf)("fx:modal:editor-mounted", modalOpenStart, mountedMark);
202
+ (0, import_editor3.clearFormulaXPerfMarks)(mountedMark, modalOpenStart);
203
+ queueMicrotask(() => {
204
+ if (!closed) {
205
+ nextMounted.root.focus();
206
+ }
207
+ });
208
+ return nextMounted;
209
+ }).catch((error) => {
210
+ (0, import_editor3.clearFormulaXPerfMarks)(modalOpenStart);
211
+ throw error;
212
+ });
175
213
  const close = () => {
176
214
  if (closed) return;
177
215
  closed = true;
178
- mounted.destroy();
216
+ mounted?.destroy();
179
217
  root.removeEventListener("click", onClick);
180
218
  document.removeEventListener("keydown", onKeydown, true);
181
219
  root.remove();
@@ -183,11 +221,18 @@ function openFormulaXOverlayModal(input) {
183
221
  editor.focus?.();
184
222
  };
185
223
  const submit = async () => {
186
- const latex = await mounted.getLatex();
187
- const renderHtml = mounted.getRenderHtml ? await mounted.getRenderHtml() : void 0;
224
+ const activeMounted = mounted ?? await mountedPromise;
225
+ if (!activeMounted) {
226
+ return;
227
+ }
228
+ const latex = await activeMounted.getLatex();
229
+ const renderHtml = latex.trim() ? (await options.renderer.renderLatex(latex, {
230
+ fontSize: options.editor.render?.fontsize ?? 40,
231
+ className: options.formulaClassName
232
+ })).html : void 0;
188
233
  runEditorTransaction(editor, () => {
189
234
  if (target) {
190
- const next = (0, import_editor.replaceFormulaElement)(target, latex, {
235
+ const next = (0, import_renderer.replaceFormulaElement)(target, latex, {
191
236
  attributeName: options.formulaAttributeName,
192
237
  className: options.formulaClassName,
193
238
  cursorStyle: options.cursorStyle,
@@ -233,9 +278,6 @@ function openFormulaXOverlayModal(input) {
233
278
  }
234
279
  root.addEventListener("click", onClick);
235
280
  document.addEventListener("keydown", onKeydown, true);
236
- queueMicrotask(() => {
237
- mounted.root.focus();
238
- });
239
281
  return { close };
240
282
  }
241
283
  function runEditorTransaction(editor, mutation) {
@@ -308,7 +350,7 @@ function moveSelectionAfterNode(editor, node) {
308
350
  function insertFormulaElementWithPlaceholder(editor, latex, attributeName, className, cursorStyle, renderHtml) {
309
351
  const editorDoc = editor.getDoc?.() ?? document;
310
352
  const marker = `fx-pending-${Math.random().toString(36).slice(2, 10)}`;
311
- editor.insertContent(`<span data-formulax-pending="${(0, import_editor.escapeAttribute)(marker)}">&#xfeff;</span>`);
353
+ editor.insertContent(`<span data-formulax-pending="${(0, import_renderer.escapeAttribute)(marker)}">&#xfeff;</span>`);
312
354
  const placeholder = editorDoc.querySelector(`[data-formulax-pending="${marker}"]`);
313
355
  if (!placeholder) {
314
356
  const html = createTinyMceFormulaMarkup(latex, {
@@ -369,8 +411,13 @@ function resolveOptions(options = {}) {
369
411
  cursorStyle: options.cursorStyle ?? "pointer",
370
412
  formulaClassName: options.formulaClassName ?? "formulax-math",
371
413
  formulaAttributeName: options.formulaAttributeName ?? "data-formulax-latex",
372
- renderMode: options.renderMode ?? "text",
373
414
  initialLatex: options.initialLatex ?? "",
415
+ renderer: options.renderer ?? (0, import_renderer_kity.createKityFormulaRenderer)({
416
+ fontSize: options.editor?.render?.fontsize ?? 40,
417
+ height: options.editor?.height ?? "100%",
418
+ assets: options.editor?.assets ?? {}
419
+ }),
420
+ preload: options.preload ?? "idle",
374
421
  modal: {
375
422
  title: options.modal?.title ?? "FormulaX",
376
423
  insertText: options.modal?.insertText ?? "Insert",
@@ -381,7 +428,6 @@ function resolveOptions(options = {}) {
381
428
  closeOnBackdrop: options.modal?.closeOnBackdrop ?? true
382
429
  },
383
430
  editor: {
384
- mode: "kity",
385
431
  height: options.editor?.height ?? "100%",
386
432
  autofocus: options.editor?.autofocus ?? true,
387
433
  assets: options.editor?.assets ?? {},
@@ -401,6 +447,7 @@ function registerFormulaXTinyMcePlugin(tinymce, options = {}) {
401
447
  resolved.pluginName,
402
448
  function FormulaXTinyMcePlugin(editor) {
403
449
  const compat = createTinyMceCompat(editor, tinymce);
450
+ let preloadCleanup = null;
404
451
  editor.schema?.addValidElements?.(FORMULAX_SVG_VALID_ELEMENTS);
405
452
  const open = (target) => {
406
453
  const resolvedTarget = target ?? compat.getSelectedFormulaElement();
@@ -429,9 +476,13 @@ function registerFormulaXTinyMcePlugin(tinymce, options = {}) {
429
476
  if (editorDoc) {
430
477
  ensureTinyMceStyles(editorDoc);
431
478
  }
479
+ preloadCleanup = (0, import_editor4.scheduleFormulaXEditorPreload)(
480
+ resolved.preload,
481
+ editor.getBody?.() ?? null
482
+ );
432
483
  });
433
484
  editor.on("dblclick", (event) => {
434
- const formula = (0, import_editor.findFormulaElement)(event.target);
485
+ const formula = (0, import_renderer.findFormulaElement)(event.target);
435
486
  if (!formula) return;
436
487
  event.preventDefault?.();
437
488
  open(formula);
@@ -444,6 +495,10 @@ function registerFormulaXTinyMcePlugin(tinymce, options = {}) {
444
495
  e.preventDefault?.();
445
496
  open(formula);
446
497
  });
498
+ editor.on("remove", () => {
499
+ preloadCleanup?.();
500
+ preloadCleanup = null;
501
+ });
447
502
  return void 0;
448
503
  }
449
504
  );