@editora/core 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +9 -0
  2. package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs +475 -0
  3. package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs.map +1 -0
  4. package/dist/AnchorPlugin.native-7es9PVZ9.mjs +340 -0
  5. package/dist/AnchorPlugin.native-7es9PVZ9.mjs.map +1 -0
  6. package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs +449 -0
  7. package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs.map +1 -0
  8. package/dist/BlockquotePlugin.native-JFmOLsxN.mjs +48 -0
  9. package/dist/BlockquotePlugin.native-JFmOLsxN.mjs.map +1 -0
  10. package/dist/BoldPlugin.native-BAzzoqU5.mjs +45 -0
  11. package/dist/BoldPlugin.native-BAzzoqU5.mjs.map +1 -0
  12. package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs +79 -0
  13. package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs.map +1 -0
  14. package/dist/ChecklistPlugin.native-Dccs3nLe.mjs +153 -0
  15. package/dist/ChecklistPlugin.native-Dccs3nLe.mjs.map +1 -0
  16. package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs +27 -0
  17. package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs.map +1 -0
  18. package/dist/CodePlugin.native-DD9xFIid.mjs +1679 -0
  19. package/dist/CodePlugin.native-DD9xFIid.mjs.map +1 -0
  20. package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs +326 -0
  21. package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs.map +1 -0
  22. package/dist/CommentsPlugin.native-2zQV8Ia4.mjs +473 -0
  23. package/dist/CommentsPlugin.native-2zQV8Ia4.mjs.map +1 -0
  24. package/dist/DirectionPlugin.native-Be7wCzkI.mjs +59 -0
  25. package/dist/DirectionPlugin.native-Be7wCzkI.mjs.map +1 -0
  26. package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs +116 -0
  27. package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs.map +1 -0
  28. package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs +461 -0
  29. package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs.map +1 -0
  30. package/dist/EmojisPlugin.native-D6mJSnSR.mjs +1033 -0
  31. package/dist/EmojisPlugin.native-D6mJSnSR.mjs.map +1 -0
  32. package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs +106 -0
  33. package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs.map +1 -0
  34. package/dist/FontSizePlugin.native-DkLMLPue.mjs +186 -0
  35. package/dist/FontSizePlugin.native-DkLMLPue.mjs.map +1 -0
  36. package/dist/FootnotePlugin.native-BciVc9W6.mjs +128 -0
  37. package/dist/FootnotePlugin.native-BciVc9W6.mjs.map +1 -0
  38. package/dist/FullscreenPlugin.native-ChXyxeNw.mjs +77 -0
  39. package/dist/FullscreenPlugin.native-ChXyxeNw.mjs.map +1 -0
  40. package/dist/HeadingPlugin.native-DrLYwQnQ.mjs +64 -0
  41. package/dist/HeadingPlugin.native-DrLYwQnQ.mjs.map +1 -0
  42. package/dist/HistoryPlugin.native-DoDRifCf.mjs +89 -0
  43. package/dist/HistoryPlugin.native-DoDRifCf.mjs.map +1 -0
  44. package/dist/IndentPlugin.native-CbFugPoi.mjs +133 -0
  45. package/dist/IndentPlugin.native-CbFugPoi.mjs.map +1 -0
  46. package/dist/ItalicPlugin.native-CQjjDyUL.mjs +43 -0
  47. package/dist/ItalicPlugin.native-CQjjDyUL.mjs.map +1 -0
  48. package/dist/LineHeightPlugin.native-CWQT2FIa.mjs +73 -0
  49. package/dist/LineHeightPlugin.native-CWQT2FIa.mjs.map +1 -0
  50. package/dist/LinkPlugin.native-BdAOV-iu.mjs +206 -0
  51. package/dist/LinkPlugin.native-BdAOV-iu.mjs.map +1 -0
  52. package/dist/ListPlugin.native-CLFU5AUQ.mjs +59 -0
  53. package/dist/ListPlugin.native-CLFU5AUQ.mjs.map +1 -0
  54. package/dist/MathPlugin.native-DE_ii-LA.mjs +182 -0
  55. package/dist/MathPlugin.native-DE_ii-LA.mjs.map +1 -0
  56. package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs +533 -0
  57. package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs.map +1 -0
  58. package/dist/MergeTagPlugin.native-CrxyThyn.mjs +178 -0
  59. package/dist/MergeTagPlugin.native-CrxyThyn.mjs.map +1 -0
  60. package/dist/PageBreakPlugin.native-DDjcDyRW.mjs +172 -0
  61. package/dist/PageBreakPlugin.native-DDjcDyRW.mjs.map +1 -0
  62. package/dist/PreviewPlugin.native-DBvfpmIv.mjs +322 -0
  63. package/dist/PreviewPlugin.native-DBvfpmIv.mjs.map +1 -0
  64. package/dist/PrintPlugin.native-BUpm52VJ.mjs +311 -0
  65. package/dist/PrintPlugin.native-BUpm52VJ.mjs.map +1 -0
  66. package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs +731 -0
  67. package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs.map +1 -0
  68. package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs +465 -0
  69. package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs.map +1 -0
  70. package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs +43 -0
  71. package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs.map +1 -0
  72. package/dist/TablePlugin.native-EEWXn1-s.mjs +491 -0
  73. package/dist/TablePlugin.native-EEWXn1-s.mjs.map +1 -0
  74. package/dist/TemplatePlugin.native-BlSn1c9h.mjs +564 -0
  75. package/dist/TemplatePlugin.native-BlSn1c9h.mjs.map +1 -0
  76. package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs +97 -0
  77. package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs.map +1 -0
  78. package/dist/TextColorPlugin.native-D6SmTglm.mjs +432 -0
  79. package/dist/TextColorPlugin.native-D6SmTglm.mjs.map +1 -0
  80. package/dist/UnderlinePlugin.native-QpIcK4L2.mjs +35 -0
  81. package/dist/UnderlinePlugin.native-QpIcK4L2.mjs.map +1 -0
  82. package/dist/core.css +1 -0
  83. package/dist/documentManager-irzj9n3V.mjs +37627 -0
  84. package/dist/documentManager-irzj9n3V.mjs.map +1 -0
  85. package/dist/editorContainerHelpers-C7kdWnS0.mjs +27 -0
  86. package/dist/editorContainerHelpers-C7kdWnS0.mjs.map +1 -0
  87. package/dist/editora.min.js +519 -4
  88. package/dist/editora.min.js.map +1 -0
  89. package/dist/editora.umd.js +519 -4
  90. package/dist/editora.umd.js.map +1 -0
  91. package/dist/index-BF5RBhL9.js +4 -0
  92. package/dist/index-BF5RBhL9.js.map +1 -0
  93. package/dist/index-BPsf460l.mjs +1243 -0
  94. package/dist/index-BPsf460l.mjs.map +1 -0
  95. package/dist/index.cjs.js +517 -4
  96. package/dist/index.cjs.js.map +1 -0
  97. package/dist/index.es-CuicffkQ.mjs +6665 -0
  98. package/dist/index.es-CuicffkQ.mjs.map +1 -0
  99. package/dist/index.esm.js +1403 -122
  100. package/dist/index.esm.js.map +1 -0
  101. package/dist/plugin-loader.js +55 -0
  102. package/dist/plugin-loader.js.map +1 -0
  103. package/dist/purify.es-CKpwg8Tk.mjs +471 -0
  104. package/dist/purify.es-CKpwg8Tk.mjs.map +1 -0
  105. package/dist/webcomponent-core.js +1243 -0
  106. package/dist/webcomponent-core.js.map +1 -0
  107. package/dist/webcomponent-core.min.css +1 -0
  108. package/dist/webcomponent-core.min.js +597 -0
  109. package/dist/webcomponent-core.min.js.map +1 -0
  110. package/dist/webcomponent.cjs.js +2 -0
  111. package/dist/webcomponent.cjs.js.map +1 -0
  112. package/dist/webcomponent.esm.js +6 -0
  113. package/dist/webcomponent.esm.js.map +1 -0
  114. package/dist/webcomponent.js +1286 -0
  115. package/dist/webcomponent.js.map +1 -0
  116. package/dist/webcomponent.min.css +1 -0
  117. package/dist/webcomponent.min.js +4076 -0
  118. package/dist/webcomponent.min.js.map +1 -0
  119. package/package.json +64 -6
