@editora/plugins 1.0.7 → 1.0.8

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 (58) hide show
  1. package/README.md +50 -4
  2. package/dist/_commonjsHelpers-BH3jXuIh.js +1 -0
  3. package/dist/_commonjsHelpers-ByX85dGu.mjs +33 -0
  4. package/dist/anchor.cjs.js +11 -11
  5. package/dist/anchor.esm.js +130 -107
  6. package/dist/anchoredPopover-BzqGPOAE.js +1 -0
  7. package/dist/anchoredPopover-Dts0IrgU.mjs +106 -0
  8. package/dist/background-color.cjs.js +3 -3
  9. package/dist/background-color.esm.js +116 -119
  10. package/dist/code.cjs.js +82 -102
  11. package/dist/code.esm.js +1172 -662
  12. package/dist/comments.cjs.js +10 -10
  13. package/dist/comments.esm.js +195 -177
  14. package/dist/document-manager.cjs.js +1 -1
  15. package/dist/document-manager.esm.js +1 -1
  16. package/dist/documentManager-CTqRftU8.mjs +8369 -0
  17. package/dist/documentManager-Jf0RbSks.js +17 -0
  18. package/dist/embed-iframe.cjs.js +2 -2
  19. package/dist/embed-iframe.esm.js +8 -5
  20. package/dist/emojis.cjs.js +64 -39
  21. package/dist/emojis.esm.js +133 -104
  22. package/dist/html2canvas.esm-B5qzocYs.js +5 -0
  23. package/dist/html2canvas.esm-BWVIUcAF.mjs +4802 -0
  24. package/dist/{index-Bskk414V.mjs → index-BFsKNTTj.mjs} +50 -50
  25. package/dist/index-CvJk4DKa.js +221 -0
  26. package/dist/index-D3CycEFU.mjs +16543 -0
  27. package/dist/index-tqLTHcO6.js +1 -0
  28. package/dist/index.cjs.js +1 -1
  29. package/dist/{index.es-Cz1qItab.js → index.es-CE_A4QSm.js} +5 -5
  30. package/dist/{index.es-DEcRmSTY.mjs → index.es-DQ78mYYo.mjs} +4 -3
  31. package/dist/index.esm.js +87 -79
  32. package/dist/jspdf.es.min-BoS80556.js +77 -0
  33. package/dist/jspdf.es.min-DQCoX5yh.mjs +7889 -0
  34. package/dist/link.cjs.js +6 -6
  35. package/dist/link.esm.js +41 -39
  36. package/dist/math.cjs.js +21 -21
  37. package/dist/math.esm.js +151 -112
  38. package/dist/media-manager.cjs.js +15 -15
  39. package/dist/media-manager.esm.js +227 -206
  40. package/dist/merge-tag.cjs.js +44 -12
  41. package/dist/merge-tag.esm.js +368 -241
  42. package/dist/page-break.cjs.js +2 -2
  43. package/dist/page-break.esm.js +77 -69
  44. package/dist/special-characters.cjs.js +83 -45
  45. package/dist/special-characters.esm.js +149 -100
  46. package/dist/spell-check.cjs.js +9 -9
  47. package/dist/spell-check.esm.js +235 -216
  48. package/dist/template.cjs.js +14 -14
  49. package/dist/template.esm.js +157 -131
  50. package/dist/text-color.cjs.js +9 -9
  51. package/dist/text-color.esm.js +131 -115
  52. package/index.d.ts +51 -1
  53. package/package.json +3 -3
  54. package/dist/colorSelectionApply-C0iOfMWb.js +0 -1
  55. package/dist/colorSelectionApply-D8r_gV32.mjs +0 -63
  56. package/dist/documentManager-DRUc1-Cs.mjs +0 -37581
  57. package/dist/documentManager-_tQQfQi9.js +0 -317
  58. package/dist/index-D3pJyAsj.js +0 -1
package/dist/code.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- class H {
1
+ class D {
2
2
  constructor(e = "") {
3
3
  this._lines = [], this._version = 0, this.setText(e);
4
4
  }
@@ -30,28 +30,28 @@ class H {
30
30
  return this.getLine(e.start.line).substring(e.start.column, e.end.column);
31
31
  const t = [];
32
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));
33
+ for (let s = e.start.line + 1; s < e.end.line; s++)
34
+ t.push(this.getLine(s));
35
35
  return e.end.line < this.getLineCount() && t.push(this.getLine(e.end.line).substring(0, e.end.column)), t.join(`
36
36
  `);
37
37
  }
38
38
  // Replace text in range
39
39
  replaceRange(e, t) {
40
- const i = this.getTextInRange(e);
40
+ const s = this.getTextInRange(e);
41
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;
42
+ const i = this.getLine(e.start.line), n = i.substring(0, e.start.column) + t + i.substring(e.end.column);
43
+ this._lines[e.start.line] = n;
44
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(`
45
+ const i = this.getLine(e.start.line), n = this.getLine(e.end.line), r = i.substring(0, e.start.column) + t, o = n.substring(e.end.column), l = t.split(`
46
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);
47
+ l[0] = r + l[0], l[l.length - 1] = l[l.length - 1] + o, this._lines.splice(e.start.line, e.end.line - e.start.line + 1, ...l);
48
48
  }
49
- return this._version++, { range: e, text: t, oldText: i };
49
+ return this._version++, { range: e, text: t, oldText: s };
50
50
  }
51
51
  // Insert text at position
52
52
  insertText(e, t) {
53
- const i = { start: e, end: e };
54
- return this.replaceRange(i, t);
53
+ const s = { start: e, end: e };
54
+ return this.replaceRange(s, t);
55
55
  }
56
56
  // Delete text in range
