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