@@ -0,0 +1,1243 @@
1
+ class m {
2
+ constructor(t, e, o) {
3
+ this.doc = t, this.selection = e, this.schema = o;
4
+ }
5
+ static create(t, e) {
6
+ const o = e || t.node("doc", {}, [t.node("paragraph")]);
7
+ return new m(o, { anchor: 0, head: 0 }, t);
8
+ }
9
+ apply(t, e) {
10
+ return new m(t, e || this.selection, this.schema);
11
+ }
12
+ }
13
+ class w {
14
+ constructor(t, e) {
15
+ this.nodes = new Map(Object.entries(t)), this.marks = new Map(Object.entries(e));
16
+ }
17
+ node(t, e, o) {
18
+ return { type: t, attrs: e, content: o };
19
+ }
20
+ text(t, e) {
21
+ return { type: "text", text: t, marks: e };
22
+ }
23
+ }
24
+ class C {
25
+ constructor() {
26
+ this.plugins = [], this.pluginConfigs = /* @__PURE__ */ new Map();
27
+ }
28
+ register(t, e) {
29
+ if (this.plugins.push(t), e && this.pluginConfigs.set(t.name, e), t.initialize) {
30
+ const o = this.pluginConfigs.get(t.name) || t.config;
31
+ t.initialize(o);
32
+ }
33
+ }
34
+ unregister(t) {
35
+ const e = this.plugins.findIndex((o) => o.name === t);
36
+ if (e > -1) {
37
+ const o = this.plugins[e];
38
+ o.destroy && o.destroy(), this.plugins.splice(e, 1), this.pluginConfigs.delete(t);
39
+ }
40
+ }
41
+ getPlugin(t) {
42
+ return this.plugins.find((e) => e.name === t);
43
+ }
44
+ getPluginConfig(t) {
45
+ return this.pluginConfigs.get(t);
46
+ }
47
+ buildSchema() {
48
+ const t = {}, e = {};
49
+ return this.plugins.forEach((o) => {
50
+ o.nodes && Object.assign(t, o.nodes), o.marks && Object.assign(e, o.marks);
51
+ }), new w(t, e);
52
+ }
53
+ getCommands() {
54
+ const t = {};
55
+ return this.plugins.forEach((e) => {
56
+ e.commands && Object.assign(t, e.commands);
57
+ }), t;
58
+ }
59
+ getToolbarItems() {
60
+ return this.plugins.flatMap((t) => t.toolbar || []);
61
+ }
62
+ /**
63
+ * Execute plugin command with mode awareness
64
+ */
65
+ async executePluginCommand(t, e, ...o) {
66
+ const i = this.getPlugin(t);
67
+ if (!i)
68
+ throw new Error(`Plugin not found: ${t}`);
69
+ const n = this.getPluginConfig(t) || i.config || {}, a = n.mode || "local";
70
+ try {
71
+ switch (a) {
72
+ case "local":
73
+ return i.executeLocal ? i.executeLocal(e, ...o) : null;
74
+ case "api":
75
+ if (!i.executeAPI)
76
+ throw new Error(`Plugin ${t} does not support API mode`);
77
+ return await i.executeAPI(e, ...o);
78
+ case "hybrid":
79
+ if (i.executeHybrid)
80
+ return await i.executeHybrid(e, ...o);
81
+ try {
82
+ if (i.executeAPI)
83
+ return await i.executeAPI(e, ...o);
84
+ } catch (r) {
85
+ if (console.warn(`API execution failed for ${t}, falling back to local`, r), i.executeLocal && n.fallbackToLocal !== !1)
86
+ return i.executeLocal(e, ...o);
87
+ throw r;
88
+ }
89
+ break;
90
+ default:
91
+ throw new Error(`Unknown plugin mode: ${a}`);
92
+ }
93
+ } catch (r) {
94
+ throw console.error(`Error executing command ${e} on plugin ${t}:`, r), r;
95
+ }
96
+ }
97
+ /**
98
+ * Destroy all plugins
99
+ */
100
+ async destroyAll() {
101
+ const t = this.plugins.filter((e) => e.destroy).map((e) => e.destroy());
102
+ await Promise.all(t), this.plugins = [], this.pluginConfigs.clear();
103
+ }
104
+ }
105
+ class E {
106
+ constructor(t = {}) {
107
+ this.commands = /* @__PURE__ */ new Map(), Object.entries(t).forEach(([e, o]) => {
108
+ this.register(e, o);
109
+ });
110
+ }
111
+ /**
112
+ * Register a command
113
+ */
114
+ register(t, e) {
115
+ this.commands.has(t) && console.warn(`Command ${t} is being overwritten`), this.commands.set(t, e);
116
+ }
117
+ /**
118
+ * Unregister a command
119
+ */
120
+ unregister(t) {
121
+ this.commands.delete(t);
122
+ }
123
+ /**
124
+ * Get a command handler
125
+ */
126
+ get(t) {
127
+ return this.commands.get(t);
128
+ }
129
+ /**
130
+ * Check if command exists
131
+ */
132
+ has(t) {
133
+ return this.commands.has(t);
134
+ }
135
+ /**
136
+ * Get all command names
137
+ */
138
+ getCommandNames() {
139
+ return Array.from(this.commands.keys());
140
+ }
141
+ /**
142
+ * Clear all commands
143
+ */
144
+ clear() {
145
+ this.commands.clear();
146
+ }
147
+ }
148
+ class k {
149
+ constructor(t = {}) {
150
+ this.listeners = /* @__PURE__ */ new Map(), this.isReadonly = !1, this.isDestroyed = !1, this.isReadonly = t.readonly || !1, this.pluginManager = new C(), t.plugins && Array.isArray(t.plugins) && t.plugins.forEach((o) => this.pluginManager.register(o));
151
+ const e = this.pluginManager.buildSchema();
152
+ this.state = m.create(e), this.commandRegistry = new E(this.pluginManager.getCommands());
153
+ }
154
+ /**
155
+ * Execute a command
156
+ */
157
+ execCommand(t, e) {
158
+ if (this.isReadonly)
159
+ return console.warn("Cannot execute commands in readonly mode"), !1;
160
+ if (this.isDestroyed)
161
+ return console.warn("Cannot execute commands on destroyed editor"), !1;
162
+ const o = this.commandRegistry.get(t);
163
+ if (!o)
164
+ return console.warn(`Command not found: ${t}`), !1;
165
+ let i;
166
+ return e !== void 0 ? i = o(this.state, e) : i = o(this.state), i ? (this.setState(i), this.emit("change", this.state), !0) : !1;
167
+ }
168
+ /**
169
+ * Update editor state
170
+ */
171
+ setState(t) {
172
+ this.isDestroyed || (this.state = t, this.emit("stateChange", t));
173
+ }
174
+ /**
175
+ * Get current state
176
+ */
177
+ getState() {
178
+ return this.state;
179
+ }
180
+ /**
181
+ * Set readonly mode
182
+ */
183
+ setReadonly(t) {
184
+ this.isReadonly = t, this.emit("readonlyChange", t);
185
+ }
186
+ /**
187
+ * Check if readonly
188
+ */
189
+ isReadOnly() {
190
+ return this.isReadonly;
191
+ }
192
+ /**
193
+ * Event emitter
194
+ */
195
+ on(t, e) {
196
+ return this.listeners.has(t) || this.listeners.set(t, []), this.listeners.get(t).push(e), () => {
197
+ const o = this.listeners.get(t);
198
+ if (o) {
199
+ const i = o.indexOf(e);
200
+ i > -1 && o.splice(i, 1);
201
+ }
202
+ };
203
+ }
204
+ /**
205
+ * Emit event
206
+ */
207
+ emit(t, ...e) {
208
+ const o = this.listeners.get(t);
209
+ o && o.forEach((i) => {
210
+ try {
211
+ i(...e);
212
+ } catch (n) {
213
+ console.error(`Error in ${t} handler:`, n);
214
+ }
215
+ });
216
+ }
217
+ /**
218
+ * Destroy editor instance
219
+ */
220
+ destroy() {
221
+ this.isDestroyed || (this.isDestroyed = !0, this.listeners.clear(), this.emit("destroy"));
222
+ }
223
+ /**
224
+ * Check if destroyed
225
+ */
226
+ isEditorDestroyed() {
227
+ return this.isDestroyed;
228
+ }
229
+ }
230
+ class v {
231
+ // PluginLoader instance to get all registered plugins
232
+ constructor(t, e, o) {
233
+ this.config = t, this.plugins = e, this.pluginLoader = o;
234
+ }
235
+ /**
236
+ * Set command handler for toolbar buttons
237
+ */
238
+ setCommandHandler(t) {
239
+ this.commandHandler = t;
240
+ }
241
+ /**
242
+ * Parse toolbar string into button groups
243
+ */
244
+ parseToolbarString(t) {
245
+ const e = [], o = t.split("|").map((r) => r.trim()), i = this.getAvailableToolbarItems(), n = /* @__PURE__ */ new Map();
246
+ i.forEach((r) => {
247
+ r.command && n.set(r.command, r), r.type === "group" && r.label && n.set(r.label, r);
248
+ });
249
+ const a = {
250
+ bold: "toggleBold",
251
+ italic: "toggleItalic",
252
+ underline: "toggleUnderline",
253
+ strikethrough: "toggleStrikethrough",
254
+ bullist: "toggleBulletList",
255
+ numlist: "toggleOrderedList",
256
+ checklist: "toggleChecklist",
257
+ link: "openLinkDialog",
258
+ image: "openImageDialog",
259
+ table: "insertTable",
260
+ anchor: "insertAnchor",
261
+ code: "toggleSourceView",
262
+ blockquote: "toggleBlockquote",
263
+ undo: "undo",
264
+ redo: "redo",
265
+ textColor: "openTextColorPicker",
266
+ backgroundColor: "openBackgroundColorPicker",
267
+ fontSize: "fontSize",
268
+ fontFamily: "setFontFamily",
269
+ lineHeight: "setLineHeight",
270
+ heading: "setBlockType",
271
+ paragraph: "setParagraph",
272
+ textAlignment: "setTextAlignment",
273
+ direction: "setDirectionLTR",
274
+ indent: "increaseIndent",
275
+ outdent: "decreaseIndent",
276
+ capitalization: "setCapitalization",
277
+ math: "insertMath",
278
+ specialCharacters: "insertSpecialCharacter",
279
+ emojis: "openEmojiDialog",
280
+ embedIframe: "openEmbedIframeDialog",
281
+ fullscreen: "toggleFullscreen",
282
+ preview: "togglePreview",
283
+ print: "print",
284
+ a11yChecker: "toggleA11yChecker",
285
+ spellCheck: "toggleSpellCheck",
286
+ comments: "addComment",
287
+ showHideComments: "toggleComments",
288
+ toggleComments: "toggleComments",
289
+ footnote: "insertFootnote",
290
+ mergeTags: "insertMergeTag",
291
+ pageBreak: "insertPageBreak",
292
+ template: "insertTemplate",
293
+ importWord: "importWord",
294
+ exportWord: "exportWord",
295
+ exportPdf: "exportPdf",
296
+ insertImage: "insertImage",
297
+ insertVideo: "insertVideo",
298
+ codeBlock: "insertCodeBlock"
299
+ };
300
+ return o.forEach((r) => {
301
+ const s = [];
302
+ r.split(/\s+/).filter(Boolean).forEach((u) => {
303
+ if (u === "direction") {
304
+ const c = n.get("setDirectionLTR"), h = n.get("setDirectionRTL");
305
+ c && s.push({
306
+ id: "directionLTR",
307
+ label: c.label,
308
+ command: c.command,
309
+ icon: c.icon,
310
+ type: c.type || "button",
311
+ options: c.options
312
+ }), h && s.push({
313
+ id: "directionRTL",
314
+ label: h.label,
315
+ command: h.command,
316
+ icon: h.icon,
317
+ type: h.type || "button",
318
+ options: h.options
319
+ });
320
+ return;
321
+ }
322
+ if (u === "comments") {
323
+ const c = n.get("addComment"), h = n.get("toggleComments");
324
+ c && s.push({
325
+ id: "addComment",
326
+ label: c.label,
327
+ command: c.command,
328
+ icon: c.icon,
329
+ type: c.type || "button",
330
+ options: c.options
331
+ }), h && s.push({
332
+ id: "toggleComments",
333
+ label: h.label,
334
+ command: h.command,
335
+ icon: h.icon,
336
+ type: h.type || "button",
337
+ options: h.options
338
+ });
339
+ return;
340
+ }
341
+ const p = a[u] || u;
342
+ let d = n.get(p);
343
+ d || (d = n.get(u)), d && s.push({
344
+ id: u,
345
+ label: d.label,
346
+ command: d.command,
347
+ icon: d.icon,
348
+ type: d.type === "separator" ? "separator" : d.type || "button",
349
+ options: d.options,
350
+ items: d.items
351
+ });
352
+ }), s.length > 0 && e.push(s);
353
+ }), e;
354
+ }
355
+ /**
356
+ * Get all available toolbar items from plugins
357
+ */
358
+ getAvailableToolbarItems() {
359
+ return this.plugins.flatMap((e) => e.toolbar || []);
360
+ }
361
+ /**
362
+ * Render toolbar to DOM element
363
+ */
364
+ render(t) {
365
+ this.container = t, t.innerHTML = "", t.className = "editora-toolbar", this.config.sticky && t.classList.add("editora-toolbar-sticky"), this.config.position && t.classList.add(`editora-toolbar-${this.config.position}`);
366
+ const e = this.config.items || this.getDefaultToolbarString(), o = this.parseToolbarString(e);
367
+ o.forEach((i, n) => {
368
+ const a = document.createElement("div");
369
+ if (a.className = "editora-toolbar-group", i.forEach((r) => {
370
+ this.appendToolbarButton(a, r);
371
+ }), t.appendChild(a), n < o.length - 1) {
372
+ const r = document.createElement("div");
373
+ r.className = "editora-toolbar-separator", t.appendChild(r);
374
+ }
375
+ });
376
+ }
377
+ /**
378
+ * Append a toolbar button or group to a parent element
379
+ */
380
+ appendToolbarButton(t, e) {
381
+ if (e.type === "separator") {
382
+ const o = document.createElement("div");
383
+ o.className = "editora-toolbar-separator", t.appendChild(o);
384
+ } else if (e.type === "dropdown") {
385
+ const o = this.createDropdown(e);
386
+ t.appendChild(o);
387
+ } else if (e.type === "inline-menu") {
388
+ const o = this.createInlineMenu(e);
389
+ t.appendChild(o);
390
+ } else if (e.type === "group" && e.items && e.items.length) {
391
+ const o = this.createGroupButton(e);
392
+ t.appendChild(o);
393
+ } else if (e.type === "input") {
394
+ const o = this.createInput(e);
395
+ t.appendChild(o);
396
+ } else {
397
+ const o = this.createButton(e);
398
+ t.appendChild(o);
399
+ }
400
+ }
401
+ /**
402
+ * Create a toolbar button element
403
+ */
404
+ createGroupButton(t) {
405
+ const e = document.createElement("div");
406
+ if (e.className = "editora-toolbar-group-button", e.title = t.label, t.icon)
407
+ if (t.icon.startsWith("<svg") && t.icon.endsWith("</svg>")) {
408
+ const o = document.createElement("span");
409
+ o.className = "editora-toolbar-icon", o.innerHTML = t.icon, e.appendChild(o);
410
+ } else
411
+ e.innerHTML = t.icon;
412
+ if (t.items && t.items.length) {
413
+ const o = document.createElement("div");
414
+ o.className = "editora-toolbar-group-items", t.items.forEach((i) => {
415
+ this.appendToolbarButton(o, i);
416
+ }), e.appendChild(o);
417
+ }
418
+ return e;
419
+ }
420
+ /**
421
+ * Create a toolbar button element
422
+ */
423
+ createInput(t) {
424
+ const e = document.createElement("input");
425
+ return e.className = `editora-toolbar-input ${t.label.toLowerCase().replace(/\s+/g, "-")}`, e.type = "text", e.title = t.label, e.placeholder = t.placeholder || "", e.setAttribute("data-command", t.command), t.active && e.classList.add("active"), t.disabled && (e.disabled = !0), e.addEventListener("click", (o) => {
426
+ o.preventDefault(), this.commandHandler && this.commandHandler(t.command);
427
+ }), e;
428
+ }
429
+ /**
430
+ * Create a toolbar button element
431
+ */
432
+ createButton(t) {
433
+ const e = document.createElement("button");
434
+ if (e.className = "editora-toolbar-button", e.type = "button", e.title = t.label, e.setAttribute("data-command", t.command), t.icon)
435
+ if (t.icon.startsWith("<svg") && t.icon.endsWith("</svg>")) {
436
+ const o = document.createElement("span");
437
+ o.className = "editora-toolbar-icon", o.innerHTML = t.icon, e.appendChild(o);
438
+ } else
439
+ e.innerHTML = t.icon;
440
+ else
441
+ e.textContent = t.label;
442
+ return t.active && e.classList.add("active"), t.disabled && (e.disabled = !0), e.addEventListener("click", (o) => {
443
+ o.preventDefault(), this.commandHandler && this.commandHandler(t.command);
444
+ }), e;
445
+ }
446
+ /**
447
+ * Create a dropdown element
448
+ */
449
+ createDropdown(t) {
450
+ const e = document.createElement("div");
451
+ e.className = "editora-toolbar-dropdown";
452
+ const o = document.createElement("button");
453
+ o.className = "editora-toolbar-button editora-toolbar-dropdown-trigger", o.type = "button", o.textContent = t.label;
454
+ const i = document.createElement("div");
455
+ i.className = "editora-toolbar-dropdown-menu", i.style.display = "none", t.options && t.options.forEach((a) => {
456
+ const r = document.createElement("button");
457
+ r.className = "editora-toolbar-dropdown-item", r.type = "button", r.textContent = a.label, r.setAttribute("data-value", a.value), r.addEventListener("click", (s) => {
458
+ s.preventDefault(), this.commandHandler && this.commandHandler(t.command, a.value), i.style.display = "none";
459
+ }), i.appendChild(r);
460
+ }), o.addEventListener("click", (a) => {
461
+ a.preventDefault(), a.stopPropagation();
462
+ const r = i.style.display === "block";
463
+ i.style.display = r ? "none" : "block";
464
+ });
465
+ const n = (a) => {
466
+ e.contains(a.target) || (i.style.display = "none");
467
+ };
468
+ return document.addEventListener("click", n), e._cleanupDropdown = () => {
469
+ document.removeEventListener("click", n);
470
+ }, e.appendChild(o), e.appendChild(i), e;
471
+ }
472
+ /**
473
+ * Create an inline menu element (like dropdown but triggered by button click)
474
+ */
475
+ createInlineMenu(t) {
476
+ const e = document.createElement("div");
477
+ e.className = "editora-toolbar-dropdown editora-toolbar-inline-menu";
478
+ const o = document.createElement("button");
479
+ if (o.className = "editora-toolbar-button", o.type = "button", o.title = t.label, t.icon)
480
+ if (t.icon.startsWith("<svg") && t.icon.endsWith("</svg>")) {
481
+ const n = document.createElement("span");
482
+ n.className = "editora-toolbar-icon", n.innerHTML = t.icon, o.appendChild(n);
483
+ } else
484
+ o.innerHTML = t.icon;
485
+ else
486
+ o.textContent = t.label;
487
+ const i = document.createElement("div");
488
+ return i.className = "editora-toolbar-dropdown-menu", i.style.display = "none", t.options && t.options.forEach((n) => {
489
+ const a = document.createElement("button");
490
+ a.className = "editora-toolbar-dropdown-item", a.type = "button", a.textContent = n.label, a.setAttribute("data-value", n.value), a.addEventListener("click", (r) => {
491
+ r.preventDefault(), r.stopPropagation(), this.commandHandler && this.commandHandler(t.command, n.value), i.style.display = "none";
492
+ }), i.appendChild(a);
493
+ }), o.addEventListener("click", (n) => {
494
+ var r;
495
+ n.preventDefault(), n.stopPropagation();
496
+ const a = (r = this.container) == null ? void 0 : r.querySelectorAll(
497
+ ".editora-toolbar-dropdown-menu"
498
+ );
499
+ a == null || a.forEach((s) => {
500
+ s !== i && (s.style.display = "none");
501
+ }), i.style.display = i.style.display === "none" ? "block" : "none";
502
+ }), document.addEventListener("click", (n) => {
503
+ e.contains(n.target) || (i.style.display = "none");
504
+ }), e.appendChild(o), e.appendChild(i), e;
505
+ }
506
+ /**
507
+ * Get default toolbar string if none provided
508
+ */
509
+ getDefaultToolbarString() {
510
+ return this.getAvailableToolbarItems().map((e) => e.command).join(" ");
511
+ }
512
+ /**
513
+ * Update button state
514
+ */
515
+ updateButtonState(t, e) {
516
+ if (!this.container) return;
517
+ const o = this.container.querySelector(
518
+ `[data-command="${t}"]`
519
+ );
520
+ o && (e.active !== void 0 && o.classList.toggle("active", e.active), e.disabled !== void 0 && (o.disabled = e.disabled));
521
+ }
522
+ /**
523
+ * Destroy toolbar
524
+ */
525
+ destroy() {
526
+ this.container && (this.container.querySelectorAll(".editora-toolbar-dropdown").forEach((e) => {
527
+ const o = e._cleanupDropdown;
528
+ o && o();
529
+ }), this.container.innerHTML = ""), this.commandHandler = void 0;
530
+ }
531
+ }
532
+ class L {
533
+ constructor(t) {
534
+ this.visible = !1, this.config = t;
535
+ }
536
+ /**
537
+ * Create and mount floating toolbar
538
+ */
539
+ create(t) {
540
+ const e = document.createElement("div");
541
+ return e.className = "editora-floating-toolbar", e.style.display = "none", e.style.position = "absolute", e.style.zIndex = "1000", this.container = e, t.appendChild(e), e;
542
+ }
543
+ /**
544
+ * Show toolbar at position
545
+ */
546
+ show(t, e) {
547
+ this.container && (this.container.style.display = "block", this.container.style.left = `${t}px`, this.container.style.top = `${e}px`, this.visible = !0);
548
+ }
549
+ /**
550
+ * Hide toolbar
551
+ */
552
+ hide() {
553
+ this.container && (this.container.style.display = "none", this.visible = !1);
554
+ }
555
+ /**
556
+ * Update position
557
+ */
558
+ updatePosition(t, e) {
559
+ !this.container || !this.visible || (this.container.style.left = `${t}px`, this.container.style.top = `${e}px`);
560
+ }
561
+ /**
562
+ * Check if visible
563
+ */
564
+ isVisible() {
565
+ return this.visible;
566
+ }
567
+ /**
568
+ * Destroy floating toolbar
569
+ */
570
+ destroy() {
571
+ this.container && this.container.parentNode && this.container.parentNode.removeChild(this.container), this.container = void 0, this.visible = !1;
572
+ }
573
+ }
574
+ class T {
575
+ constructor(t = {}) {
576
+ this.statusInfo = {}, this.config = t;
577
+ }
578
+ /**
579
+ * Create and mount status bar
580
+ */
581
+ create(t) {
582
+ const e = document.createElement("div");
583
+ return e.className = "editora-statusbar", this.config.position && e.classList.add(`editora-statusbar-${this.config.position}`), this.container = e, t.appendChild(e), e;
584
+ }
585
+ /**
586
+ * Update status information
587
+ */
588
+ update(t) {
589
+ this.statusInfo = { ...this.statusInfo, ...t }, this.render();
590
+ }
591
+ /**
592
+ * Render status bar content
593
+ */
594
+ render() {
595
+ if (!this.container) return;
596
+ this.container.innerHTML = "";
597
+ const t = document.createElement("div");
598
+ t.className = "editora-statusbar-left";
599
+ const e = document.createElement("div");
600
+ e.className = "editora-statusbar-right";
601
+ const o = [];
602
+ if (this.statusInfo.selectionInfo) {
603
+ const n = this.statusInfo.selectionInfo;
604
+ n.startLine === n.endLine && n.startColumn === n.endColumn ? o.push(`Ln ${n.startLine}, Col ${n.startColumn}`) : (n.startLine === n.endLine ? o.push(`Ln ${n.startLine}, Col ${n.startColumn}-${n.endColumn}`) : o.push(`Ln ${n.startLine}:${n.startColumn} - ${n.endLine}:${n.endColumn}`), o.push(`${n.selectedChars} chars selected`));
605
+ } else if (this.statusInfo.cursorPosition) {
606
+ const n = this.statusInfo.cursorPosition;
607
+ o.push(`Ln ${n.line}, Col ${n.column}`);
608
+ }
609
+ this.statusInfo.language && o.push(this.statusInfo.language);
610
+ const i = [];
611
+ this.statusInfo.wordCount !== void 0 && i.push(`${this.statusInfo.wordCount} words`), this.statusInfo.charCount !== void 0 && i.push(`${this.statusInfo.charCount} chars`), this.statusInfo.lineCount !== void 0 && i.push(`${this.statusInfo.lineCount} lines`), this.statusInfo.custom && Object.entries(this.statusInfo.custom).forEach(([n, a]) => {
612
+ i.push(`${n}: ${a}`);
613
+ }), o.forEach((n, a) => {
614
+ const r = document.createElement("span");
615
+ if (r.className = "editora-statusbar-item", r.textContent = n, t.appendChild(r), a < o.length - 1) {
616
+ const s = document.createElement("span");
617
+ s.className = "editora-statusbar-separator", s.textContent = "|", t.appendChild(s);
618
+ }
619
+ }), i.forEach((n, a) => {
620
+ const r = document.createElement("span");
621
+ if (r.className = "editora-statusbar-item", r.textContent = n, e.appendChild(r), a < i.length - 1) {
622
+ const s = document.createElement("span");
623
+ s.className = "editora-statusbar-separator", s.textContent = "|", e.appendChild(s);
624
+ }
625
+ }), this.container.appendChild(t), this.container.appendChild(e);
626
+ }
627
+ /**
628
+ * Destroy status bar
629
+ */
630
+ destroy() {
631
+ this.container && this.container.parentNode && this.container.parentNode.removeChild(this.container), this.container = void 0;
632
+ }
633
+ }
634
+ function I(l, t) {
635
+ const e = l.textContent || "", o = P(l, t.startContainer, t.startOffset), n = e.substring(0, o).split(`
636
+ `), a = n.length, r = n[n.length - 1].length + 1;
637
+ return { line: a, column: r };
638
+ }
639
+ function P(l, t, e) {
640
+ var a;
641
+ let o = 0;
642
+ const i = document.createTreeWalker(
643
+ l,
644
+ NodeFilter.SHOW_TEXT,
645
+ null
646
+ );
647
+ let n = i.firstChild();
648
+ for (; n; ) {
649
+ if (n === t) {
650
+ o += e;
651
+ break;
652
+ } else n.nodeType === Node.TEXT_NODE && (o += ((a = n.textContent) == null ? void 0 : a.length) || 0);
653
+ n = i.nextNode();
654
+ }
655
+ return o;
656
+ }
657
+ function A(l) {
658
+ var o, i;
659
+ const t = l.querySelectorAll("div, p, br, h1, h2, h3, h4, h5, h6, blockquote, li, pre");
660
+ let e = 1;
661
+ if (t.length > 0) {
662
+ e = t.length;
663
+ const n = t[t.length - 1];
664
+ (n.tagName === "BR" || ((o = n.innerHTML) == null ? void 0 : o.trim()) === "" || ((i = n.textContent) == null ? void 0 : i.trim()) === "") && e++;
665
+ } else {
666
+ const a = (l.textContent || "").split(`
667
+ `).length;
668
+ e = Math.max(1, a);
669
+ }
670
+ return e;
671
+ }
672
+ function N(l) {
673
+ const t = l.trim() ? l.trim().split(/\s+/).length : 0, e = l.length;
674
+ return { words: t, chars: e };
675
+ }
676
+ function S(l, t) {
677
+ const e = l.toString();
678
+ return {
679
+ startLine: t.line,
680
+ startColumn: t.column,
681
+ endLine: t.line,
682
+ // For now, assuming single line selections
683
+ endColumn: t.column + e.length,
684
+ selectedChars: e.length,
685
+ selectedWords: e.trim().split(/\s+/).filter(Boolean).length
686
+ };
687
+ }
688
+ const y = class y {
689
+ /**
690
+ * Resolve configuration from multiple sources with priority
691
+ */
692
+ static resolve(t) {
693
+ const e = {};
694
+ if (Object.assign(e, this.EDITOR_DEFAULTS), t.pluginDefaults && Object.assign(e, t.pluginDefaults), t.attributes) {
695
+ const o = this.parseAttributes(t.attributes);
696
+ Object.assign(e, o);
697
+ }
698
+ return t.jsConfig && Object.assign(e, t.jsConfig), e;
699
+ }
700
+ /**
701
+ * Parse web component attributes
702
+ */
703
+ static parseAttributes(t) {
704
+ const e = {};
705
+ for (const [o, i] of Object.entries(t)) {
706
+ const n = this.kebabToCamel(o);
707
+ e[n] = this.parseAttributeValue(i);
708
+ }
709
+ return e;
710
+ }
711
+ /**
712
+ * Parse attribute value to appropriate type
713
+ */
714
+ static parseAttributeValue(t) {
715
+ if (t === "true") return !0;
716
+ if (t === "false") return !1;
717
+ if (/^\d+$/.test(t)) return parseInt(t, 10);
718
+ if (/^\d+\.\d+$/.test(t)) return parseFloat(t);
719
+ if (t.startsWith("{") || t.startsWith("["))
720
+ try {
721
+ return JSON.parse(t);
722
+ } catch (e) {
723
+ return t;
724
+ }
725
+ return t;
726
+ }
727
+ /**
728
+ * Convert kebab-case to camelCase
729
+ */
730
+ static kebabToCamel(t) {
731
+ return t.replace(/-([a-z])/g, (e, o) => o.toUpperCase());
732
+ }
733
+ /**
734
+ * Validate configuration
735
+ */
736
+ static validate(t) {
737
+ const e = [];
738
+ return t.height !== void 0 && typeof t.height == "number" && t.height < 0 && e.push("height must be a positive number"), t.width !== void 0 && typeof t.width == "number" && t.width < 0 && e.push("width must be a positive number"), t.plugins !== void 0 && !Array.isArray(t.plugins) && typeof t.plugins != "string" && e.push("plugins must be an array or string"), t.theme !== void 0 && typeof t.theme != "string" && e.push("theme must be a string"), {
739
+ valid: e.length === 0,
740
+ errors: e
741
+ };
742
+ }
743
+ /**
744
+ * Get default configuration
745
+ */
746
+ static getDefaults() {
747
+ return { ...this.EDITOR_DEFAULTS };
748
+ }
749
+ /**
750
+ * Merge configurations (deep merge)
751
+ */
752
+ static merge(...t) {
753
+ const e = {};
754
+ for (const o of t)
755
+ for (const [i, n] of Object.entries(o))
756
+ n != null && (typeof n == "object" && !Array.isArray(n) && e[i] ? e[i] = this.merge(e[i], n) : e[i] = n);
757
+ return e;
758
+ }
759
+ };
760
+ y.EDITOR_DEFAULTS = {
761
+ height: 400,
762
+ width: "100%",
763
+ readonly: !1,
764
+ disabled: !1,
765
+ menubar: !0,
766
+ toolbar: !0,
767
+ plugins: [],
768
+ theme: "light",
769
+ content: "",
770
+ placeholder: "Start typing...",
771
+ autofocus: !1,
772
+ autosave: !1,
773
+ spellcheck: !1,
774
+ language: "en"
775
+ };
776
+ let x = y;
777
+ class M {
778
+ constructor() {
779
+ this.loadedPlugins = /* @__PURE__ */ new Map(), this.pluginRegistry = /* @__PURE__ */ new Map();
780
+ }
781
+ /**
782
+ * Register a plugin factory (sync or async)
783
+ */
784
+ register(t, e) {
785
+ this.pluginRegistry.set(t, e);
786
+ }
787
+ /**
788
+ * Load a plugin by name (async)
789
+ */
790
+ async load(t, e) {
791
+ if (this.loadedPlugins.has(t))
792
+ return this.loadedPlugins.get(t);
793
+ const o = this.pluginRegistry.get(t);
794
+ if (!o)
795
+ return console.warn(`Plugin not found: ${t}`), null;
796
+ const i = await o();
797
+ return e && this.applyPluginConfig(i, e), this.loadedPlugins.set(t, i), i;
798
+ }
799
+ /**
800
+ * Load multiple plugins
801
+ */
802
+ async loadMultiple(t, e) {
803
+ return (await Promise.all(
804
+ t.map((i) => this.load(i, e))
805
+ )).filter((i) => i !== null);
806
+ }
807
+ /**
808
+ * Parse plugin string "lists link image media"
809
+ */
810
+ async parsePluginString(t, e) {
811
+ const o = t.split(/\s+/).filter(Boolean);
812
+ return this.loadMultiple(o, e);
813
+ }
814
+ /**
815
+ * Apply configuration to plugin
816
+ */
817
+ applyPluginConfig(t, e) {
818
+ t.__pluginConfig = e;
819
+ }
820
+ /**
821
+ * Unload a plugin
822
+ */
823
+ unload(t) {
824
+ this.loadedPlugins.delete(t);
825
+ }
826
+ /**
827
+ * Clear all loaded plugins
828
+ */
829
+ clear() {
830
+ this.loadedPlugins.clear();
831
+ }
832
+ /**
833
+ * Get all loaded plugins
834
+ */
835
+ getLoadedPlugins() {
836
+ return Array.from(this.loadedPlugins.values());
837
+ }
838
+ /**
839
+ * Get all registered plugin names (available for loading)
840
+ */
841
+ getRegisteredPluginNames() {
842
+ return Array.from(this.pluginRegistry.keys());
843
+ }
844
+ /**
845
+ * Check if plugin is loaded
846
+ */
847
+ isLoaded(t) {
848
+ return this.loadedPlugins.has(t);
849
+ }
850
+ }
851
+ const H = '.editora-editor{display:flex;flex-direction:column;border:1px solid #ddd;border-radius:4px;background:#fff;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;overflow:hidden}.editora-editor *{box-sizing:border-box}.editora-theme-light{background:#fff;color:#333}.editora-theme-dark{background:#1e1e1e;color:#d4d4d4;border-color:#3c3c3c}.editora-toolbar{display:flex;align-items:center;gap:4px;padding:8px;background:#f5f5f5;border-bottom:1px solid #ddd;flex-wrap:wrap}.editora-theme-dark .editora-toolbar{background:#252526;border-bottom-color:#3c3c3c}.editora-toolbar-sticky{position:sticky;top:0;z-index:100;position:-webkit-sticky}.editora-toolbar-group{display:flex;align-items:center;gap:2px}.editora-toolbar-button{padding:6px 12px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:14px;height:30px;display:flex;align-items:center;white-space:nowrap}.editora-toolbar-input.font-size{width:40px;padding:.25rem;text-align:center;font-size:14px;background:#fff;border:1px solid var(--rte-color-border-light);border-radius:var(--rte-radius-sm)}.editora-toolbar-group-items{display:flex;align-items:center;border:1px solid #ccc;.editora-toolbar-button{border:none;border-radius:0;&:first-child{border-right:1px solid #ccc;border-top-left-radius:3px;border-bottom-left-radius:3px}&:last-child{border-left:1px solid #ccc;border-top-right-radius:3px;border-bottom-right-radius:3px}}}.editora-theme-dark .editora-toolbar-button{color:#d4d4d4}.editora-toolbar-button:hover{background:#e0e0e0;border-color:#ccc}.editora-theme-dark .editora-toolbar-button:hover{background:#37373d;border-color:#555}.editora-toolbar-button:active,.editora-toolbar-button.active{background:#d0d0d0;border-color:#999}.editora-theme-dark .editora-toolbar-button:active,.editora-theme-dark .editora-toolbar-button.active{background:#2a2d2e;border-color:#666}.editora-toolbar-button:disabled{opacity:.5;cursor:not-allowed}.editora-toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;line-height:1}.editora-toolbar-button svg,.editora-toolbar-icon svg{width:24px;height:24px;display:block}.editora-toolbar-separator{width:1px;height:24px;background:#ddd;margin:0 4px}.editora-theme-dark .editora-toolbar-separator{background:#3c3c3c}.editora-toolbar-dropdown{position:relative}.editora-toolbar-dropdown-menu{position:absolute;top:100%;left:0;min-width:150px;margin-top:4px;padding:4px 0;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-toolbar-dropdown-menu{background:#252526;border-color:#3c3c3c;box-shadow:0 2px 8px #00000080}.editora-toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;color:#333;text-align:left;cursor:pointer;font-size:13px;transition:background .15s ease}.editora-theme-dark .editora-toolbar-dropdown-item{color:#d4d4d4}.editora-toolbar-dropdown-item:hover{background:#f5f5f5}.editora-theme-dark .editora-toolbar-dropdown-item:hover{background:#37373d}.editora-content{flex:1;min-height:200px;padding:16px;outline:none;overflow-y:auto;line-height:1.6}.editora-content:empty:before{content:attr(data-placeholder);color:#999;pointer-events:none}.editora-theme-dark .editora-content:empty:before{color:#6a6a6a}.editora-content h1{font-size:2em;margin:.67em 0;font-weight:600}.editora-content h2{font-size:1.5em;margin:.75em 0;font-weight:600}.editora-content h3{font-size:1.17em;margin:.83em 0;font-weight:600}.editora-content p{margin:1em 0}.editora-content ul,.editora-content ol{margin:1em 0;padding-left:2em}.editora-content a{color:#06c;text-decoration:underline}.editora-theme-dark .editora-content a{color:#4db8ff}.editora-content code{padding:2px 4px;background:#f5f5f5;border-radius:3px;font-family:Monaco,Menlo,Consolas,monospace;font-size:.9em}.editora-theme-dark .editora-content code{background:#1e1e1e}.editora-content pre{padding:12px;background:#f5f5f5;border-radius:4px;overflow-x:auto;margin:1em 0}.editora-theme-dark .editora-content pre{background:#1e1e1e}.editora-content blockquote{margin:1em 0;padding-left:1em;border-left:4px solid #ddd;color:#666}.editora-theme-dark .editora-content blockquote{border-left-color:#3c3c3c;color:#9a9a9a}.editora-floating-toolbar{position:absolute;padding:4px;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-floating-toolbar{background:#252526;border-color:#3c3c3c;box-shadow:0 2px 8px #00000080}.editora-statusbar-container{display:flex;flex-direction:column}.editora-statusbar-left{display:flex;align-items:center;gap:8px}.editora-statusbar-right{display:flex;align-items:center;gap:8px;margin-left:auto}.editora-statusbar{display:flex;align-items:center;gap:12px;padding:6px 12px;background:#f5f5f5;border-top:1px solid #ddd;font-size:12px;color:#666}.editora-theme-dark .editora-statusbar{background:#252526;border-top-color:#3c3c3c;color:#9a9a9a}.editora-statusbar-item{white-space:nowrap}.editora-statusbar-separator{color:#ddd}.editora-theme-dark .editora-statusbar-separator{color:#3c3c3c}.editora-editor[readonly] .editora-content{background:#fafafa;cursor:not-allowed}.editora-theme-dark.editora-editor[readonly] .editora-content{background:#1a1a1a}.editora-editor:focus-within{border-color:#06c;box-shadow:0 0 0 3px #0066cc1a}.editora-theme-dark.editora-editor:focus-within{border-color:#4db8ff;box-shadow:0 0 0 3px #4db8ff1a}.editora-editor[disabled]{opacity:.6;pointer-events:none}@media(max-width:768px){.editora-toolbar{padding:4px}.editora-toolbar-button{min-width:28px;min-height:28px;padding:4px 8px;font-size:12px}.editora-content{padding:12px}}.editora-content ::selection{background:#06c3}.editora-theme-dark .editora-content ::selection{background:#4db8ff33}.editora-content table{border-collapse:collapse;width:100%;margin:1em 0}.editora-content th,.editora-content td{border:1px solid #ddd;padding:8px 12px;text-align:left}.editora-theme-dark .editora-content th,.editora-theme-dark .editora-content td{border-color:#3c3c3c}.editora-content th{background:#f5f5f5;font-weight:600}.editora-theme-dark .editora-content th{background:#252526}.editora-content img{max-width:100%;height:auto;border-radius:4px;display:block}.editora-content video{max-width:100%;height:auto;border-radius:4px;display:block}.editora-editor.loading{opacity:.7;pointer-events:none}.editora-editor.loading:after{content:"";position:absolute;top:50%;left:50%;width:24px;height:24px;margin:-12px 0 0 -12px;border:3px solid #ddd;border-top-color:#06c;border-radius:50%;animation:editora-spin .8s linear infinite}@keyframes editora-spin{to{transform:rotate(360deg)}}.toolbar-container-wrapper{display:flex;align-items:center;background:#fff;border-bottom:1px solid #e0e0e0;padding:0;margin:0;width:100%;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:1.5;position:relative}.toolbar-container-wrapper[data-toolbar-sticky=true]{position:sticky;top:0;z-index:999;box-shadow:0 2px 4px #0000001a}.toolbar-container-wrapper[data-toolbar-floating=true]{position:fixed;top:0;left:0;right:0;z-index:1000;box-shadow:0 4px 12px #00000026}.toolbar-container-wrapper[data-toolbar-position=bottom]{border-bottom:none;border-top:1px solid #e0e0e0}.toolbar-container-wrapper .toolbar-wrapper{display:flex;width:100%;padding:8px;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar{display:flex;width:100%;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar-container{display:flex;gap:4px;flex-wrap:wrap;align-items:center;flex:1;position:relative}.toolbar-container-wrapper .toolbar-item{display:flex;align-items:center;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:6px 10px;border:1px solid #d1d5db;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;gap:4px;transition:all .15s ease;min-height:32px;white-space:nowrap}.toolbar-container-wrapper .toolbar-button:hover{background-color:#f3f4f6;border-color:#9ca3af}.toolbar-container-wrapper .toolbar-button:active,.toolbar-container-wrapper .toolbar-button[data-active=true]{background-color:#06c;color:#fff;border-color:#0052a3;box-shadow:inset 0 1px 3px #0000001a}.toolbar-container-wrapper .toolbar-button:disabled{opacity:.5;cursor:not-allowed;background-color:#f9fafb}.toolbar-container-wrapper .toolbar-more-button{padding:6px 8px;font-size:16px;font-weight:500;line-height:1}.toolbar-container-wrapper .toolbar-separator{width:1px;height:24px;background-color:#d1d5db;margin:0 4px}.toolbar-container-wrapper .toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0}.toolbar-container-wrapper .toolbar-icon svg{width:100%;height:100%}.toolbar-container-wrapper .toolbar-dropdown{position:relative;display:flex;align-items:center}.toolbar-container-wrapper .toolbar-dropdown-arrow{font-size:10px;margin-left:2px;line-height:1}.toolbar-container-wrapper .toolbar-dropdown-menu{position:absolute;top:100%;left:0;background:#fff;border:1px solid #d1d5db;border-radius:6px;box-shadow:0 4px 12px #00000026;z-index:1000;min-width:160px;padding:4px 0;margin-top:4px;display:none}.toolbar-container-wrapper .toolbar-dropdown-menu.show{display:block}.toolbar-container-wrapper .toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;text-align:left;cursor:pointer;font-size:13px;color:#1f2937;transition:background-color .15s ease;font-family:inherit}.toolbar-container-wrapper .toolbar-dropdown-item:hover{background-color:#f3f4f6}.toolbar-container-wrapper .toolbar-dropdown-item:active{background-color:#e5e7eb}.toolbar-container-wrapper .toolbar-input{padding:6px 8px;border:1px solid #d1d5db;border-radius:4px;font-size:13px;font-family:inherit;background-color:#fff;color:#1f2937;transition:all .15s ease}.toolbar-container-wrapper .toolbar-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 3px #0066cc1a;background-color:#fff}.toolbar-container-wrapper .toolbar-input::placeholder{color:#9ca3af}.toolbar-overflow-menu{animation:slideDown .2s ease-out}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.toolbar-overflow-item{transition:background-color .15s ease}.floating-toolbar{user-select:none;-webkit-user-select:none;font-family:system-ui,-apple-system,sans-serif;font-size:14px;animation:fadeInUp .15s ease-out}@keyframes fadeInUp{0%{opacity:0;transform:translate(-50%) translateY(10px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.floating-toolbar-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#495057;cursor:pointer;font-size:14px;font-weight:500;transition:all .15s ease;outline:none}.floating-toolbar-btn:hover{background:#f8f9fa;color:#212529}.floating-toolbar-btn:active{background:#e9ecef;transform:scale(.95)}.floating-toolbar-btn.floating-toolbar-toggle{color:#dc3545;font-weight:700}.floating-toolbar-btn.floating-toolbar-toggle:hover{background:#f8d7da;color:#721c24}.floating-toolbar-separator{width:1px;height:20px;background:#e1e5e9;margin:0 2px}@media(max-width:768px){.toolbar-container-wrapper .toolbar-button{padding:5px 8px;font-size:12px;min-height:28px}.toolbar-container-wrapper .toolbar-icon{width:16px;height:16px}.toolbar-container-wrapper .toolbar-dropdown-menu{min-width:140px}.toolbar-container-wrapper .toolbar-dropdown-item{padding:6px 10px;font-size:12px}.floating-toolbar{padding:4px;gap:2px}.floating-toolbar-btn{width:28px;height:28px;font-size:12px}}@media(max-width:480px){.toolbar-container-wrapper{padding:4px}.toolbar-container-wrapper .toolbar-wrapper{padding:4px;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:4px 6px;font-size:11px;min-height:24px}.toolbar-container-wrapper .toolbar-icon{width:14px;height:14px}}.floating-toolbar{pointer-events:auto}.floating-toolbar{max-width:calc(100vw - 20px);overflow-x:auto}@media(prefers-color-scheme:dark){.floating-toolbar{background:#2d3748;border-color:#4a5568;color:#e2e8f0}.floating-toolbar-btn:hover{background:#4a5568;color:#f7fafc}.floating-toolbar-btn:active{background:#718096}.floating-toolbar-separator{background:#4a5568}}';
852
+ let f;
853
+ function z() {
854
+ const l = "editora-webcomponent-styles";
855
+ if (!document.getElementById(l)) {
856
+ const t = document.createElement("style");
857
+ t.id = l, t.textContent = H, document.head.appendChild(t);
858
+ }
859
+ }
860
+ function B() {
861
+ if (!f) {
862
+ const l = g.__globalPluginLoader;
863
+ l ? f = l : f = new M();
864
+ }
865
+ return f;
866
+ }
867
+ function D(l) {
868
+ const t = B();
869
+ Object.entries(l).forEach(([e, o]) => {
870
+ t.register(e, o);
871
+ });
872
+ }
873
+ class g extends HTMLElement {
874
+ constructor() {
875
+ if (super(), this.config = {}, this.isInitialized = !1, z(), !this.hasAttribute("data-initial-content")) {
876
+ const t = this.innerHTML.trim();
877
+ t && this.setAttribute("data-initial-content", t);
878
+ }
879
+ }
880
+ // Observed attributes for reactive updates
881
+ static get observedAttributes() {
882
+ return [
883
+ "height",
884
+ "width",
885
+ "menubar",
886
+ "plugins",
887
+ "toolbar",
888
+ "toolbar-items",
889
+ "readonly",
890
+ "disabled",
891
+ "theme",
892
+ "placeholder",
893
+ "autofocus",
894
+ "language",
895
+ "spellcheck",
896
+ "statusbar"
897
+ ];
898
+ }
899
+ /**
900
+ * Called when element is added to DOM
901
+ */
902
+ connectedCallback() {
903
+ this.config = this.resolveConfig(), this.waitForPluginLoader().then(() => {
904
+ setTimeout(async () => {
905
+ await this.initialize();
906
+ }, 0);
907
+ });
908
+ }
909
+ /**
910
+ * Wait for the global plugin loader to be available
911
+ */
912
+ async waitForPluginLoader() {
913
+ if (g.__globalPluginLoader) {
914
+ this.pluginLoader = g.__globalPluginLoader;
915
+ return;
916
+ }
917
+ return new Promise((t) => {
918
+ const e = () => {
919
+ g.__globalPluginLoader ? (this.pluginLoader = g.__globalPluginLoader, t()) : setTimeout(e, 0);
920
+ };
921
+ e();
922
+ });
923
+ }
924
+ /**
925
+ * Called when element is removed from DOM
926
+ */
927
+ disconnectedCallback() {
928
+ this.destroy();
929
+ }
930
+ /**
931
+ * Called when an observed attribute changes
932
+ */
933
+ attributeChangedCallback(t, e, o) {
934
+ e !== o && (this.config = this.resolveConfig(), this.handleAttributeChange(t, o));
935
+ }
936
+ /**
937
+ * Set configuration via JavaScript API
938
+ */
939
+ async setConfig(t) {
940
+ this.jsConfig = t, this.config = this.resolveConfig(), this.isConnected && (this.destroy(), await this.waitForPluginLoader(), await this.initialize());
941
+ }
942
+ /**
943
+ * Initialize the editor
944
+ */
945
+ async initialize() {
946
+ if (this.querySelector(".editora-toolbar") || this.isInitialized) return;
947
+ this.setAttribute("data-editora-editor", "true"), this.config.height && (this.style.height = typeof this.config.height == "number" ? `${this.config.height}px` : this.config.height), this.config.width && (this.style.width = typeof this.config.width == "number" ? `${this.config.width}px` : this.config.width), this.classList.add("editora-editor"), this.config.theme && this.classList.add(`editora-theme-${this.config.theme}`);
948
+ const t = await this.loadPlugins();
949
+ t.forEach((o) => {
950
+ if (o.init && typeof o.init == "function")
951
+ try {
952
+ o.init({ editorElement: this });
953
+ } catch (i) {
954
+ console.error(`[RichTextEditor] Error initializing plugin ${o.name}:`, i);
955
+ }
956
+ });
957
+ const e = this.getAttribute("data-initial-content") || "";
958
+ this.engine = new k({
959
+ content: e,
960
+ plugins: t,
961
+ readonly: this.config.readonly
962
+ }), this.createUI(t, e), this.setupEventListeners(), this.isInitialized = !0, this.dispatchEvent(new CustomEvent("editor-ready", {
963
+ detail: { api: this.getAPI() },
964
+ bubbles: !0
965
+ }));
966
+ }
967
+ /**
968
+ * Get initial content from slot or attribute
969
+ */
970
+ getInitialContent() {
971
+ if (this.config.content)
972
+ return this.config.content;
973
+ const t = this.querySelector("[slot]");
974
+ return t ? t.innerHTML : this.hasChildNodes() ? Array.from(this.childNodes).map((o) => o.nodeType === Node.TEXT_NODE ? o.textContent : o.nodeType === Node.ELEMENT_NODE ? o.outerHTML : "").join("").trim() : "";
975
+ }
976
+ /**
977
+ * Load plugins based on configuration
978
+ */
979
+ async loadPlugins() {
980
+ this.pluginLoader || await this.waitForPluginLoader();
981
+ const t = [];
982
+ if (this.config.plugins && (typeof this.config.plugins == "string" && this.config.plugins.length > 0 || Array.isArray(this.config.plugins) && this.config.plugins.length > 0)) {
983
+ if (typeof this.config.plugins == "string") {
984
+ const o = await this.pluginLoader.parsePluginString(this.config.plugins);
985
+ t.push(...o);
986
+ } else if (Array.isArray(this.config.plugins))
987
+ for (const o of this.config.plugins)
988
+ if (typeof o == "string") {
989
+ const i = await this.pluginLoader.load(o);
990
+ i && t.push(i);
991
+ } else
992
+ t.push(o);
993
+ } else {
994
+ const o = this.pluginLoader.getRegisteredPluginNames(), i = await this.pluginLoader.loadMultiple(o);
995
+ t.push(...i);
996
+ }
997
+ return t;
998
+ }
999
+ /**
1000
+ * Create UI elements
1001
+ */
1002
+ createUI(t, e) {
1003
+ const o = this.querySelector('[slot="toolbar"]'), i = this.querySelector('[slot="statusbar"]');
1004
+ if (this.innerHTML = "", this.config.toolbar !== !1 && !o) {
1005
+ this.toolbarElement = document.createElement("div"), this.toolbarElement.className = "editora-toolbar-container", this.appendChild(this.toolbarElement);
1006
+ const n = this.config.toolbarItems || this.config.toolbar;
1007
+ this.toolbar = new v(
1008
+ {
1009
+ items: typeof n == "string" ? n : void 0,
1010
+ sticky: this.config.toolbar && typeof this.config.toolbar == "object" ? this.config.toolbar.sticky : !1,
1011
+ position: "top"
1012
+ },
1013
+ t,
1014
+ this.pluginLoader
1015
+ // Pass plugin loader to get all registered plugins
1016
+ ), this.toolbar.setCommandHandler((a, r) => {
1017
+ var b, u;
1018
+ if (this.contentElement) {
1019
+ this.contentElement.focus();
1020
+ const p = window.getSelection();
1021
+ if (!p || p.rangeCount === 0 || !this.contentElement.contains(p.anchorNode)) {
1022
+ const d = document.createRange(), c = this.contentElement.lastChild || this.contentElement;
1023
+ c.nodeType === Node.TEXT_NODE ? d.setStart(c, ((b = c.textContent) == null ? void 0 : b.length) || 0) : c.nodeType === Node.ELEMENT_NODE ? (d.selectNodeContents(c), d.collapse(!1)) : d.setStart(this.contentElement, 0), d.collapse(!0), p == null || p.removeAllRanges(), p == null || p.addRange(d);
1024
+ }
1025
+ }
1026
+ const s = t.find((p) => p.commands && p.commands[a]);
1027
+ if (s && s.commands) {
1028
+ const p = s.commands[a];
1029
+ if (typeof p == "function")
1030
+ try {
1031
+ return p(a === "toggleFullscreen" ? this : r);
1032
+ } catch (d) {
1033
+ return console.error(`[RichTextEditor] Error executing native command ${a}:`, d), !1;
1034
+ }
1035
+ }
1036
+ return ((u = this.engine) == null ? void 0 : u.execCommand(a, r)) || !1;
1037
+ }), this.toolbar.render(this.toolbarElement);
1038
+ } else o && this.appendChild(o);
1039
+ this.contentElement = document.createElement("div"), this.contentElement.className = "editora-content rte-content", this.contentElement.contentEditable = this.config.readonly ? "false" : "true", this.contentElement.setAttribute("role", "textbox"), this.contentElement.setAttribute("aria-multiline", "true"), this.config.placeholder && this.contentElement.setAttribute("data-placeholder", this.config.placeholder);
1040
+ try {
1041
+ document.execCommand("defaultParagraphSeparator", !1, "p");
1042
+ } catch (n) {
1043
+ console.warn("defaultParagraphSeparator not supported:", n);
1044
+ }
1045
+ if (e) {
1046
+ const n = document.createElement("div");
1047
+ n.innerHTML = e.trim(), !Array.from(n.childNodes).some((r) => {
1048
+ if (r.nodeType === Node.ELEMENT_NODE) {
1049
+ const s = r.tagName;
1050
+ return ["P", "DIV", "H1", "H2", "H3", "H4", "H5", "H6", "UL", "OL", "BLOCKQUOTE", "PRE"].includes(s);
1051
+ }
1052
+ return !1;
1053
+ }) && e.trim() ? this.contentElement.innerHTML = `<p>${e.trim()}</p>` : this.contentElement.innerHTML = e;
1054
+ } else
1055
+ this.config.placeholder ? this.contentElement.innerHTML = "" : this.contentElement.innerHTML = "<p><br></p>";
1056
+ this.appendChild(this.contentElement), this.config.toolbar && typeof this.config.toolbar == "object" && this.config.toolbar.floating && (this.floatingToolbar = new L({ enabled: !0 }), this.floatingToolbar.create(this)), i ? this.appendChild(i) : this.config.statusbar && (this.statusBarElement = document.createElement("div"), this.statusBarElement.className = "editora-statusbar-container", this.appendChild(this.statusBarElement), this.statusBar = new T({ position: "bottom" }), this.statusBar.create(this.statusBarElement)), this.config.autofocus && setTimeout(() => {
1057
+ var n;
1058
+ return (n = this.contentElement) == null ? void 0 : n.focus();
1059
+ }, 0);
1060
+ }
1061
+ /**
1062
+ * Setup event listeners
1063
+ */
1064
+ setupEventListeners() {
1065
+ if (!this.contentElement || !this.engine) return;
1066
+ this.contentElement.addEventListener("input", () => {
1067
+ const e = this.contentElement.innerHTML;
1068
+ this.dispatchEvent(new CustomEvent("content-change", {
1069
+ detail: { html: e },
1070
+ bubbles: !0
1071
+ })), this.updateStatusBar();
1072
+ }), this.contentElement.addEventListener("focus", () => {
1073
+ this.dispatchEvent(new Event("editor-focus", { bubbles: !0 }));
1074
+ }), this.contentElement.addEventListener("blur", () => {
1075
+ this.dispatchEvent(new Event("editor-blur", { bubbles: !0 }));
1076
+ });
1077
+ const t = () => {
1078
+ this.updateFloatingToolbar(), this.updateStatusBar();
1079
+ };
1080
+ document.addEventListener("selectionchange", t);
1081
+ }
1082
+ /**
1083
+ * Update floating toolbar position
1084
+ */
1085
+ updateFloatingToolbar() {
1086
+ if (!this.floatingToolbar) return;
1087
+ const t = window.getSelection();
1088
+ if (!t || t.rangeCount === 0) {
1089
+ this.floatingToolbar.hide();
1090
+ return;
1091
+ }
1092
+ const e = t.getRangeAt(0);
1093
+ if (e.collapsed) {
1094
+ this.floatingToolbar.hide();
1095
+ return;
1096
+ }
1097
+ const o = e.getBoundingClientRect();
1098
+ this.floatingToolbar.show(o.left, o.top - 40);
1099
+ }
1100
+ /**
1101
+ * Update status bar with selection and cursor information
1102
+ */
1103
+ /**
1104
+ * Update status bar with current content and cursor information
1105
+ */
1106
+ updateStatusBar() {
1107
+ if (!this.statusBar || !this.contentElement) return;
1108
+ const t = this.contentElement.textContent || "", { words: e, chars: o } = N(t), i = A(this.contentElement), n = window.getSelection();
1109
+ let a, r;
1110
+ if (n && n.rangeCount > 0) {
1111
+ const s = n.getRangeAt(0);
1112
+ a = I(this.contentElement, s), s.collapsed || (r = S(s, a), a = void 0);
1113
+ }
1114
+ this.statusBar.update({
1115
+ wordCount: e,
1116
+ charCount: o,
1117
+ lineCount: i,
1118
+ cursorPosition: a,
1119
+ selectionInfo: r
1120
+ });
1121
+ }
1122
+ /**
1123
+ * Handle attribute changes
1124
+ */
1125
+ handleAttributeChange(t, e) {
1126
+ switch (t) {
1127
+ case "readonly":
1128
+ this.contentElement && (this.contentElement.contentEditable = e === "true" ? "false" : "true"), this.engine && this.engine.setReadonly(e === "true");
1129
+ break;
1130
+ case "theme":
1131
+ this.classList.forEach((o) => {
1132
+ o.startsWith("editora-theme-") && this.classList.remove(o);
1133
+ }), e && this.classList.add(`editora-theme-${e}`);
1134
+ break;
1135
+ case "placeholder":
1136
+ this.contentElement && this.contentElement.setAttribute("data-placeholder", e);
1137
+ break;
1138
+ case "toolbar":
1139
+ case "plugins":
1140
+ this.isConnected && (this.destroy(), this.waitForPluginLoader().then(() => {
1141
+ this.initialize().catch((o) => {
1142
+ console.error("[RichTextEditor] Error during attribute change re-initialization:", o);
1143
+ });
1144
+ }));
1145
+ break;
1146
+ }
1147
+ }
1148
+ /**
1149
+ * Resolve configuration from all sources
1150
+ */
1151
+ resolveConfig() {
1152
+ const t = {};
1153
+ for (let e = 0; e < this.attributes.length; e++) {
1154
+ const o = this.attributes[e];
1155
+ t[o.name] = o.value;
1156
+ }
1157
+ return x.resolve({
1158
+ jsConfig: this.jsConfig,
1159
+ attributes: t
1160
+ });
1161
+ }
1162
+ /**
1163
+ * Get public API
1164
+ */
1165
+ getAPI() {
1166
+ return {
1167
+ getContent: () => {
1168
+ var t;
1169
+ return ((t = this.contentElement) == null ? void 0 : t.innerHTML) || "";
1170
+ },
1171
+ setContent: (t) => {
1172
+ this.contentElement && (this.contentElement.innerHTML = t);
1173
+ },
1174
+ execCommand: (t, e) => {
1175
+ var o;
1176
+ return ((o = this.engine) == null ? void 0 : o.execCommand(t, e)) || !1;
1177
+ },
1178
+ focus: () => {
1179
+ var t;
1180
+ (t = this.contentElement) == null || t.focus();
1181
+ },
1182
+ blur: () => {
1183
+ var t;
1184
+ (t = this.contentElement) == null || t.blur();
1185
+ },
1186
+ destroy: () => {
1187
+ this.destroy();
1188
+ },
1189
+ on: (t, e) => (this.addEventListener(t, e), () => this.removeEventListener(t, e)),
1190
+ getConfig: () => ({ ...this.config }),
1191
+ setReadonly: (t) => {
1192
+ this.setAttribute("readonly", t.toString());
1193
+ }
1194
+ };
1195
+ }
1196
+ /**
1197
+ * Destroy the editor
1198
+ */
1199
+ destroy() {
1200
+ var t, e, o, i;
1201
+ (t = this.engine) == null || t.destroy(), (e = this.toolbar) == null || e.destroy(), (o = this.floatingToolbar) == null || o.destroy(), (i = this.statusBar) == null || i.destroy(), this.innerHTML = "", this.isInitialized = !1, this.dispatchEvent(new Event("editor-destroy", { bubbles: !0 }));
1202
+ }
1203
+ // Public API methods
1204
+ getContent() {
1205
+ var t;
1206
+ return ((t = this.contentElement) == null ? void 0 : t.innerHTML) || "";
1207
+ }
1208
+ setContent(t) {
1209
+ this.contentElement && (this.contentElement.innerHTML = t);
1210
+ }
1211
+ execCommand(t, e) {
1212
+ var o;
1213
+ return ((o = this.engine) == null ? void 0 : o.execCommand(t, e)) || !1;
1214
+ }
1215
+ focus() {
1216
+ var t;
1217
+ (t = this.contentElement) == null || t.focus();
1218
+ }
1219
+ blur() {
1220
+ var t;
1221
+ (t = this.contentElement) == null || t.blur();
1222
+ }
1223
+ }
1224
+ export {
1225
+ E as C,
1226
+ m as E,
1227
+ L as F,
1228
+ C as P,
1229
+ g as R,
1230
+ w as S,
1231
+ v as T,
1232
+ k as a,
1233
+ T as b,
1234
+ P as c,
1235
+ A as d,
1236
+ N as e,
1237
+ S as f,
1238
+ I as g,
1239
+ x as h,
1240
+ M as i,
1241
+ D as j
1242
+ };
1243
+ //# sourceMappingURL=index-BPsf460l.mjs.map