57
57
  deleteRange(e) {
@@ -60,18 +60,18 @@ class H {
60
60
  // Convert position to offset
61
61
  positionToOffset(e) {
62
62
  let t = 0;
63
- for (let i = 0; i < e.line; i++)
64
- t += this.getLine(i).length + 1;
63
+ for (let s = 0; s < e.line; s++)
64
+ t += this.getLine(s).length + 1;
65
65
  return t += e.column, t;
66
66
  }
67
67
  // Convert offset to position
68
68
  offsetToPosition(e) {
69
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;
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
75
  }
76
76
  return {
77
77
  line: this.getLineCount() - 1,
@@ -92,18 +92,18 @@ class H {
92
92
  }
93
93
  // Clone the model
94
94
  clone() {
95
- const e = new H();
95
+ const e = new D();
96
96
  return e._lines = [...this._lines], e._version = this._version, e;
97
97
  }
98
98
  }
99
- class P {
99
+ class Z {
100
100
  constructor(e) {
101
- this.gutterWidth = 50, this.lineHeight = 21, this.trailingNewlineMarkerAttr = "data-lce-trailing-newline-marker", this.container = e, this.createDOM();
101
+ this.gutterWidth = 50, this.lineHeight = 21, this.trailingNewlineMarkerAttr = "data-lce-trailing-newline-marker", this.virtualMarkerRegex = /[\u200B\uE000]/, this.container = e, this.createDOM();
102
102
  }
103
103
  createDOM() {
104
104
  this.container.innerHTML = "";
105
105
  const e = document.createElement("div");
106
- this.editorContainer = e, e.style.cssText = `
106
+ this.editorContainer = e, e.setAttribute("data-lce-editor-container", "true"), e.style.cssText = `
107
107
  position: relative;
108
108
  display: flex;
109
109
  width: 100%;
@@ -149,8 +149,8 @@ class P {
149
149
  }
150
150
  // Update line numbers
151
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("");
152
+ const t = Math.max(e, 20), s = Array.from({ length: t }, (i, n) => n + 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
154
  }
155
155
  // Get content element
156
156
  getContentElement() {
@@ -175,11 +175,11 @@ class P {
175
175
  }
176
176
  // Set inner HTML (used for syntax highlighted content)
177
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(`
178
+ const t = /\n$/.test(e), s = /&lt;|&gt;/.test(e), i = /<span\b/i.test(e), n = /<[^>]+>/.test(e);
179
+ s && i ? this.contentElement.innerHTML = e : n && !s ? this.contentElement.textContent = e : this.contentElement.innerHTML = e, this.syncTrailingNewlineMarker(t);
180
+ const r = (this.contentElement.textContent || "").split(`
181
181
  `).length;
182
- this.updateLineNumbers(o);
182
+ this.updateLineNumbers(r);
183
183
  }
184
184
  // Keep trailing-newline caret marker in sync for live contenteditable edits
185
185
  // (without forcing a full setText/setHTML render).
@@ -192,53 +192,38 @@ class P {
192
192
  const e = window.getSelection();
193
193
  if (!e || e.rangeCount === 0)
194
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(`
195
+ const t = e.getRangeAt(0), s = t.cloneRange();
196
+ s.selectNodeContents(this.contentElement), s.setEnd(t.endContainer, t.endOffset);
197
+ const i = s.toString().replace(/\u200B/g, "").split(`
198
198
  `);
199
199
  return {
200
- line: s.length - 1,
201
- column: s[s.length - 1].length
200
+ line: i.length - 1,
201
+ column: i[i.length - 1].length
202
202
  };
203
203
  }
204
204
  // Set cursor position
205
205
  setCursorPosition(e) {
206
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)
207
+ `), s = Math.min(e.line, t.length - 1), i = Math.min(e.column, t[s]?.length || 0);
208
+ let n = 0;
209
+ for (let h = 0; h < s; h++)
210
+ n += t[h].length + 1;
211
+ n += i;
212
+ const r = document.createRange(), o = window.getSelection(), l = this.resolveOffsetToDomPoint(n);
213
+ if (l)
229
214
  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);
215
+ r.setStart(l.node, l.offset), r.setEnd(l.node, l.offset), o?.removeAllRanges(), o?.addRange(r), this.ensureCaretVisible();
216
+ } catch (h) {
217
+ console.warn("Could not set cursor position:", h);
233
218
  }
234
219
  else {
235
- const u = this.contentElement.querySelector(
220
+ const h = this.contentElement.querySelector(
236
221
  `[${this.trailingNewlineMarkerAttr}]`
237
222
  );
238
223
  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);
224
+ h && h.parentNode === this.contentElement ? r.setStartBefore(h) : (r.selectNodeContents(this.contentElement), r.collapse(!1)), r.collapse(!0), o?.removeAllRanges(), o?.addRange(r), this.ensureCaretVisible();
225
+ } catch (a) {
226
+ console.warn("Could not set fallback cursor position:", a);
242
227
  }
243
228
  }
244
229
  }
@@ -247,27 +232,46 @@ class P {
247
232
  const e = window.getSelection();
248
233
  if (!e || e.rangeCount === 0 || e.isCollapsed)
249
234
  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(`
235
+ const t = e.getRangeAt(0), s = t.cloneRange();
236
+ s.selectNodeContents(this.contentElement), s.setEnd(t.startContainer, t.startOffset);
237
+ const i = s.toString().replace(/\u200B/g, "").split(`
238
+ `), n = t.cloneRange();
239
+ n.selectNodeContents(this.contentElement), n.setEnd(t.endContainer, t.endOffset);
240
+ const r = n.toString().replace(/\u200B/g, "").split(`
256
241
  `);
257
242
  return {
258
243
  start: {
259
- line: s.length - 1,
260
- column: s[s.length - 1].length
244
+ line: i.length - 1,
245
+ column: i[i.length - 1].length
261
246
  },
262
247
  end: {
263
- line: o.length - 1,
264
- column: o[o.length - 1].length
248
+ line: r.length - 1,
249
+ column: r[r.length - 1].length
265
250
  }
266
251
  };
267
252
  }
268
253
  // Set selection range
269
254
  setSelectionRange(e) {
270
- this.setCursorPosition(e.start);
255
+ const t = this.getText().split(`
256
+ `), s = (c) => {
257
+ const u = Math.max(0, Math.min(c.line, t.length - 1)), f = Math.max(
258
+ 0,
259
+ Math.min(c.column, t[u] ? t[u].length : 0)
260
+ );
261
+ let d = 0;
262
+ for (let g = 0; g < u; g++)
263
+ d += t[g].length + 1;
264
+ return d + f;
265
+ }, i = s(e.start), n = s(e.end), [r, o] = i <= n ? [i, n] : [n, i], l = this.resolveOffsetToDomPoint(r), h = this.resolveOffsetToDomPoint(o);
266
+ if (!l || !h) return;
267
+ const a = document.createRange();
268
+ try {
269
+ a.setStart(l.node, l.offset), a.setEnd(h.node, h.offset);
270
+ const c = window.getSelection();
271
+ c?.removeAllRanges(), c?.addRange(a), this.ensureCaretVisible();
272
+ } catch (c) {
273
+ console.warn("Could not set selection range:", c);
274
+ }
271
275
  }
272
276
  // Focus the editor
273
277
  focus() {
@@ -283,8 +287,8 @@ class P {
283
287
  }
284
288
  // Apply theme
285
289
  applyTheme(e) {
286
- Object.entries(e).forEach(([t, i]) => {
287
- this.container.style.setProperty(`--${t}`, i);
290
+ Object.entries(e).forEach(([t, s]) => {
291
+ this.container.style.setProperty(`--${t}`, s);
288
292
  });
289
293
  }
290
294
  // Scroll to position
@@ -296,12 +300,16 @@ class P {
296
300
  getScrollTop() {
297
301
  return this.editorContainer.scrollTop;
298
302
  }
303
+ // Get primary scroll element
304
+ getScrollElement() {
305
+ return this.editorContainer;
306
+ }
299
307
  // Set scroll position
300
308
  setScrollTop(e) {
301
309
  this.editorContainer.scrollTop = e;
302
310
  }
303
311
  syncTrailingNewlineMarker(e) {
304
- if (this.contentElement.querySelectorAll(`[${this.trailingNewlineMarkerAttr}]`).forEach((i) => i.remove()), !e) return;
312
+ if (this.contentElement.querySelectorAll(`[${this.trailingNewlineMarkerAttr}]`).forEach((s) => s.remove()), !e) return;
305
313
  const t = document.createElement("span");
306
314
  t.setAttribute(this.trailingNewlineMarkerAttr, "true"), t.setAttribute("aria-hidden", "true"), t.contentEditable = "false", t.style.cssText = `
307
315
  display: inline-block;
@@ -317,17 +325,55 @@ class P {
317
325
  if (!e || e.rangeCount === 0) return;
318
326
  const t = e.getRangeAt(0).cloneRange();
319
327
  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);
328
+ let s = t.getClientRects()[0] || t.getBoundingClientRect();
329
+ if ((!s || s.width === 0 && s.height === 0) && e.focusNode instanceof Element ? s = e.focusNode.getBoundingClientRect() : (!s || s.width === 0 && s.height === 0) && e.focusNode?.parentElement && (s = e.focusNode.parentElement.getBoundingClientRect()), !s) return;
330
+ const i = this.editorContainer.getBoundingClientRect(), n = 12;
331
+ s.bottom > i.bottom - n ? this.editorContainer.scrollTop += s.bottom - (i.bottom - n) : s.top < i.top + n && (this.editorContainer.scrollTop -= i.top + n - s.top);
324
332
  }
325
333
  // Destroy the view
326
334
  destroy() {
327
335
  this.container && this.container.parentNode && this.container.parentNode.removeChild(this.container), this._rafId && (cancelAnimationFrame(this._rafId), this._rafId = void 0);
328
336
  }
337
+ resolveOffsetToDomPoint(e) {
338
+ const t = Math.max(0, e);
339
+ let s = 0;
340
+ const i = document.createTreeWalker(
341
+ this.contentElement,
342
+ NodeFilter.SHOW_TEXT,
343
+ null
344
+ );
345
+ let n = null, r;
346
+ for (; r = i.nextNode(); ) {
347
+ if (r.parentElement?.hasAttribute(this.trailingNewlineMarkerAttr))
348
+ continue;
349
+ n = r;
350
+ const o = r.textContent || "", l = this.buildVisibleToDomMap(o), h = Math.max(0, l.length - 1);
351
+ if (s + h >= t) {
352
+ const a = Math.max(0, t - s), c = l[a] ?? o.length;
353
+ return {
354
+ node: r,
355
+ offset: c
356
+ };
357
+ }
358
+ s += h;
359
+ }
360
+ if (n) {
361
+ const o = n.textContent?.length || 0;
362
+ return { node: n, offset: o };
363
+ }
364
+ return null;
365
+ }
366
+ buildVisibleToDomMap(e) {
367
+ const t = [0];
368
+ let s = 0;
369
+ for (let i = 0; i < e.length; i++) {
370
+ const n = e[i];
371
+ this.virtualMarkerRegex.test(n) || (s += 1, t[s] = i + 1);
372
+ }
373
+ return t;
374
+ }
329
375
  }
330
- const $ = class M {
376
+ const F = class L {
331
377
  constructor(e, t = {}) {
332
378
  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
379
  value: "",
@@ -337,7 +383,7 @@ const $ = class M {
337
383
  lineWrapping: !1,
338
384
  lineNumbers: !0,
339
385
  ...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();
386
+ }, this.textModel = new D(this.config.value), this.view = new Z(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();
341
387
  }
342
388
  // Public accessors for extensions
343
389
  getTextModel() {
@@ -363,21 +409,21 @@ const $ = class M {
363
409
  setupEventHandlers() {
364
410
  const e = this.view.getContentElement();
365
411
  e.addEventListener("input", () => {
366
- const t = this.view.getText(), i = this.textModel.getText();
367
- if (t !== i) {
412
+ const t = this.view.getText(), s = this.textModel.getText();
413
+ if (t !== s) {
368
414
  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;
415
+ const i = this.getCursor().position, n = this.textModel.positionToOffset(i), r = this.getSelection();
416
+ let o, l;
417
+ r && (o = this.textModel.positionToOffset(r.start), l = this.textModel.positionToOffset(r.end)), this.undoStack.push({ text: s, cursorOffset: n, anchorOffset: o, focusOffset: l }), this.undoStack.length > 100 && this.undoStack.shift(), this.redoStack.length = 0;
372
418
  }
373
419
  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 }]);
420
+ const i = this.view.getText();
421
+ i !== this.textModel.getText() && this.textModel.setText(i), this.renderTextWithHighlight(this.textModel.getText(), !1), this.highlightTimeout = null;
422
+ }, 300), this.updateLineNumbers(), this.emit("change", [{ range: this.getFullRange(), text: t, oldText: s }]);
377
423
  }
378
424
  }), e.addEventListener("selectionchange", () => {
379
- const t = this.getCursor(), i = this.getSelection();
380
- this.emit("cursor", t), i && this.emit("selection", i);
425
+ const t = this.getCursor(), s = this.getSelection();
426
+ this.emit("cursor", t), s && this.emit("selection", s);
381
427
  }), e.addEventListener("keydown", (t) => {
382
428
  if (this.emit("keydown", t), t.key === "Tab") {
383
429
  this.config.readOnly || this.insertTab(), t.preventDefault(), t.stopPropagation();
@@ -385,33 +431,33 @@ const $ = class M {
385
431
  }
386
432
  if (t.key === "Enter") {
387
433
  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(`
434
+ const s = window.getSelection();
435
+ if (s && s.rangeCount > 0) {
436
+ const i = this.getCursor().position, n = this.textModel.positionToOffset(i), r = this.getSelection();
437
+ let o, l;
438
+ r && (o = this.textModel.positionToOffset(r.start), l = this.textModel.positionToOffset(r.end));
439
+ const h = r && o !== void 0 && l !== void 0 ? Math.min(o, l) : n;
440
+ this.suppressHistory || (this.undoStack.push({ text: this.textModel.getText(), cursorOffset: n, anchorOffset: o, focusOffset: l }), this.undoStack.length > 100 && this.undoStack.shift(), this.redoStack.length = 0);
441
+ const a = s.getRangeAt(0);
442
+ a.deleteContents();
443
+ const c = document.createTextNode(`
398
444
  `);
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,
445
+ a.insertNode(c), a.setStartAfter(c), a.collapse(!0), s.removeAllRanges(), s.addRange(a), this.view.ensureCaretVisible();
446
+ const u = this.view.getText();
447
+ this.textModel.setText(u), this.view.syncTrailingNewlineMarkerForText(u);
448
+ const f = Math.min(
449
+ h + 1,
404
450
  this.textModel.getText().length
405
451
  );
406
452
  try {
407
- const d = this.textModel.offsetToPosition(u);
453
+ const d = this.textModel.offsetToPosition(f);
408
454
  this.setCursor(d), this.view.ensureCaretVisible();
409
455
  } catch {
410
456
  }
411
457
  this.highlightTimeout && clearTimeout(this.highlightTimeout), this.highlightTimeout = setTimeout(() => {
412
458
  this.renderTextWithHighlight(this.textModel.getText(), !1), requestAnimationFrame(() => {
413
459
  try {
414
- const d = this.textModel.offsetToPosition(u);
460
+ const d = this.textModel.offsetToPosition(f);
415
461
  this.setCursor(d), this.view.ensureCaretVisible();
416
462
  } catch {
417
463
  }
@@ -422,15 +468,15 @@ const $ = class M {
422
468
  t.preventDefault(), t.stopPropagation();
423
469
  return;
424
470
  }
425
- for (const i of this.extensions.values())
426
- if (i.onKeyDown && i.onKeyDown(t) === !1) {
471
+ for (const s of this.extensions.values())
472
+ if (s.onKeyDown && s.onKeyDown(t) === !1) {
427
473
  t.preventDefault(), t.stopPropagation();
428
474
  return;
429
475
  }
430
476
  }), e.addEventListener("mousedown", (t) => {
431
477
  this.emit("mousedown", t);
432
- for (const i of this.extensions.values())
433
- if (i.onMouseDown && i.onMouseDown(t) === !1) {
478
+ for (const s of this.extensions.values())
479
+ if (s.onMouseDown && s.onMouseDown(t) === !1) {
434
480
  t.preventDefault(), t.stopPropagation();
435
481
  return;
436
482
  }
@@ -457,8 +503,8 @@ const $ = class M {
457
503
  }
458
504
  // Emit events to listeners
459
505
  emit(e, ...t) {
460
- const i = this.eventListeners.get(e);
461
- i && i.forEach((s) => s(...t));
506
+ const s = this.eventListeners.get(e);
507
+ s && s.forEach((i) => i(...t));
462
508
  }
463
509
  // State management
464
510
  getValue() {
@@ -506,12 +552,12 @@ const $ = class M {
506
552
  "editor-gutter-border": e === "dark" ? "#3e3e42" : "#e1e5e9"
507
553
  };
508
554
  this.view.applyTheme(t);
509
- const i = this.extensions.get("syntax-highlighting");
510
- if (i && typeof i.setTheme == "function")
555
+ const s = this.extensions.get("syntax-highlighting");
556
+ if (s && typeof s.setTheme == "function")
511
557
  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);
558
+ s.setTheme(e === "dark" ? "dark" : "light"), this.renderTextWithHighlight(this.textModel.getText());
559
+ } catch (i) {
560
+ console.warn("Error applying theme to syntax-highlighting extension", i);
515
561
  }
516
562
  }
517
563
  setReadOnly(e) {
@@ -528,8 +574,8 @@ const $ = class M {
528
574
  t && t.destroy && t.destroy(), this.extensions.delete(e);
529
575
  }
530
576
  executeCommand(e, ...t) {
531
- const i = this.commands.get(e);
532
- i ? i(this, ...t) : console.warn(`Command '${e}' not found`);
577
+ const s = this.commands.get(e);
578
+ s ? s(this, ...t) : console.warn(`Command '${e}' not found`);
533
579
  }
534
580
  // Register a command
535
581
  registerCommand(e, t) {
@@ -537,52 +583,94 @@ const $ = class M {
537
583
  }
538
584
  // Search & Navigation
539
585
  search(e, t = {}) {
540
- const i = {
586
+ if (!e) return [];
587
+ const s = {
588
+ query: e,
541
589
  caseSensitive: !1,
590
+ wholeWord: !1,
542
591
  regex: !1,
543
592
  ...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");
593
+ }, i = [], n = this.textModel.getText(), { normalizedText: r, normalizedToRawOffsets: o } = this.buildSearchTextAndOffsetMap(n), l = s.caseSensitive ? r : r.toLowerCase(), h = s.caseSensitive ? e : e.toLowerCase();
594
+ if (s.regex) {
550
595
  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
- });
596
+ try {
597
+ a = new RegExp(e, s.caseSensitive ? "g" : "gi");
598
+ } catch {
599
+ return [];
600
+ }
601
+ let c;
602
+ for (; (c = a.exec(r)) !== null; ) {
603
+ const u = c[0] ?? "";
604
+ if (u.length === 0) {
605
+ a.lastIndex = c.index + 1;
606
+ continue;
607
+ }
608
+ const f = c.index, d = c.index + u.length;
609
+ s.wholeWord && !this.isWholeWordBoundary(r, f, d) || this.pushSearchResultFromOffsets(
610
+ i,
611
+ f,
612
+ d,
613
+ r,
614
+ o
615
+ );
557
616
  }
558
617
  } 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);
618
+ let a = 0, c = l.indexOf(h, a);
619
+ for (; c !== -1; ) {
620
+ const u = c + h.length;
621
+ !s.wholeWord || this.isWholeWordBoundary(r, c, u) ? (this.pushSearchResultFromOffsets(
622
+ i,
623
+ c,
624
+ u,
625
+ r,
626
+ o
627
+ ), a = u) : a = c + 1, c = l.indexOf(h, a);
566
628
  }
567
629
  }
568
- return s;
630
+ return i;
631
+ }
632
+ pushSearchResultFromOffsets(e, t, s, i, n) {
633
+ const r = n[t] ?? t, o = n[s] ?? r, l = this.textModel.offsetToPosition(r), h = this.textModel.offsetToPosition(o);
634
+ e.push({
635
+ range: { start: l, end: h },
636
+ match: i.substring(t, s)
637
+ });
638
+ }
639
+ isWholeWordBoundary(e, t, s) {
640
+ const i = t > 0 ? e[t - 1] : "", n = s < e.length ? e[s] : "";
641
+ return !this.isWordChar(i) && !this.isWordChar(n);
642
+ }
643
+ isWordChar(e) {
644
+ return /^[A-Za-z0-9_]$/.test(e);
645
+ }
646
+ buildSearchTextAndOffsetMap(e) {
647
+ const t = [], s = [0];
648
+ let i = 0;
649
+ for (let n = 0; n < e.length; n++) {
650
+ const r = e[n];
651
+ r === "​" || r === L.CURSOR_SENTINEL || (t.push(r), i += 1, s[i] = n + 1);
652
+ }
653
+ return s[i] = e.length, {
654
+ normalizedText: t.join(""),
655
+ normalizedToRawOffsets: s
656
+ };
569
657
  }
570
658
  replace(e, t) {
571
- const i = this.getValue();
659
+ const s = this.getValue();
572
660
  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;
661
+ const n = this.getCursor().position, r = this.textModel.positionToOffset(n), o = this.getSelection();
662
+ let l, h;
663
+ o && (l = this.textModel.positionToOffset(o.start), h = this.textModel.positionToOffset(o.end)), this.undoStack.push({ text: s, cursorOffset: r, anchorOffset: l, focusOffset: h }), this.undoStack.length > 100 && this.undoStack.shift(), this.redoStack.length = 0;
576
664
  }
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;
665
+ const i = this.textModel.replaceRange(e, t);
666
+ this.expectingProgrammaticCursor = !0, this.renderTextWithHighlight(this.getValue(), !1), this.expectingProgrammaticCursor = !1, this.emit("change", [i]);
667
+ }
668
+ replaceAll(e, t, s = {}) {
669
+ const i = this.search(e, s);
670
+ let n = 0;
671
+ for (let r = i.length - 1; r >= 0; r--)
672
+ this.replace(i[r].range, t), n++;
673
+ return n;
586
674
  }
587
675
  // Folding (basic implementation)
588
676
  fold(e) {
@@ -614,42 +702,42 @@ const $ = class M {
614
702
  // and restores it after updating the DOM. Callers that will explicitly set the caret
615
703
  // should pass `false` to avoid stomping programmatic cursor changes.
616
704
  renderTextWithHighlight(e, t = !0) {
617
- const i = this.extensions.get("syntax-highlighting");
618
- if (i && typeof i.highlightHTML == "function")
705
+ const s = this.extensions.get("syntax-highlighting");
706
+ if (s && typeof s.highlightHTML == "function")
619
707
  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;
708
+ const i = !t && !this.expectingProgrammaticCursor;
709
+ let n, r, o, l;
710
+ if (t || i) {
711
+ n = this.getSelection();
712
+ const u = this.getCollapsedSelectionOffsetInEditor();
713
+ if (u !== void 0)
714
+ r = u;
627
715
  else {
628
- const u = this.getCursor().position;
629
- o = this.textModel.positionToOffset(u);
716
+ const f = this.getCursor().position;
717
+ r = this.textModel.positionToOffset(f);
630
718
  }
631
- r && (n = this.textModel.positionToOffset(r.start), l = this.textModel.positionToOffset(r.end));
719
+ n && (o = this.textModel.positionToOffset(n.start), l = this.textModel.positionToOffset(n.end));
632
720
  }
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(() => {
721
+ const h = (t || i) && !n && r !== void 0 && this.hasCollapsedSelectionInEditor(), a = h ? this.insertSentinelAtOffset(e, r) : e, c = s.highlightHTML(a);
722
+ typeof this.view.setHighlightHTML == "function" ? this.view.setHighlightHTML(c) : this.view.setHTML(c), this.view.syncTrailingNewlineMarkerForText(e), (t || i) && requestAnimationFrame(() => {
635
723
  try {
636
- if (a && this.restoreCursorFromSentinel()) {
724
+ if (h && this.restoreCursorFromSentinel()) {
637
725
  this.view.ensureCaretVisible();
638
726
  return;
639
727
  }
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);
728
+ if (n && (o !== void 0 || l !== void 0)) {
729
+ const u = o !== void 0 ? o : r, f = l !== void 0 ? l : r, d = Math.min(u, f), g = Math.max(u, f), p = this.textModel.offsetToPosition(d), y = this.textModel.offsetToPosition(g);
730
+ this.view.setSelectionRange({ start: p, end: y });
731
+ } else if (r !== void 0) {
732
+ const u = this.textModel.offsetToPosition(r);
733
+ this.view.setCursorPosition(u);
646
734
  }
647
735
  } catch {
648
736
  }
649
737
  });
650
738
  return;
651
- } catch (s) {
652
- console.warn("Syntax highlighting failed, falling back to plain text", s);
739
+ } catch (i) {
740
+ console.warn("Syntax highlighting failed, falling back to plain text", i);
653
741
  }
654
742
  this.view.setText(e);
655
743
  }
@@ -664,30 +752,30 @@ const $ = class M {
664
752
  const e = window.getSelection();
665
753
  if (!e || e.rangeCount === 0 || !e.isCollapsed)
666
754
  return;
667
- const t = e.getRangeAt(0), i = this.view.getContentElement();
668
- if (!i.contains(t.commonAncestorContainer))
755
+ const t = e.getRangeAt(0), s = this.view.getContentElement();
756
+ if (!s.contains(t.commonAncestorContainer))
669
757
  return;
670
- const s = t.cloneRange();
671
- return s.selectNodeContents(i), s.setEnd(t.endContainer, t.endOffset), this.stripVirtualMarkers(s.toString()).length;
758
+ const i = t.cloneRange();
759
+ return i.selectNodeContents(s), i.setEnd(t.endContainer, t.endOffset), this.stripVirtualMarkers(i.toString()).length;
672
760
  }
673
761
  stripVirtualMarkers(e) {
674
- return e.replace(/\u200B/g, "").split(M.CURSOR_SENTINEL).join("");
762
+ return e.replace(/\u200B/g, "").split(L.CURSOR_SENTINEL).join("");
675
763
  }
676
764
  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);
765
+ const s = Math.max(0, Math.min(t, e.length));
766
+ return e.slice(0, s) + L.CURSOR_SENTINEL + e.slice(s);
679
767
  }
680
768
  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();
769
+ const e = this.view.getContentElement(), t = window.getSelection(), s = document.createTreeWalker(e, NodeFilter.SHOW_TEXT);
770
+ let i = s.nextNode(), n = null, r = 0;
771
+ for (; i; ) {
772
+ const o = i.textContent ?? "", l = o.indexOf(L.CURSOR_SENTINEL);
773
+ l !== -1 && (n || (n = i, r = l), i.textContent = o.split(L.CURSOR_SENTINEL).join("")), i = s.nextNode();
686
774
  }
687
- if (!r || !t) return !1;
775
+ if (!n || !t) return !1;
688
776
  try {
689
- const n = document.createRange();
690
- return n.setStart(r, o), n.collapse(!0), t.removeAllRanges(), t.addRange(n), !0;
777
+ const o = document.createRange();
778
+ return o.setStart(n, r), o.collapse(!0), t.removeAllRanges(), t.addRange(o), !0;
691
779
  } catch {
692
780
  return !1;
693
781
  }
@@ -707,16 +795,16 @@ const $ = class M {
707
795
  this.redoStack.push(t);
708
796
  try {
709
797
  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(() => {
798
+ let s, i;
799
+ typeof e == "string" ? s = e : (s = e.text, i = e.cursorOffset), this.setValue(s), requestAnimationFrame(() => {
712
800
  try {
713
- if (s != null)
801
+ if (i != null)
714
802
  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 });
803
+ const n = e.anchorOffset !== void 0 ? e.anchorOffset : i, r = e.focusOffset !== void 0 ? e.focusOffset : i, o = Math.min(n, r), l = Math.max(n, r), h = this.textModel.offsetToPosition(o), a = this.textModel.offsetToPosition(l);
804
+ this.setSelection({ start: h, end: a });
717
805
  } else {
718
- const r = this.textModel.offsetToPosition(s);
719
- this.setCursor(r);
806
+ const n = this.textModel.offsetToPosition(i);
807
+ this.setCursor(n);
720
808
  }
721
809
  } catch {
722
810
  }
@@ -733,16 +821,16 @@ const $ = class M {
733
821
  this.undoStack.push(t);
734
822
  try {
735
823
  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(() => {
824
+ let s, i;
825
+ typeof e == "string" ? s = e : (s = e.text, i = e.cursorOffset), this.setValue(s), requestAnimationFrame(() => {
738
826
  try {
739
- if (s != null)
827
+ if (i != null)
740
828
  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 });
829
+ const n = e.anchorOffset !== void 0 ? e.anchorOffset : i, r = e.focusOffset !== void 0 ? e.focusOffset : i, o = Math.min(n, r), l = Math.max(n, r), h = this.textModel.offsetToPosition(o), a = this.textModel.offsetToPosition(l);
830
+ this.setSelection({ start: h, end: a });
743
831
  } else {
744
- const r = this.textModel.offsetToPosition(s);
745
- this.setCursor(r);
832
+ const n = this.textModel.offsetToPosition(i);
833
+ this.setCursor(n);
746
834
  }
747
835
  } catch {
748
836
  }
@@ -756,29 +844,29 @@ const $ = class M {
756
844
  // Insert a tab character or spaces at current cursor
757
845
  insertTab() {
758
846
  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);
847
+ const e = this.getCursor().position, t = this.textModel.positionToOffset(e), s = " ".repeat(this.config.tabSize || 2), i = this.textModel.insertText(e, s), n = this.textModel.offsetToPosition(this.textModel.positionToOffset(e) + s.length);
760
848
  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;
849
+ const r = this.getSelection();
850
+ let o, l;
851
+ r && (o = this.textModel.positionToOffset(r.start), l = this.textModel.positionToOffset(r.end)), this.undoStack.push({ text: this.getValue(), cursorOffset: t, anchorOffset: o, focusOffset: l }), this.redoStack.length = 0;
764
852
  }
765
- this.expectingProgrammaticCursor = !0, this.renderTextWithHighlight(this.getValue(), !1), this.setCursor(r), setTimeout(() => {
853
+ this.expectingProgrammaticCursor = !0, this.renderTextWithHighlight(this.getValue(), !1), this.setCursor(n), setTimeout(() => {
766
854
  this.expectingProgrammaticCursor = !1;
767
- }, 20), this.emit("change", [s]);
855
+ }, 20), this.emit("change", [i]);
768
856
  }
769
857
  // Insert a newline at current cursor position
770
858
  insertNewLine() {
771
859
  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);
860
+ const e = this.getCursor().position, t = this.textModel.positionToOffset(e), s = this.textModel.insertText(e, `
861
+ `), i = this.textModel.offsetToPosition(this.textModel.positionToOffset(e) + 1);
774
862
  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;
863
+ const n = this.getSelection();
864
+ let r, o;
865
+ n && (r = this.textModel.positionToOffset(n.start), o = this.textModel.positionToOffset(n.end)), this.undoStack.push({ text: this.getValue(), cursorOffset: t, anchorOffset: r, focusOffset: o }), this.redoStack.length = 0;
778
866
  }
779
- this.expectingProgrammaticCursor = !0, this.renderTextWithHighlight(this.getValue(), !1), this.setCursor(s), setTimeout(() => {
867
+ this.expectingProgrammaticCursor = !0, this.renderTextWithHighlight(this.getValue(), !1), this.setCursor(i), setTimeout(() => {
780
868
  this.expectingProgrammaticCursor = !1;
781
- }, 20), this.emit("change", [i]);
869
+ }, 20), this.emit("change", [s]);
782
870
  }
783
871
  // Events
784
872
  on(e, t) {
@@ -786,17 +874,17 @@ const $ = class M {
786
874
  }
787
875
  off(e, t) {
788
876
  if (!this.eventListeners.has(e)) return;
789
- const i = this.eventListeners.get(e);
877
+ const s = this.eventListeners.get(e);
790
878
  if (t) {
791
- const s = i.indexOf(t);
792
- s !== -1 && i.splice(s, 1);
879
+ const i = s.indexOf(t);
880
+ i !== -1 && s.splice(i, 1);
793
881
  } else
794
- i.length = 0;
882
+ s.length = 0;
795
883
  }
796
884
  };
797
- $.CURSOR_SENTINEL = "";
798
- let A = $;
799
- class B {
885
+ F.CURSOR_SENTINEL = "";
886
+ let X = F;
887
+ class J {
800
888
  constructor(e) {
801
889
  this.name = "keymap", this.editor = null, this.keymap = {}, this.isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0, this.keymap = e || this.getDefaultKeymap();
802
890
  }
@@ -810,12 +898,12 @@ class B {
810
898
  return this.editor.executeCommand(t.command), e.preventDefault(), e.stopPropagation(), !1;
811
899
  }
812
900
  findMatchingBinding(e) {
813
- const { key: t, ctrlKey: i, altKey: s, shiftKey: r, metaKey: o } = e, n = String(t).toLowerCase(), l = this.keymap[n];
901
+ const { key: t, ctrlKey: s, altKey: i, shiftKey: n, metaKey: r } = e, o = String(t).toLowerCase(), l = this.keymap[o];
814
902
  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;
903
+ for (const h of l) {
904
+ const a = h.ctrlKey === void 0 || h.ctrlKey === s, c = h.altKey === void 0 || h.altKey === i, u = h.shiftKey === void 0 || h.shiftKey === n, f = h.metaKey === void 0 || h.metaKey === r;
905
+ if (a && c && u && f)
906
+ return h;
819
907
  }
820
908
  return null;
821
909
  }
@@ -827,12 +915,12 @@ class B {
827
915
  const e = {};
828
916
  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
917
  }
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
918
+ addBinding(e, t, s, i) {
919
+ const n = t.toLowerCase();
920
+ e[n] || (e[n] = []), e[n].push({
921
+ key: n,
922
+ command: i,
923
+ ...s
836
924
  });
837
925
  }
838
926
  // Public API for customizing keymap
@@ -841,23 +929,23 @@ class B {
841
929
  }
842
930
  addKeyBinding(e) {
843
931
  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({
932
+ this.keymap[t] || (this.keymap[t] = []), this.keymap[t] = this.keymap[t].filter((s) => s.command !== e.command), this.keymap[t].push({
845
933
  ...e,
846
934
  key: t
847
935
  });
848
936
  }
849
937
  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];
938
+ const s = e.toLowerCase();
939
+ 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];
852
940
  }
853
941
  getKeymap() {
854
942
  return { ...this.keymap };
855
943
  }
856
944
  getBindingsForCommand(e) {
857
945
  const t = [];
858
- for (const i in this.keymap)
859
- for (const s of this.keymap[i])
860
- s.command === e && t.push({ ...s });
946
+ for (const s in this.keymap)
947
+ for (const i of this.keymap[s])
948
+ i.command === e && t.push({ ...i });
861
949
  return t;
862
950
  }
863
951
  getPlatformInfo() {
@@ -870,19 +958,19 @@ class B {
870
958
  this.keymap = {}, this.editor = null;
871
959
  }
872
960
  }
873
- class V {
961
+ class Y {
874
962
  constructor() {
875
963
  this.name = "transaction", this.transactions = [];
876
964
  }
877
965
  setup(e) {
878
966
  e.on("change", (t) => {
879
- const i = {
967
+ const s = {
880
968
  changes: t,
881
969
  selection: e.getSelection(),
882
970
  effects: [],
883
971
  annotations: []
884
972
  };
885
- this.transactions.push(i);
973
+ this.transactions.push(s);
886
974
  });
887
975
  }
888
976
  getTransactions() {
@@ -892,7 +980,7 @@ class V {
892
980
  this.transactions = [];
893
981
  }
894
982
  }
895
- class K {
983
+ class G {
896
984
  constructor() {
897
985
  this.name = "line-numbers", this.editor = null, this.lineNumbersElement = null, this.isEnabled = !0;
898
986
  }
@@ -911,8 +999,8 @@ class K {
911
999
  updateLineNumbers() {
912
1000
  if (!this.lineNumbersElement || !this.editor || !this.isEnabled) return;
913
1001
  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("");
1002
+ `).length, t = Array.from({ length: Math.max(e, 20) }, (s, i) => i + 1);
1003
+ this.lineNumbersElement.innerHTML = t.map((s) => `<div style="height: 21px; line-height: 21px; padding-right: 12px;">${s}</div>`).join("");
916
1004
  }
917
1005
  toggle() {
918
1006
  if (!this.editor) return;
@@ -924,7 +1012,7 @@ class K {
924
1012
  this.lineNumbersElement = null, this.editor = null;
925
1013
  }
926
1014
  }
927
- class U {
1015
+ class _ {
928
1016
  constructor() {
929
1017
  this.name = "theme", this.editor = null, this.currentTheme = "dark";
930
1018
  }
@@ -949,7 +1037,7 @@ class U {
949
1037
  this.editor = null;
950
1038
  }
951
1039
  }
952
- class z {
1040
+ class ee {
953
1041
  constructor() {
954
1042
  this.name = "read-only", this.editor = null, this.isReadOnly = !1;
955
1043
  }
@@ -976,12 +1064,20 @@ class z {
976
1064
  this.editor = null;
977
1065
  }
978
1066
  }
979
- class q {
980
- constructor() {
981
- this.name = "search", this.editor = null, this.searchUI = null, this.isVisible = !1, this.currentResults = [], this.currentIndex = -1;
1067
+ let te = 0;
1068
+ const W = class m {
1069
+ constructor(e = {}) {
1070
+ this.name = "search", this.editor = null, this.searchUI = null, this.isVisible = !1, this.currentResults = [], this.currentIndex = -1, this.searchDebounceTimer = null, this.liveRefreshTimer = null, this.statusResetTimer = null, this.statusFreezeUntil = 0, this.findInput = null, this.replaceInputEl = null, this.statusDiv = null, this.modeDiv = null, this.caseSensitiveInput = null, this.wholeWordInput = null, this.regexInput = null, this.currentQuery = "", this.savedCursor = null, this.editorChangeHandler = null, this.searchOptions = {
1071
+ caseSensitive: !1,
1072
+ wholeWord: !1,
1073
+ regex: !1
1074
+ }, this.trailingMarkerAttr = "data-lce-trailing-newline-marker", this.editorContainerSelector = '[data-lce-editor-container="true"]', this.highlightId = ++te, this.highlightMatchName = `editora-search-match-${this.highlightId}`, this.highlightActiveName = `editora-search-active-${this.highlightId}`, this.highlightStyleId = `editora-search-highlight-style-${this.highlightId}`, this.maxCustomHighlightRanges = 2e3, this.virtualMarkerRegex = /[\u200B\uE000]/, this.hasCustomHighlightSupport = !1, this.config = {
1075
+ replaceAndFindNext: !0,
1076
+ ...e
1077
+ };
982
1078
  }
983
1079
  setup(e) {
984
- this.editor = e, e.registerCommand("find", () => {
1080
+ this.editor = e, this.hasCustomHighlightSupport = this.detectCustomHighlightSupport(), this.hasCustomHighlightSupport && this.ensureHighlightStyles(), e.registerCommand("find", () => {
985
1081
  this.showSearch();
986
1082
  }), e.registerCommand("findNext", () => {
987
1083
  this.findNext();
@@ -989,173 +1085,556 @@ class q {
989
1085
  this.findPrev();
990
1086
  }), e.registerCommand("replace", () => {
991
1087
  this.showReplace();
992
- }), e.registerCommand("replaceAll", (t, i) => {
993
- this.replaceAll(t, i);
994
- });
1088
+ }), e.registerCommand("replaceAll", (t, s) => {
1089
+ this.replaceAll(t, s);
1090
+ }), this.editorChangeHandler = () => {
1091
+ !this.isVisible || !this.currentQuery || this.scheduleLiveRefresh(!0);
1092
+ }, e.on("change", this.editorChangeHandler);
995
1093
  }
996
1094
  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
- }
1095
+ this.editor && (this.searchUI || this.createSearchUI(), this.isVisible || this.captureSelectionState(), this.isVisible = !0, this.searchUI && (this.searchUI.style.display = "block", this.updateModeHint(!1), this.findInput && (this.findInput.focus(), this.findInput.select())), this.currentQuery && this.performSearch(this.currentQuery, !0, !1));
1002
1096
  }
1003
1097
  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");
1098
+ this.showSearch(), this.replaceInputEl && (this.replaceInputEl.style.display = "block", this.replaceInputEl.focus()), this.updateModeHint(!0), this.currentQuery && this.performSearch(this.currentQuery, !1, !0);
1009
1099
  }
1010
1100
  hideSearch() {
1011
- this.isVisible = !1, this.searchUI && (this.searchUI.style.display = "none"), this.clearHighlights();
1101
+ this.isVisible = !1, this.searchUI && (this.searchUI.style.display = "none"), this.replaceInputEl && (this.replaceInputEl.style.display = "none", this.replaceInputEl.value = ""), this.updateModeHint(!1), this.clearHighlights(), this.restoreSelectionState();
1012
1102
  }
1013
1103
  createSearchUI() {
1014
1104
  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>
1105
+ const e = this.editor.getView().getContentElement(), t = e.closest(
1106
+ this.editorContainerSelector
1107
+ ), s = e.closest(".rte-source-editor-modal") || t || e.parentElement;
1108
+ if (!s) return;
1109
+ window.getComputedStyle(s).position === "static" && (s.style.position = "relative"), this.searchUI = document.createElement("div"), this.searchUI.className = m.css.root, this.searchUI.style.display = "none", this.searchUI.innerHTML = `
1110
+ <div class="${m.css.row}">
1111
+ <input type="text" class="${m.css.findInput} ${m.css.inputBase}" placeholder="Find..." />
1112
+ <button class="${m.css.prevButton} ${m.css.buttonBase}" type="button" aria-label="Previous match">↑</button>
1113
+ <button class="${m.css.nextButton} ${m.css.buttonBase}" type="button" aria-label="Next match">↓</button>
1114
+ <button class="${m.css.closeButton} ${m.css.buttonBase}" type="button" aria-label="Close search">×</button>
1115
+ </div>
1116
+ <div class="${m.css.options}">
1117
+ <label class="${m.css.optionLabel}" title="Case sensitive">
1118
+ <input type="checkbox" class="${m.css.optionInput} ${m.css.caseSensitive}" />
1119
+ <span>Aa</span>
1120
+ </label>
1121
+ <label class="${m.css.optionLabel}" title="Whole word">
1122
+ <input type="checkbox" class="${m.css.optionInput} ${m.css.wholeWord}" />
1123
+ <span>Whole</span>
1124
+ </label>
1125
+ <label class="${m.css.optionLabel}" title="Regular expression">
1126
+ <input type="checkbox" class="${m.css.optionInput} ${m.css.regex}" />
1127
+ <span>.*</span>
1128
+ </label>
1129
+ </div>
1130
+ <div class="${m.css.meta}">
1131
+ <div class="${m.css.status} ${m.css.statusLayout}"></div>
1132
+ <div class="${m.css.mode} ${m.css.modeLayout}" aria-live="polite"></div>
1068
1133
  </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
- " />
1134
+ <input type="text" class="${m.css.replaceInput} ${m.css.inputBase} ${m.css.replaceInputLayout}" placeholder="Replace with..." />
1086
1135
  `;
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) {
1136
+ const i = this.searchUI.querySelector(
1137
+ `.${m.css.findInput}`
1138
+ ), n = this.searchUI.querySelector(
1139
+ `.${m.css.replaceInput}`
1140
+ ), r = this.searchUI.querySelector(
1141
+ `.${m.css.prevButton}`
1142
+ ), o = this.searchUI.querySelector(
1143
+ `.${m.css.nextButton}`
1144
+ ), l = this.searchUI.querySelector(
1145
+ `.${m.css.closeButton}`
1146
+ ), h = this.searchUI.querySelector(
1147
+ `.${m.css.status}`
1148
+ ), a = this.searchUI.querySelector(
1149
+ `.${m.css.mode}`
1150
+ ), c = this.searchUI.querySelector(
1151
+ `.${m.css.caseSensitive}`
1152
+ ), u = this.searchUI.querySelector(
1153
+ `.${m.css.wholeWord}`
1154
+ ), f = this.searchUI.querySelector(
1155
+ `.${m.css.regex}`
1156
+ );
1157
+ this.findInput = i, this.replaceInputEl = n, this.statusDiv = h, this.modeDiv = a, this.caseSensitiveInput = c, this.wholeWordInput = u, this.regexInput = f, c.checked = !!this.searchOptions.caseSensitive, u.checked = !!this.searchOptions.wholeWord, f.checked = !!this.searchOptions.regex, i.addEventListener("input", () => {
1158
+ this.searchDebounceTimer && clearTimeout(this.searchDebounceTimer);
1159
+ const g = i.value;
1160
+ this.searchDebounceTimer = setTimeout(() => {
1161
+ this.performSearch(g, !1, !1);
1162
+ }, 120);
1163
+ });
1164
+ const d = () => {
1165
+ this.searchOptions.caseSensitive = c.checked, this.searchOptions.wholeWord = u.checked, this.searchOptions.regex = f.checked;
1166
+ const g = i.value;
1167
+ g.trim() ? this.performSearch(g, !1, !1) : this.performSearch("", !1, !1);
1168
+ };
1169
+ c.addEventListener("change", d), u.addEventListener("change", d), f.addEventListener("change", d), i.addEventListener("keydown", (g) => {
1170
+ g.key === "Enter" ? (g.preventDefault(), g.shiftKey ? this.findPrev() : this.findNext()) : g.key === "Escape" && (g.preventDefault(), this.hideSearch());
1171
+ }), n.addEventListener("keydown", (g) => {
1172
+ g.key === "Enter" ? (g.preventDefault(), g.shiftKey ? this.replaceAll(i.value, n.value) : this.replaceCurrent(i.value, n.value)) : g.key === "Escape" && (g.preventDefault(), this.hideSearch());
1173
+ }), r.addEventListener("click", () => this.findPrev()), o.addEventListener("click", () => this.findNext()), l.addEventListener("click", () => this.hideSearch()), s.appendChild(this.searchUI);
1174
+ }
1175
+ updateModeHint(e) {
1176
+ this.modeDiv && (this.modeDiv.textContent = e ? `Replace: move next ${this.config.replaceAndFindNext ? "ON" : "OFF"}` : "Find mode");
1177
+ }
1178
+ performSearch(e, t, s) {
1097
1179
  if (!this.editor || !e.trim()) {
1098
- this.clearHighlights(), this.updateStatus("");
1180
+ this.currentQuery = "", this.currentResults = [], this.currentIndex = -1, this.clearHighlights(), this.updateStatus("");
1099
1181
  return;
1100
1182
  }
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);
1183
+ if (this.searchOptions.regex && !this.isValidRegex(e)) {
1184
+ this.currentQuery = e, this.currentResults = [], this.currentIndex = -1, this.clearHighlights(), this.updateStatus("Invalid regular expression");
1185
+ return;
1109
1186
  }
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 };
1187
+ this.currentQuery = e;
1188
+ const i = this.currentIndex, n = this.editor.search(e, this.searchOptions);
1189
+ if (this.currentResults = n, n.length === 0) {
1190
+ this.currentIndex = -1, this.clearHighlights(), this.updateStatus("No matches");
1191
+ return;
1192
+ }
1193
+ t && i >= 0 ? this.currentIndex = Math.min(i, n.length - 1) : this.currentIndex = 0, this.updateHighlights(s);
1116
1194
  }
1117
1195
  findNext() {
1118
- this.currentResults.length !== 0 && (this.currentIndex = (this.currentIndex + 1) % this.currentResults.length, this.updateHighlights());
1196
+ if (this.currentResults.length === 0) {
1197
+ this.currentQuery && this.performSearch(this.currentQuery, !0, !0);
1198
+ return;
1199
+ }
1200
+ this.currentIndex = (this.currentIndex + 1) % this.currentResults.length, this.updateHighlights(!0);
1119
1201
  }
1120
1202
  findPrev() {
1121
- this.currentResults.length !== 0 && (this.currentIndex = this.currentIndex <= 0 ? this.currentResults.length - 1 : this.currentIndex - 1, this.updateHighlights());
1203
+ if (this.currentResults.length === 0) {
1204
+ this.currentQuery && this.performSearch(this.currentQuery, !0, !0);
1205
+ return;
1206
+ }
1207
+ this.currentIndex = this.currentIndex <= 0 ? this.currentResults.length - 1 : this.currentIndex - 1, this.updateHighlights(!0);
1122
1208
  }
1123
1209
  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");
1210
+ if (!this.editor || !e.trim() || ((this.currentQuery !== e || this.currentResults.length === 0) && this.performSearch(e, !1, !0), this.currentIndex < 0 || this.currentResults.length === 0)) return;
1211
+ const s = this.currentResults[this.currentIndex];
1212
+ if (!s) return;
1213
+ const i = this.computeReplacementRange(s.range.start, t);
1214
+ if (this.editor.replace(s.range, t), this.config.replaceAndFindNext) {
1215
+ this.currentQuery = e;
1216
+ const n = this.editor.search(e, this.searchOptions);
1217
+ if (this.currentResults = n, n.length === 0) {
1218
+ this.currentIndex = -1, this.clearHighlights(), this.updateStatus("Replaced current occurrence"), this.restoreReplaceInputFocus();
1219
+ return;
1220
+ }
1221
+ this.currentIndex = this.findNextResultIndexAfter(i.end, n), this.updateHighlights(!0);
1222
+ } else
1223
+ this.scrollLogicalRangeIntoView(i, !0), this.performSearch(e, !0, !1);
1224
+ this.currentResults.length > 0 || this.showTransientStatus("Replaced current occurrence"), this.restoreReplaceInputFocus(), this.revealActiveResultAfterFocusRestore();
1129
1225
  }
1130
1226
  replaceAll(e, t) {
1131
1227
  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`));
1228
+ const s = this.editor.replaceAll(e, t, this.searchOptions);
1229
+ this.performSearch(e, !1, !1), this.showTransientStatus(`Replaced ${s} occurrence${s === 1 ? "" : "s"}`), this.restoreReplaceInputFocus(), this.revealActiveResultAfterFocusRestore();
1136
1230
  }
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;
1231
+ updateHighlights(e) {
1232
+ if (this.clearHighlights(), this.currentResults.length === 0 || this.currentIndex === -1 || !this.editor)
1233
+ return;
1234
+ this.applyCustomHighlights();
1235
+ const t = this.currentResults[this.currentIndex];
1236
+ t && ((e || !this.hasCustomHighlightSupport) && this.navigateToResult(t, !this.hasCustomHighlightSupport), this.updateStatus(
1237
+ `${this.currentResults.length} matches (showing ${this.currentIndex + 1}/${this.currentResults.length})`
1238
+ ));
1144
1239
  }
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})`));
1240
+ navigateToResult(e, t) {
1241
+ if (!this.editor) return;
1242
+ const s = document.activeElement, i = !!s && (s === this.findInput || s === this.replaceInputEl);
1243
+ t ? (this.editor.setSelection(e.range), this.centerCurrentSelectionInView()) : this.scrollResultIntoView(e);
1244
+ const n = this.editor.getView();
1245
+ t && typeof n.ensureCaretVisible == "function" && n.ensureCaretVisible(), t && i && s && requestAnimationFrame(() => {
1246
+ this.focusWithoutScrolling(s);
1247
+ });
1147
1248
  }
1148
1249
  clearHighlights() {
1250
+ if (this.hasCustomHighlightSupport)
1251
+ try {
1252
+ const e = CSS;
1253
+ e.highlights?.delete(this.highlightMatchName), e.highlights?.delete(this.highlightActiveName);
1254
+ } catch {
1255
+ }
1256
+ }
1257
+ scrollResultIntoView(e) {
1258
+ this.scrollLogicalRangeIntoView(e.range, !0);
1259
+ }
1260
+ scrollLogicalRangeIntoView(e, t) {
1261
+ if (!this.editor) return;
1262
+ const s = this.editor.getView().getContentElement(), i = this.editor.getValue(), { lineStarts: n, lines: r } = this.buildLineStarts(i), o = this.buildTextNodeIndex(s);
1263
+ if (o.length === 0) return;
1264
+ const l = this.toDomRange(e, n, r, o);
1265
+ if (!l) return;
1266
+ const h = l.startContainer.nodeType === Node.TEXT_NODE ? l.startContainer.parentElement : l.startContainer, a = this.resolveScrollContainer(s);
1267
+ if (a) {
1268
+ const c = l.getClientRects()[0] || l.getBoundingClientRect(), u = a.getBoundingClientRect(), f = a.scrollTop + (c.top - u.top) - u.height / 2 + c.height / 2, d = 18;
1269
+ let g = t ? f : a.scrollTop, p = a.scrollLeft;
1270
+ const y = a.scrollLeft + (c.left - u.left), k = y + c.width;
1271
+ c.right > u.right - d ? p = k - u.width + d : c.left < u.left + d && (p = Math.max(0, y - d));
1272
+ const v = Math.max(0, a.scrollHeight - a.clientHeight), C = Math.max(0, a.scrollWidth - a.clientWidth);
1273
+ if (g = Math.min(v, Math.max(0, g)), p = Math.min(C, Math.max(0, p)), v === 0 && C === 0) {
1274
+ h?.scrollIntoView({
1275
+ block: t ? "center" : "nearest",
1276
+ inline: "nearest",
1277
+ behavior: "smooth"
1278
+ });
1279
+ return;
1280
+ }
1281
+ (g !== a.scrollTop || p !== a.scrollLeft) && a.scrollTo({
1282
+ top: g,
1283
+ left: p,
1284
+ behavior: "smooth"
1285
+ });
1286
+ return;
1287
+ }
1288
+ h?.scrollIntoView({
1289
+ block: t ? "center" : "nearest",
1290
+ inline: "nearest",
1291
+ behavior: "smooth"
1292
+ });
1149
1293
  }
1150
- updateStatus(e) {
1151
- const t = this.searchUI?.querySelector(".search-status");
1152
- t && (t.textContent = e);
1294
+ restoreReplaceInputFocus() {
1295
+ const e = this.replaceInputEl;
1296
+ !e || e.style.display === "none" || requestAnimationFrame(() => {
1297
+ this.focusWithoutScrolling(e);
1298
+ const t = e.value.length;
1299
+ try {
1300
+ e.setSelectionRange(t, t);
1301
+ } catch {
1302
+ }
1303
+ });
1304
+ }
1305
+ centerCurrentSelectionInView() {
1306
+ if (!this.editor) return;
1307
+ const e = this.editor.getView().getContentElement(), t = this.resolveScrollContainer(e);
1308
+ if (!t) return;
1309
+ const s = window.getSelection();
1310
+ if (!s || s.rangeCount === 0) return;
1311
+ const i = s.getRangeAt(0).cloneRange(), n = i.getClientRects()[0] || i.getBoundingClientRect();
1312
+ if (!n) return;
1313
+ const r = t.getBoundingClientRect(), o = t.scrollTop + (n.top - r.top) - r.height / 2 + n.height / 2, l = Math.max(0, t.scrollHeight - t.clientHeight), h = Math.min(l, Math.max(0, o));
1314
+ h !== t.scrollTop && t.scrollTo({
1315
+ top: h,
1316
+ behavior: "smooth"
1317
+ });
1318
+ }
1319
+ computeReplacementRange(e, t) {
1320
+ const s = t.replace(/\r\n?/g, `
1321
+ `), i = s.split(`
1322
+ `);
1323
+ let n;
1324
+ return i.length <= 1 ? (n = {
1325
+ start: e,
1326
+ end: {
1327
+ line: e.line,
1328
+ column: e.column + s.length
1329
+ }
1330
+ }, this.clampRangeToDocument(n)) : (n = {
1331
+ start: e,
1332
+ end: {
1333
+ line: e.line + i.length - 1,
1334
+ column: i[i.length - 1].length
1335
+ }
1336
+ }, this.clampRangeToDocument(n));
1337
+ }
1338
+ findNextResultIndexAfter(e, t) {
1339
+ for (let s = 0; s < t.length; s++)
1340
+ if (this.comparePositions(t[s].range.start, e) >= 0)
1341
+ return s;
1342
+ return 0;
1343
+ }
1344
+ comparePositions(e, t) {
1345
+ return e.line !== t.line ? e.line - t.line : e.column - t.column;
1346
+ }
1347
+ clampRangeToDocument(e) {
1348
+ const t = this.editor;
1349
+ if (!t) return e;
1350
+ const s = t.getValue().split(`
1351
+ `), i = Math.max(0, s.length - 1), n = Math.max(0, Math.min(e.start.line, i)), r = Math.max(0, Math.min(e.end.line, i)), o = Math.max(
1352
+ 0,
1353
+ Math.min(e.start.column, s[n]?.length || 0)
1354
+ ), l = Math.max(
1355
+ 0,
1356
+ Math.min(e.end.column, s[r]?.length || 0)
1357
+ );
1358
+ return {
1359
+ start: { line: n, column: o },
1360
+ end: { line: r, column: l }
1361
+ };
1362
+ }
1363
+ focusWithoutScrolling(e) {
1364
+ try {
1365
+ e.focus({
1366
+ preventScroll: !0
1367
+ });
1368
+ } catch {
1369
+ const t = [];
1370
+ let s = e.parentElement;
1371
+ for (; s; )
1372
+ this.canScroll(s) && t.push({
1373
+ el: s,
1374
+ top: s.scrollTop,
1375
+ left: s.scrollLeft
1376
+ }), s = s.parentElement;
1377
+ const i = window.scrollX, n = window.scrollY;
1378
+ e.focus();
1379
+ for (let r = 0; r < t.length; r++) {
1380
+ const o = t[r];
1381
+ o.el.scrollTop = o.top, o.el.scrollLeft = o.left;
1382
+ }
1383
+ window.scrollTo(i, n);
1384
+ }
1385
+ }
1386
+ findScrollContainer(e) {
1387
+ let t = e;
1388
+ for (; t; ) {
1389
+ const s = window.getComputedStyle(t).overflowY;
1390
+ if ((s === "auto" || s === "scroll") && t.scrollHeight > t.clientHeight)
1391
+ return t;
1392
+ t = t.parentElement;
1393
+ }
1394
+ return null;
1395
+ }
1396
+ resolveScrollContainer(e) {
1397
+ const t = this.editor?.getView()?.getScrollElement?.() || null;
1398
+ return t && this.canScroll(t) ? t : this.findScrollContainer(e);
1399
+ }
1400
+ canScroll(e) {
1401
+ return e.scrollHeight > e.clientHeight || e.scrollWidth > e.clientWidth;
1402
+ }
1403
+ revealActiveResultAfterFocusRestore() {
1404
+ !this.currentResults.length || this.currentIndex < 0 || requestAnimationFrame(() => {
1405
+ const e = this.currentResults[this.currentIndex];
1406
+ e && this.scrollResultIntoView(e);
1407
+ });
1408
+ }
1409
+ applyCustomHighlights() {
1410
+ if (!this.editor || !this.hasCustomHighlightSupport || this.currentResults.length === 0)
1411
+ return;
1412
+ const e = this.editor.getView().getContentElement(), t = this.editor.getValue(), { lineStarts: s, lines: i } = this.buildLineStarts(t), n = this.buildTextNodeIndex(e);
1413
+ if (n.length === 0) return;
1414
+ const r = this.buildVisibleDocumentText(n), o = [];
1415
+ let l = null;
1416
+ const h = Math.min(this.currentResults.length, this.maxCustomHighlightRanges);
1417
+ for (let a = 0; a < h; a++) {
1418
+ const c = this.currentResults[a], u = this.searchOptions.regex ? c.match || this.currentQuery : this.currentQuery || c.match, f = this.toDomRange(
1419
+ c.range,
1420
+ s,
1421
+ i,
1422
+ n,
1423
+ r,
1424
+ u
1425
+ );
1426
+ f && (o.push(f), a === this.currentIndex && (l = f));
1427
+ }
1428
+ if (o.length !== 0)
1429
+ try {
1430
+ const a = CSS, c = window.Highlight;
1431
+ if (!a.highlights || !c) return;
1432
+ a.highlights.set(this.highlightMatchName, new c(...o)), l && a.highlights.set(this.highlightActiveName, new c(l));
1433
+ } catch {
1434
+ }
1435
+ }
1436
+ buildLineStarts(e) {
1437
+ const t = e.split(`
1438
+ `), s = new Array(t.length);
1439
+ let i = 0;
1440
+ for (let n = 0; n < t.length; n++)
1441
+ s[n] = i, i += t[n].length + 1;
1442
+ return { lineStarts: s, lines: t };
1443
+ }
1444
+ positionToOffset(e, t, s) {
1445
+ const i = Math.max(0, Math.min(e.line, s.length - 1)), n = Math.max(0, Math.min(e.column, s[i]?.length || 0));
1446
+ return t[i] + n;
1447
+ }
1448
+ buildTextNodeIndex(e) {
1449
+ const t = document.createTreeWalker(e, NodeFilter.SHOW_TEXT, null), s = [];
1450
+ let i = 0, n;
1451
+ for (; n = t.nextNode(); ) {
1452
+ const r = n;
1453
+ if (r.parentElement?.hasAttribute(this.trailingMarkerAttr))
1454
+ continue;
1455
+ const o = r.textContent || "", l = this.buildVisibleToDomMap(o), h = Math.max(0, l.length - 1);
1456
+ h === 0 && o.length === 0 || (s.push({
1457
+ node: r,
1458
+ start: i,
1459
+ end: i + h,
1460
+ visibleToDom: l
1461
+ }), i += h);
1462
+ }
1463
+ return s;
1464
+ }
1465
+ resolveDomPoint(e, t) {
1466
+ const s = Math.max(0, e);
1467
+ for (let n = 0; n < t.length; n++) {
1468
+ const r = t[n];
1469
+ if (s <= r.end) {
1470
+ const o = Math.max(0, s - r.start), l = r.visibleToDom[o] ?? r.node.textContent?.length ?? 0;
1471
+ return {
1472
+ node: r.node,
1473
+ offset: l
1474
+ };
1475
+ }
1476
+ }
1477
+ const i = t[t.length - 1];
1478
+ return i ? {
1479
+ node: i.node,
1480
+ offset: i.visibleToDom[i.visibleToDom.length - 1] ?? i.node.textContent?.length ?? 0
1481
+ } : null;
1482
+ }
1483
+ toDomRange(e, t, s, i, n, r) {
1484
+ const o = this.positionToOffset(e.start, t, s), l = this.positionToOffset(e.end, t, s);
1485
+ let h = Math.min(o, l), a = Math.max(o, l);
1486
+ if (n && r) {
1487
+ const d = r, g = n.slice(h, a);
1488
+ if (g.length === d.length && g.toLowerCase() !== d.toLowerCase()) {
1489
+ const p = this.findNearestMatchOffset(
1490
+ n,
1491
+ d,
1492
+ h
1493
+ );
1494
+ p !== -1 && (h = p, a = p + d.length);
1495
+ }
1496
+ }
1497
+ const c = this.resolveDomPoint(h, i), u = this.resolveDomPoint(a, i);
1498
+ if (!c || !u) return null;
1499
+ const f = document.createRange();
1500
+ try {
1501
+ return f.setStart(c.node, c.offset), f.setEnd(u.node, u.offset), f;
1502
+ } catch {
1503
+ return null;
1504
+ }
1505
+ }
1506
+ buildVisibleDocumentText(e) {
1507
+ let t = "";
1508
+ for (let s = 0; s < e.length; s++) {
1509
+ const i = e[s].node.textContent || "";
1510
+ for (let n = 0; n < i.length; n++) {
1511
+ const r = i[n];
1512
+ this.virtualMarkerRegex.test(r) || (t += r);
1513
+ }
1514
+ }
1515
+ return t;
1516
+ }
1517
+ findNearestMatchOffset(e, t, s) {
1518
+ const i = t.toLowerCase();
1519
+ let n = e.toLowerCase().indexOf(i);
1520
+ if (n === -1) return -1;
1521
+ let r = n, o = Math.abs(n - s);
1522
+ for (; n !== -1; ) {
1523
+ const l = Math.abs(n - s);
1524
+ if (l < o && (o = l, r = n), l === 0) return n;
1525
+ n = e.toLowerCase().indexOf(i, n + 1);
1526
+ }
1527
+ return r;
1528
+ }
1529
+ scheduleLiveRefresh(e) {
1530
+ this.liveRefreshTimer && clearTimeout(this.liveRefreshTimer);
1531
+ const t = this.currentQuery;
1532
+ this.liveRefreshTimer = setTimeout(() => {
1533
+ !this.isVisible || !t || this.performSearch(t, e, !1);
1534
+ }, 90);
1535
+ }
1536
+ updateStatus(e, t = !1) {
1537
+ if (this.statusDiv) {
1538
+ if (!t && Date.now() < this.statusFreezeUntil)
1539
+ return;
1540
+ this.statusDiv.textContent = e;
1541
+ }
1542
+ }
1543
+ showTransientStatus(e, t = 900) {
1544
+ this.statusFreezeUntil = Date.now() + t, this.updateStatus(e, !0), this.statusResetTimer && clearTimeout(this.statusResetTimer), this.statusResetTimer = setTimeout(() => {
1545
+ this.statusFreezeUntil = 0, this.syncMatchStatus();
1546
+ }, t);
1547
+ }
1548
+ syncMatchStatus() {
1549
+ if (!this.currentQuery) {
1550
+ this.updateStatus("", !0);
1551
+ return;
1552
+ }
1553
+ if (this.currentResults.length === 0 || this.currentIndex < 0) {
1554
+ this.updateStatus("No matches", !0);
1555
+ return;
1556
+ }
1557
+ this.updateStatus(
1558
+ `${this.currentResults.length} matches (showing ${this.currentIndex + 1}/${this.currentResults.length})`,
1559
+ !0
1560
+ );
1561
+ }
1562
+ isValidRegex(e) {
1563
+ try {
1564
+ const t = this.searchOptions.caseSensitive ? "g" : "gi";
1565
+ return new RegExp(e, t), !0;
1566
+ } catch {
1567
+ return !1;
1568
+ }
1569
+ }
1570
+ captureSelectionState() {
1571
+ this.editor && (this.savedSelection = this.editor.getSelection(), this.savedCursor = this.editor.getCursor().position);
1572
+ }
1573
+ restoreSelectionState() {
1574
+ this.editor && (this.savedSelection ? this.editor.setSelection(this.savedSelection) : this.savedCursor && this.editor.setCursor(this.savedCursor), this.savedSelection = void 0, this.savedCursor = null);
1575
+ }
1576
+ detectCustomHighlightSupport() {
1577
+ try {
1578
+ const e = CSS, t = window.Highlight;
1579
+ return !!e.highlights && !!t;
1580
+ } catch {
1581
+ return !1;
1582
+ }
1583
+ }
1584
+ buildVisibleToDomMap(e) {
1585
+ const t = [0];
1586
+ let s = 0;
1587
+ for (let i = 0; i < e.length; i++) {
1588
+ const n = e[i];
1589
+ this.virtualMarkerRegex.test(n) || (s += 1, t[s] = i + 1);
1590
+ }
1591
+ return t;
1592
+ }
1593
+ ensureHighlightStyles() {
1594
+ if (document.getElementById(this.highlightStyleId)) return;
1595
+ const e = document.createElement("style");
1596
+ e.id = this.highlightStyleId, e.textContent = `
1597
+ ::highlight(${this.highlightMatchName}) {
1598
+ background: var(--lce-search-match-bg, rgba(255, 214, 10, 0.34));
1599
+ border-radius: 2px;
1600
+ }
1601
+ ::highlight(${this.highlightActiveName}) {
1602
+ background: var(--lce-search-active-bg, rgba(255, 154, 0, 0.45));
1603
+ border-radius: 2px;
1604
+ }
1605
+ `, document.head.appendChild(e);
1153
1606
  }
1154
1607
  destroy() {
1155
- this.searchUI && this.searchUI.parentNode && this.searchUI.parentNode.removeChild(this.searchUI), this.searchUI = null, this.editor = null;
1608
+ this.searchDebounceTimer && (clearTimeout(this.searchDebounceTimer), this.searchDebounceTimer = null), this.liveRefreshTimer && (clearTimeout(this.liveRefreshTimer), this.liveRefreshTimer = null), this.statusResetTimer && (clearTimeout(this.statusResetTimer), this.statusResetTimer = null), this.clearHighlights(), this.searchUI && this.searchUI.parentNode && this.searchUI.parentNode.removeChild(this.searchUI), this.editor && this.editorChangeHandler && this.editor.off("change", this.editorChangeHandler), this.editorChangeHandler = null, this.findInput = null, this.replaceInputEl = null, this.statusDiv = null, this.modeDiv = null, this.caseSensitiveInput = null, this.wholeWordInput = null, this.regexInput = null, this.searchUI = null;
1609
+ const e = document.getElementById(this.highlightStyleId);
1610
+ e?.parentNode && e.parentNode.removeChild(e), this.editor = null;
1156
1611
  }
1157
- }
1158
- class F {
1612
+ };
1613
+ W.css = {
1614
+ root: "lce-search-ui",
1615
+ row: "lce-search-row",
1616
+ options: "lce-search-options",
1617
+ optionLabel: "lce-search-option",
1618
+ optionInput: "lce-search-option-input",
1619
+ caseSensitive: "search-case-sensitive",
1620
+ wholeWord: "search-whole-word",
1621
+ regex: "search-regex",
1622
+ meta: "lce-search-meta",
1623
+ findInput: "search-find-input",
1624
+ replaceInput: "search-replace-input",
1625
+ inputBase: "lce-search-input",
1626
+ replaceInputLayout: "lce-search-replace",
1627
+ prevButton: "search-prev",
1628
+ nextButton: "search-next",
1629
+ closeButton: "search-close",
1630
+ buttonBase: "lce-search-btn",
1631
+ status: "search-status",
1632
+ statusLayout: "lce-search-status",
1633
+ mode: "search-mode",
1634
+ modeLayout: "lce-search-mode"
1635
+ };
1636
+ let se = W;
1637
+ class ie {
1159
1638
  constructor() {
1160
1639
  this.name = "bracket-matching", this.editor = null, this.bracketPairs = {
1161
1640
  "(": ")",
@@ -1180,58 +1659,58 @@ class F {
1180
1659
  if (!this.editor) return;
1181
1660
  const e = this.editor.getCursor(), t = this.editor.getValue();
1182
1661
  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));
1662
+ const s = this.getBracketAtPosition(t, e.position);
1663
+ if (!s) return;
1664
+ const i = this.findMatchingBracket(t, s);
1665
+ i && (this.currentMatch = i, this.highlightBrackets(i));
1187
1666
  }
1188
1667
  getBracketAtPosition(e, t) {
1189
- const i = e.split(`
1668
+ const s = e.split(`
1190
1669
  `);
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;
1670
+ if (t.line >= s.length) return null;
1671
+ const i = s[t.line];
1672
+ if (t.column >= i.length) return null;
1673
+ const n = i[t.column];
1674
+ return this.bracketPairs[n] || this.reverseBracketPairs[n] ? { char: n, position: t } : null;
1196
1675
  }
1197
1676
  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))
1677
+ const s = e.split(`
1678
+ `), i = t.position.line, n = t.position.column, r = t.char;
1679
+ return this.bracketPairs[r] ? this.findClosingBracket(e, s, i, n, r) : this.reverseBracketPairs[r] ? this.findOpeningBracket(e, s, i, n, r) : null;
1680
+ }
1681
+ findClosingBracket(e, t, s, i, n) {
1682
+ const r = this.bracketPairs[n];
1683
+ let o = 0;
1684
+ for (let l = s; l < t.length; l++) {
1685
+ const h = t[l], a = l === s ? i : 0;
1686
+ for (let c = a; c < h.length; c++) {
1687
+ const u = h[c];
1688
+ if (u === n)
1689
+ o++;
1690
+ else if (u === r && (o--, o === 0))
1212
1691
  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
1692
+ open: { start: { line: s, column: i }, end: { line: s, column: i + 1 } },
1693
+ close: { start: { line: l, column: c }, end: { line: l, column: c + 1 } },
1694
+ type: n
1216
1695
  };
1217
1696
  }
1218
1697
  }
1219
1698
  return null;
1220
1699
  }
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))
1700
+ findOpeningBracket(e, t, s, i, n) {
1701
+ const r = this.reverseBracketPairs[n];
1702
+ let o = 0;
1703
+ for (let l = s; l >= 0; l--) {
1704
+ const h = t[l], a = l === s ? i : h.length - 1;
1705
+ for (let c = a; c >= 0; c--) {
1706
+ const u = h[c];
1707
+ if (u === n)
1708
+ o++;
1709
+ else if (u === r && (o--, o === 0))
1231
1710
  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
1711
+ open: { start: { line: l, column: c }, end: { line: l, column: c + 1 } },
1712
+ close: { start: { line: s, column: i }, end: { line: s, column: i + 1 } },
1713
+ type: r
1235
1714
  };
1236
1715
  }
1237
1716
  }
@@ -1249,9 +1728,9 @@ class F {
1249
1728
  this.clearBracketHighlighting(), this.editor = null;
1250
1729
  }
1251
1730
  }
1252
- class _ {
1731
+ class ne {
1253
1732
  constructor() {
1254
- this.name = "code-folding", this.editor = null, this.foldIndicators = [], this.foldingUI = null;
1733
+ this.name = "code-folding", this.editor = null, this.foldIndicators = [], this.foldingUI = null, this.pendingUpdateRaf = null, this.lastSnapshot = "", this.changeHandler = null;
1255
1734
  }
1256
1735
  setup(e) {
1257
1736
  this.editor = e, e.registerCommand("fold", () => {
@@ -1262,14 +1741,14 @@ class _ {
1262
1741
  this.foldAll();
1263
1742
  }), e.registerCommand("unfoldAll", () => {
1264
1743
  this.unfoldAll();
1265
- }), e.on("change", () => {
1266
- this.updateFoldIndicators();
1267
- }), this.createFoldingUI(), this.updateFoldIndicators();
1744
+ }), this.changeHandler = () => {
1745
+ this.scheduleFoldIndicatorUpdate();
1746
+ }, e.on("change", this.changeHandler), this.createFoldingUI(), this.scheduleFoldIndicatorUpdate();
1268
1747
  }
1269
1748
  createFoldingUI() {
1270
1749
  if (!this.editor) return;
1271
- const e = document.querySelector(".rte-source-editor-modal");
1272
- e && (this.foldingUI = document.createElement("div"), this.foldingUI.style.cssText = `
1750
+ const e = this.editor.getView().getContentElement(), t = e.closest(".rte-source-editor-modal") || e.parentElement;
1751
+ t && (this.foldingUI = document.createElement("div"), this.foldingUI.style.cssText = `
1273
1752
  position: absolute;
1274
1753
  left: 40px;
1275
1754
  top: 0;
@@ -1277,29 +1756,36 @@ class _ {
1277
1756
  width: 20px;
1278
1757
  pointer-events: none;
1279
1758
  z-index: 2;
1280
- `, e.appendChild(this.foldingUI));
1759
+ `, t.appendChild(this.foldingUI));
1760
+ }
1761
+ scheduleFoldIndicatorUpdate() {
1762
+ this.pendingUpdateRaf === null && (this.pendingUpdateRaf = requestAnimationFrame(() => {
1763
+ this.pendingUpdateRaf = null, this.updateFoldIndicators();
1764
+ }));
1281
1765
  }
1282
1766
  updateFoldIndicators() {
1283
1767
  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
- });
1768
+ const e = this.editor.getValue();
1769
+ if (e === this.lastSnapshot) return;
1770
+ this.lastSnapshot = e, this.foldingUI.innerHTML = "", this.foldIndicators = [];
1771
+ const t = e.split(`
1772
+ `), s = this.findFoldableLines(t), i = document.createDocumentFragment();
1773
+ s.forEach((n) => {
1774
+ const r = this.createFoldIndicator(n);
1775
+ i.appendChild(r), this.foldIndicators.push(r);
1776
+ }), this.foldingUI.appendChild(i);
1290
1777
  }
1291
1778
  findFoldableLines(e) {
1292
1779
  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);
1780
+ for (let s = 0; s < e.length; s++) {
1781
+ const i = e[s].trim();
1782
+ (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);
1296
1783
  }
1297
1784
  return t;
1298
1785
  }
1299
1786
  createFoldIndicator(e) {
1300
- if (!this.foldingUI) return;
1301
1787
  const t = document.createElement("div");
1302
- t.style.cssText = `
1788
+ return t.style.cssText = `
1303
1789
  position: absolute;
1304
1790
  left: 0;
1305
1791
  top: ${e * 21}px;
@@ -1314,7 +1800,7 @@ class _ {
1314
1800
  font-size: 10px;
1315
1801
  user-select: none;
1316
1802
  `, 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);
1803
+ }), t;
1318
1804
  }
1319
1805
  foldAtCursor() {
1320
1806
  }
@@ -1325,15 +1811,15 @@ class _ {
1325
1811
  unfoldAll() {
1326
1812
  }
1327
1813
  destroy() {
1328
- this.foldingUI && this.foldingUI.parentNode && this.foldingUI.parentNode.removeChild(this.foldingUI), this.foldingUI = null, this.foldIndicators = [], this.editor = null;
1814
+ this.pendingUpdateRaf !== null && (cancelAnimationFrame(this.pendingUpdateRaf), this.pendingUpdateRaf = null), this.editor && this.changeHandler && this.editor.off("change", this.changeHandler), this.foldingUI && this.foldingUI.parentNode && this.foldingUI.parentNode.removeChild(this.foldingUI), this.changeHandler = null, this.lastSnapshot = "", this.foldingUI = null, this.foldIndicators = [], this.editor = null;
1329
1815
  }
1330
1816
  }
1331
- class W {
1817
+ class re {
1332
1818
  constructor() {
1333
1819
  this.name = "syntax-highlighting", this.editor = null, this.currentTheme = "dark", this.currentLanguage = null, this.modes = /* @__PURE__ */ new Map();
1334
1820
  }
1335
1821
  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) });
1822
+ 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) });
1337
1823
  }
1338
1824
  // Extension provides methods that can be called by the editor
1339
1825
  setTheme(e) {
@@ -1393,8 +1879,8 @@ class W {
1393
1879
  }
1394
1880
  // Public API: highlight a source string using the chosen mode (or detect html)
1395
1881
  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);
1882
+ const s = this.getSyntaxColors(), i = (t || this.currentLanguage || "html").toLowerCase();
1883
+ return (this.modes.get(i) || this.modes.get("html")).highlight(e, s);
1398
1884
  }
1399
1885
  // Backwards-compatible method
1400
1886
  highlightHTML(e) {
@@ -1407,127 +1893,127 @@ class W {
1407
1893
  // Robustly unescape common HTML entities, repeating a few times to handle nested encoding like &amp;amp;...
1408
1894
  unescapeEntitiesRepeated(e) {
1409
1895
  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;
1896
+ for (let s = 0; s < 5; s++) {
1897
+ const i = t;
1898
+ if (t = t.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'"), t === i) break;
1413
1899
  }
1414
1900
  return t;
1415
1901
  }
1416
1902
  _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 = [];
1903
+ const s = t, i = (h) => this.escapeHTML(h);
1904
+ let n = i(e);
1905
+ const r = (h) => {
1906
+ let a = h.replace(/&quot;/g, '"').replace(/&#39;/g, "'");
1907
+ return a = a.replace(/(\/\*[\s\S]*?\*\/)/g, `<span style="color: ${s.comment};">$1</span>`), a = a.replace(/([a-zA-Z-]+)(\s*:\s*)([^;{]+)(;?)/g, (c, u, f, d, g) => {
1908
+ const p = String(d).trim(), y = i(p);
1909
+ return `<span style="color: ${s.styleProp};">${u}</span>${f}<span style="color: ${s.styleVal};">${y}</span>${g}`;
1910
+ }), a;
1911
+ }, o = [];
1426
1912
  try {
1427
- e.replace(/<script\b([^>]*)>([\s\S]*?)<\/script>/gi, (a, c, g) => (n.push({ attrs: String(c || ""), inner: String(g || "") }), a));
1913
+ e.replace(/<script\b([^>]*)>([\s\S]*?)<\/script>/gi, (h, a, c) => (o.push({ attrs: String(a || ""), inner: String(c || "") }), h));
1428
1914
  } catch {
1429
1915
  }
1430
1916
  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(
1917
+ return n = n.replace(/(&lt;script\b([^&>]*)&gt;)([\s\S]*?)(&lt;\/script&gt;)/gi, (h, a, c, u, f) => {
1918
+ const d = o[l++]?.inner ?? this.unescapeEntitiesRepeated(u || "");
1919
+ (o[l - 1]?.attrs || c || "").toLowerCase();
1920
+ const g = this._highlightJS(d, s);
1921
+ return `${a}${g}${f}`;
1922
+ }), n = n.replace(/(&lt;style\b[^&]*&gt;)([\s\S]*?)(&lt;\/style&gt;)/gi, (h, a, c, u) => {
1923
+ const f = r(c);
1924
+ return `${a}${f}${u}`;
1925
+ }), n = n.replace(/(&lt;!--[\s\S]*?--&gt;)/g, `<span style="color: ${s.comment};">$1</span>`), n = n.replace(/(&lt;!DOCTYPE[\s\S]*?&gt;)/i, `<span style="color: ${s.doctype};">$1</span>`), n = n.replace(/(&lt;\/?\s*)([^\s&>\/]+)([\s\S]*?)(\/?&gt;)/g, (h, a, c, u, f) => {
1926
+ const d = `<span style="color: ${s.tag};">${c}</span>`;
1927
+ let g = u;
1928
+ return g = g.replace(
1443
1929
  /([\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>`;
1930
+ (p, y, k, v) => {
1931
+ const C = String(y).toLowerCase(), E = `<span style="color: ${s.attrName};">${y}</span>`;
1932
+ let S = v, b = "";
1933
+ v.startsWith("&quot;") && v.endsWith("&quot;") ? (S = v.slice(6, -6), b = "&quot;") : v.startsWith("&#39;") && v.endsWith("&#39;") && (S = v.slice(5, -5), b = "&#39;");
1934
+ let T = v;
1935
+ if (C === "style") {
1936
+ const I = S.replace(/([\w-]+)\s*:\s*([^;]+)(;?)/g, (B, N, $, O) => `<span style="color: ${s.styleProp};">${N}</span>:<span style="color: ${s.styleVal};">${$.trim()}</span>${O}`);
1937
+ b ? T = `${b}${I}${b}` : T = I, T = `<span style="color: ${s.attrValue};">${T}</span>`;
1452
1938
  } else
1453
- b && (k = `${b}${C}${b}`), k = `<span style="color: ${i.attrValue};">${k}</span>`;
1454
- return `${L}${w}${k}`;
1939
+ b && (T = `${b}${S}${b}`), T = `<span style="color: ${s.attrValue};">${T}</span>`;
1940
+ return `${E}${k}${T}`;
1455
1941
  }
1456
- ), `${c}${d}${f}${u}`;
1457
- }), r;
1942
+ ), `${a}${d}${g}${f}`;
1943
+ }), n;
1458
1944
  }
1459
1945
  _highlightJS(e, t) {
1460
- const i = this.unescapeEntitiesRepeated(e);
1461
- this.escapeHTML(i);
1462
- const s = [], r = (h) => {
1463
- let u = "", d = h;
1946
+ const s = this.unescapeEntitiesRepeated(e);
1947
+ this.escapeHTML(s);
1948
+ const i = [], n = (u) => {
1949
+ let f = "", d = u;
1464
1950
  do
1465
- u = String.fromCharCode(97 + d % 26) + u, d = Math.floor(d / 26) - 1;
1951
+ f = String.fromCharCode(97 + d % 26) + f, d = Math.floor(d / 26) - 1;
1466
1952
  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);
1953
+ return f || "a";
1954
+ }, r = (u) => `\0${n(u)}\0`, o = (u) => {
1955
+ const f = i.length;
1956
+ return i.push(u), r(f);
1471
1957
  };
1472
1958
  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;
1959
+ const h = /(\/\*[\s\S]*?\*\/)|(\/\/[^\n\r]*)|("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)/g;
1960
+ let a = 0, c = "";
1961
+ for (; l = h.exec(s); ) {
1962
+ const u = l.index;
1963
+ a < u && (c += this.escapeHTML(s.slice(a, u)));
1964
+ const f = l[0];
1965
+ /^\/\*/.test(f) || /^\/\//.test(f) ? c += o(`<span style="color: ${t.comment};">${this.escapeHTML(f)}</span>`) : c += o(`<span style="color: ${t.string};">${this.escapeHTML(f)}</span>`), a = h.lastIndex;
1480
1966
  }
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) => {
1967
+ return a < s.length && (c += this.escapeHTML(s.slice(a))), c = c.replace(/\b(0x[0-9a-fA-F]+|\d+\.?\d*|\d*\.\d+)\b/g, (u, f, d) => {
1968
+ const g = c[d - 1] || "", p = c[d + u.length] || "";
1969
+ return g === "&" || g === "#" || p === ";" || p === "#" ? u : `<span style="color: ${t.number};">${u}</span>`;
1970
+ }), c = c.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>`), c.replace(/\u0000([a-z]+)\u0000/g, (u, f) => {
1485
1971
  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] || "";
1972
+ for (let g = 0; g < f.length; g++)
1973
+ d = d * 26 + (f.charCodeAt(g) - 97 + 1);
1974
+ return d = d - 1, i[d] || "";
1489
1975
  });
1490
1976
  }
1491
1977
  _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;
1978
+ const s = this.unescapeEntitiesRepeated(e);
1979
+ let i = this.escapeHTML(s);
1980
+ const n = [], r = (d) => {
1981
+ let g = "", p = d;
1496
1982
  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);
1983
+ g = String.fromCharCode(97 + p % 26) + g, p = Math.floor(p / 26) - 1;
1984
+ while (p >= 0);
1985
+ return g || "a";
1986
+ }, o = (d) => {
1987
+ const g = n.length;
1988
+ return n.push(d), `\0${r(g)}\0`;
1989
+ }, l = (d, g) => {
1990
+ const p = i.indexOf(d);
1991
+ return p === -1 ? !1 : (i = i.slice(0, p) + g + i.slice(p + d.length), !0);
1506
1992
  };
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>`));
1993
+ let h;
1994
+ const a = /\/\*[\s\S]*?\*\//g, c = /\/\/[^\n\r]*/g, u = /\#([^\n\r]*)/g, f = /("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')/g;
1995
+ for (; h = a.exec(s); ) {
1996
+ const d = h[0];
1997
+ l(this.escapeHTML(d), o(`<span style="color: ${t.comment};">${this.escapeHTML(d)}</span>`));
1512
1998
  }
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>`));
1999
+ for (; h = c.exec(s); ) {
2000
+ const d = h[0];
2001
+ l(this.escapeHTML(d), o(`<span style="color: ${t.comment};">${this.escapeHTML(d)}</span>`));
1516
2002
  }
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>`));
2003
+ for (; h = u.exec(s); ) {
2004
+ const d = h[0];
2005
+ l(this.escapeHTML(d), o(`<span style="color: ${t.comment};">${this.escapeHTML(d)}</span>`));
1520
2006
  }
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>`));
2007
+ for (; h = f.exec(s); ) {
2008
+ const d = h[0];
2009
+ l(this.escapeHTML(d), o(`<span style="color: ${t.string};">${this.escapeHTML(d)}</span>`));
1524
2010
  }
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;
2011
+ 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, (d, g) => {
2012
+ let p = 0;
2013
+ for (let y = 0; y < g.length; y++)
2014
+ p = p * 26 + (g.charCodeAt(y) - 97 + 1);
2015
+ return p = p - 1, n[p] || "";
2016
+ }), i;
1531
2017
  }
1532
2018
  // Method to check if content contains syntax that should be highlighted
1533
2019
  shouldHighlight(e) {
@@ -1537,11 +2023,11 @@ class W {
1537
2023
  this.editor = null, this.modes.clear();
1538
2024
  }
1539
2025
  }
1540
- function D(v, e) {
2026
+ function oe(w, e) {
1541
2027
  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);
2028
+ return t.extensions || (t.extensions = []), t.extensions.some((s) => s.name === "keymap") || t.extensions.unshift(new J(t.keymap)), t.extensions.some((s) => s.name === "transaction") || t.extensions.unshift(new Y()), new X(w, t);
1543
2029
  }
1544
- const R = '[data-theme="dark"], .dark, .editora-theme-dark', j = `/* Source Editor Dialog Styles */
2030
+ const P = '[data-theme="dark"], .dark, .editora-theme-dark', le = `/* Source Editor Dialog Styles */
1545
2031
  .rte-source-editor-overlay {
1546
2032
  position: fixed !important;
1547
2033
  top: 0 !important;
@@ -1918,7 +2404,7 @@ const R = '[data-theme="dark"], .dark, .editora-theme-dark', j = `/* Source Edit
1918
2404
  flex: 1;
1919
2405
  text-align: center;
1920
2406
  }
1921
- }`, Z = () => ({
2407
+ }`, ae = () => ({
1922
2408
  name: "code",
1923
2409
  // Toolbar button configuration
1924
2410
  toolbar: [
@@ -1938,35 +2424,35 @@ const R = '[data-theme="dark"], .dark, .editora-theme-dark', j = `/* Source Edit
1938
2424
  */
1939
2425
  toggleSourceView: () => {
1940
2426
  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;
2427
+ const n = window.getSelection();
2428
+ if (n && n.anchorNode) {
2429
+ let o = n.anchorNode instanceof HTMLElement ? n.anchorNode : n.anchorNode.parentElement;
2430
+ for (; o; ) {
2431
+ if (o.classList?.contains("rte-content"))
2432
+ return o;
2433
+ o = o.parentElement;
1948
2434
  }
1949
2435
  }
1950
2436
  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(
2437
+ let o = document.activeElement;
2438
+ if (o.classList?.contains("rte-content"))
2439
+ return o;
2440
+ for (; o && o !== document.body; ) {
2441
+ if (o.classList?.contains("rte-content"))
2442
+ return o;
2443
+ const l = o.querySelector(
1958
2444
  ".rte-content"
1959
2445
  );
1960
2446
  if (l) return l;
1961
- n = n.parentElement;
2447
+ o = o.parentElement;
1962
2448
  }
1963
2449
  }
1964
- const o = document.querySelector("[data-editora-editor]");
1965
- if (o) {
1966
- const n = o.querySelector(
2450
+ const r = document.querySelector("[data-editora-editor]");
2451
+ if (r) {
2452
+ const o = r.querySelector(
1967
2453
  ".rte-content"
1968
2454
  );
1969
- if (n) return n;
2455
+ if (o) return o;
1970
2456
  }
1971
2457
  return document.querySelector(".rte-content");
1972
2458
  })();
@@ -1974,24 +2460,25 @@ const R = '[data-theme="dark"], .dark, .editora-theme-dark', j = `/* Source Edit
1974
2460
  return console.error("[CodePlugin] Editor content area not found"), alert(
1975
2461
  "Editor content area not found. Please click inside the editor first."
1976
2462
  ), !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();
2463
+ const t = e.innerHTML, s = (n) => {
2464
+ let r = "", o = 0;
2465
+ const l = 2, h = n.split(/(<\/?[a-zA-Z][^>]*>)/);
2466
+ for (const a of h)
2467
+ a.trim() && (a.match(/^<\/[a-zA-Z]/) ? (o = Math.max(0, o - 1), r += `
2468
+ ` + " ".repeat(o * l) + a) : a.match(/^<[a-zA-Z]/) && !a.match(/\/>$/) ? (r += `
2469
+ ` + " ".repeat(o * l) + a, o++) : a.match(/^<[a-zA-Z].*\/>$/) ? r += `
2470
+ ` + " ".repeat(o * l) + a : r += a.trim());
2471
+ return r.trim();
1986
2472
  };
1987
2473
  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 = `
2474
+ const r = s(t);
2475
+ let o = null, l = "dark", h = !1, a = !1, c = !1, u = !1;
2476
+ const f = !!e.closest(P) || document.body.matches(P) || document.documentElement.matches(P), d = document.createElement("div");
2477
+ d.className = "rte-source-editor-overlay", f && d.classList.add("rte-theme-dark");
2478
+ const g = document.createElement("div");
2479
+ g.className = "rte-source-editor-modal", g.setAttribute("role", "dialog"), g.setAttribute("aria-modal", "true"), g.setAttribute("aria-labelledby", "source-editor-title");
2480
+ const p = document.createElement("div");
2481
+ p.className = "rte-source-editor-header", p.innerHTML = `
1995
2482
  <h2 id="source-editor-title">Source Editor</h2>
1996
2483
  <div class="rte-source-editor-header-toolbar">
1997
2484
  <button class="rte-source-editor-toolbar-btn theme-toggle-btn" title="Switch theme">
@@ -2028,16 +2515,16 @@ const R = '[data-theme="dark"], .dark, .editora-theme-dark', j = `/* Source Edit
2028
2515
  </button>
2029
2516
  </div>
2030
2517
  `;
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
2518
  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 = `
2519
+ y.className = "rte-source-editor-body";
2520
+ const k = document.createElement("div");
2521
+ k.className = "rte-source-editor-content";
2522
+ const v = document.createElement("div");
2523
+ v.className = "rte-source-editor-warning", v.textContent = "⚠️ Advanced users only. Invalid HTML may break the editor.";
2524
+ const C = document.createElement("div");
2525
+ C.className = "rte-source-editor-light-editor", C.style.height = "400px", k.appendChild(v), k.appendChild(C), y.appendChild(k);
2526
+ const E = document.createElement("div");
2527
+ if (E.className = "rte-source-editor-footer", E.innerHTML = `
2041
2528
  <div class="rte-source-editor-footer-info">
2042
2529
  <span class="unsaved-changes" style="display: none;">• Unsaved changes</span>
2043
2530
  </div>
@@ -2045,64 +2532,69 @@ const R = '[data-theme="dark"], .dark, .editora-theme-dark', j = `/* Source Edit
2045
2532
  <button class="rte-source-editor-btn rte-source-editor-btn-cancel">Cancel</button>
2046
2533
  <button class="rte-source-editor-btn rte-source-editor-btn-save">Save</button>
2047
2534
  </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);
2535
+ `, g.appendChild(p), g.appendChild(y), g.appendChild(E), d.appendChild(g), !document.getElementById("rte-source-editor-styles")) {
2536
+ const x = document.createElement("style");
2537
+ x.id = "rte-source-editor-styles", x.textContent = le, document.head.appendChild(x);
2076
2538
  }
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 = `
2539
+ const S = p.querySelector(
2540
+ ".theme-toggle-btn"
2541
+ ), b = p.querySelector(
2542
+ ".readonly-toggle-btn"
2543
+ ), T = p.querySelector(
2544
+ ".rte-source-editor-fullscreen-btn"
2545
+ ), I = p.querySelector(
2546
+ ".rte-source-editor-close-btn"
2547
+ ), B = E.querySelector(
2548
+ ".rte-source-editor-btn-cancel"
2549
+ ), N = E.querySelector(
2550
+ ".rte-source-editor-btn-save"
2551
+ ), $ = E.querySelector(
2552
+ ".unsaved-changes"
2553
+ ), O = [], R = (x, M, V, A) => {
2554
+ x.addEventListener(M, V, A), O.push(
2555
+ () => x.removeEventListener(M, V, A)
2556
+ );
2557
+ }, U = (x) => {
2558
+ c !== x && (c = x, $ && ($.style.display = c ? "inline" : "none"));
2559
+ }, H = () => {
2560
+ if (!u) {
2561
+ for (u = !0; O.length; )
2562
+ O.pop()?.();
2563
+ o && (o.destroy(), o = null), d.isConnected && d.remove();
2564
+ }
2565
+ }, K = () => {
2566
+ l = l === "dark" ? "light" : "dark", o?.setTheme(l), S && (S.innerHTML = l === "light" ? `
2081
2567
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2082
2568
  <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
2083
2569
  </svg>
2570
+ ` : `
2571
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2572
+ <circle cx="12" cy="12" r="5"/>
2573
+ <line x1="12" y1="1" x2="12" y2="3"/>
2574
+ <line x1="12" y1="21" x2="12" y2="23"/>
2575
+ <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
2576
+ <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
2577
+ <line x1="1" y1="12" x2="3" y2="12"/>
2578
+ <line x1="21" y1="12" x2="23" y2="12"/>
2579
+ <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
2580
+ <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
2581
+ </svg>
2084
2582
  `);
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 = `
2583
+ }, z = () => {
2584
+ h = !h, o?.setReadOnly(h), b && (b.classList.toggle("active", h), b.innerHTML = h ? `
2089
2585
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2090
2586
  <rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
2091
2587
  <circle cx="12" cy="16" r="1"/>
2092
2588
  <path d="M7 11V7a5 5 0 0 1 10 0v4"/>
2093
2589
  </svg>
2094
- `) : (p.classList.remove("active"), p.innerHTML = `
2590
+ ` : `
2095
2591
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2096
2592
  <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
2097
2593
  <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
2098
2594
  </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 ? `
2595
+ `);
2596
+ }, q = () => {
2597
+ a = !a, d.classList.toggle("fullscreen", a), C.style.height = a ? "calc(100vh - 200px)" : "400px", T && (T.innerHTML = a ? `
2106
2598
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2107
2599
  <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
2600
  </svg>
@@ -2111,18 +2603,14 @@ const R = '[data-theme="dark"], .dark, .editora-theme-dark', j = `/* Source Edit
2111
2603
  <path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
2112
2604
  </svg>
2113
2605
  `);
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 = () => {
2606
+ }, Q = () => {
2607
+ c && !confirm("You have unsaved changes. Are you sure you want to cancel?") || H();
2608
+ }, j = () => {
2121
2609
  try {
2122
- const p = r?.getValue() || "", T = document.createElement("div");
2123
- T.innerHTML = p, T.querySelectorAll(
2610
+ const x = o?.getValue() || "", M = document.createElement("div");
2611
+ M.innerHTML = x, M.querySelectorAll(
2124
2612
  'script, iframe[src^="javascript:"], object, embed'
2125
- ).forEach((I) => I.remove()), e.innerHTML = T.innerHTML;
2613
+ ).forEach((A) => A.remove()), e.innerHTML = M.innerHTML;
2126
2614
  try {
2127
2615
  e.dispatchEvent(
2128
2616
  new InputEvent("input", {
@@ -2138,18 +2626,40 @@ const R = '[data-theme="dark"], .dark, .editora-theme-dark', j = `/* Source Edit
2138
2626
  }
2139
2627
  e.dispatchEvent(
2140
2628
  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);
2629
+ ), U(!1), H();
2630
+ } catch (x) {
2631
+ alert("Failed to update HTML. Please check your syntax."), console.error("HTML update error:", x);
2144
2632
  }
2145
2633
  };
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();
2634
+ S && R(S, "click", K), b && R(b, "click", z), T && R(T, "click", q), I && R(I, "click", H), B && R(B, "click", Q), N && R(N, "click", j), R(d, "click", (x) => {
2635
+ x.target === d && H();
2636
+ }), R(document, "keydown", (x) => {
2637
+ const M = x;
2638
+ M.key === "Escape" && (M.preventDefault(), H());
2639
+ }), document.body.appendChild(d), requestAnimationFrame(() => {
2640
+ if (!(u || !d.isConnected))
2641
+ try {
2642
+ o = oe(C, {
2643
+ value: r,
2644
+ theme: "dark",
2645
+ readOnly: !1,
2646
+ extensions: [
2647
+ new G(),
2648
+ new _(),
2649
+ new ee(),
2650
+ new ie(),
2651
+ new se(),
2652
+ new ne(),
2653
+ new re()
2654
+ ]
2655
+ }), o.on("change", () => {
2656
+ const x = o?.getValue() || "";
2657
+ U(x !== r);
2658
+ }), requestAnimationFrame(() => o?.focus());
2659
+ } catch (x) {
2660
+ console.error("Failed to initialize code editor:", x);
2661
+ }
2148
2662
  });
2149
- const O = (p) => {
2150
- p.key === "Escape" && (b(), document.removeEventListener("keydown", O));
2151
- };
2152
- document.addEventListener("keydown", O);
2153
2663
  })(), !0;
2154
2664
  }
2155
2665
  },
@@ -2160,5 +2670,5 @@ const R = '[data-theme="dark"], .dark, .editora-theme-dark', j = `/* Source Edit
2160
2670
  }
2161
2671
  });
2162
2672
  export {
2163
- Z as CodePlugin
2673
+ ae as CodePlugin
2164
2674
  };