@editora/plugins 1.0.2 → 1.0.5

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 (105) hide show
  1. package/README.md +30 -5
  2. package/dist/a11y-checker.cjs.js +109 -0
  3. package/dist/a11y-checker.esm.js +509 -0
  4. package/dist/anchor.cjs.js +176 -0
  5. package/dist/anchor.esm.js +400 -0
  6. package/dist/background-color.cjs.js +218 -0
  7. package/dist/background-color.esm.js +482 -0
  8. package/dist/blockquote.cjs.js +1 -0
  9. package/dist/blockquote.esm.js +47 -0
  10. package/dist/bold.cjs.js +1 -0
  11. package/dist/bold.esm.js +44 -0
  12. package/dist/capitalization.cjs.js +1 -0
  13. package/dist/capitalization.esm.js +78 -0
  14. package/dist/checklist.cjs.js +1 -0
  15. package/dist/checklist.esm.js +305 -0
  16. package/dist/clear-formatting.cjs.js +1 -0
  17. package/dist/clear-formatting.esm.js +138 -0
  18. package/dist/code-sample.cjs.js +161 -0
  19. package/dist/code-sample.esm.js +381 -0
  20. package/dist/code.cjs.js +606 -0
  21. package/dist/code.esm.js +2164 -0
  22. package/dist/colorSelectionApply-C0iOfMWb.js +1 -0
  23. package/dist/colorSelectionApply-D8r_gV32.mjs +63 -0
  24. package/dist/comments.cjs.js +354 -0
  25. package/dist/comments.esm.js +692 -0
  26. package/dist/direction.cjs.js +1 -0
  27. package/dist/direction.esm.js +129 -0
  28. package/dist/document-manager.cjs.js +1 -0
  29. package/dist/document-manager.esm.js +6 -0
  30. package/dist/{documentManager-CYC9totK.mjs → documentManager-DRUc1-Cs.mjs} +3 -3
  31. package/dist/{documentManager-BGlu3WRB.js → documentManager-_tQQfQi9.js} +3 -3
  32. package/dist/editorContainerHelpers-C7kdWnS0.mjs +26 -0
  33. package/dist/editorContainerHelpers-CFbfiOJI.js +1 -0
  34. package/dist/embed-iframe.cjs.js +361 -0
  35. package/dist/embed-iframe.esm.js +556 -0
  36. package/dist/emojis.cjs.js +284 -0
  37. package/dist/emojis.esm.js +1080 -0
  38. package/dist/font-family.cjs.js +1 -0
  39. package/dist/font-family.esm.js +152 -0
  40. package/dist/font-size.cjs.js +1 -0
  41. package/dist/font-size.esm.js +278 -0
  42. package/dist/footnote.cjs.js +85 -0
  43. package/dist/footnote.esm.js +397 -0
  44. package/dist/fullscreen.cjs.js +1 -0
  45. package/dist/fullscreen.esm.js +73 -0
  46. package/dist/heading.cjs.js +1 -0
  47. package/dist/heading.esm.js +63 -0
  48. package/dist/history.cjs.js +1 -0
  49. package/dist/history.esm.js +246 -0
  50. package/dist/indent.cjs.js +1 -0
  51. package/dist/indent.esm.js +146 -0
  52. package/dist/index-Bskk414V.mjs +145 -0
  53. package/dist/index-D3pJyAsj.js +1 -0
  54. package/dist/index.cjs.js +1 -1
  55. package/dist/{index.es-B-to-4j4.js → index.es-Cz1qItab.js} +1 -1
  56. package/dist/{index.es-BbXJ7tyO.mjs → index.es-DEcRmSTY.mjs} +1 -1
  57. package/dist/index.esm.js +89 -49
  58. package/dist/italic.cjs.js +1 -0
  59. package/dist/italic.esm.js +40 -0
  60. package/dist/line-height.cjs.js +1 -0
  61. package/dist/line-height.esm.js +145 -0
  62. package/dist/link.cjs.js +138 -0
  63. package/dist/link.esm.js +276 -0
  64. package/dist/list.cjs.js +1 -0
  65. package/dist/list.esm.js +102 -0
  66. package/dist/lite.cjs.js +1 -0
  67. package/dist/lite.esm.js +61 -0
  68. package/dist/math.cjs.js +45 -0
  69. package/dist/math.esm.js +249 -0
  70. package/dist/media-manager.cjs.js +619 -0
  71. package/dist/media-manager.esm.js +994 -0
  72. package/dist/merge-tag.cjs.js +93 -0
  73. package/dist/merge-tag.esm.js +412 -0
  74. package/dist/page-break.cjs.js +72 -0
  75. package/dist/page-break.esm.js +295 -0
  76. package/dist/plugins.css +1 -1
  77. package/dist/preview.cjs.js +230 -0
  78. package/dist/preview.esm.js +321 -0
  79. package/dist/print.cjs.js +254 -0
  80. package/dist/print.esm.js +309 -0
  81. package/dist/purify.es-DHhaBdbu.mjs +470 -0
  82. package/dist/purify.es-T2a3nLiC.js +3 -0
  83. package/dist/shared-config.cjs.js +1 -0
  84. package/dist/shared-config.esm.js +30 -0
  85. package/dist/special-characters.cjs.js +257 -0
  86. package/dist/special-characters.esm.js +772 -0
  87. package/dist/spell-check.cjs.js +512 -0
  88. package/dist/spell-check.esm.js +1013 -0
  89. package/dist/strikethrough.cjs.js +1 -0
  90. package/dist/strikethrough.esm.js +71 -0
  91. package/dist/table.cjs.js +35 -0
  92. package/dist/table.esm.js +477 -0
  93. package/dist/template.cjs.js +356 -0
  94. package/dist/template.esm.js +560 -0
  95. package/dist/text-alignment.cjs.js +1 -0
  96. package/dist/text-alignment.esm.js +105 -0
  97. package/dist/text-color.cjs.js +300 -0
  98. package/dist/text-color.esm.js +507 -0
  99. package/dist/underline.cjs.js +1 -0
  100. package/dist/underline.esm.js +34 -0
  101. package/index.d.ts +62 -0
  102. package/package.json +220 -7
  103. package/LICENSE +0 -21
  104. package/dist/index-BbORIHoM.mjs +0 -11763
  105. package/dist/index-C-OCBS_6.js +0 -3753
