@editora/plugins 1.0.2 → 1.0.4

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