@@ -0,0 +1,2164 @@
1
+ class H {
2
+ constructor(e = "") {
3
+ this._lines = [], this._version = 0, this.setText(e);
4
+ }
5
+ // Get line at index
6
+ getLine(e) {
7
+ return this._lines[e] || "";
8
+ }
9
+ // Get all lines
10
+ getLines() {
11
+ return [...this._lines];
12
+ }
13
+ // Get total number of lines
14
+ getLineCount() {
15
+ return this._lines.length;
16
+ }
17
+ // Get total text content
18
+ getText() {
19
+ return this._lines.join(`
20
+ `);
21
+ }
22
+ // Set entire text content
23
+ setText(e) {
24
+ this._lines = e.split(`
25
+ `), this._version++;
26
+ }
27
+ // Get text in a range
28
+ getTextInRange(e) {
29
+ if (e.start.line === e.end.line)
30
+ return this.getLine(e.start.line).substring(e.start.column, e.end.column);
31
+ const t = [];
32
+ t.push(this.getLine(e.start.line).substring(e.start.column));
33
+ for (let i = e.start.line + 1; i < e.end.line; i++)
34
+ t.push(this.getLine(i));
35
+ return e.end.line < this.getLineCount() && t.push(this.getLine(e.end.line).substring(0, e.end.column)), t.join(`
36
+ `);
37
+ }
38
+ // Replace text in range
39
+ replaceRange(e, t) {
40
+ const i = this.getTextInRange(e);
41
+ if (e.start.line === e.end.line) {
42
+ const s = this.getLine(e.start.line), r = s.substring(0, e.start.column) + t + s.substring(e.end.column);
43
+ this._lines[e.start.line] = r;
44
+ } else {
45
+ const s = this.getLine(e.start.line), r = this.getLine(e.end.line), o = s.substring(0, e.start.column) + t, n = r.substring(e.end.column), l = t.split(`
46
+ `);
47
+ l[0] = o + l[0], l[l.length - 1] = l[l.length - 1] + n, this._lines.splice(e.start.line, e.end.line - e.start.line + 1, ...l);
48
+ }
49
+ return this._version++, { range: e, text: t, oldText: i };
50
+ }
51
+ // Insert text at position
52
+ insertText(e, t) {
53
+ const i = { start: e, end: e };
54
+ return this.replaceRange(i, t);
55
+ }
56
+ // Delete text in range
57
+ deleteRange(e) {
58
+ return this.replaceRange(e, "");
59
+ }
60
+ // Convert position to offset
61
+ positionToOffset(e) {
62
+ let t = 0;
63
+ for (let i = 0; i < e.line; i++)
64
+ t += this.getLine(i).length + 1;
65
+ return t += e.column, t;
66
+ }
67
+ // Convert offset to position
68
+ offsetToPosition(e) {
69
+ let t = e;
70
+ for (let i = 0; i < this.getLineCount(); i++) {
71
+ const s = this.getLine(i).length;
72
+ if (t <= s)
73
+ return { line: i, column: t };
74
+ t -= s + 1;
75
+ }
76
+ return {
77
+ line: this.getLineCount() - 1,
78
+ column: this.getLine(this.getLineCount() - 1).length
79
+ };
80
+ }
81
+ // Validate position
82
+ isValidPosition(e) {
83
+ return !(e.line < 0 || e.line >= this.getLineCount() || e.column < 0 || e.column > this.getLine(e.line).length);
84
+ }
85
+ // Validate range
86
+ isValidRange(e) {
87
+ return this.isValidPosition(e.start) && this.isValidPosition(e.end);
88
+ }
89
+ // Get version for change tracking
90
+ getVersion() {
91
+ return this._version;
92
+ }
93
+ // Clone the model
94
+ clone() {
95
+ const e = new H();
96
+ return e._lines = [...this._lines], e._version = this._version, e;
97
+ }
98
+ }
99
+ class P {
100
+ constructor(e) {
101
+ this.gutterWidth = 50, this.lineHeight = 21, this.trailingNewlineMarkerAttr = "data-lce-trailing-newline-marker", this.container = e, this.createDOM();
102
+ }
103
+ createDOM() {
104
+ this.container.innerHTML = "";
105
+ const e = document.createElement("div");
106
+ this.editorContainer = e, e.style.cssText = `
107
+ position: relative;
108
+ display: flex;
109
+ width: 100%;
110
+ height: 100%;
111
+ background: var(--editor-background, #1e1e1e);
112
+ color: var(--editor-foreground, #f8f9fa);
113
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
114
+ font-size: 14px;
115
+ line-height: ${this.lineHeight}px;
116
+ /* make the outer container the single scrollable element so gutter and content scroll together */
117
+ overflow: auto;
118
+ `, this.lineNumbersElement = document.createElement("div"), this.lineNumbersElement.setAttribute("data-editor-gutter", "true"), this.lineNumbersElement.style.cssText = `
119
+ display: table-cell;
120
+ vertical-align: top;
121
+ width: ${this.gutterWidth}px;
122
+ background: var(--editor-gutter-background, #252526);
123
+ color: var(--editor-gutter-foreground, #858585);
124
+ padding: 0 8px 0 0;
125
+ text-align: right;
126
+ border-right: 1px solid var(--editor-gutter-border, #3e3e42);
127
+ user-select: none;
128
+ z-index: 1;
129
+ `, this.contentElement = document.createElement("div"), this.contentElement.style.cssText = `
130
+ display: table-cell;
131
+ vertical-align: top;
132
+ padding: 0 12px;
133
+ background: transparent;
134
+ border: none;
135
+ outline: none;
136
+ white-space: pre;
137
+ overflow-x: auto;
138
+ overflow-y: visible;
139
+ min-height: 400px;
140
+ font-family: inherit;
141
+ font-size: inherit;
142
+ line-height: inherit;
143
+ color: inherit;
144
+ tab-size: 2;
145
+ -moz-tab-size: 2;
146
+ `, this.contentElement.contentEditable = "true", this.contentElement.spellcheck = !1;
147
+ const t = document.createElement("div");
148
+ t.setAttribute("data-editora-editor", "true"), t.style.cssText = "display: table; table-layout: fixed; width: 100%; height: 100%;", t.appendChild(this.lineNumbersElement), t.appendChild(this.contentElement), e.appendChild(t), this.container.appendChild(e), this.updateLineNumbers(1);
149
+ }
150
+ // Update line numbers
151
+ updateLineNumbers(e) {
152
+ const t = Math.max(e, 20), i = Array.from({ length: t }, (s, r) => r + 1);
153
+ this.lineNumbersElement.innerHTML = i.map((s) => `<div style="height: ${this.lineHeight}px; line-height: ${this.lineHeight}px; padding-right: 12px;">${s}</div>`).join("");
154
+ }
155
+ // Get content element
156
+ getContentElement() {
157
+ return this.contentElement;
158
+ }
159
+ // Get line numbers element
160
+ getLineNumbersElement() {
161
+ return this.lineNumbersElement;
162
+ }
163
+ // Get text content
164
+ getText() {
165
+ const e = this.contentElement.textContent || "";
166
+ return this.contentElement.querySelector(`[${this.trailingNewlineMarkerAttr}]`) && e.endsWith("​") ? e.slice(0, -1) : e;
167
+ }
168
+ // Set text content
169
+ setText(e) {
170
+ this.contentElement.textContent = e, this.syncTrailingNewlineMarker(e.endsWith(`
171
+ `));
172
+ const t = e.split(`
173
+ `).length;
174
+ this.updateLineNumbers(t);
175
+ }
176
+ // Set inner HTML (used for syntax highlighted content)
177
+ setHTML(e) {
178
+ const t = /\n$/.test(e), i = /&lt;|&gt;/.test(e), s = /<span\b/i.test(e), r = /<[^>]+>/.test(e);
179
+ i && s ? this.contentElement.innerHTML = e : r && !i ? this.contentElement.textContent = e : this.contentElement.innerHTML = e, this.syncTrailingNewlineMarker(t);
180
+ const o = (this.contentElement.textContent || "").split(`
181
+ `).length;
182
+ this.updateLineNumbers(o);
183
+ }
184
+ // Keep trailing-newline caret marker in sync for live contenteditable edits
185
+ // (without forcing a full setText/setHTML render).
186
+ syncTrailingNewlineMarkerForText(e) {
187
+ this.syncTrailingNewlineMarker(e.endsWith(`
188
+ `));
189
+ }
190
+ // Get cursor position from DOM selection
191
+ getCursorPosition() {
192
+ const e = window.getSelection();
193
+ if (!e || e.rangeCount === 0)
194
+ return { line: 0, column: 0 };
195
+ const t = e.getRangeAt(0), i = t.cloneRange();
196
+ i.selectNodeContents(this.contentElement), i.setEnd(t.endContainer, t.endOffset);
197
+ const s = i.toString().replace(/\u200B/g, "").split(`
198
+ `);
199
+ return {
200
+ line: s.length - 1,
201
+ column: s[s.length - 1].length
202
+ };
203
+ }
204
+ // Set cursor position
205
+ setCursorPosition(e) {
206
+ const t = this.getText().split(`
207
+ `), i = Math.min(e.line, t.length - 1), s = Math.min(e.column, t[i]?.length || 0);
208
+ let r = 0;
209
+ for (let u = 0; u < i; u++)
210
+ r += t[u].length + 1;
211
+ r += s;
212
+ const o = document.createRange(), n = window.getSelection();
213
+ let l = 0, a = null, c = 0;
214
+ const g = document.createTreeWalker(
215
+ this.contentElement,
216
+ NodeFilter.SHOW_TEXT,
217
+ null
218
+ );
219
+ let h;
220
+ for (; h = g.nextNode(); ) {
221
+ const u = h.textContent?.length || 0;
222
+ if (l + u >= r) {
223
+ a = h, c = r - l;
224
+ break;
225
+ }
226
+ l += u;
227
+ }
228
+ if (a)
229
+ try {
230
+ o.setStart(a, c), o.setEnd(a, c), n?.removeAllRanges(), n?.addRange(o), this.ensureCaretVisible();
231
+ } catch (u) {
232
+ console.warn("Could not set cursor position:", u);
233
+ }
234
+ else {
235
+ const u = this.contentElement.querySelector(
236
+ `[${this.trailingNewlineMarkerAttr}]`
237
+ );
238
+ try {
239
+ u && u.parentNode === this.contentElement ? o.setStartBefore(u) : (o.selectNodeContents(this.contentElement), o.collapse(!1)), o.collapse(!0), n?.removeAllRanges(), n?.addRange(o), this.ensureCaretVisible();
240
+ } catch (d) {
241
+ console.warn("Could not set fallback cursor position:", d);
242
+ }
243
+ }
244
+ }
245
+ // Get selection range
246
+ getSelectionRange() {
247
+ const e = window.getSelection();
248
+ if (!e || e.rangeCount === 0 || e.isCollapsed)
249
+ return;
250
+ const t = e.getRangeAt(0), i = t.cloneRange();
251
+ i.selectNodeContents(this.contentElement), i.setEnd(t.startContainer, t.startOffset);
252
+ const s = i.toString().replace(/\u200B/g, "").split(`
253
+ `), r = t.cloneRange();
254
+ r.selectNodeContents(this.contentElement), r.setEnd(t.endContainer, t.endOffset);
255
+ const o = r.toString().replace(/\u200B/g, "").split(`
256
+ `);
257
+ return {
258
+ start: {
259
+ line: s.length - 1,
260
+ column: s[s.length - 1].length
261
+ },
262
+ end: {
263
+ line: o.length - 1,
264
+ column: o[o.length - 1].length
265
+ }
266
+ };
267
+ }
268
+ // Set selection range
269
+ setSelectionRange(e) {
270
+ this.setCursorPosition(e.start);
271
+ }
272
+ // Focus the editor
273
+ focus() {
274
+ this.contentElement.focus(), this.ensureCaretVisible();
275
+ }
276
+ // Blur the editor
277
+ blur() {
278
+ this.contentElement.blur();
279
+ }
280
+ // Set read-only mode
281
+ setReadOnly(e) {
282
+ this.contentElement.contentEditable = e ? "false" : "true";
283
+ }
284
+ // Apply theme
285
+ applyTheme(e) {
286
+ Object.entries(e).forEach(([t, i]) => {
287
+ this.container.style.setProperty(`--${t}`, i);
288
+ });
289
+ }
290
+ // Scroll to position
291
+ scrollToPosition(e) {
292
+ const t = this.lineNumbersElement.children[e.line];
293
+ t && t.scrollIntoView({ block: "center", behavior: "smooth" });
294
+ }
295
+ // Get scroll position
296
+ getScrollTop() {
297
+ return this.editorContainer.scrollTop;
298
+ }
299
+ // Set scroll position
300
+ setScrollTop(e) {
301
+ this.editorContainer.scrollTop = e;
302
+ }
303
+ syncTrailingNewlineMarker(e) {
304
+ if (this.contentElement.querySelectorAll(`[${this.trailingNewlineMarkerAttr}]`).forEach((i) => i.remove()), !e) return;
305
+ const t = document.createElement("span");
306
+ t.setAttribute(this.trailingNewlineMarkerAttr, "true"), t.setAttribute("aria-hidden", "true"), t.contentEditable = "false", t.style.cssText = `
307
+ display: inline-block;
308
+ width: 0;
309
+ overflow: hidden;
310
+ pointer-events: none;
311
+ user-select: none;
312
+ `, t.appendChild(document.createTextNode("​")), this.contentElement.appendChild(t);
313
+ }
314
+ // Ensure caret is visible inside the editor scroll container
315
+ ensureCaretVisible() {
316
+ const e = window.getSelection();
317
+ if (!e || e.rangeCount === 0) return;
318
+ const t = e.getRangeAt(0).cloneRange();
319
+ t.collapse(!1);
320
+ let i = t.getClientRects()[0] || t.getBoundingClientRect();
321
+ if ((!i || i.width === 0 && i.height === 0) && e.focusNode instanceof Element ? i = e.focusNode.getBoundingClientRect() : (!i || i.width === 0 && i.height === 0) && e.focusNode?.parentElement && (i = e.focusNode.parentElement.getBoundingClientRect()), !i) return;
322
+ const s = this.editorContainer.getBoundingClientRect(), r = 12;
323
+ i.bottom > s.bottom - r ? this.editorContainer.scrollTop += i.bottom - (s.bottom - r) : i.top < s.top + r && (this.editorContainer.scrollTop -= s.top + r - i.top);
324
+ }
325
+ // Destroy the view
326
+ destroy() {
327
+ this.container && this.container.parentNode && this.container.parentNode.removeChild(this.container), this._rafId && (cancelAnimationFrame(this._rafId), this._rafId = void 0);
328
+ }
329
+ }
330
+ const $ = class M {
331
+ constructor(e, t = {}) {
332
+ this.extensions = /* @__PURE__ */ new Map(), this.commands = /* @__PURE__ */ new Map(), this.eventListeners = /* @__PURE__ */ new Map(), this.folds = [], this.currentTheme = "default", this.isDestroyed = !1, this.undoStack = [], this.redoStack = [], this.suppressHistory = !1, this.highlightTimeout = null, this.expectingProgrammaticCursor = !1, this.config = {
333
+ value: "",
334
+ theme: "default",
335
+ readOnly: !1,
336
+ tabSize: 2,
337
+ lineWrapping: !1,
338
+ lineNumbers: !0,
339
+ ...t
340
+ }, this.textModel = new H(this.config.value), this.view = new P(e), this.setupEventHandlers(), this.config.extensions && this.config.extensions.forEach((i) => this.addExtension(i)), this.setTheme(this.config.theme), this.view.setReadOnly(this.config.readOnly || !1), this.renderTextWithHighlight(this.textModel.getText()), this.registerBuiltInCommands();
341
+ }
342
+ // Public accessors for extensions
343
+ getTextModel() {
344
+ return this.textModel;
345
+ }
346
+ getView() {
347
+ return this.view;
348
+ }
349
+ getConfig() {
350
+ return { ...this.config };
351
+ }
352
+ // Register built-in editor commands like undo/redo/insertTab
353
+ registerBuiltInCommands() {
354
+ this.registerCommand("undo", () => this.undo()), this.registerCommand("redo", () => this.redo()), this.registerCommand("insertTab", () => this.insertTab()), this.registerCommand("save", () => {
355
+ this.emit("save");
356
+ });
357
+ }
358
+ // Get keymap extension if available
359
+ getKeymapExtension() {
360
+ return this.extensions.get("keymap");
361
+ }
362
+ // Setup DOM event handlers
363
+ setupEventHandlers() {
364
+ const e = this.view.getContentElement();
365
+ e.addEventListener("input", () => {
366
+ const t = this.view.getText(), i = this.textModel.getText();
367
+ if (t !== i) {
368
+ if (!this.suppressHistory) {
369
+ const s = this.getCursor().position, r = this.textModel.positionToOffset(s), o = this.getSelection();
370
+ let n, l;
371
+ o && (n = this.textModel.positionToOffset(o.start), l = this.textModel.positionToOffset(o.end)), this.undoStack.push({ text: i, cursorOffset: r, anchorOffset: n, focusOffset: l }), this.undoStack.length > 100 && this.undoStack.shift(), this.redoStack.length = 0;
372
+ }
373
+ this.textModel.setText(t), this.view.syncTrailingNewlineMarkerForText(t), this.highlightTimeout && clearTimeout(this.highlightTimeout), this.highlightTimeout = setTimeout(() => {
374
+ const s = this.view.getText();
375
+ s !== this.textModel.getText() && this.textModel.setText(s), this.renderTextWithHighlight(this.textModel.getText(), !1), this.highlightTimeout = null;
376
+ }, 300), this.updateLineNumbers(), this.emit("change", [{ range: this.getFullRange(), text: t, oldText: i }]);
377
+ }
378
+ }), e.addEventListener("selectionchange", () => {
379
+ const t = this.getCursor(), i = this.getSelection();
380
+ this.emit("cursor", t), i && this.emit("selection", i);
381
+ }), e.addEventListener("keydown", (t) => {
382
+ if (this.emit("keydown", t), t.key === "Tab") {
383
+ this.config.readOnly || this.insertTab(), t.preventDefault(), t.stopPropagation();
384
+ return;
385
+ }
386
+ if (t.key === "Enter") {
387
+ if (!this.config.readOnly) {
388
+ const i = window.getSelection();
389
+ if (i && i.rangeCount > 0) {
390
+ const s = this.getCursor().position, r = this.textModel.positionToOffset(s), o = this.getSelection();
391
+ let n, l;
392
+ o && (n = this.textModel.positionToOffset(o.start), l = this.textModel.positionToOffset(o.end));
393
+ const a = o && n !== void 0 && l !== void 0 ? Math.min(n, l) : r;
394
+ this.suppressHistory || (this.undoStack.push({ text: this.textModel.getText(), cursorOffset: r, anchorOffset: n, focusOffset: l }), this.undoStack.length > 100 && this.undoStack.shift(), this.redoStack.length = 0);
395
+ const c = i.getRangeAt(0);
396
+ c.deleteContents();
397
+ const g = document.createTextNode(`
398
+ `);
399
+ c.insertNode(g), c.setStartAfter(g), c.collapse(!0), i.removeAllRanges(), i.addRange(c), this.view.ensureCaretVisible();
400
+ const h = this.view.getText();
401
+ this.textModel.setText(h), this.view.syncTrailingNewlineMarkerForText(h);
402
+ const u = Math.min(
403
+ a + 1,
404
+ this.textModel.getText().length
405
+ );
406
+ try {
407
+ const d = this.textModel.offsetToPosition(u);
408
+ this.setCursor(d), this.view.ensureCaretVisible();
409
+ } catch {
410
+ }
411
+ this.highlightTimeout && clearTimeout(this.highlightTimeout), this.highlightTimeout = setTimeout(() => {
412
+ this.renderTextWithHighlight(this.textModel.getText(), !1), requestAnimationFrame(() => {
413
+ try {
414
+ const d = this.textModel.offsetToPosition(u);
415
+ this.setCursor(d), this.view.ensureCaretVisible();
416
+ } catch {
417
+ }
418
+ }), this.highlightTimeout = null;
419
+ }, 300), this.updateLineNumbers(), this.emit("change", [{ range: this.getFullRange(), text: this.getValue(), oldText: "" }]);
420
+ }
421
+ }
422
+ t.preventDefault(), t.stopPropagation();
423
+ return;
424
+ }
425
+ for (const i of this.extensions.values())
426
+ if (i.onKeyDown && i.onKeyDown(t) === !1) {
427
+ t.preventDefault(), t.stopPropagation();
428
+ return;
429
+ }
430
+ }), e.addEventListener("mousedown", (t) => {
431
+ this.emit("mousedown", t);
432
+ for (const i of this.extensions.values())
433
+ if (i.onMouseDown && i.onMouseDown(t) === !1) {
434
+ t.preventDefault(), t.stopPropagation();
435
+ return;
436
+ }
437
+ }), e.addEventListener("focus", () => {
438
+ this.emit("focus");
439
+ }), e.addEventListener("blur", () => {
440
+ this.emit("blur");
441
+ });
442
+ }
443
+ // Update line numbers display
444
+ updateLineNumbers() {
445
+ const e = this.textModel.getLineCount();
446
+ this.view.updateLineNumbers(e);
447
+ }
448
+ // Get full range of document
449
+ getFullRange() {
450
+ return {
451
+ start: { line: 0, column: 0 },
452
+ end: {
453
+ line: this.textModel.getLineCount() - 1,
454
+ column: this.textModel.getLine(this.textModel.getLineCount() - 1).length
455
+ }
456
+ };
457
+ }
458
+ // Emit events to listeners
459
+ emit(e, ...t) {
460
+ const i = this.eventListeners.get(e);
461
+ i && i.forEach((s) => s(...t));
462
+ }
463
+ // State management
464
+ getValue() {
465
+ return this.textModel.getText();
466
+ }
467
+ setValue(e) {
468
+ const t = this.textModel.getText();
469
+ this.textModel.setText(e), this.renderTextWithHighlight(e, !1), this.updateLineNumbers(), this.emit("change", [{ range: this.getFullRange(), text: e, oldText: t }]);
470
+ }
471
+ getState() {
472
+ return {
473
+ text: this.getValue(),
474
+ cursor: this.getCursor(),
475
+ selection: this.getSelection(),
476
+ readOnly: this.config.readOnly || !1,
477
+ theme: this.currentTheme
478
+ };
479
+ }
480
+ // Cursor & Selection
481
+ getCursor() {
482
+ const e = this.view.getCursorPosition();
483
+ return {
484
+ position: e,
485
+ anchor: e
486
+ // For now, cursor and anchor are the same
487
+ };
488
+ }
489
+ setCursor(e) {
490
+ this.view.setCursorPosition(e), this.emit("cursor", this.getCursor());
491
+ }
492
+ getSelection() {
493
+ return this.view.getSelectionRange();
494
+ }
495
+ setSelection(e) {
496
+ this.view.setSelectionRange(e), this.emit("selection", e);
497
+ }
498
+ // Configuration
499
+ setTheme(e) {
500
+ this.currentTheme = e;
501
+ const t = {
502
+ "editor-background": e === "dark" ? "#1e1e1e" : "#ffffff",
503
+ "editor-foreground": e === "dark" ? "#f8f9fa" : "#1a1a1a",
504
+ "editor-gutter-background": e === "dark" ? "#252526" : "#f8f9fa",
505
+ "editor-gutter-foreground": e === "dark" ? "#858585" : "#666666",
506
+ "editor-gutter-border": e === "dark" ? "#3e3e42" : "#e1e5e9"
507
+ };
508
+ this.view.applyTheme(t);
509
+ const i = this.extensions.get("syntax-highlighting");
510
+ if (i && typeof i.setTheme == "function")
511
+ try {
512
+ i.setTheme(e === "dark" ? "dark" : "light"), this.renderTextWithHighlight(this.textModel.getText());
513
+ } catch (s) {
514
+ console.warn("Error applying theme to syntax-highlighting extension", s);
515
+ }
516
+ }
517
+ setReadOnly(e) {
518
+ this.config.readOnly = e, this.view.setReadOnly(e);
519
+ }
520
+ // Extensions & Commands
521
+ addExtension(e) {
522
+ if (this.extensions.has(e.name))
523
+ throw new Error(`Extension '${e.name}' already exists`);
524
+ this.extensions.set(e.name, e), e.setup(this), e.name === "syntax-highlighting" && typeof e.highlightHTML == "function" && this.renderTextWithHighlight(this.textModel.getText());
525
+ }
526
+ removeExtension(e) {
527
+ const t = this.extensions.get(e);
528
+ t && t.destroy && t.destroy(), this.extensions.delete(e);
529
+ }
530
+ executeCommand(e, ...t) {
531
+ const i = this.commands.get(e);
532
+ i ? i(this, ...t) : console.warn(`Command '${e}' not found`);
533
+ }
534
+ // Register a command
535
+ registerCommand(e, t) {
536
+ this.commands.set(e, t);
537
+ }
538
+ // Search & Navigation
539
+ search(e, t = {}) {
540
+ const i = {
541
+ caseSensitive: !1,
542
+ regex: !1,
543
+ ...t
544
+ }, s = [], r = this.getValue();
545
+ r.split(`
546
+ `);
547
+ let o = i.caseSensitive ? r : r.toLowerCase(), n = i.caseSensitive ? e : e.toLowerCase();
548
+ if (i.regex) {
549
+ const l = new RegExp(n, i.caseSensitive ? "g" : "gi");
550
+ let a;
551
+ for (; (a = l.exec(o)) !== null; ) {
552
+ const c = this.textModel.offsetToPosition(a.index), g = this.textModel.offsetToPosition(a.index + a[0].length);
553
+ s.push({
554
+ range: { start: c, end: g },
555
+ match: a[0]
556
+ });
557
+ }
558
+ } else {
559
+ let l = 0, a = o.indexOf(n, l);
560
+ for (; a !== -1; ) {
561
+ const c = a + e.length, g = this.textModel.offsetToPosition(a), h = this.textModel.offsetToPosition(c);
562
+ s.push({
563
+ range: { start: g, end: h },
564
+ match: r.substring(a, c)
565
+ }), l = c, a = o.indexOf(n, l);
566
+ }
567
+ }
568
+ return s;
569
+ }
570
+ replace(e, t) {
571
+ const i = this.getValue();
572
+ if (!this.suppressHistory) {
573
+ const r = this.getCursor().position, o = this.textModel.positionToOffset(r), n = this.getSelection();
574
+ let l, a;
575
+ n && (l = this.textModel.positionToOffset(n.start), a = this.textModel.positionToOffset(n.end)), this.undoStack.push({ text: i, cursorOffset: o, anchorOffset: l, focusOffset: a }), this.undoStack.length > 100 && this.undoStack.shift(), this.redoStack.length = 0;
576
+ }
577
+ const s = this.textModel.replaceRange(e, t);
578
+ this.renderTextWithHighlight(this.getValue(), !1), this.emit("change", [s]);
579
+ }
580
+ replaceAll(e, t, i = {}) {
581
+ const s = this.search(e, i);
582
+ let r = 0;
583
+ for (let o = s.length - 1; o >= 0; o--)
584
+ this.replace(s[o].range, t), r++;
585
+ return r;
586
+ }
587
+ // Folding (basic implementation)
588
+ fold(e) {
589
+ const t = {
590
+ start: e.start,
591
+ end: e.end,
592
+ collapsed: !0,
593
+ level: 0
594
+ };
595
+ this.folds.push(t);
596
+ }
597
+ unfold(e) {
598
+ this.folds = this.folds.filter(
599
+ (t) => !(t.start.line === e.start.line && t.end.line === e.end.line)
600
+ );
601
+ }
602
+ getFolds() {
603
+ return [...this.folds];
604
+ }
605
+ // Utilities
606
+ focus() {
607
+ this.view.focus();
608
+ }
609
+ blur() {
610
+ this.view.blur();
611
+ }
612
+ // Render text using syntax highlighting extension if available
613
+ // If `restoreSelection` is true (default), the method captures current selection/caret
614
+ // and restores it after updating the DOM. Callers that will explicitly set the caret
615
+ // should pass `false` to avoid stomping programmatic cursor changes.
616
+ renderTextWithHighlight(e, t = !0) {
617
+ const i = this.extensions.get("syntax-highlighting");
618
+ if (i && typeof i.highlightHTML == "function")
619
+ try {
620
+ const s = !t && !this.expectingProgrammaticCursor;
621
+ let r, o, n, l;
622
+ if (t || s) {
623
+ r = this.getSelection();
624
+ const h = this.getCollapsedSelectionOffsetInEditor();
625
+ if (h !== void 0)
626
+ o = h;
627
+ else {
628
+ const u = this.getCursor().position;
629
+ o = this.textModel.positionToOffset(u);
630
+ }
631
+ r && (n = this.textModel.positionToOffset(r.start), l = this.textModel.positionToOffset(r.end));
632
+ }
633
+ const a = (t || s) && !r && o !== void 0 && this.hasCollapsedSelectionInEditor(), c = a ? this.insertSentinelAtOffset(e, o) : e, g = i.highlightHTML(c);
634
+ typeof this.view.setHighlightHTML == "function" ? this.view.setHighlightHTML(g) : this.view.setHTML(g), this.view.syncTrailingNewlineMarkerForText(e), (t || s) && requestAnimationFrame(() => {
635
+ try {
636
+ if (a && this.restoreCursorFromSentinel()) {
637
+ this.view.ensureCaretVisible();
638
+ return;
639
+ }
640
+ if (r && (n !== void 0 || l !== void 0)) {
641
+ const h = n !== void 0 ? n : o, u = l !== void 0 ? l : o, d = Math.min(h, u), f = Math.max(h, u), m = this.textModel.offsetToPosition(d), y = this.textModel.offsetToPosition(f);
642
+ this.view.setSelectionRange({ start: m, end: y });
643
+ } else if (o !== void 0) {
644
+ const h = this.textModel.offsetToPosition(o);
645
+ this.view.setCursorPosition(h);
646
+ }
647
+ } catch {
648
+ }
649
+ });
650
+ return;
651
+ } catch (s) {
652
+ console.warn("Syntax highlighting failed, falling back to plain text", s);
653
+ }
654
+ this.view.setText(e);
655
+ }
656
+ hasCollapsedSelectionInEditor() {
657
+ const e = window.getSelection();
658
+ if (!e || e.rangeCount === 0 || !e.isCollapsed)
659
+ return !1;
660
+ const t = e.getRangeAt(0);
661
+ return this.view.getContentElement().contains(t.commonAncestorContainer);
662
+ }
663
+ getCollapsedSelectionOffsetInEditor() {
664
+ const e = window.getSelection();
665
+ if (!e || e.rangeCount === 0 || !e.isCollapsed)
666
+ return;
667
+ const t = e.getRangeAt(0), i = this.view.getContentElement();
668
+ if (!i.contains(t.commonAncestorContainer))
669
+ return;
670
+ const s = t.cloneRange();
671
+ return s.selectNodeContents(i), s.setEnd(t.endContainer, t.endOffset), this.stripVirtualMarkers(s.toString()).length;
672
+ }
673
+ stripVirtualMarkers(e) {
674
+ return e.replace(/\u200B/g, "").split(M.CURSOR_SENTINEL).join("");
675
+ }
676
+ insertSentinelAtOffset(e, t) {
677
+ const i = Math.max(0, Math.min(t, e.length));
678
+ return e.slice(0, i) + M.CURSOR_SENTINEL + e.slice(i);
679
+ }
680
+ restoreCursorFromSentinel() {
681
+ const e = this.view.getContentElement(), t = window.getSelection(), i = document.createTreeWalker(e, NodeFilter.SHOW_TEXT);
682
+ let s = i.nextNode(), r = null, o = 0;
683
+ for (; s; ) {
684
+ const n = s.textContent ?? "", l = n.indexOf(M.CURSOR_SENTINEL);
685
+ l !== -1 && (r || (r = s, o = l), s.textContent = n.split(M.CURSOR_SENTINEL).join("")), s = i.nextNode();
686
+ }
687
+ if (!r || !t) return !1;
688
+ try {
689
+ const n = document.createRange();
690
+ return n.setStart(r, o), n.collapse(!0), t.removeAllRanges(), t.addRange(n), !0;
691
+ } catch {
692
+ return !1;
693
+ }
694
+ }
695
+ destroy() {
696
+ if (!this.isDestroyed) {
697
+ this.isDestroyed = !0;
698
+ for (const e of this.extensions.values())
699
+ e.destroy && e.destroy();
700
+ this.extensions.clear(), this.view.destroy(), this.commands.clear(), this.eventListeners.clear();
701
+ }
702
+ }
703
+ // History: undo/redo
704
+ undo() {
705
+ if (this.undoStack.length === 0) return;
706
+ const e = this.undoStack.pop(), t = { text: this.getValue(), cursorOffset: this.textModel.positionToOffset(this.getCursor().position) };
707
+ this.redoStack.push(t);
708
+ try {
709
+ this.suppressHistory = !0, this.expectingProgrammaticCursor = !0;
710
+ let i, s;
711
+ typeof e == "string" ? i = e : (i = e.text, s = e.cursorOffset), this.setValue(i), requestAnimationFrame(() => {
712
+ try {
713
+ if (s != null)
714
+ if (typeof e != "string" && (e.anchorOffset !== void 0 || e.focusOffset !== void 0)) {
715
+ const r = e.anchorOffset !== void 0 ? e.anchorOffset : s, o = e.focusOffset !== void 0 ? e.focusOffset : s, n = Math.min(r, o), l = Math.max(r, o), a = this.textModel.offsetToPosition(n), c = this.textModel.offsetToPosition(l);
716
+ this.setSelection({ start: a, end: c });
717
+ } else {
718
+ const r = this.textModel.offsetToPosition(s);
719
+ this.setCursor(r);
720
+ }
721
+ } catch {
722
+ }
723
+ }), setTimeout(() => {
724
+ this.expectingProgrammaticCursor = !1;
725
+ }, 30);
726
+ } finally {
727
+ this.suppressHistory = !1;
728
+ }
729
+ }
730
+ redo() {
731
+ if (this.redoStack.length === 0) return;
732
+ const e = this.redoStack.pop(), t = { text: this.getValue(), cursorOffset: this.textModel.positionToOffset(this.getCursor().position) };
733
+ this.undoStack.push(t);
734
+ try {
735
+ this.suppressHistory = !0, this.expectingProgrammaticCursor = !0;
736
+ let i, s;
737
+ typeof e == "string" ? i = e : (i = e.text, s = e.cursorOffset), this.setValue(i), requestAnimationFrame(() => {
738
+ try {
739
+ if (s != null)
740
+ if (typeof e != "string" && (e.anchorOffset !== void 0 || e.focusOffset !== void 0)) {
741
+ const r = e.anchorOffset !== void 0 ? e.anchorOffset : s, o = e.focusOffset !== void 0 ? e.focusOffset : s, n = Math.min(r, o), l = Math.max(r, o), a = this.textModel.offsetToPosition(n), c = this.textModel.offsetToPosition(l);
742
+ this.setSelection({ start: a, end: c });
743
+ } else {
744
+ const r = this.textModel.offsetToPosition(s);
745
+ this.setCursor(r);
746
+ }
747
+ } catch {
748
+ }
749
+ }), setTimeout(() => {
750
+ this.expectingProgrammaticCursor = !1;
751
+ }, 30);
752
+ } finally {
753
+ this.suppressHistory = !1;
754
+ }
755
+ }
756
+ // Insert a tab character or spaces at current cursor
757
+ insertTab() {
758
+ if (this.config.readOnly) return;
759
+ const e = this.getCursor().position, t = this.textModel.positionToOffset(e), i = " ".repeat(this.config.tabSize || 2), s = this.textModel.insertText(e, i), r = this.textModel.offsetToPosition(this.textModel.positionToOffset(e) + i.length);
760
+ if (!this.suppressHistory) {
761
+ const o = this.getSelection();
762
+ let n, l;
763
+ o && (n = this.textModel.positionToOffset(o.start), l = this.textModel.positionToOffset(o.end)), this.undoStack.push({ text: this.getValue(), cursorOffset: t, anchorOffset: n, focusOffset: l }), this.redoStack.length = 0;
764
+ }
765
+ this.expectingProgrammaticCursor = !0, this.renderTextWithHighlight(this.getValue(), !1), this.setCursor(r), setTimeout(() => {
766
+ this.expectingProgrammaticCursor = !1;
767
+ }, 20), this.emit("change", [s]);
768
+ }
769
+ // Insert a newline at current cursor position
770
+ insertNewLine() {
771
+ if (this.config.readOnly) return;
772
+ const e = this.getCursor().position, t = this.textModel.positionToOffset(e), i = this.textModel.insertText(e, `
773
+ `), s = this.textModel.offsetToPosition(this.textModel.positionToOffset(e) + 1);
774
+ if (!this.suppressHistory) {
775
+ const r = this.getSelection();
776
+ let o, n;
777
+ r && (o = this.textModel.positionToOffset(r.start), n = this.textModel.positionToOffset(r.end)), this.undoStack.push({ text: this.getValue(), cursorOffset: t, anchorOffset: o, focusOffset: n }), this.redoStack.length = 0;
778
+ }
779
+ this.expectingProgrammaticCursor = !0, this.renderTextWithHighlight(this.getValue(), !1), this.setCursor(s), setTimeout(() => {
780
+ this.expectingProgrammaticCursor = !1;
781
+ }, 20), this.emit("change", [i]);
782
+ }
783
+ // Events
784
+ on(e, t) {
785
+ this.eventListeners.has(e) || this.eventListeners.set(e, []), this.eventListeners.get(e).push(t);
786
+ }
787
+ off(e, t) {
788
+ if (!this.eventListeners.has(e)) return;
789
+ const i = this.eventListeners.get(e);
790
+ if (t) {
791
+ const s = i.indexOf(t);
792
+ s !== -1 && i.splice(s, 1);
793
+ } else
794
+ i.length = 0;
795
+ }
796
+ };
797
+ $.CURSOR_SENTINEL = "";
798
+ let A = $;
799
+ class B {
800
+ constructor(e) {
801
+ this.name = "keymap", this.editor = null, this.keymap = {}, this.isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0, this.keymap = e || this.getDefaultKeymap();
802
+ }
803
+ setup(e) {
804
+ this.editor = e;
805
+ }
806
+ handleKeyDown(e) {
807
+ if (!this.editor) return;
808
+ const t = this.findMatchingBinding(e);
809
+ if (t)
810
+ return this.editor.executeCommand(t.command), e.preventDefault(), e.stopPropagation(), !1;
811
+ }
812
+ findMatchingBinding(e) {
813
+ const { key: t, ctrlKey: i, altKey: s, shiftKey: r, metaKey: o } = e, n = String(t).toLowerCase(), l = this.keymap[n];
814
+ if (!l) return null;
815
+ for (const a of l) {
816
+ const c = a.ctrlKey === void 0 || a.ctrlKey === i, g = a.altKey === void 0 || a.altKey === s, h = a.shiftKey === void 0 || a.shiftKey === r, u = a.metaKey === void 0 || a.metaKey === o;
817
+ if (c && g && h && u)
818
+ return a;
819
+ }
820
+ return null;
821
+ }
822
+ // Allow EditorCore to call this directly when checking extension.onKeyDown
823
+ onKeyDown(e) {
824
+ return this.handleKeyDown(e);
825
+ }
826
+ getDefaultKeymap() {
827
+ const e = {};
828
+ return this.addBinding(e, "f", { ctrlKey: !this.isMac, metaKey: this.isMac }, "find"), this.addBinding(e, "h", { ctrlKey: !this.isMac, metaKey: this.isMac }, "replace"), this.addBinding(e, "f3", {}, "findNext"), this.addBinding(e, "f3", { shiftKey: !0 }, "findPrev"), this.addBinding(e, "g", { ctrlKey: !this.isMac, metaKey: this.isMac }, "findNext"), this.addBinding(e, "[", { ctrlKey: !this.isMac, metaKey: this.isMac, shiftKey: !0 }, "fold"), this.addBinding(e, "]", { ctrlKey: !this.isMac, metaKey: this.isMac, shiftKey: !0 }, "unfold"), this.addBinding(e, "s", { ctrlKey: !0 }, "save"), this.addBinding(e, "s", { metaKey: !0 }, "save"), this.addBinding(e, "z", { ctrlKey: !0 }, "undo"), this.addBinding(e, "z", { metaKey: !0 }, "undo"), this.addBinding(e, "y", { ctrlKey: !0 }, "redo"), this.addBinding(e, "y", { metaKey: !0 }, "redo"), this.addBinding(e, "z", { ctrlKey: !0, shiftKey: !0 }, "redo"), this.addBinding(e, "z", { metaKey: !0, shiftKey: !0 }, "redo"), this.addBinding(e, "tab", {}, "insertTab"), this.addBinding(e, "t", { ctrlKey: !this.isMac, metaKey: this.isMac, shiftKey: !0 }, "toggleTheme"), e;
829
+ }
830
+ addBinding(e, t, i, s) {
831
+ const r = t.toLowerCase();
832
+ e[r] || (e[r] = []), e[r].push({
833
+ key: r,
834
+ command: s,
835
+ ...i
836
+ });
837
+ }
838
+ // Public API for customizing keymap
839
+ setKeymap(e) {
840
+ this.keymap = { ...e };
841
+ }
842
+ addKeyBinding(e) {
843
+ const t = e.key.toLowerCase();
844
+ this.keymap[t] || (this.keymap[t] = []), this.keymap[t] = this.keymap[t].filter((i) => i.command !== e.command), this.keymap[t].push({
845
+ ...e,
846
+ key: t
847
+ });
848
+ }
849
+ removeKeyBinding(e, t) {
850
+ const i = e.toLowerCase();
851
+ t ? this.keymap[i] && (this.keymap[i] = this.keymap[i].filter((s) => s.command !== t), this.keymap[i].length === 0 && delete this.keymap[i]) : delete this.keymap[i];
852
+ }
853
+ getKeymap() {
854
+ return { ...this.keymap };
855
+ }
856
+ getBindingsForCommand(e) {
857
+ const t = [];
858
+ for (const i in this.keymap)
859
+ for (const s of this.keymap[i])
860
+ s.command === e && t.push({ ...s });
861
+ return t;
862
+ }
863
+ getPlatformInfo() {
864
+ return {
865
+ isMac: this.isMac,
866
+ platform: navigator.platform
867
+ };
868
+ }
869
+ destroy() {
870
+ this.keymap = {}, this.editor = null;
871
+ }
872
+ }
873
+ class V {
874
+ constructor() {
875
+ this.name = "transaction", this.transactions = [];
876
+ }
877
+ setup(e) {
878
+ e.on("change", (t) => {
879
+ const i = {
880
+ changes: t,
881
+ selection: e.getSelection(),
882
+ effects: [],
883
+ annotations: []
884
+ };
885
+ this.transactions.push(i);
886
+ });
887
+ }
888
+ getTransactions() {
889
+ return this.transactions;
890
+ }
891
+ destroy() {
892
+ this.transactions = [];
893
+ }
894
+ }
895
+ class K {
896
+ constructor() {
897
+ this.name = "line-numbers", this.editor = null, this.lineNumbersElement = null, this.isEnabled = !0;
898
+ }
899
+ setup(e) {
900
+ this.editor = e, this.createLineNumbers(), e.registerCommand("toggleLineNumbers", () => {
901
+ this.toggle();
902
+ }), e.on("change", () => {
903
+ this.updateLineNumbers();
904
+ }), this.updateLineNumbers();
905
+ }
906
+ createLineNumbers() {
907
+ if (!this.editor) return;
908
+ const e = this.editor.getView().getLineNumbersElement();
909
+ e && (this.lineNumbersElement = e);
910
+ }
911
+ updateLineNumbers() {
912
+ if (!this.lineNumbersElement || !this.editor || !this.isEnabled) return;
913
+ const e = this.editor.getValue().split(`
914
+ `).length, t = Array.from({ length: Math.max(e, 20) }, (i, s) => s + 1);
915
+ this.lineNumbersElement.innerHTML = t.map((i) => `<div style="height: 21px; line-height: 21px; padding-right: 12px;">${i}</div>`).join("");
916
+ }
917
+ toggle() {
918
+ if (!this.editor) return;
919
+ this.isEnabled = !this.isEnabled, this.lineNumbersElement && (this.lineNumbersElement.style.display = this.isEnabled ? "block" : "none");
920
+ const e = this.editor.getView().getContentElement();
921
+ e && (e.style.marginLeft = this.isEnabled ? "60px" : "0"), this.updateLineNumbers();
922
+ }
923
+ destroy() {
924
+ this.lineNumbersElement = null, this.editor = null;
925
+ }
926
+ }
927
+ class U {
928
+ constructor() {
929
+ this.name = "theme", this.editor = null, this.currentTheme = "dark";
930
+ }
931
+ setup(e) {
932
+ this.editor = e, e.registerCommand("setTheme", (t) => {
933
+ this.setTheme(t);
934
+ }), e.registerCommand("toggleTheme", () => {
935
+ this.toggleTheme();
936
+ }), this.setTheme(this.currentTheme);
937
+ }
938
+ setTheme(e) {
939
+ this.editor && (this.currentTheme = e, this.editor.setTheme(e));
940
+ }
941
+ toggleTheme() {
942
+ const e = this.currentTheme === "dark" ? "light" : "dark";
943
+ this.setTheme(e);
944
+ }
945
+ getCurrentTheme() {
946
+ return this.currentTheme;
947
+ }
948
+ destroy() {
949
+ this.editor = null;
950
+ }
951
+ }
952
+ class z {
953
+ constructor() {
954
+ this.name = "read-only", this.editor = null, this.isReadOnly = !1;
955
+ }
956
+ setup(e) {
957
+ this.editor = e, e.registerCommand("setReadOnly", (t) => {
958
+ this.setReadOnly(t);
959
+ }), e.registerCommand("toggleReadOnly", () => {
960
+ this.toggleReadOnly();
961
+ }), e.on("keydown", (t) => {
962
+ if (t.ctrlKey && t.key === "r")
963
+ return t.preventDefault(), this.toggleReadOnly(), !1;
964
+ });
965
+ }
966
+ setReadOnly(e) {
967
+ this.editor && (this.isReadOnly = e, this.editor.setReadOnly(e));
968
+ }
969
+ toggleReadOnly() {
970
+ this.setReadOnly(!this.isReadOnly);
971
+ }
972
+ isCurrentlyReadOnly() {
973
+ return this.isReadOnly;
974
+ }
975
+ destroy() {
976
+ this.editor = null;
977
+ }
978
+ }
979
+ class q {
980
+ constructor() {
981
+ this.name = "search", this.editor = null, this.searchUI = null, this.isVisible = !1, this.currentResults = [], this.currentIndex = -1;
982
+ }
983
+ setup(e) {
984
+ this.editor = e, e.registerCommand("find", () => {
985
+ this.showSearch();
986
+ }), e.registerCommand("findNext", () => {
987
+ this.findNext();
988
+ }), e.registerCommand("findPrev", () => {
989
+ this.findPrev();
990
+ }), e.registerCommand("replace", () => {
991
+ this.showReplace();
992
+ }), e.registerCommand("replaceAll", (t, i) => {
993
+ this.replaceAll(t, i);
994
+ });
995
+ }
996
+ showSearch() {
997
+ if (this.editor && (this.searchUI || this.createSearchUI(), this.isVisible = !0, this.searchUI)) {
998
+ this.searchUI.style.display = "block";
999
+ const e = this.searchUI.querySelector("input");
1000
+ e && (e.focus(), e.select());
1001
+ }
1002
+ }
1003
+ showReplace() {
1004
+ this.showSearch();
1005
+ const e = this.searchUI?.querySelector(".search-replace-input");
1006
+ e && (e.style.display = "block", e.focus());
1007
+ const t = this.searchUI?.querySelector(".search-status");
1008
+ t && (t.textContent = "Replace mode - Enter to replace, Shift+Enter to replace all");
1009
+ }
1010
+ hideSearch() {
1011
+ this.isVisible = !1, this.searchUI && (this.searchUI.style.display = "none"), this.clearHighlights();
1012
+ }
1013
+ createSearchUI() {
1014
+ if (!this.editor) return;
1015
+ const e = document.querySelector(".rte-source-editor-modal");
1016
+ if (!e) return;
1017
+ this.searchUI = document.createElement("div"), this.searchUI.style.cssText = `
1018
+ position: absolute;
1019
+ top: 10px;
1020
+ right: 10px;
1021
+ background: var(--editor-background, #1e1e1e);
1022
+ border: 1px solid var(--editor-gutter-border, #3e3e42);
1023
+ border-radius: 4px;
1024
+ padding: 8px;
1025
+ z-index: 1000;
1026
+ display: none;
1027
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
1028
+ min-width: 250px;
1029
+ `, this.searchUI.innerHTML = `
1030
+ <div style="display: flex; align-items: center; gap: 4px; margin-bottom: 4px;">
1031
+ <input type="text" placeholder="Find..." style="
1032
+ flex: 1;
1033
+ padding: 4px 8px;
1034
+ background: var(--editor-gutter-background, #252526);
1035
+ color: var(--editor-foreground, #f8f9fa);
1036
+ border: 1px solid var(--editor-gutter-border, #3e3e42);
1037
+ border-radius: 3px;
1038
+ font-size: 12px;
1039
+ outline: none;
1040
+ " />
1041
+ <button class="search-prev" style="
1042
+ padding: 2px 6px;
1043
+ background: var(--editor-gutter-background, #252526);
1044
+ color: var(--editor-gutter-foreground, #858585);
1045
+ border: 1px solid var(--editor-gutter-border, #3e3e42);
1046
+ border-radius: 3px;
1047
+ cursor: pointer;
1048
+ font-size: 11px;
1049
+ ">↑</button>
1050
+ <button class="search-next" style="
1051
+ padding: 2px 6px;
1052
+ background: var(--editor-gutter-background, #252526);
1053
+ color: var(--editor-gutter-foreground, #858585);
1054
+ border: 1px solid var(--editor-gutter-border, #3e3e42);
1055
+ border-radius: 3px;
1056
+ cursor: pointer;
1057
+ font-size: 11px;
1058
+ ">↓</button>
1059
+ <button class="search-close" style="
1060
+ padding: 2px 6px;
1061
+ background: var(--editor-gutter-background, #252526);
1062
+ color: var(--editor-gutter-foreground, #858585);
1063
+ border: 1px solid var(--editor-gutter-border, #3e3e42);
1064
+ border-radius: 3px;
1065
+ cursor: pointer;
1066
+ font-size: 11px;
1067
+ ">×</button>
1068
+ </div>
1069
+ <div class="search-status" style="
1070
+ font-size: 11px;
1071
+ color: var(--editor-gutter-foreground, #858585);
1072
+ text-align: center;
1073
+ "></div>
1074
+ <input type="text" class="search-replace-input" placeholder="Replace with..." style="
1075
+ width: 100%;
1076
+ padding: 4px 8px;
1077
+ background: var(--editor-gutter-background, #252526);
1078
+ color: var(--editor-foreground, #f8f9fa);
1079
+ border: 1px solid var(--editor-gutter-border, #3e3e42);
1080
+ border-radius: 3px;
1081
+ font-size: 12px;
1082
+ outline: none;
1083
+ display: none;
1084
+ margin-top: 4px;
1085
+ " />
1086
+ `;
1087
+ const t = this.searchUI.querySelector("input"), i = this.searchUI.querySelector(".search-replace-input"), s = this.searchUI.querySelector(".search-prev"), r = this.searchUI.querySelector(".search-next"), o = this.searchUI.querySelector(".search-close");
1088
+ t.addEventListener("input", () => {
1089
+ this.performSearch(t.value);
1090
+ }), t.addEventListener("keydown", (n) => {
1091
+ n.key === "Enter" && (n.preventDefault(), n.shiftKey ? this.findPrev() : this.findNext());
1092
+ }), i.addEventListener("keydown", (n) => {
1093
+ n.key === "Enter" && (n.preventDefault(), n.shiftKey ? this.replaceAll(t.value, i.value) : this.replaceCurrent(t.value, i.value));
1094
+ }), s.addEventListener("click", () => this.findPrev()), r.addEventListener("click", () => this.findNext()), o.addEventListener("click", () => this.hideSearch()), e.appendChild(this.searchUI);
1095
+ }
1096
+ performSearch(e) {
1097
+ if (!this.editor || !e.trim()) {
1098
+ this.clearHighlights(), this.updateStatus("");
1099
+ return;
1100
+ }
1101
+ const t = this.editor.getValue(), i = [];
1102
+ let s = t.toLowerCase().indexOf(e.toLowerCase());
1103
+ for (; s !== -1; ) {
1104
+ const r = this.getPositionFromOffset(t, s), o = this.getPositionFromOffset(t, s + e.length);
1105
+ i.push({
1106
+ range: { start: r, end: o },
1107
+ match: t.substring(s, s + e.length)
1108
+ }), s = t.toLowerCase().indexOf(e.toLowerCase(), s + 1);
1109
+ }
1110
+ this.currentResults = i, this.currentIndex = this.currentResults.length > 0 ? 0 : -1, this.updateHighlights(), this.updateStatus(`${this.currentResults.length} matches`);
1111
+ }
1112
+ getPositionFromOffset(e, t) {
1113
+ const i = e.substring(0, t).split(`
1114
+ `), s = i.length - 1, r = i[i.length - 1].length;
1115
+ return { line: s, column: r };
1116
+ }
1117
+ findNext() {
1118
+ this.currentResults.length !== 0 && (this.currentIndex = (this.currentIndex + 1) % this.currentResults.length, this.updateHighlights());
1119
+ }
1120
+ findPrev() {
1121
+ this.currentResults.length !== 0 && (this.currentIndex = this.currentIndex <= 0 ? this.currentResults.length - 1 : this.currentIndex - 1, this.updateHighlights());
1122
+ }
1123
+ replaceCurrent(e, t) {
1124
+ if (!this.editor || !e.trim() || this.currentIndex === -1) return;
1125
+ const i = this.currentResults[this.currentIndex];
1126
+ if (!i) return;
1127
+ const s = this.editor.getValue(), r = this.getOffsetFromPosition(s, i.range.start), o = s.substring(0, r), n = s.substring(r + e.length), l = o + t + n;
1128
+ this.editor.setValue(l), this.performSearch(e), this.updateStatus("Replaced current occurrence");
1129
+ }
1130
+ replaceAll(e, t) {
1131
+ if (!this.editor || !e.trim()) return;
1132
+ let i = this.editor.getValue(), s = 0, r = i.toLowerCase().indexOf(e.toLowerCase());
1133
+ for (; r !== -1; )
1134
+ i = i.substring(0, r) + t + i.substring(r + e.length), s++, r = i.toLowerCase().indexOf(e.toLowerCase(), r + t.length);
1135
+ s > 0 && (this.editor.setValue(i), this.updateStatus(`Replaced ${s} occurrences`));
1136
+ }
1137
+ getOffsetFromPosition(e, t) {
1138
+ const i = e.split(`
1139
+ `);
1140
+ let s = 0;
1141
+ for (let r = 0; r < t.line; r++)
1142
+ s += i[r].length + 1;
1143
+ return s += t.column, s;
1144
+ }
1145
+ updateHighlights() {
1146
+ this.clearHighlights(), !(this.currentResults.length === 0 || this.currentIndex === -1) && (this.currentResults[this.currentIndex], this.updateStatus(`${this.currentResults.length} matches (showing ${this.currentIndex + 1}/${this.currentResults.length})`));
1147
+ }
1148
+ clearHighlights() {
1149
+ }
1150
+ updateStatus(e) {
1151
+ const t = this.searchUI?.querySelector(".search-status");
1152
+ t && (t.textContent = e);
1153
+ }
1154
+ destroy() {
1155
+ this.searchUI && this.searchUI.parentNode && this.searchUI.parentNode.removeChild(this.searchUI), this.searchUI = null, this.editor = null;
1156
+ }
1157
+ }
1158
+ class F {
1159
+ constructor() {
1160
+ this.name = "bracket-matching", this.editor = null, this.bracketPairs = {
1161
+ "(": ")",
1162
+ "[": "]",
1163
+ "{": "}",
1164
+ "<": ">"
1165
+ }, this.reverseBracketPairs = {
1166
+ ")": "(",
1167
+ "]": "[",
1168
+ "}": "{",
1169
+ ">": "<"
1170
+ }, this.currentMatch = null;
1171
+ }
1172
+ setup(e) {
1173
+ this.editor = e, e.on("cursor", () => {
1174
+ this.updateBracketMatching();
1175
+ }), e.on("change", () => {
1176
+ this.updateBracketMatching();
1177
+ });
1178
+ }
1179
+ updateBracketMatching() {
1180
+ if (!this.editor) return;
1181
+ const e = this.editor.getCursor(), t = this.editor.getValue();
1182
+ this.clearBracketHighlighting();
1183
+ const i = this.getBracketAtPosition(t, e.position);
1184
+ if (!i) return;
1185
+ const s = this.findMatchingBracket(t, i);
1186
+ s && (this.currentMatch = s, this.highlightBrackets(s));
1187
+ }
1188
+ getBracketAtPosition(e, t) {
1189
+ const i = e.split(`
1190
+ `);
1191
+ if (t.line >= i.length) return null;
1192
+ const s = i[t.line];
1193
+ if (t.column >= s.length) return null;
1194
+ const r = s[t.column];
1195
+ return this.bracketPairs[r] || this.reverseBracketPairs[r] ? { char: r, position: t } : null;
1196
+ }
1197
+ findMatchingBracket(e, t) {
1198
+ const i = e.split(`
1199
+ `), s = t.position.line, r = t.position.column, o = t.char;
1200
+ return this.bracketPairs[o] ? this.findClosingBracket(e, i, s, r, o) : this.reverseBracketPairs[o] ? this.findOpeningBracket(e, i, s, r, o) : null;
1201
+ }
1202
+ findClosingBracket(e, t, i, s, r) {
1203
+ const o = this.bracketPairs[r];
1204
+ let n = 0;
1205
+ for (let l = i; l < t.length; l++) {
1206
+ const a = t[l], c = l === i ? s : 0;
1207
+ for (let g = c; g < a.length; g++) {
1208
+ const h = a[g];
1209
+ if (h === r)
1210
+ n++;
1211
+ else if (h === o && (n--, n === 0))
1212
+ return {
1213
+ open: { start: { line: i, column: s }, end: { line: i, column: s + 1 } },
1214
+ close: { start: { line: l, column: g }, end: { line: l, column: g + 1 } },
1215
+ type: r
1216
+ };
1217
+ }
1218
+ }
1219
+ return null;
1220
+ }
1221
+ findOpeningBracket(e, t, i, s, r) {
1222
+ const o = this.reverseBracketPairs[r];
1223
+ let n = 0;
1224
+ for (let l = i; l >= 0; l--) {
1225
+ const a = t[l], c = l === i ? s : a.length - 1;
1226
+ for (let g = c; g >= 0; g--) {
1227
+ const h = a[g];
1228
+ if (h === r)
1229
+ n++;
1230
+ else if (h === o && (n--, n === 0))
1231
+ return {
1232
+ open: { start: { line: l, column: g }, end: { line: l, column: g + 1 } },
1233
+ close: { start: { line: i, column: s }, end: { line: i, column: s + 1 } },
1234
+ type: o
1235
+ };
1236
+ }
1237
+ }
1238
+ return null;
1239
+ }
1240
+ highlightBrackets(e) {
1241
+ }
1242
+ clearBracketHighlighting() {
1243
+ this.currentMatch = null;
1244
+ }
1245
+ getCurrentMatch() {
1246
+ return this.currentMatch;
1247
+ }
1248
+ destroy() {
1249
+ this.clearBracketHighlighting(), this.editor = null;
1250
+ }
1251
+ }
1252
+ class _ {
1253
+ constructor() {
1254
+ this.name = "code-folding", this.editor = null, this.foldIndicators = [], this.foldingUI = null;
1255
+ }
1256
+ setup(e) {
1257
+ this.editor = e, e.registerCommand("fold", () => {
1258
+ this.foldAtCursor();
1259
+ }), e.registerCommand("unfold", () => {
1260
+ this.unfoldAtCursor();
1261
+ }), e.registerCommand("foldAll", () => {
1262
+ this.foldAll();
1263
+ }), e.registerCommand("unfoldAll", () => {
1264
+ this.unfoldAll();
1265
+ }), e.on("change", () => {
1266
+ this.updateFoldIndicators();
1267
+ }), this.createFoldingUI(), this.updateFoldIndicators();
1268
+ }
1269
+ createFoldingUI() {
1270
+ if (!this.editor) return;
1271
+ const e = document.querySelector(".rte-source-editor-modal");
1272
+ e && (this.foldingUI = document.createElement("div"), this.foldingUI.style.cssText = `
1273
+ position: absolute;
1274
+ left: 40px;
1275
+ top: 0;
1276
+ bottom: 0;
1277
+ width: 20px;
1278
+ pointer-events: none;
1279
+ z-index: 2;
1280
+ `, e.appendChild(this.foldingUI));
1281
+ }
1282
+ updateFoldIndicators() {
1283
+ if (!this.editor || !this.foldingUI) return;
1284
+ this.foldingUI.innerHTML = "", this.foldIndicators = [];
1285
+ const e = this.editor.getValue().split(`
1286
+ `);
1287
+ this.findFoldableLines(e).forEach((t) => {
1288
+ this.createFoldIndicator(t);
1289
+ });
1290
+ }
1291
+ findFoldableLines(e) {
1292
+ const t = [];
1293
+ for (let i = 0; i < e.length; i++) {
1294
+ const s = e[i].trim();
1295
+ (s.startsWith("{") || s.startsWith("function") || s.startsWith("class") || s.startsWith("if") || s.includes("=>") || s.startsWith("for") || s.startsWith("while") || s.startsWith("try")) && t.push(i);
1296
+ }
1297
+ return t;
1298
+ }
1299
+ createFoldIndicator(e) {
1300
+ if (!this.foldingUI) return;
1301
+ const t = document.createElement("div");
1302
+ t.style.cssText = `
1303
+ position: absolute;
1304
+ left: 0;
1305
+ top: ${e * 21}px;
1306
+ width: 20px;
1307
+ height: 21px;
1308
+ display: flex;
1309
+ align-items: center;
1310
+ justify-content: center;
1311
+ cursor: pointer;
1312
+ pointer-events: auto;
1313
+ color: var(--editor-gutter-foreground, #858585);
1314
+ font-size: 10px;
1315
+ user-select: none;
1316
+ `, t.innerHTML = "▶", t.title = "Code folding not yet implemented - click shows fold indicators", t.addEventListener("click", () => {
1317
+ }), this.foldingUI.appendChild(t), this.foldIndicators.push(t);
1318
+ }
1319
+ foldAtCursor() {
1320
+ }
1321
+ unfoldAtCursor() {
1322
+ }
1323
+ foldAll() {
1324
+ }
1325
+ unfoldAll() {
1326
+ }
1327
+ destroy() {
1328
+ this.foldingUI && this.foldingUI.parentNode && this.foldingUI.parentNode.removeChild(this.foldingUI), this.foldingUI = null, this.foldIndicators = [], this.editor = null;
1329
+ }
1330
+ }
1331
+ class W {
1332
+ constructor() {
1333
+ this.name = "syntax-highlighting", this.editor = null, this.currentTheme = "dark", this.currentLanguage = null, this.modes = /* @__PURE__ */ new Map();
1334
+ }
1335
+ setup(e) {
1336
+ this.editor = e, this.registerMode("html", { name: "html", highlight: (t, i) => this._highlightHTML(t, i) }), this.registerMode("javascript", { name: "javascript", highlight: (t, i) => this._highlightJS(t, i) }), this.registerMode("typescript", { name: "typescript", highlight: (t, i) => this._highlightJS(t, i) }), this.registerMode("php", { name: "php", highlight: (t, i) => this._highlightPHP(t, i) });
1337
+ }
1338
+ // Extension provides methods that can be called by the editor
1339
+ setTheme(e) {
1340
+ this.currentTheme = e;
1341
+ }
1342
+ setLanguage(e) {
1343
+ this.currentLanguage = e;
1344
+ }
1345
+ registerMode(e, t) {
1346
+ this.modes.set(e.toLowerCase(), t);
1347
+ }
1348
+ // Method to get syntax highlighting colors for a given theme
1349
+ getSyntaxColors() {
1350
+ return this.currentTheme === "dark" ? {
1351
+ tag: "#569cd6",
1352
+ // Blue
1353
+ comment: "#6a9955",
1354
+ // Green
1355
+ attrName: "#9cdcfe",
1356
+ // Light blue for attribute names
1357
+ attrValue: "#ce9178",
1358
+ // Orange for attribute values
1359
+ styleProp: "#c586c0",
1360
+ // Purple for CSS property names
1361
+ styleVal: "#dcdcaa",
1362
+ // Yellow-ish for CSS values
1363
+ doctype: "#808080",
1364
+ // Gray for doctype
1365
+ text: "#d4d4d4",
1366
+ // Light gray for normal text
1367
+ keyword: "#c586c0",
1368
+ // JS/PHP keywords (purple)
1369
+ string: "#ce9178",
1370
+ // JS strings
1371
+ number: "#b5cea8",
1372
+ // numbers
1373
+ variable: "#9cdcfe"
1374
+ // php variable color
1375
+ } : {
1376
+ tag: "#0000ff",
1377
+ // Blue
1378
+ comment: "#008000",
1379
+ // Green
1380
+ attrName: "#001080",
1381
+ attrValue: "#a31515",
1382
+ // Red
1383
+ styleProp: "#6a00a8",
1384
+ styleVal: "#804000",
1385
+ doctype: "#444444",
1386
+ text: "#000000",
1387
+ // Black
1388
+ keyword: "#000080",
1389
+ string: "#a31515",
1390
+ number: "#0086b3",
1391
+ variable: "#001080"
1392
+ };
1393
+ }
1394
+ // Public API: highlight a source string using the chosen mode (or detect html)
1395
+ highlight(e, t) {
1396
+ const i = this.getSyntaxColors(), s = (t || this.currentLanguage || "html").toLowerCase();
1397
+ return (this.modes.get(s) || this.modes.get("html")).highlight(e, i);
1398
+ }
1399
+ // Backwards-compatible method
1400
+ highlightHTML(e) {
1401
+ return this.highlight(e, "html");
1402
+ }
1403
+ // --- Internal mode implementations ---
1404
+ escapeHTML(e) {
1405
+ return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\"/g, "&quot;").replace(/'/g, "&#39;");
1406
+ }
1407
+ // Robustly unescape common HTML entities, repeating a few times to handle nested encoding like &amp;amp;...
1408
+ unescapeEntitiesRepeated(e) {
1409
+ let t = e || "";
1410
+ for (let i = 0; i < 5; i++) {
1411
+ const s = t;
1412
+ if (t = t.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'"), t === s) break;
1413
+ }
1414
+ return t;
1415
+ }
1416
+ _highlightHTML(e, t) {
1417
+ const i = t, s = (a) => this.escapeHTML(a);
1418
+ let r = s(e);
1419
+ const o = (a) => {
1420
+ let c = a.replace(/&quot;/g, '"').replace(/&#39;/g, "'");
1421
+ return c = c.replace(/(\/\*[\s\S]*?\*\/)/g, `<span style="color: ${i.comment};">$1</span>`), c = c.replace(/([a-zA-Z-]+)(\s*:\s*)([^;{]+)(;?)/g, (g, h, u, d, f) => {
1422
+ const m = String(d).trim(), y = s(m);
1423
+ return `<span style="color: ${i.styleProp};">${h}</span>${u}<span style="color: ${i.styleVal};">${y}</span>${f}`;
1424
+ }), c;
1425
+ }, n = [];
1426
+ try {
1427
+ e.replace(/<script\b([^>]*)>([\s\S]*?)<\/script>/gi, (a, c, g) => (n.push({ attrs: String(c || ""), inner: String(g || "") }), a));
1428
+ } catch {
1429
+ }
1430
+ let l = 0;
1431
+ return r = r.replace(/(&lt;script\b([^&>]*)&gt;)([\s\S]*?)(&lt;\/script&gt;)/gi, (a, c, g, h, u) => {
1432
+ const d = n[l++]?.inner ?? this.unescapeEntitiesRepeated(h || "");
1433
+ (n[l - 1]?.attrs || g || "").toLowerCase();
1434
+ const f = this._highlightJS(d, i);
1435
+ return `${c}${f}${u}`;
1436
+ }), r = r.replace(/(&lt;style\b[^&]*&gt;)([\s\S]*?)(&lt;\/style&gt;)/gi, (a, c, g, h) => {
1437
+ const u = o(g);
1438
+ return `${c}${u}${h}`;
1439
+ }), r = r.replace(/(&lt;!--[\s\S]*?--&gt;)/g, `<span style="color: ${i.comment};">$1</span>`), r = r.replace(/(&lt;!DOCTYPE[\s\S]*?&gt;)/i, `<span style="color: ${i.doctype};">$1</span>`), r = r.replace(/(&lt;\/?\s*)([^\s&>\/]+)([\s\S]*?)(\/?&gt;)/g, (a, c, g, h, u) => {
1440
+ const d = `<span style="color: ${i.tag};">${g}</span>`;
1441
+ let f = h;
1442
+ return f = f.replace(
1443
+ /([\w:-]+)(\s*=\s*)((&quot;[\s\S]*?&quot;|&#39;[\s\S]*?&#39;|[^\s&>]+))/g,
1444
+ (m, y, w, x) => {
1445
+ const E = String(y).toLowerCase(), L = `<span style="color: ${i.attrName};">${y}</span>`;
1446
+ let C = x, b = "";
1447
+ x.startsWith("&quot;") && x.endsWith("&quot;") ? (C = x.slice(6, -6), b = "&quot;") : x.startsWith("&#39;") && x.endsWith("&#39;") && (C = x.slice(5, -5), b = "&#39;");
1448
+ let k = x;
1449
+ if (E === "style") {
1450
+ const S = C.replace(/([\w-]+)\s*:\s*([^;]+)(;?)/g, (O, p, T, N) => `<span style="color: ${i.styleProp};">${p}</span>:<span style="color: ${i.styleVal};">${T.trim()}</span>${N}`);
1451
+ b ? k = `${b}${S}${b}` : k = S, k = `<span style="color: ${i.attrValue};">${k}</span>`;
1452
+ } else
1453
+ b && (k = `${b}${C}${b}`), k = `<span style="color: ${i.attrValue};">${k}</span>`;
1454
+ return `${L}${w}${k}`;
1455
+ }
1456
+ ), `${c}${d}${f}${u}`;
1457
+ }), r;
1458
+ }
1459
+ _highlightJS(e, t) {
1460
+ const i = this.unescapeEntitiesRepeated(e);
1461
+ this.escapeHTML(i);
1462
+ const s = [], r = (h) => {
1463
+ let u = "", d = h;
1464
+ do
1465
+ u = String.fromCharCode(97 + d % 26) + u, d = Math.floor(d / 26) - 1;
1466
+ while (d >= 0);
1467
+ return u || "a";
1468
+ }, o = (h) => `\0${r(h)}\0`, n = (h) => {
1469
+ const u = s.length;
1470
+ return s.push(h), o(u);
1471
+ };
1472
+ let l;
1473
+ const a = /(\/\*[\s\S]*?\*\/)|(\/\/[^\n\r]*)|("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)/g;
1474
+ let c = 0, g = "";
1475
+ for (; l = a.exec(i); ) {
1476
+ const h = l.index;
1477
+ c < h && (g += this.escapeHTML(i.slice(c, h)));
1478
+ const u = l[0];
1479
+ /^\/\*/.test(u) || /^\/\//.test(u) ? g += n(`<span style="color: ${t.comment};">${this.escapeHTML(u)}</span>`) : g += n(`<span style="color: ${t.string};">${this.escapeHTML(u)}</span>`), c = a.lastIndex;
1480
+ }
1481
+ return c < i.length && (g += this.escapeHTML(i.slice(c))), g = g.replace(/\b(0x[0-9a-fA-F]+|\d+\.?\d*|\d*\.\d+)\b/g, (h, u, d) => {
1482
+ const f = g[d - 1] || "", m = g[d + h.length] || "";
1483
+ return f === "&" || f === "#" || m === ";" || m === "#" ? h : `<span style="color: ${t.number};">${h}</span>`;
1484
+ }), g = g.replace(/\b(const|let|var|function|class|if|else|return|for|while|switch|case|break|import|from|export|extends|new|try|catch|finally|throw|await|async|interface|type)\b/g, `<span style="color: ${t.keyword};">$1</span>`), g.replace(/\u0000([a-z]+)\u0000/g, (h, u) => {
1485
+ let d = 0;
1486
+ for (let f = 0; f < u.length; f++)
1487
+ d = d * 26 + (u.charCodeAt(f) - 97 + 1);
1488
+ return d = d - 1, s[d] || "";
1489
+ });
1490
+ }
1491
+ _highlightPHP(e, t) {
1492
+ const i = this.unescapeEntitiesRepeated(e);
1493
+ let s = this.escapeHTML(i);
1494
+ const r = [], o = (d) => {
1495
+ let f = "", m = d;
1496
+ do
1497
+ f = String.fromCharCode(97 + m % 26) + f, m = Math.floor(m / 26) - 1;
1498
+ while (m >= 0);
1499
+ return f || "a";
1500
+ }, n = (d) => {
1501
+ const f = r.length;
1502
+ return r.push(d), `\0${o(f)}\0`;
1503
+ }, l = (d, f) => {
1504
+ const m = s.indexOf(d);
1505
+ return m === -1 ? !1 : (s = s.slice(0, m) + f + s.slice(m + d.length), !0);
1506
+ };
1507
+ let a;
1508
+ const c = /\/\*[\s\S]*?\*\//g, g = /\/\/[^\n\r]*/g, h = /\#([^\n\r]*)/g, u = /("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')/g;
1509
+ for (; a = c.exec(i); ) {
1510
+ const d = a[0];
1511
+ l(this.escapeHTML(d), n(`<span style="color: ${t.comment};">${this.escapeHTML(d)}</span>`));
1512
+ }
1513
+ for (; a = g.exec(i); ) {
1514
+ const d = a[0];
1515
+ l(this.escapeHTML(d), n(`<span style="color: ${t.comment};">${this.escapeHTML(d)}</span>`));
1516
+ }
1517
+ for (; a = h.exec(i); ) {
1518
+ const d = a[0];
1519
+ l(this.escapeHTML(d), n(`<span style="color: ${t.comment};">${this.escapeHTML(d)}</span>`));
1520
+ }
1521
+ for (; a = u.exec(i); ) {
1522
+ const d = a[0];
1523
+ l(this.escapeHTML(d), n(`<span style="color: ${t.string};">${this.escapeHTML(d)}</span>`));
1524
+ }
1525
+ return s = s.replace(/(\$[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)/g, `<span style="color: ${t.variable};">$1</span>`), s = s.replace(/\b(echo|print|function|class|if|else|elseif|foreach|as|return|namespace|use|new|extends|public|protected|private|static)\b/g, `<span style="color: ${t.keyword};">$1</span>`), s = s.replace(/\u0000([a-z]+)\u0000/g, (d, f) => {
1526
+ let m = 0;
1527
+ for (let y = 0; y < f.length; y++)
1528
+ m = m * 26 + (f.charCodeAt(y) - 97 + 1);
1529
+ return m = m - 1, r[m] || "";
1530
+ }), s;
1531
+ }
1532
+ // Method to check if content contains syntax that should be highlighted
1533
+ shouldHighlight(e) {
1534
+ return /<\/?[\w:-]+|<!--/.test(e);
1535
+ }
1536
+ destroy() {
1537
+ this.editor = null, this.modes.clear();
1538
+ }
1539
+ }
1540
+ function D(v, e) {
1541
+ const t = { ...e };
1542
+ return t.extensions || (t.extensions = []), t.extensions.some((i) => i.name === "keymap") || t.extensions.unshift(new B(t.keymap)), t.extensions.some((i) => i.name === "transaction") || t.extensions.unshift(new V()), new A(v, t);
1543
+ }
1544
+ const R = '[data-theme="dark"], .dark, .editora-theme-dark', j = `/* Source Editor Dialog Styles */
1545
+ .rte-source-editor-overlay {
1546
+ position: fixed !important;
1547
+ top: 0 !important;
1548
+ left: 0 !important;
1549
+ right: 0 !important;
1550
+ bottom: 0 !important;
1551
+ width: 100vw !important;
1552
+ height: 100vh !important;
1553
+ background-color: rgba(0, 0, 0, 0.6) !important;
1554
+ display: flex !important;
1555
+ align-items: center !important;
1556
+ justify-content: center !important;
1557
+ z-index: 10000 !important;
1558
+ padding: 20px !important;
1559
+ box-sizing: border-box !important;
1560
+ margin: 0 !important;
1561
+ }
1562
+
1563
+ .rte-source-editor-overlay.fullscreen {
1564
+ padding: 0 !important;
1565
+ }
1566
+
1567
+ .rte-source-editor-modal {
1568
+ background: white;
1569
+ border-radius: 8px;
1570
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
1571
+ width: 100%;
1572
+ max-width: 1200px;
1573
+ max-height: 90vh;
1574
+ display: flex;
1575
+ flex-direction: column;
1576
+ overflow: hidden;
1577
+ position: relative;
1578
+ }
1579
+
1580
+ .rte-source-editor-overlay.fullscreen .rte-source-editor-modal {
1581
+ border-radius: 0;
1582
+ max-width: 100%;
1583
+ max-height: 100vh;
1584
+ width: 100%;
1585
+ height: 100vh;
1586
+ }
1587
+
1588
+ .rte-source-editor-header {
1589
+ display: flex;
1590
+ align-items: center;
1591
+ justify-content: space-between;
1592
+ padding: 16px 20px;
1593
+ border-bottom: 1px solid #e1e5e9;
1594
+ background: #f8f9fa;
1595
+ border-radius: 8px 8px 0 0;
1596
+ }
1597
+
1598
+ .rte-source-editor-overlay.fullscreen .rte-source-editor-header {
1599
+ border-radius: 0;
1600
+ }
1601
+
1602
+ .rte-source-editor-header h2 {
1603
+ margin: 0;
1604
+ font-size: 18px;
1605
+ font-weight: 600;
1606
+ color: #1a1a1a;
1607
+ }
1608
+
1609
+ .rte-source-editor-header-toolbar {
1610
+ display: flex;
1611
+ gap: 8px;
1612
+ margin-left: auto;
1613
+ margin-right: 16px;
1614
+ }
1615
+
1616
+ .rte-source-editor-toolbar-btn {
1617
+ background: none;
1618
+ border: none;
1619
+ cursor: pointer;
1620
+ padding: 6px;
1621
+ border-radius: 4px;
1622
+ font-size: 16px;
1623
+ line-height: 1;
1624
+ transition: all 0.2s ease;
1625
+ color: #666;
1626
+ }
1627
+
1628
+ .rte-source-editor-toolbar-btn:hover:not(:disabled) {
1629
+ background: #e1e5e9;
1630
+ color: #1a1a1a;
1631
+ }
1632
+
1633
+ .rte-source-editor-toolbar-btn:disabled {
1634
+ opacity: 0.5;
1635
+ cursor: not-allowed;
1636
+ }
1637
+
1638
+ .rte-source-editor-toolbar-btn.active {
1639
+ background: #007acc;
1640
+ color: white;
1641
+ }
1642
+
1643
+ .rte-source-editor-toolbar-btn.active:hover {
1644
+ background: #0056b3;
1645
+ }
1646
+
1647
+ .rte-source-editor-header-actions {
1648
+ display: flex;
1649
+ gap: 8px;
1650
+ }
1651
+
1652
+ .rte-source-editor-fullscreen-btn,
1653
+ .rte-source-editor-close-btn {
1654
+ background: none;
1655
+ border: none;
1656
+ cursor: pointer;
1657
+ padding: 4px;
1658
+ border-radius: 4px;
1659
+ color: #666;
1660
+ font-size: 16px;
1661
+ line-height: 1;
1662
+ transition: all 0.2s ease;
1663
+ }
1664
+
1665
+ .rte-source-editor-fullscreen-btn:hover,
1666
+ .rte-source-editor-close-btn:hover {
1667
+ background: #e1e5e9;
1668
+ color: #1a1a1a;
1669
+ }
1670
+
1671
+ .rte-source-editor-body {
1672
+ flex: 1;
1673
+ overflow: hidden;
1674
+ display: flex;
1675
+ flex-direction: column;
1676
+ }
1677
+
1678
+ .rte-source-editor-loading {
1679
+ display: flex;
1680
+ flex-direction: column;
1681
+ align-items: center;
1682
+ justify-content: center;
1683
+ padding: 40px;
1684
+ color: #666;
1685
+ position: absolute;
1686
+ z-index: 9;
1687
+ margin: 0 auto;
1688
+ width: 100%;
1689
+ top: 44%;
1690
+ }
1691
+
1692
+ .rte-source-editor-spinner {
1693
+ width: 32px;
1694
+ height: 32px;
1695
+ border: 3px solid #e1e5e9;
1696
+ border-top: 3px solid #007acc;
1697
+ border-radius: 50%;
1698
+ animation: spin 1s linear infinite;
1699
+ margin-bottom: 16px;
1700
+ }
1701
+
1702
+ @keyframes spin {
1703
+ 0% { transform: rotate(0deg); }
1704
+ 100% { transform: rotate(360deg); }
1705
+ }
1706
+
1707
+ .rte-source-editor-error {
1708
+ background: #fee;
1709
+ color: #c53030;
1710
+ padding: 12px 16px;
1711
+ border-left: 4px solid #c53030;
1712
+ margin: 16px;
1713
+ border-radius: 4px;
1714
+ font-size: 14px;
1715
+ }
1716
+
1717
+ .rte-source-editor-content {
1718
+ flex: 1;
1719
+ display: flex;
1720
+ flex-direction: column;
1721
+ overflow: hidden;
1722
+ }
1723
+
1724
+ .rte-source-editor-warning {
1725
+ background: #fefcbf;
1726
+ color: #744210;
1727
+ padding: 8px 16px;
1728
+ font-size: 12px;
1729
+ font-weight: 500;
1730
+ border-bottom: 1px solid #f6e05e;
1731
+ }
1732
+
1733
+ .rte-source-editor-codemirror {
1734
+ flex: 1;
1735
+ overflow: auto;
1736
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
1737
+ font-size: 14px;
1738
+ line-height: 1.5;
1739
+ }
1740
+
1741
+ .rte-source-editor-codemirror .cm-editor {
1742
+ height: 100%;
1743
+ }
1744
+
1745
+ .rte-source-editor-codemirror .cm-focused {
1746
+ outline: none;
1747
+ }
1748
+
1749
+ .rte-source-editor-footer {
1750
+ display: flex;
1751
+ align-items: center;
1752
+ justify-content: space-between;
1753
+ padding: 16px 20px;
1754
+ border-top: 1px solid #e1e5e9;
1755
+ background: #f8f9fa;
1756
+ border-radius: 0 0 8px 8px;
1757
+ }
1758
+
1759
+ .rte-source-editor-overlay.fullscreen .rte-source-editor-footer {
1760
+ border-radius: 0;
1761
+ }
1762
+
1763
+ .rte-source-editor-footer-info {
1764
+ font-size: 12px;
1765
+ color: #666;
1766
+ }
1767
+
1768
+ .unsaved-changes {
1769
+ color: #d69e2e;
1770
+ font-weight: 500;
1771
+ }
1772
+
1773
+ .rte-source-editor-footer-actions {
1774
+ display: flex;
1775
+ gap: 12px;
1776
+ }
1777
+
1778
+ .rte-source-editor-btn {
1779
+ padding: 8px 16px;
1780
+ border-radius: 4px;
1781
+ font-size: 14px;
1782
+ font-weight: 500;
1783
+ cursor: pointer;
1784
+ border: 1px solid transparent;
1785
+ transition: all 0.2s ease;
1786
+ }
1787
+
1788
+ .rte-source-editor-btn:disabled {
1789
+ opacity: 0.6;
1790
+ cursor: not-allowed;
1791
+ }
1792
+
1793
+ .rte-source-editor-btn-cancel {
1794
+ background: white;
1795
+ border-color: #d1d5db;
1796
+ color: #374151;
1797
+ }
1798
+
1799
+ .rte-source-editor-btn-cancel:hover:not(:disabled) {
1800
+ background: #f9fafb;
1801
+ border-color: #9ca3af;
1802
+ }
1803
+
1804
+ .rte-source-editor-btn-save {
1805
+ background: #007acc;
1806
+ color: white;
1807
+ }
1808
+
1809
+ .rte-source-editor-btn-save:hover:not(:disabled) {
1810
+ background: #0056b3;
1811
+ }
1812
+
1813
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-modal {
1814
+ background: #1e1e1e;
1815
+ color: #f8f9fa;
1816
+ border: 1px solid #434d5f;
1817
+ }
1818
+
1819
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-header,
1820
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-footer {
1821
+ background: #2a3442;
1822
+ border-color: #434d5f;
1823
+ }
1824
+
1825
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-header h2 {
1826
+ color: #f8f9fa;
1827
+ }
1828
+
1829
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn,
1830
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-fullscreen-btn,
1831
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-close-btn {
1832
+ color: #c1cede;
1833
+ }
1834
+
1835
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn:hover:not(:disabled),
1836
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-fullscreen-btn:hover,
1837
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-close-btn:hover {
1838
+ background: #404a5a;
1839
+ color: #f8fafc;
1840
+ }
1841
+
1842
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn.active {
1843
+ background: #3b82f6;
1844
+ color: #ffffff;
1845
+ }
1846
+
1847
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn.active:hover {
1848
+ background: #2563eb;
1849
+ }
1850
+
1851
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-loading,
1852
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-footer-info {
1853
+ color: #cbd5e1;
1854
+ }
1855
+
1856
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-spinner {
1857
+ border-color: #3f4b60;
1858
+ border-top-color: #58a6ff;
1859
+ }
1860
+
1861
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-error {
1862
+ background: #3f2124;
1863
+ color: #fecaca;
1864
+ border-color: #ef4444;
1865
+ }
1866
+
1867
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-warning {
1868
+ background: #3b3220;
1869
+ color: #fde68a;
1870
+ border-color: #f59e0b;
1871
+ }
1872
+
1873
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-cancel {
1874
+ background: #334155;
1875
+ border-color: #475569;
1876
+ color: #f1f5f9;
1877
+ }
1878
+
1879
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-cancel:hover:not(:disabled) {
1880
+ background: #475569;
1881
+ border-color: #64748b;
1882
+ }
1883
+
1884
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-save {
1885
+ background: #3b82f6;
1886
+ }
1887
+
1888
+ .rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-save:hover:not(:disabled) {
1889
+ background: #2563eb;
1890
+ }
1891
+
1892
+ /* Responsive design */
1893
+ @media (max-width: 768px) {
1894
+ .rte-source-editor-overlay {
1895
+ padding: 10px;
1896
+ }
1897
+
1898
+ .rte-source-editor-modal {
1899
+ max-height: 95vh;
1900
+ }
1901
+
1902
+ .rte-source-editor-header {
1903
+ padding: 12px 16px;
1904
+ }
1905
+
1906
+ .rte-source-editor-footer {
1907
+ padding: 12px 16px;
1908
+ flex-direction: column;
1909
+ gap: 12px;
1910
+ align-items: stretch;
1911
+ }
1912
+
1913
+ .rte-source-editor-footer-actions {
1914
+ justify-content: stretch;
1915
+ }
1916
+
1917
+ .rte-source-editor-btn {
1918
+ flex: 1;
1919
+ text-align: center;
1920
+ }
1921
+ }`, Z = () => ({
1922
+ name: "code",
1923
+ // Toolbar button configuration
1924
+ toolbar: [
1925
+ {
1926
+ label: "Source",
1927
+ command: "toggleSourceView",
1928
+ // type: "button",
1929
+ icon: '<svg width="24" height="24" focusable="false"><g fill-rule="nonzero"><path d="M9.8 15.7c.3.3.3.8 0 1-.3.4-.9.4-1.2 0l-4.4-4.1a.8.8 0 0 1 0-1.2l4.4-4.2c.3-.3.9-.3 1.2 0 .3.3.3.8 0 1.1L6 12l3.8 3.7ZM14.2 15.7c-.3.3-.3.8 0 1 .4.4.9.4 1.2 0l4.4-4.1c.3-.3.3-.9 0-1.2l-4.4-4.2a.8.8 0 0 0-1.2 0c-.3.3-.3.8 0 1.1L18 12l-3.8 3.7Z"></path></g></svg>',
1930
+ shortcut: "Mod-Shift-S"
1931
+ }
1932
+ ],
1933
+ // Native command implementations
1934
+ commands: {
1935
+ /**
1936
+ * Toggle HTML source view
1937
+ * Opens a dialog to edit raw HTML
1938
+ */
1939
+ toggleSourceView: () => {
1940
+ const e = (() => {
1941
+ const r = window.getSelection();
1942
+ if (r && r.anchorNode) {
1943
+ let n = r.anchorNode instanceof HTMLElement ? r.anchorNode : r.anchorNode.parentElement;
1944
+ for (; n; ) {
1945
+ if (n.classList?.contains("rte-content"))
1946
+ return n;
1947
+ n = n.parentElement;
1948
+ }
1949
+ }
1950
+ if (document.activeElement) {
1951
+ let n = document.activeElement;
1952
+ if (n.classList?.contains("rte-content"))
1953
+ return n;
1954
+ for (; n && n !== document.body; ) {
1955
+ if (n.classList?.contains("rte-content"))
1956
+ return n;
1957
+ const l = n.querySelector(
1958
+ ".rte-content"
1959
+ );
1960
+ if (l) return l;
1961
+ n = n.parentElement;
1962
+ }
1963
+ }
1964
+ const o = document.querySelector("[data-editora-editor]");
1965
+ if (o) {
1966
+ const n = o.querySelector(
1967
+ ".rte-content"
1968
+ );
1969
+ if (n) return n;
1970
+ }
1971
+ return document.querySelector(".rte-content");
1972
+ })();
1973
+ if (!e)
1974
+ return console.error("[CodePlugin] Editor content area not found"), alert(
1975
+ "Editor content area not found. Please click inside the editor first."
1976
+ ), !1;
1977
+ const t = e.innerHTML, i = (r) => {
1978
+ let o = "", n = 0;
1979
+ const l = 2, a = r.split(/(<\/?[a-zA-Z][^>]*>)/);
1980
+ for (const c of a)
1981
+ c.trim() && (c.match(/^<\/[a-zA-Z]/) ? (n = Math.max(0, n - 1), o += `
1982
+ ` + " ".repeat(n * l) + c) : c.match(/^<[a-zA-Z]/) && !c.match(/\/>$/) ? (o += `
1983
+ ` + " ".repeat(n * l) + c, n++) : c.match(/^<[a-zA-Z].*\/>$/) ? o += `
1984
+ ` + " ".repeat(n * l) + c : o += c.trim());
1985
+ return o.trim();
1986
+ };
1987
+ return (() => {
1988
+ let r = null, o = "dark", n = !1, l = !1, a = !1;
1989
+ const c = t, g = !!e.closest(R) || document.body.matches(R) || document.documentElement.matches(R), h = document.createElement("div");
1990
+ h.className = "rte-source-editor-overlay", g && h.classList.add("rte-theme-dark");
1991
+ const u = document.createElement("div");
1992
+ u.className = "rte-source-editor-modal", u.setAttribute("role", "dialog"), u.setAttribute("aria-modal", "true"), u.setAttribute("aria-labelledby", "source-editor-title");
1993
+ const d = document.createElement("div");
1994
+ d.className = "rte-source-editor-header", d.innerHTML = `
1995
+ <h2 id="source-editor-title">Source Editor</h2>
1996
+ <div class="rte-source-editor-header-toolbar">
1997
+ <button class="rte-source-editor-toolbar-btn theme-toggle-btn" title="Switch theme">
1998
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1999
+ <circle cx="12" cy="12" r="5"/>
2000
+ <line x1="12" y1="1" x2="12" y2="3"/>
2001
+ <line x1="12" y1="21" x2="12" y2="23"/>
2002
+ <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
2003
+ <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
2004
+ <line x1="1" y1="12" x2="3" y2="12"/>
2005
+ <line x1="21" y1="12" x2="23" y2="12"/>
2006
+ <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
2007
+ <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
2008
+ </svg>
2009
+ </button>
2010
+ <button class="rte-source-editor-toolbar-btn readonly-toggle-btn" title="Toggle read-only">
2011
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2012
+ <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
2013
+ <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
2014
+ </svg>
2015
+ </button>
2016
+ </div>
2017
+ <div class="rte-source-editor-header-actions">
2018
+ <button class="rte-source-editor-fullscreen-btn" title="Toggle fullscreen">
2019
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2020
+ <path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
2021
+ </svg>
2022
+ </button>
2023
+ <button class="rte-source-editor-close-btn" aria-label="Close source editor">
2024
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2025
+ <line x1="18" y1="6" x2="6" y2="18"/>
2026
+ <line x1="6" y1="6" x2="18" y2="18"/>
2027
+ </svg>
2028
+ </button>
2029
+ </div>
2030
+ `;
2031
+ const f = document.createElement("div");
2032
+ f.className = "rte-source-editor-body";
2033
+ const m = document.createElement("div");
2034
+ m.className = "rte-source-editor-content";
2035
+ const y = document.createElement("div");
2036
+ y.className = "rte-source-editor-warning", y.textContent = "⚠️ Advanced users only. Invalid HTML may break the editor.";
2037
+ const w = document.createElement("div");
2038
+ w.className = "rte-source-editor-light-editor", w.style.height = "400px", m.appendChild(y), m.appendChild(w), f.appendChild(m);
2039
+ const x = document.createElement("div");
2040
+ if (x.className = "rte-source-editor-footer", x.innerHTML = `
2041
+ <div class="rte-source-editor-footer-info">
2042
+ <span class="unsaved-changes" style="display: none;">• Unsaved changes</span>
2043
+ </div>
2044
+ <div class="rte-source-editor-footer-actions">
2045
+ <button class="rte-source-editor-btn rte-source-editor-btn-cancel">Cancel</button>
2046
+ <button class="rte-source-editor-btn rte-source-editor-btn-save">Save</button>
2047
+ </div>
2048
+ `, u.appendChild(d), u.appendChild(f), u.appendChild(x), h.appendChild(u), !document.getElementById("rte-source-editor-styles")) {
2049
+ const p = document.createElement("style");
2050
+ p.id = "rte-source-editor-styles", p.textContent = j, document.head.appendChild(p);
2051
+ }
2052
+ document.body.appendChild(h);
2053
+ try {
2054
+ r = D(w, {
2055
+ value: i(t),
2056
+ theme: "dark",
2057
+ readOnly: !1,
2058
+ extensions: [
2059
+ new K(),
2060
+ new U(),
2061
+ new z(),
2062
+ new F(),
2063
+ new q(),
2064
+ new _(),
2065
+ new W()
2066
+ ]
2067
+ }), r.on("change", () => {
2068
+ a = (r?.getValue() || "") !== i(c);
2069
+ const T = x.querySelector(
2070
+ ".unsaved-changes"
2071
+ );
2072
+ T && (T.style.display = a ? "inline" : "none");
2073
+ }), setTimeout(() => r?.focus(), 100);
2074
+ } catch (p) {
2075
+ console.error("Failed to initialize code editor:", p);
2076
+ }
2077
+ const E = () => {
2078
+ o = o === "dark" ? "light" : "dark", r?.setTheme(o);
2079
+ const p = d.querySelector(".theme-toggle-btn");
2080
+ p && o === "light" && (p.innerHTML = `
2081
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2082
+ <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
2083
+ </svg>
2084
+ `);
2085
+ }, L = () => {
2086
+ n = !n, r?.setReadOnly(n);
2087
+ const p = d.querySelector(".readonly-toggle-btn");
2088
+ p && (n ? (p.classList.add("active"), p.innerHTML = `
2089
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2090
+ <rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
2091
+ <circle cx="12" cy="16" r="1"/>
2092
+ <path d="M7 11V7a5 5 0 0 1 10 0v4"/>
2093
+ </svg>
2094
+ `) : (p.classList.remove("active"), p.innerHTML = `
2095
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2096
+ <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
2097
+ <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
2098
+ </svg>
2099
+ `));
2100
+ }, C = () => {
2101
+ l = !l, l ? (h.classList.add("fullscreen"), w.style.height = "calc(100vh - 200px)") : (h.classList.remove("fullscreen"), w.style.height = "400px");
2102
+ const p = d.querySelector(
2103
+ ".rte-source-editor-fullscreen-btn"
2104
+ );
2105
+ p && (p.innerHTML = l ? `
2106
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2107
+ <path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 0 2-2h3M3 16h3a2 2 0 0 0 2 2v3"/>
2108
+ </svg>
2109
+ ` : `
2110
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2111
+ <path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
2112
+ </svg>
2113
+ `);
2114
+ }, b = () => {
2115
+ r && (r.destroy(), r = null), document.body.removeChild(h);
2116
+ }, k = () => {
2117
+ a && !confirm(
2118
+ "You have unsaved changes. Are you sure you want to cancel?"
2119
+ ) || b();
2120
+ }, S = () => {
2121
+ try {
2122
+ const p = r?.getValue() || "", T = document.createElement("div");
2123
+ T.innerHTML = p, T.querySelectorAll(
2124
+ 'script, iframe[src^="javascript:"], object, embed'
2125
+ ).forEach((I) => I.remove()), e.innerHTML = T.innerHTML;
2126
+ try {
2127
+ e.dispatchEvent(
2128
+ new InputEvent("input", {
2129
+ bubbles: !0,
2130
+ cancelable: !1,
2131
+ inputType: "insertReplacementText"
2132
+ })
2133
+ );
2134
+ } catch {
2135
+ e.dispatchEvent(
2136
+ new Event("input", { bubbles: !0 })
2137
+ );
2138
+ }
2139
+ e.dispatchEvent(
2140
+ new Event("change", { bubbles: !0 })
2141
+ ), a = !1, b();
2142
+ } catch (p) {
2143
+ alert("Failed to update HTML. Please check your syntax."), console.error("HTML update error:", p);
2144
+ }
2145
+ };
2146
+ d.querySelector(".theme-toggle-btn")?.addEventListener("click", E), d.querySelector(".readonly-toggle-btn")?.addEventListener("click", L), d.querySelector(".rte-source-editor-fullscreen-btn")?.addEventListener("click", C), d.querySelector(".rte-source-editor-close-btn")?.addEventListener("click", b), x.querySelector(".rte-source-editor-btn-cancel")?.addEventListener("click", k), x.querySelector(".rte-source-editor-btn-save")?.addEventListener("click", S), h.addEventListener("click", (p) => {
2147
+ p.target === h && b();
2148
+ });
2149
+ const O = (p) => {
2150
+ p.key === "Escape" && (b(), document.removeEventListener("keydown", O));
2151
+ };
2152
+ document.addEventListener("keydown", O);
2153
+ })(), !0;
2154
+ }
2155
+ },
2156
+ // Keyboard shortcuts
2157
+ keymap: {
2158
+ "Mod-Shift-s": "toggleSourceView",
2159
+ "Mod-Shift-S": "toggleSourceView"
2160
+ }
2161
+ });
2162
+ export {
2163
+ Z as CodePlugin
2164
+ };