autumnnote 1.6.0 → 1.6.1

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 (47) hide show
  1. package/README.md +4 -4
  2. package/dist/autumnnote.css +0 -2
  3. package/dist/autumnnote.es.js +348 -342
  4. package/dist/autumnnote.es.js.map +1 -1
  5. package/dist/autumnnote.umd.js +341 -336
  6. package/dist/autumnnote.umd.js.map +1 -1
  7. package/package.json +21 -3
  8. package/src/js/Context.js +16 -14
  9. package/src/js/core/dom.js +9 -9
  10. package/src/js/core/env.js +1 -1
  11. package/src/js/core/func.js +1 -1
  12. package/src/js/core/lists.js +1 -1
  13. package/src/js/core/markdown.js +18 -18
  14. package/src/js/core/range.js +6 -6
  15. package/src/js/editing/History.js +4 -4
  16. package/src/js/editing/Style.js +32 -32
  17. package/src/js/editing/Table.js +2 -2
  18. package/src/js/editing/Typing.js +15 -15
  19. package/src/js/module/AutoSaveRestore.js +2 -4
  20. package/src/js/module/BubbleToolbar.js +25 -25
  21. package/src/js/module/Buttons.js +4 -4
  22. package/src/js/module/Clipboard.js +12 -13
  23. package/src/js/module/CodeTooltip.js +14 -16
  24. package/src/js/module/Codeview.js +3 -5
  25. package/src/js/module/ContextMenu.js +27 -27
  26. package/src/js/module/Editor.js +17 -18
  27. package/src/js/module/EmojiDialog.js +5 -5
  28. package/src/js/module/FindReplace.js +8 -7
  29. package/src/js/module/IconDialog.js +13 -15
  30. package/src/js/module/ImageCropOverlay.js +7 -7
  31. package/src/js/module/ImageDialog.js +1 -1
  32. package/src/js/module/ImageResizer.js +4 -4
  33. package/src/js/module/ImageTooltip.js +14 -14
  34. package/src/js/module/LinkDialog.js +2 -2
  35. package/src/js/module/LinkTooltip.js +12 -12
  36. package/src/js/module/MarkdownShortcuts.js +11 -14
  37. package/src/js/module/Mention.js +8 -10
  38. package/src/js/module/Placeholder.js +1 -1
  39. package/src/js/module/ShortcutsDialog.js +2 -4
  40. package/src/js/module/Statusbar.js +3 -5
  41. package/src/js/module/TableTooltip.js +30 -32
  42. package/src/js/module/Toolbar.js +21 -21
  43. package/src/js/module/VideoDialog.js +8 -8
  44. package/src/js/module/VideoResizer.js +5 -7
  45. package/src/js/module/VideoTooltip.js +7 -7
  46. package/src/js/renderer.js +1 -1
  47. package/src/styles/autumnnote.scss +0 -3
@@ -29,7 +29,7 @@ function debounce(fn, delay) {
29
29
  /**
30
30
  * Create a wrapper that limits how often `fn` can be invoked while ensuring the last call in a burst is executed.
31
31
  * @param {Function} fn - Function to be throttled.
32
- * @param {number} limit - Time window in milliseconds during which at most one call is allowed.
32
+ * @param {number} limit - Time globalThis in milliseconds during which at most one call is allowed.
33
33
  * @returns {Function} A wrapper function that invokes `fn` at most once per `limit` milliseconds; calls preserve `this` and original arguments and schedule a trailing invocation for the final call in a burst.
34
34
  */
35
35
  function throttle(fn, limit) {
@@ -252,7 +252,8 @@ function createElement(tag, attrs = {}, childNodes = []) {
252
252
  * @param {Node} node
253
253
  */
254
254
  function remove(node) {
255
- if (node && node.parentNode) node.parentNode.removeChild(node);
255
+ if (node && node.parentNode)
256
+ /** @type {ChildNode} */ node.remove();
256
257
  }
257
258
  /**
258
259
  * Unwraps a node — replaces the node with its children.
@@ -262,7 +263,7 @@ function unwrap(node) {
262
263
  const parent = node.parentNode;
263
264
  if (!parent) return;
264
265
  while (node.firstChild) parent.insertBefore(node.firstChild, node);
265
- parent.removeChild(node);
266
+ /** @type {ChildNode} */ node.remove();
266
267
  }
267
268
  /**
268
269
  * Wraps a node with a wrapper element.
@@ -321,7 +322,7 @@ function placeCaret(el) {
321
322
  const range = document.createRange();
322
323
  range.selectNodeContents(el);
323
324
  range.collapse(false);
324
- const sel = window.getSelection();
325
+ const sel = globalThis.getSelection();
325
326
  if (sel) {
326
327
  sel.removeAllRanges();
327
328
  sel.addRange(range);
@@ -364,14 +365,14 @@ function trapFocus(container, onEscape) {
364
365
  const handler = (e) => {
365
366
  if (e.key === "Escape") {
366
367
  e.stopPropagation();
367
- onEscape && onEscape();
368
+ onEscape?.();
368
369
  return;
369
370
  }
370
371
  if (e.key !== "Tab") return;
371
372
  const els = getFocusable();
372
373
  if (!els.length) return;
373
374
  const first = els[0];
374
- const last = els[els.length - 1];
375
+ const last = els.at(-1);
375
376
  if (e.shiftKey) {
376
377
  if (document.activeElement === first) {
377
378
  e.preventDefault();
@@ -409,14 +410,14 @@ function makeDraggable(handle, box) {
409
410
  box.style.top = `${r.top}px`;
410
411
  box.dataset.anDragPinned = "1";
411
412
  }
412
- const startX = e.clientX - parseFloat(box.style.left);
413
- const startY = e.clientY - parseFloat(box.style.top);
413
+ const startX = e.clientX - Number.parseFloat(box.style.left);
414
+ const startY = e.clientY - Number.parseFloat(box.style.top);
414
415
  handle.style.cursor = "grabbing";
415
416
  const onMove = (ev) => {
416
417
  const bw = box.offsetWidth;
417
418
  const bh = box.offsetHeight;
418
- box.style.left = `${Math.max(0, Math.min(ev.clientX - startX, window.innerWidth - bw))}px`;
419
- box.style.top = `${Math.max(0, Math.min(ev.clientY - startY, window.innerHeight - bh))}px`;
419
+ box.style.left = `${Math.max(0, Math.min(ev.clientX - startX, globalThis.innerWidth - bw))}px`;
420
+ box.style.top = `${Math.max(0, Math.min(ev.clientY - startY, globalThis.innerHeight - bh))}px`;
420
421
  };
421
422
  const onUp = () => {
422
423
  handle.style.cursor = "grab";
@@ -462,10 +463,10 @@ var WrappedRange = class {
462
463
  return range;
463
464
  }
464
465
  /**
465
- * Select this wrapped range in the window.
466
+ * Select this wrapped range in the globalThis.
466
467
  */
467
468
  select() {
468
- const sel = window.getSelection();
469
+ const sel = globalThis.getSelection();
469
470
  if (!sel) return;
470
471
  sel.removeAllRanges();
471
472
  sel.addRange(this.toNativeRange());
@@ -518,13 +519,13 @@ function fromNativeRange(range) {
518
519
  return new WrappedRange(range.startContainer, range.startOffset, range.endContainer, range.endOffset);
519
520
  }
520
521
  /**
521
- * Returns a WrappedRange for the current window selection,
522
+ * Returns a WrappedRange for the current globalThis selection,
522
523
  * optionally restricted to a given editable element.
523
524
  * @param {HTMLElement} [editable]
524
525
  * @returns {WrappedRange|null}
525
526
  */
526
527
  function currentRange(editable) {
527
- const sel = window.getSelection();
528
+ const sel = globalThis.getSelection();
528
529
  if (!sel || sel.rangeCount === 0) return null;
529
530
  const native = sel.getRangeAt(0);
530
531
  if (editable && !editable.contains(native.commonAncestorContainer)) return null;
@@ -553,7 +554,7 @@ function collapsedRange(node, offset = 0) {
553
554
  * @returns {boolean}
554
555
  */
555
556
  function isSelectionInside(el) {
556
- const sel = window.getSelection();
557
+ const sel = globalThis.getSelection();
557
558
  if (!sel || sel.rangeCount === 0) return false;
558
559
  return el.contains(sel.getRangeAt(0).commonAncestorContainer);
559
560
  }
@@ -562,7 +563,7 @@ function isSelectionInside(el) {
562
563
  * @param {Function} fn
563
564
  */
564
565
  function withSavedRange(fn) {
565
- const sel = window.getSelection();
566
+ const sel = globalThis.getSelection();
566
567
  if (!sel || sel.rangeCount === 0) {
567
568
  fn(null);
568
569
  return;
@@ -606,16 +607,16 @@ var italic = () => execCommand("italic");
606
607
  * execCommand's state detection is unreliable.
607
608
  */
608
609
  function underline() {
609
- const sel = window.getSelection();
610
+ const sel = globalThis.getSelection();
610
611
  if (!sel || !sel.rangeCount) return;
611
612
  let container = sel.getRangeAt(0).commonAncestorContainer;
612
613
  if (container.nodeType === 3) container = container.parentElement;
613
- const uEl = container && container.closest("u");
614
+ const uEl = container?.closest("u");
614
615
  const nativeState = document.queryCommandState("underline");
615
616
  if (uEl && !nativeState) {
616
617
  const parent = uEl.parentNode;
617
618
  while (uEl.firstChild) parent.insertBefore(uEl.firstChild, uEl);
618
- parent.removeChild(uEl);
619
+ uEl.remove();
619
620
  return;
620
621
  }
621
622
  execCommand("underline");
@@ -626,16 +627,16 @@ function underline() {
626
627
  * execCommand's state detection is unreliable (mirrors underline() logic).
627
628
  */
628
629
  function strikethrough() {
629
- const sel = window.getSelection();
630
+ const sel = globalThis.getSelection();
630
631
  if (!sel || !sel.rangeCount) return;
631
632
  let sc = sel.getRangeAt(0).startContainer;
632
633
  if (sc.nodeType === 3) sc = sc.parentElement;
633
- const sEl = sc && (sc.closest("s") || sc.closest("strike"));
634
+ const sEl = sc?.closest("s") || sc?.closest("strike");
634
635
  const nativeState = document.queryCommandState("strikeThrough");
635
636
  if (sEl && !nativeState) {
636
637
  const parent = sEl.parentNode;
637
638
  while (sEl.firstChild) parent.insertBefore(sEl.firstChild, sEl);
638
- parent.removeChild(sEl);
639
+ sEl.remove();
639
640
  return;
640
641
  }
641
642
  execCommand("strikeThrough");
@@ -670,7 +671,7 @@ var fontName = (name) => execCommand("fontName", name);
670
671
  * @param {HTMLElement|Document} [editable] - scoping element to avoid touching nodes outside this editor
671
672
  */
672
673
  function fontSize(size, editable = document) {
673
- const sel = window.getSelection();
674
+ const sel = globalThis.getSelection();
674
675
  const wasCollapsed = !sel || !sel.rangeCount || sel.getRangeAt(0).collapsed;
675
676
  if (wasCollapsed && sel && sel.rangeCount > 0) {
676
677
  try {
@@ -696,12 +697,12 @@ function fontSize(size, editable = document) {
696
697
  span.style.fontSize = size;
697
698
  el.parentNode.insertBefore(span, el);
698
699
  while (el.firstChild) span.appendChild(el.firstChild);
699
- el.parentNode.removeChild(el);
700
+ el.remove();
700
701
  newSpans.push(span);
701
702
  });
702
703
  if (!wasCollapsed && sel && newSpans.length > 0) {
703
704
  const first = newSpans[0];
704
- const last = newSpans[newSpans.length - 1];
705
+ const last = newSpans.at(-1);
705
706
  try {
706
707
  const nr = document.createRange();
707
708
  const startNode = first.firstChild || first;
@@ -745,11 +746,11 @@ var indent = () => execCommand("indent");
745
746
  * (which would destroy the ul > li checklist structure).
746
747
  */
747
748
  function outdent() {
748
- const sel = window.getSelection();
749
+ const sel = globalThis.getSelection();
749
750
  if (sel && sel.rangeCount) {
750
751
  let container = sel.getRangeAt(0).commonAncestorContainer;
751
752
  if (container.nodeType === 3) container = container.parentElement;
752
- const checkLi = container && container.closest(".an-checklist li");
753
+ const checkLi = container?.closest(".an-checklist li");
753
754
  if (checkLi) {
754
755
  _checklistItemToP(checkLi);
755
756
  return;
@@ -779,7 +780,7 @@ function _checklistItemToP(checkLi) {
779
780
  if (child.nodeType === 1 && child.tagName === "INPUT") continue;
780
781
  p.appendChild(child.cloneNode(true));
781
782
  }
782
- p.innerHTML = p.innerHTML.replace(/\u200B/g, "");
783
+ p.innerHTML = p.innerHTML.replaceAll("​", "");
783
784
  if (!p.hasChildNodes() || !p.textContent.trim()) {
784
785
  p.innerHTML = "";
785
786
  p.appendChild(document.createTextNode("\xA0"));
@@ -791,14 +792,14 @@ function _checklistItemToP(checkLi) {
791
792
  checkUl.parentNode.insertBefore(newUl, checkUl.nextSibling);
792
793
  }
793
794
  checkUl.parentNode.insertBefore(p, checkUl.nextSibling);
794
- checkUl.removeChild(checkLi);
795
- if (checkUl.children.length === 0) checkUl.parentNode.removeChild(checkUl);
795
+ checkLi.remove();
796
+ if (checkUl.children.length === 0) checkUl.remove();
796
797
  try {
797
798
  const nr = document.createRange();
798
799
  const firstChild = p.firstChild;
799
800
  nr.setStart(firstChild && firstChild.nodeType === 3 ? firstChild : p, 0);
800
801
  nr.collapse(true);
801
- const s = window.getSelection();
802
+ const s = globalThis.getSelection();
802
803
  if (s) {
803
804
  s.removeAllRanges();
804
805
  s.addRange(nr);
@@ -822,7 +823,7 @@ var insertOrderedList = () => execCommand("insertOrderedList");
822
823
  * @param {string} value - Line-height value to apply; typically a unitless multiplier (for example, "1.5").
823
824
  */
824
825
  function lineHeight(value) {
825
- const sel = window.getSelection();
826
+ const sel = globalThis.getSelection();
826
827
  if (!sel || sel.rangeCount === 0) return;
827
828
  const range = sel.getRangeAt(0);
828
829
  const BLOCK_TAGS = new Set([
@@ -874,22 +875,22 @@ function lineHeight(value) {
874
875
  * @param {HTMLElement} [_editable]
875
876
  */
876
877
  function toggleInlineCode(_editable) {
877
- const sel = window.getSelection();
878
+ const sel = globalThis.getSelection();
878
879
  if (!sel || !sel.rangeCount) return;
879
880
  const range = sel.getRangeAt(0);
880
881
  let container = range.commonAncestorContainer;
881
882
  if (container.nodeType === 3) container = container.parentElement;
882
- const codeEl = container && container.closest("code");
883
+ const codeEl = container?.closest("code");
883
884
  if (codeEl && !codeEl.closest("pre")) {
884
885
  const parent = codeEl.parentNode;
885
886
  const prevSibling = codeEl.previousSibling;
886
887
  const movedChildren = Array.from(codeEl.childNodes);
887
888
  while (codeEl.firstChild) parent.insertBefore(codeEl.firstChild, codeEl);
888
- parent.removeChild(codeEl);
889
- if (parent && parent.normalize) parent.normalize();
889
+ codeEl.remove();
890
+ parent?.normalize();
890
891
  if (movedChildren.length > 0) try {
891
892
  const firstMoved = movedChildren[0];
892
- const lastMoved = movedChildren[movedChildren.length - 1];
893
+ const lastMoved = movedChildren.at(-1);
893
894
  const nr = document.createRange();
894
895
  const anchorNode = firstMoved.parentNode === parent ? firstMoved : prevSibling ? prevSibling.nextSibling : parent.firstChild;
895
896
  if (anchorNode) {
@@ -930,11 +931,11 @@ function toggleInlineCode(_editable) {
930
931
  * @returns {boolean}
931
932
  */
932
933
  function isInlineCode() {
933
- const sel = window.getSelection();
934
+ const sel = globalThis.getSelection();
934
935
  if (!sel || !sel.rangeCount) return false;
935
936
  let sc = sel.getRangeAt(0).startContainer;
936
937
  if (sc.nodeType === 3) sc = sc.parentElement;
937
- const code = sc && sc.closest("code");
938
+ const code = sc?.closest("code");
938
939
  return !!(code && !code.closest("pre"));
939
940
  }
940
941
  /**
@@ -952,12 +953,12 @@ function isInlineCode() {
952
953
  * Empty or whitespace-only selections do not create a checklist.
953
954
  */
954
955
  function toggleChecklist() {
955
- const sel = window.getSelection();
956
+ const sel = globalThis.getSelection();
956
957
  if (!sel || !sel.rangeCount) return;
957
958
  const range = sel.getRangeAt(0);
958
959
  let container = range.commonAncestorContainer;
959
960
  if (container.nodeType === 3) container = container.parentElement;
960
- const ul = container && container.closest(".an-checklist");
961
+ const ul = container?.closest(".an-checklist");
961
962
  if (ul) {
962
963
  const selectedLis = Array.from(ul.querySelectorAll("li")).filter((li) => sel.containsNode(li, true));
963
964
  if (selectedLis.length > 0) {
@@ -968,14 +969,14 @@ function toggleChecklist() {
968
969
  if (child.nodeType === 1 && child.tagName === "INPUT") continue;
969
970
  p.appendChild(child.cloneNode(true));
970
971
  }
971
- p.innerHTML = p.innerHTML.replace(/\u200b/g, "");
972
+ p.innerHTML = p.innerHTML.replaceAll("​", "");
972
973
  if (!p.hasChildNodes() || !p.textContent.trim()) {
973
974
  p.innerHTML = "";
974
975
  p.appendChild(document.createTextNode("\xA0"));
975
976
  }
976
977
  ul.parentNode.insertBefore(p, ul);
977
978
  if (!firstP) firstP = p;
978
- ul.removeChild(li);
979
+ li.remove();
979
980
  });
980
981
  if (ul.children.length === 0) ul.remove();
981
982
  if (firstP) {
@@ -1003,7 +1004,7 @@ function toggleChecklist() {
1003
1004
  ]);
1004
1005
  let block = container;
1005
1006
  while (block && block.parentNode && !BLOCK_TAGS.has(block.tagName)) block = block.parentNode;
1006
- const itemText = block && BLOCK_TAGS.has(block.tagName) ? Array.from(block.childNodes).map((n) => n.textContent).join("").replace(/\u00a0/g, " ") : "";
1007
+ const itemText = block && BLOCK_TAGS.has(block.tagName) ? Array.from(block.childNodes).map((n) => n.textContent).join("").replaceAll("\xA0", " ") : "";
1007
1008
  const ul = document.createElement("ul");
1008
1009
  ul.className = "an-checklist";
1009
1010
  const li = document.createElement("li");
@@ -1074,7 +1075,7 @@ function toggleChecklist() {
1074
1075
  });
1075
1076
  const firstBlock = blocks[0];
1076
1077
  firstBlock.parentNode.insertBefore(newUl, firstBlock);
1077
- blocks.forEach((block) => block.parentNode && block.parentNode.removeChild(block));
1078
+ blocks.forEach((block) => block.remove());
1078
1079
  if (lastTextNode) {
1079
1080
  const nr = document.createRange();
1080
1081
  nr.setStart(lastTextNode, lastTextNode.textContent.length);
@@ -1088,11 +1089,11 @@ function toggleChecklist() {
1088
1089
  * @returns {boolean}
1089
1090
  */
1090
1091
  function isInChecklist() {
1091
- const sel = window.getSelection();
1092
+ const sel = globalThis.getSelection();
1092
1093
  if (!sel || !sel.rangeCount) return false;
1093
1094
  let container = sel.getRangeAt(0).commonAncestorContainer;
1094
1095
  if (container.nodeType === 3) container = container.parentElement;
1095
- return !!(container && container.closest(".an-checklist li"));
1096
+ return !!container?.closest(".an-checklist li");
1096
1097
  }
1097
1098
  //#endregion
1098
1099
  //#region src/js/module/Buttons.js
@@ -1174,7 +1175,7 @@ var boldBtn = btn("bold", "bold", "Bold (Ctrl+B)", () => bold(), () => document.
1174
1175
  var italicBtn = btn("italic", "italic", "Italic (Ctrl+I)", () => italic(), () => document.queryCommandState("italic"));
1175
1176
  var underlineBtn = btn("underline", "underline", "Underline (Ctrl+U)", () => underline(), () => {
1176
1177
  if (document.queryCommandState("underline")) return true;
1177
- const sel = window.getSelection();
1178
+ const sel = globalThis.getSelection();
1178
1179
  if (!sel || !sel.rangeCount) return false;
1179
1180
  let sc = sel.getRangeAt(0).startContainer;
1180
1181
  if (sc.nodeType === 3) sc = sc.parentElement;
@@ -1237,7 +1238,7 @@ var fontSizeBtn = {
1237
1238
  action: (ctx, value) => fontSize(value, ctx.layoutInfo.editable),
1238
1239
  getValue: (ctx) => {
1239
1240
  try {
1240
- const sel = window.getSelection();
1241
+ const sel = globalThis.getSelection();
1241
1242
  if (sel && sel.rangeCount) {
1242
1243
  let el = sel.getRangeAt(0).startContainer;
1243
1244
  if (el && el.nodeType === 3) el = el.parentElement;
@@ -1245,7 +1246,7 @@ var fontSizeBtn = {
1245
1246
  const size = el && el.style.fontSize ? el.style.fontSize : "";
1246
1247
  if (size) return size;
1247
1248
  }
1248
- const editable = ctx && ctx.layoutInfo && ctx.layoutInfo.editable;
1249
+ const editable = ctx?.layoutInfo?.editable;
1249
1250
  if (editable) return editable.style.fontSize || "";
1250
1251
  return "";
1251
1252
  } catch {
@@ -1349,7 +1350,7 @@ var lineHeightBtn = {
1349
1350
  action: (_ctx, value) => lineHeight(value),
1350
1351
  getValue: () => {
1351
1352
  try {
1352
- const sel = window.getSelection();
1353
+ const sel = globalThis.getSelection();
1353
1354
  if (!sel || !sel.rangeCount) return "";
1354
1355
  const BLOCKS = new Set([
1355
1356
  "P",
@@ -4474,7 +4475,7 @@ function renderLayout(targetEl, options) {
4474
4475
  } catch (_) {}
4475
4476
  if (!initialContent) initialContent = targetEl.tagName === "TEXTAREA" ? (targetEl.value || "").trim() : (targetEl.innerHTML || "").trim();
4476
4477
  editable.innerHTML = sanitiseHTML(initialContent, { allowIframes: true });
4477
- const defaultFont = options.defaultFontFamily || options.fontFamilies && options.fontFamilies[0];
4478
+ const defaultFont = options.defaultFontFamily || options.fontFamilies?.[0];
4478
4479
  if (defaultFont) editable.style.fontFamily = defaultFont;
4479
4480
  if (options.defaultFontSize) editable.style.fontSize = options.defaultFontSize;
4480
4481
  if (options.height) editable.style.minHeight = `${options.height}px`;
@@ -4536,7 +4537,7 @@ var History = class {
4536
4537
  * @returns {{ start: number, end: number }|null}
4537
4538
  */
4538
4539
  _serializeSelection() {
4539
- const sel = window.getSelection();
4540
+ const sel = globalThis.getSelection();
4540
4541
  if (!sel || sel.rangeCount === 0) return null;
4541
4542
  const range = sel.getRangeAt(0);
4542
4543
  if (!this.editable.contains(range.startContainer)) return null;
@@ -4602,7 +4603,7 @@ var History = class {
4602
4603
  const range = document.createRange();
4603
4604
  range.setStart(startNode, startOff);
4604
4605
  range.setEnd(endNode, endOff);
4605
- const sel = window.getSelection();
4606
+ const sel = globalThis.getSelection();
4606
4607
  sel.removeAllRanges();
4607
4608
  sel.addRange(range);
4608
4609
  } catch (_) {
@@ -4610,7 +4611,7 @@ var History = class {
4610
4611
  const fb = document.createRange();
4611
4612
  fb.setStart(this.editable, 0);
4612
4613
  fb.collapse(true);
4613
- const s = window.getSelection();
4614
+ const s = globalThis.getSelection();
4614
4615
  if (s) {
4615
4616
  s.removeAllRanges();
4616
4617
  s.addRange(fb);
@@ -4674,8 +4675,7 @@ var History = class {
4674
4675
  recordUndo() {
4675
4676
  const current = this._serialize();
4676
4677
  const { html: tokenized } = this._tokenizeImages(current);
4677
- const prev = this.stack[this.stackOffset];
4678
- if (prev && prev.html === tokenized) return;
4678
+ if (this.stack[this.stackOffset]?.html === tokenized) return;
4679
4679
  this._savePoint();
4680
4680
  }
4681
4681
  /**
@@ -4759,7 +4759,7 @@ function createTable(cols, rows, opts = {}) {
4759
4759
  function insertTable(cols, rows, opts = {}) {
4760
4760
  if (cols <= 0 || rows <= 0) return;
4761
4761
  const table = createTable(cols, rows, opts);
4762
- const sel = window.getSelection();
4762
+ const sel = globalThis.getSelection();
4763
4763
  if (!sel || sel.rangeCount === 0) return;
4764
4764
  const range = sel.getRangeAt(0);
4765
4765
  range.deleteContents();
@@ -4777,7 +4777,7 @@ function insertTable(cols, rows, opts = {}) {
4777
4777
  "PRE"
4778
4778
  ]);
4779
4779
  let anchor = range.startContainer;
4780
- if (anchor && anchor.nodeType === 3) anchor = anchor.parentElement;
4780
+ if (anchor?.nodeType === 3) anchor = anchor.parentElement;
4781
4781
  while (anchor && !BLOCK.has(anchor.tagName?.toUpperCase()) && anchor.parentElement) anchor = anchor.parentElement;
4782
4782
  if (anchor && BLOCK.has(anchor.tagName?.toUpperCase()) && anchor.parentNode) {
4783
4783
  anchor.after(table);
@@ -4867,8 +4867,8 @@ function isModifier(event, keyName) {
4867
4867
  * Inspired by Summernote's Typing module
4868
4868
  */
4869
4869
  var _FA_PATTERN = /\bfa-/;
4870
- var isFAIcon = (n) => !!(n && n.nodeName === "I" && _FA_PATTERN.test(n.className || ""));
4871
- var isZwsAnchor = (n) => !!(n && n.nodeType === Node.TEXT_NODE && (n.textContent === "​" || n.textContent === ""));
4870
+ var isFAIcon = (n) => !!(n?.nodeName === "I" && _FA_PATTERN.test(n.className || ""));
4871
+ var isZwsAnchor = (n) => !!(n?.nodeType === Node.TEXT_NODE && (n.textContent === "​" || n.textContent === ""));
4872
4872
  /**
4873
4873
  * Handles special keydown behaviour inside the editor.
4874
4874
  * @param {KeyboardEvent} event
@@ -4878,7 +4878,7 @@ var isZwsAnchor = (n) => !!(n && n.nodeType === Node.TEXT_NODE && (n.textContent
4878
4878
  */
4879
4879
  function handleKeydown(event, editable, options = {}) {
4880
4880
  const moveCaret = (setFn) => {
4881
- const sel = window.getSelection();
4881
+ const sel = globalThis.getSelection();
4882
4882
  if (!sel) return false;
4883
4883
  const nr = document.createRange();
4884
4884
  setFn(nr);
@@ -4888,8 +4888,8 @@ function handleKeydown(event, editable, options = {}) {
4888
4888
  return true;
4889
4889
  };
4890
4890
  if (isKey(event, key.BACKSPACE)) {
4891
- const sel = window.getSelection();
4892
- if (sel && sel.rangeCount > 0) {
4891
+ const sel = globalThis.getSelection();
4892
+ if (sel?.rangeCount > 0) {
4893
4893
  const r = sel.getRangeAt(0);
4894
4894
  if (r.collapsed && r.startContainer.nodeType === Node.TEXT_NODE) {
4895
4895
  const textNode = r.startContainer;
@@ -4919,7 +4919,7 @@ function handleKeydown(event, editable, options = {}) {
4919
4919
  return false;
4920
4920
  }
4921
4921
  if (isKey(event, key.LEFT) || isKey(event, key.RIGHT)) {
4922
- const sel = window.getSelection();
4922
+ const sel = globalThis.getSelection();
4923
4923
  if (!sel || sel.rangeCount === 0) return false;
4924
4924
  const r = sel.getRangeAt(0);
4925
4925
  if (!r.collapsed) return false;
@@ -5007,7 +5007,7 @@ function handleKeydown(event, editable, options = {}) {
5007
5007
  else execCommand("indent");
5008
5008
  return true;
5009
5009
  }
5010
- if (para && para.nodeName.toUpperCase() === "PRE") {
5010
+ if (para?.nodeName.toUpperCase() === "PRE") {
5011
5011
  if (event.shiftKey) return false;
5012
5012
  event.preventDefault();
5013
5013
  execCommand("insertText", " ".repeat(options.tabSize || 4));
@@ -5030,18 +5030,18 @@ function handleKeydown(event, editable, options = {}) {
5030
5030
  if (!range) return false;
5031
5031
  const sc = range.sc;
5032
5032
  const el = sc.nodeType === 3 ? sc.parentElement : sc;
5033
- if (el && el.nodeName === "I" && /\bfa-/.test(el.className || "")) {
5033
+ if (el?.nodeName === "I" && /\bfa-/.test(el.className || "")) {
5034
5034
  const nr = document.createRange();
5035
5035
  nr.setStartAfter(el);
5036
5036
  nr.collapse(true);
5037
- const selI = window.getSelection();
5037
+ const selI = globalThis.getSelection();
5038
5038
  if (selI) {
5039
5039
  selI.removeAllRanges();
5040
5040
  selI.addRange(nr);
5041
5041
  }
5042
5042
  return false;
5043
5043
  }
5044
- const videoWrapper = el && el.closest(".an-video-wrapper");
5044
+ const videoWrapper = el?.closest(".an-video-wrapper");
5045
5045
  if (videoWrapper) {
5046
5046
  event.preventDefault();
5047
5047
  const p = document.createElement("p");
@@ -5050,16 +5050,16 @@ function handleKeydown(event, editable, options = {}) {
5050
5050
  const nr = document.createRange();
5051
5051
  nr.setStart(p, 0);
5052
5052
  nr.collapse(true);
5053
- const sel = window.getSelection();
5053
+ const sel = globalThis.getSelection();
5054
5054
  sel.removeAllRanges();
5055
5055
  sel.addRange(nr);
5056
5056
  return true;
5057
5057
  }
5058
- const checkLi = el && el.closest(".an-checklist li");
5058
+ const checkLi = el?.closest(".an-checklist li");
5059
5059
  if (checkLi) {
5060
5060
  event.preventDefault();
5061
5061
  const ul = checkLi.closest(".an-checklist");
5062
- const sel = window.getSelection();
5062
+ const sel = globalThis.getSelection();
5063
5063
  let nativeRange = sel.getRangeAt(0);
5064
5064
  const liText = (li) => Array.from(li.childNodes).filter((n) => !(n.nodeType === 1 && n.tagName === "INPUT")).map((n) => n.textContent).join("").replace(/[\u00a0\u200B]/g, " ").trim();
5065
5065
  if (!liText(checkLi)) {
@@ -5103,12 +5103,12 @@ function handleKeydown(event, editable, options = {}) {
5103
5103
  return true;
5104
5104
  }
5105
5105
  const para = closestPara(range.sc, editable);
5106
- if (para && para.nodeName.toUpperCase() === "PRE") {
5106
+ if (para?.nodeName.toUpperCase() === "PRE") {
5107
5107
  event.preventDefault();
5108
5108
  execCommand("insertText", "\n");
5109
5109
  return true;
5110
5110
  }
5111
- if (para && para.nodeName.toUpperCase() === "BLOCKQUOTE") {
5111
+ if (para?.nodeName.toUpperCase() === "BLOCKQUOTE") {
5112
5112
  const native = range.toNativeRange();
5113
5113
  native.setEnd(para, para.childNodes.length);
5114
5114
  if (native.toString() === "" && range.isCollapsed()) {
@@ -5182,7 +5182,7 @@ function _domToMd(node, depth = 0) {
5182
5182
  return `\`${inner()}\``;
5183
5183
  case "pre": {
5184
5184
  const codeEl = el.querySelector("code");
5185
- const langMatch = (codeEl && codeEl.className || "").match(/language-(\S+)/);
5185
+ const langMatch = /language-(\S+)/.exec(codeEl && codeEl.className || "");
5186
5186
  return `\n\n\`\`\`${langMatch ? langMatch[1] : ""}\n${(codeEl || el).textContent || ""}\n\`\`\`\n\n`;
5187
5187
  }
5188
5188
  case "blockquote": return `\n\n${inner().trim().split("\n").map((l) => `> ${l}`).join("\n")}\n\n`;
@@ -5213,7 +5213,7 @@ function _domToMd(node, depth = 0) {
5213
5213
  case "table": {
5214
5214
  const rows = Array.from(el.querySelectorAll("tr"));
5215
5215
  if (!rows.length) return inner();
5216
- const cellTexts = rows.map((tr) => Array.from(tr.querySelectorAll("th, td")).map((c) => c.textContent.trim().replace(/\|/g, "\\|")));
5216
+ const cellTexts = rows.map((tr) => Array.from(tr.querySelectorAll("th, td")).map((c) => c.textContent.trim().replaceAll("|", "\\|")));
5217
5217
  const cols = Math.max(...cellTexts.map((r) => r.length));
5218
5218
  const padRow = (row) => {
5219
5219
  const r = [...row];
@@ -5222,7 +5222,7 @@ function _domToMd(node, depth = 0) {
5222
5222
  };
5223
5223
  let md = "\n\n";
5224
5224
  md += `| ${padRow(cellTexts[0]).join(" | ")} |\n`;
5225
- md += `| ${Array(cols).fill("---").join(" | ")} |\n`;
5225
+ md += `| ${new Array(cols).fill("---").join(" | ")} |\n`;
5226
5226
  for (let r = 1; r < cellTexts.length; r++) md += `| ${padRow(cellTexts[r]).join(" | ")} |\n`;
5227
5227
  return md + "\n";
5228
5228
  }
@@ -5246,12 +5246,12 @@ function isMarkdown(text) {
5246
5246
  * @returns {string}
5247
5247
  */
5248
5248
  function markdownToHTML(text) {
5249
- const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n");
5249
+ const lines = text.replaceAll("\r\n", "\n").replaceAll("\r", "\n").split("\n");
5250
5250
  const out = [];
5251
5251
  let i = 0;
5252
5252
  while (i < lines.length) {
5253
5253
  const line = lines[i];
5254
- const fenceMatch = line.match(/^```(\S*)$/);
5254
+ const fenceMatch = /^```(\S*)$/.exec(line);
5255
5255
  if (fenceMatch) {
5256
5256
  const lang = fenceMatch[1];
5257
5257
  const codeLines = [];
@@ -5270,7 +5270,7 @@ function markdownToHTML(text) {
5270
5270
  i++;
5271
5271
  continue;
5272
5272
  }
5273
- const hMatch = line.match(/^(#{1,6})\s+(.+)$/);
5273
+ const hMatch = /^(#{1,6})\s+(.+)$/.exec(line);
5274
5274
  if (hMatch) {
5275
5275
  const level = hMatch[1].length;
5276
5276
  out.push(`<h${level}>${_inline(hMatch[2])}</h${level}>`);
@@ -5317,7 +5317,8 @@ function markdownToHTML(text) {
5317
5317
  i++;
5318
5318
  }
5319
5319
  const thead = `<thead><tr>${headerCells.map((c) => `<th>${_inline(c)}</th>`).join("")}</tr></thead>`;
5320
- const tbody = bodyRows.length ? `<tbody>${bodyRows.map((row) => `<tr>${row.map((c) => `<td>${_inline(c)}</td>`).join("")}</tr>`).join("")}</tbody>` : "";
5320
+ const renderRow = (row) => `<tr>${row.map((c) => `<td>${_inline(c)}</td>`).join("")}</tr>`;
5321
+ const tbody = bodyRows.length ? `<tbody>${bodyRows.map(renderRow).join("")}</tbody>` : "";
5321
5322
  out.push(`<table>${thead}${tbody}</table>`);
5322
5323
  continue;
5323
5324
  }
@@ -5353,10 +5354,10 @@ function _inline(text) {
5353
5354
  return text;
5354
5355
  }
5355
5356
  function _esc(v) {
5356
- return String(v).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
5357
+ return String(v).replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
5357
5358
  }
5358
5359
  function _escAttr(v) {
5359
- return String(v).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
5360
+ return String(v).replaceAll("&", "&amp;").replaceAll("\"", "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
5360
5361
  }
5361
5362
  //#endregion
5362
5363
  //#region src/js/core/detectLang.js
@@ -5438,7 +5439,7 @@ var Editor = class {
5438
5439
  const onBeforeInput = (event) => this._enforceLimit(event);
5439
5440
  const onSelChange = () => {
5440
5441
  if (!this.context._alive) return;
5441
- const sel = window.getSelection();
5442
+ const sel = globalThis.getSelection();
5442
5443
  if (sel && sel.rangeCount > 0 && editable.contains(sel.anchorNode)) {
5443
5444
  this.context.invoke("toolbar.refresh");
5444
5445
  if (typeof this.options.onSelectionChange === "function") this.options.onSelectionChange(this.context);
@@ -5448,7 +5449,7 @@ var Editor = class {
5448
5449
  if (e.target.type === "checkbox" && e.target.closest(".an-checklist")) this.afterCommand();
5449
5450
  };
5450
5451
  const fixChecklistCursor = (event) => {
5451
- const sel = window.getSelection();
5452
+ const sel = globalThis.getSelection();
5452
5453
  if (!sel || !sel.rangeCount) return;
5453
5454
  const r = sel.getRangeAt(0);
5454
5455
  if (!r.collapsed) return;
@@ -5502,7 +5503,7 @@ var Editor = class {
5502
5503
  /** @type {string|null} 'superscript' | 'subscript' | null */
5503
5504
  let _compositionSupSub = null;
5504
5505
  const onCompositionStart = () => {
5505
- const sel = window.getSelection();
5506
+ const sel = globalThis.getSelection();
5506
5507
  if (!sel || !sel.rangeCount) {
5507
5508
  _compositionSupSub = null;
5508
5509
  return;
@@ -5520,12 +5521,12 @@ var Editor = class {
5520
5521
  const tag = _compositionSupSub;
5521
5522
  _compositionSupSub = null;
5522
5523
  if (!tag) return;
5523
- const sel = window.getSelection();
5524
+ const sel = globalThis.getSelection();
5524
5525
  if (!sel || !sel.rangeCount) return;
5525
5526
  let node = sel.getRangeAt(0).startContainer;
5526
5527
  if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
5527
5528
  const el = node;
5528
- if (!(el && (tag === "superscript" ? el.closest("sup") : el.closest("sub")))) document.execCommand(tag);
5529
+ if (!(tag === "superscript" ? el?.closest("sup") : el?.closest("sub"))) document.execCommand(tag);
5529
5530
  };
5530
5531
  this._disposers.push(on(editable, "compositionstart", onCompositionStart), on(editable, "compositionend", onCompositionEnd));
5531
5532
  }
@@ -5599,7 +5600,7 @@ var Editor = class {
5599
5600
  if (type === "insertFromPaste" || type === "insertFromDrop") return;
5600
5601
  if (!type.startsWith("insert")) return;
5601
5602
  const text = this.context.layoutInfo.editable.innerText || "";
5602
- const chars = text.replace(/\n/g, "").length;
5603
+ const chars = text.replaceAll("\n", "").length;
5603
5604
  if (maxChars && chars >= maxChars) {
5604
5605
  event.preventDefault();
5605
5606
  if (typeof this.options.onCharLimitReached === "function") this.options.onCharLimitReached(this.context);
@@ -5638,7 +5639,7 @@ var Editor = class {
5638
5639
  */
5639
5640
  _cleanOrphanedFigures() {
5640
5641
  this.context.layoutInfo.editable.querySelectorAll("figure.an-figure").forEach((fig) => {
5641
- if (!fig.querySelector("img")) fig.parentNode.removeChild(fig);
5642
+ if (!fig.querySelector("img")) fig.remove();
5642
5643
  });
5643
5644
  }
5644
5645
  /**
@@ -5674,7 +5675,7 @@ var Editor = class {
5674
5675
  * @returns {string}
5675
5676
  */
5676
5677
  getHTML() {
5677
- const raw = this.context.layoutInfo.editable.innerHTML.replace(/\u200B/g, "");
5678
+ const raw = this.context.layoutInfo.editable.innerHTML.replaceAll("​", "");
5678
5679
  return this.context.invoke("clipboard.resolveImages", raw) ?? raw;
5679
5680
  }
5680
5681
  /**
@@ -5719,7 +5720,7 @@ var Editor = class {
5719
5720
  * @returns {boolean}
5720
5721
  */
5721
5722
  isEmpty() {
5722
- const text = (this.context.layoutInfo.editable.innerText || "").trim().replace(/\u00a0/g, "");
5723
+ const text = (this.context.layoutInfo.editable.innerText || "").trim().replaceAll("\xA0", "");
5723
5724
  const hasMedia = !!this.context.layoutInfo.editable.querySelector("img, video, iframe, table");
5724
5725
  return !text && !hasMedia;
5725
5726
  }
@@ -5854,11 +5855,11 @@ var Editor = class {
5854
5855
  formatBlock(tagName) {
5855
5856
  formatBlock(tagName);
5856
5857
  if (tagName === "pre") {
5857
- const sel = window.getSelection();
5858
+ const sel = globalThis.getSelection();
5858
5859
  if (sel && sel.rangeCount > 0) {
5859
5860
  const container = sel.getRangeAt(0).commonAncestorContainer;
5860
5861
  const pre = container.nodeType === 1 ? container.closest("pre") : container.parentElement?.closest("pre");
5861
- if (pre && !pre.getAttribute("data-language")) {
5862
+ if (pre && !pre.dataset.language) {
5862
5863
  const lang = detectLang(pre.textContent || "");
5863
5864
  if (lang) {
5864
5865
  this.context.invoke("codeTooltip.applyLanguage", pre, lang);
@@ -5911,7 +5912,7 @@ var Editor = class {
5911
5912
  * @param {boolean} [openInNewTab=false]
5912
5913
  */
5913
5914
  insertLink(url, text, openInNewTab = false) {
5914
- const sel = window.getSelection();
5915
+ const sel = globalThis.getSelection();
5915
5916
  if (!sel || sel.rangeCount === 0) return;
5916
5917
  const safeUrl = sanitiseUrl(url);
5917
5918
  if (!safeUrl) return;
@@ -5974,7 +5975,7 @@ var Editor = class {
5974
5975
  this.afterCommand();
5975
5976
  }
5976
5977
  _getClosestAnchor() {
5977
- const sel = window.getSelection();
5978
+ const sel = globalThis.getSelection();
5978
5979
  if (!sel || sel.rangeCount === 0) return null;
5979
5980
  let node = sel.getRangeAt(0).startContainer;
5980
5981
  while (node) {
@@ -5989,7 +5990,7 @@ var Editor = class {
5989
5990
  * @returns {string}
5990
5991
  */
5991
5992
  _escapeAttr(str) {
5992
- return String(str ?? "").replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
5993
+ return String(str ?? "").replaceAll("&", "&amp;").replaceAll("\"", "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
5993
5994
  }
5994
5995
  };
5995
5996
  //#endregion
@@ -6104,7 +6105,7 @@ var Toolbar = class {
6104
6105
  this._refreshRaf = null;
6105
6106
  this._disposers.forEach((d) => d());
6106
6107
  this._disposers = [];
6107
- if (this.el && this.el.parentNode) this.el.parentNode.removeChild(this.el);
6108
+ if (this.el && this.el.parentNode) this.el.remove();
6108
6109
  this.el = null;
6109
6110
  }
6110
6111
  _buildButtons() {
@@ -6172,8 +6173,8 @@ var Toolbar = class {
6172
6173
  let isOpen = false;
6173
6174
  const setHighlight = (rows, cols) => {
6174
6175
  cells.forEach((cell) => {
6175
- const r = +cell.getAttribute("data-row");
6176
- const c = +cell.getAttribute("data-col");
6176
+ const r = +cell.dataset.row;
6177
+ const c = +cell.dataset.col;
6177
6178
  cell.classList.toggle("active", r <= rows && c <= cols);
6178
6179
  });
6179
6180
  label.textContent = rows && cols ? `${rows} × ${cols}` : this.context.locale.toolbar.insertTableLabel || "Insert Table";
@@ -6187,8 +6188,8 @@ var Toolbar = class {
6187
6188
  const ph = popup.offsetHeight;
6188
6189
  let left = rect.left;
6189
6190
  let top = rect.bottom + 4;
6190
- if (left + pw > window.innerWidth - 8) left = Math.max(8, window.innerWidth - pw - 8);
6191
- if (top + ph > window.innerHeight - 8) top = rect.top - ph - 4;
6191
+ if (left + pw > globalThis.innerWidth - 8) left = Math.max(8, globalThis.innerWidth - pw - 8);
6192
+ if (top + ph > globalThis.innerHeight - 8) top = rect.top - ph - 4;
6192
6193
  popup.style.left = `${left}px`;
6193
6194
  popup.style.top = `${top}px`;
6194
6195
  popup.style.visibility = "";
@@ -6208,14 +6209,14 @@ var Toolbar = class {
6208
6209
  const d2 = on(grid, "mouseover", (e) => {
6209
6210
  const cell = e.target?.closest(".an-table-cell");
6210
6211
  if (!cell) return;
6211
- setHighlight(+cell.getAttribute("data-row"), +cell.getAttribute("data-col"));
6212
+ setHighlight(+cell.dataset.row, +cell.dataset.col);
6212
6213
  });
6213
6214
  const d3 = on(grid, "mouseleave", () => setHighlight(0, 0));
6214
6215
  const d4 = on(grid, "click", (e) => {
6215
6216
  const cell = e.target?.closest(".an-table-cell");
6216
6217
  if (!cell) return;
6217
- const rows = +cell.getAttribute("data-row");
6218
- const cols = +cell.getAttribute("data-col");
6218
+ const rows = +cell.dataset.row;
6219
+ const cols = +cell.dataset.col;
6219
6220
  closePopup();
6220
6221
  this.context.invoke("editor.focus");
6221
6222
  def.action(this.context, rows, cols);
@@ -6224,7 +6225,7 @@ var Toolbar = class {
6224
6225
  if (isOpen) closePopup();
6225
6226
  });
6226
6227
  this._disposers.push(d1, d2, d3, d4, d5, () => {
6227
- if (popup.parentNode) popup.parentNode.removeChild(popup);
6228
+ if (popup.parentNode) popup.remove();
6228
6229
  });
6229
6230
  wrap.appendChild(btn);
6230
6231
  document.body.appendChild(popup);
@@ -6314,13 +6315,13 @@ var Toolbar = class {
6314
6315
  /** @type {Range|null} saved selection range before popup opens */
6315
6316
  let savedRange = null;
6316
6317
  const saveSelection = () => {
6317
- const sel = window.getSelection();
6318
+ const sel = globalThis.getSelection();
6318
6319
  savedRange = sel && sel.rangeCount ? sel.getRangeAt(0).cloneRange() : null;
6319
6320
  };
6320
6321
  const restoreSelection = () => {
6321
6322
  if (!savedRange) return;
6322
6323
  try {
6323
- const sel = window.getSelection();
6324
+ const sel = globalThis.getSelection();
6324
6325
  if (!sel) return;
6325
6326
  sel.removeAllRanges();
6326
6327
  sel.addRange(savedRange);
@@ -6335,7 +6336,7 @@ var Toolbar = class {
6335
6336
  const rect = arrowBtn.getBoundingClientRect();
6336
6337
  const popupMinW = 184;
6337
6338
  let left = rect.left;
6338
- if (left + popupMinW > window.innerWidth) left = rect.right - popupMinW;
6339
+ if (left + popupMinW > globalThis.innerWidth) left = rect.right - popupMinW;
6339
6340
  popup.style.top = `${rect.bottom + 4}px`;
6340
6341
  popup.style.left = `${Math.max(4, left)}px`;
6341
6342
  popup.style.display = "block";
@@ -6398,9 +6399,9 @@ var Toolbar = class {
6398
6399
  passive: true,
6399
6400
  capture: true
6400
6401
  });
6401
- window.addEventListener("resize", onScrollResize, { passive: true });
6402
- this._disposers.push(d1, d2, d2b, d3, d3b, d4, d5, d6, () => document.removeEventListener("scroll", onScrollResize, { capture: true }), () => window.removeEventListener("resize", onScrollResize), () => {
6403
- if (popup.parentNode) popup.parentNode.removeChild(popup);
6402
+ globalThis.addEventListener("resize", onScrollResize, { passive: true });
6403
+ this._disposers.push(d1, d2, d2b, d3, d3b, d4, d5, d6, () => document.removeEventListener("scroll", onScrollResize, { capture: true }), () => globalThis.removeEventListener("resize", onScrollResize), () => {
6404
+ if (popup.parentNode) popup.remove();
6404
6405
  });
6405
6406
  this._colorPickerClosers.push(closePopup);
6406
6407
  this._disposers.push(() => {
@@ -6444,7 +6445,7 @@ var Toolbar = class {
6444
6445
  /** @type {Range|null} */
6445
6446
  let _savedRange = null;
6446
6447
  const dMousedown = on(select, "mousedown", () => {
6447
- const sel = window.getSelection();
6448
+ const sel = globalThis.getSelection();
6448
6449
  _savedRange = sel && sel.rangeCount ? sel.getRangeAt(0).cloneRange() : null;
6449
6450
  });
6450
6451
  const disposer = on(select, "change", (e) => {
@@ -6453,7 +6454,7 @@ var Toolbar = class {
6453
6454
  if (!value || selectedOpt.disabled) return;
6454
6455
  this.context.invoke("editor.focus");
6455
6456
  if (_savedRange) try {
6456
- const sel = window.getSelection();
6457
+ const sel = globalThis.getSelection();
6457
6458
  if (sel) {
6458
6459
  sel.removeAllRanges();
6459
6460
  sel.addRange(_savedRange);
@@ -6518,13 +6519,19 @@ var Toolbar = class {
6518
6519
  if (!this.el) return;
6519
6520
  const btnMap = this._btnMap || /* @__PURE__ */ new Map();
6520
6521
  this.el.querySelectorAll("button[data-btn]").forEach((btn) => {
6521
- const def = btnMap.get(btn.getAttribute("data-btn"));
6522
+ const def = btnMap.get(
6523
+ /** @type {HTMLElement} */
6524
+ btn.dataset.btn
6525
+ );
6522
6526
  if (def && typeof def.isActive === "function") btn.classList.toggle("active", !!def.isActive(this.context));
6523
6527
  if (def && typeof def.isDisabled === "function")
6524
6528
  /** @type {HTMLButtonElement} */ btn.disabled = !!def.isDisabled(this.context);
6525
6529
  });
6526
6530
  this.el.querySelectorAll("select[data-btn]").forEach((select) => {
6527
- const def = btnMap.get(select.getAttribute("data-btn"));
6531
+ const def = btnMap.get(
6532
+ /** @type {HTMLElement} */
6533
+ select.dataset.btn
6534
+ );
6528
6535
  if (!def || typeof def.getValue !== "function") return;
6529
6536
  let raw = (def.getValue(this.context) || "").replace(/["']/g, "").trim();
6530
6537
  if (!raw) raw = this.options.defaultFontFamily || this.options.fontFamilies && this.options.fontFamilies[0] || "";
@@ -6650,7 +6657,7 @@ var Statusbar = class {
6650
6657
  this._dragDisposers.forEach((d) => d());
6651
6658
  this._dragDisposers = null;
6652
6659
  }
6653
- if (this.el && this.el.parentNode) this.el.parentNode.removeChild(this.el);
6660
+ this.el?.remove();
6654
6661
  this.el = null;
6655
6662
  }
6656
6663
  _bindResize(handle) {
@@ -6714,7 +6721,7 @@ var Statusbar = class {
6714
6721
  if (!this._wordCountEl || !this._charCountEl) return;
6715
6722
  const text = this.context.layoutInfo.editable.textContent || "";
6716
6723
  const words = _countWords(text);
6717
- const chars = text.replace(/\n/g, "").length;
6724
+ const chars = text.replaceAll("\n", "").length;
6718
6725
  const maxWords = this.options.maxWords || 0;
6719
6726
  const maxChars = this.options.maxChars || 0;
6720
6727
  const LS = this.context.locale.statusbar;
@@ -6736,7 +6743,7 @@ var Statusbar = class {
6736
6743
  * @returns {number}
6737
6744
  */
6738
6745
  getCharCount() {
6739
- return (this.context.layoutInfo.editable.innerText || "").replace(/\n/g, "").length;
6746
+ return (this.context.layoutInfo.editable.innerText || "").replaceAll("\n", "").length;
6740
6747
  }
6741
6748
  };
6742
6749
  //#endregion
@@ -6829,7 +6836,7 @@ var Clipboard = class {
6829
6836
  if (el.querySelector("a, strong, em, b, i, ul, ol, li, table, img, blockquote, pre, code, h1, h2, h3, h4, h5, h6")) continue;
6830
6837
  const parent = el.parentNode;
6831
6838
  while (el.firstChild) parent.insertBefore(el.firstChild, el);
6832
- parent.removeChild(el);
6839
+ el.remove();
6833
6840
  }
6834
6841
  doc.querySelectorAll("*").forEach((el) => {
6835
6842
  el.removeAttribute("class");
@@ -6871,7 +6878,7 @@ var Clipboard = class {
6871
6878
  this._forcePlain = !!val;
6872
6879
  }
6873
6880
  _onPaste(event) {
6874
- const clipboardData = event.clipboardData || window.clipboardData;
6881
+ const clipboardData = event.clipboardData || globalThis.clipboardData;
6875
6882
  if (!clipboardData) return;
6876
6883
  const forcePlain = this._forcePlain;
6877
6884
  this._forcePlain = false;
@@ -6915,7 +6922,6 @@ var Clipboard = class {
6915
6922
  if (this.options.pasteStripAttributes) html = this._stripAttributes(html);
6916
6923
  execCommand("insertHTML", html);
6917
6924
  this.context.invoke("editor.afterCommand");
6918
- return;
6919
6925
  }
6920
6926
  }
6921
6927
  _onDragover(event) {
@@ -6947,17 +6953,17 @@ var Clipboard = class {
6947
6953
  this.options.onImageUpload(files);
6948
6954
  return;
6949
6955
  }
6950
- const UNSUPPORTED = [
6956
+ const UNSUPPORTED = new Set([
6951
6957
  "image/tiff",
6952
6958
  "image/x-tiff",
6953
6959
  "image/bmp",
6954
6960
  "image/x-bmp",
6955
6961
  "image/x-ms-bmp"
6956
- ];
6962
+ ]);
6957
6963
  const maxBytes = (this.options.maxImageSize || 5) * 1024 * 1024;
6958
6964
  files.forEach((file) => {
6959
6965
  if (!file || !file.type.startsWith("image/")) return;
6960
- if (UNSUPPORTED.includes(file.type)) {
6966
+ if (UNSUPPORTED.has(file.type)) {
6961
6967
  const message = `Image format "${file.type}" is not supported for display in web browsers. Please convert to PNG, JPEG, or WebP first.`;
6962
6968
  this.context.triggerEvent("imageError", {
6963
6969
  file,
@@ -7009,10 +7015,10 @@ var Clipboard = class {
7009
7015
  */
7010
7016
  _dataUrlToBlob(dataUrl) {
7011
7017
  const [header, b64] = dataUrl.split(",");
7012
- const mime = header.match(/:(.*?);/)?.[1] ?? "image/png";
7018
+ const mime = /:(.*?);/.exec(header)?.[1] ?? "image/png";
7013
7019
  const binary = atob(b64);
7014
7020
  const arr = new Uint8Array(binary.length);
7015
- for (let i = 0; i < binary.length; i++) arr[i] = binary.charCodeAt(i);
7021
+ for (let i = 0; i < binary.length; i++) arr[i] = binary.codePointAt(i);
7016
7022
  return new Blob([arr], { type: mime });
7017
7023
  }
7018
7024
  /**
@@ -7080,7 +7086,7 @@ var Clipboard = class {
7080
7086
  }
7081
7087
  }
7082
7088
  if (!range) return;
7083
- const sel = window.getSelection();
7089
+ const sel = globalThis.getSelection();
7084
7090
  if (sel) {
7085
7091
  sel.removeAllRanges();
7086
7092
  sel.addRange(range);
@@ -7092,7 +7098,7 @@ var Clipboard = class {
7092
7098
  * @returns {string}
7093
7099
  */
7094
7100
  _escapeHTML(str) {
7095
- return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
7101
+ return str.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&#039;");
7096
7102
  }
7097
7103
  };
7098
7104
  //#endregion
@@ -7129,7 +7135,7 @@ var Placeholder = class {
7129
7135
  _update() {
7130
7136
  const editable = this.context.layoutInfo.editable;
7131
7137
  const isFocused = document.activeElement === editable;
7132
- const isEmpty = !(editable.textContent.replace(/\u200B/g, "").trim().length > 0) && !editable.querySelector("img, table, hr, .an-video-wrapper");
7138
+ const isEmpty = !(editable.textContent.replaceAll("​", "").trim().length > 0) && !editable.querySelector("img, table, hr, .an-video-wrapper");
7133
7139
  editable.classList.toggle("an-placeholder", isEmpty && !isFocused);
7134
7140
  }
7135
7141
  };
@@ -7157,7 +7163,7 @@ var Codeview = class {
7157
7163
  destroy() {
7158
7164
  this._disposers.forEach((d) => d());
7159
7165
  this._disposers = [];
7160
- if (this._textarea && this._textarea.parentNode) this._textarea.parentNode.removeChild(this._textarea);
7166
+ this._textarea?.remove();
7161
7167
  this._textarea = null;
7162
7168
  }
7163
7169
  toggle() {
@@ -7188,7 +7194,7 @@ var Codeview = class {
7188
7194
  if (!this._active || !this._textarea) return;
7189
7195
  const { editable } = this.context.layoutInfo;
7190
7196
  editable.innerHTML = sanitiseHTML(this._textarea.value, { allowIframes: true });
7191
- this._textarea.parentNode.removeChild(this._textarea);
7197
+ this._textarea.remove();
7192
7198
  this._textarea = null;
7193
7199
  editable.style.display = "";
7194
7200
  this._active = false;
@@ -7212,7 +7218,7 @@ var Codeview = class {
7212
7218
  }).split("\n").map((line) => {
7213
7219
  const stripped = line.trim();
7214
7220
  if (!stripped) return "";
7215
- if (/^<\//.test(stripped)) indent = Math.max(0, indent - 1);
7221
+ if (stripped.startsWith("</")) indent = Math.max(0, indent - 1);
7216
7222
  const out = " ".repeat(indent) + stripped;
7217
7223
  if (/^<[^/!][^>]*[^/]>/.test(stripped) && !INLINE_RE.test(stripped) && !/^<(br|hr|img|input|link|meta)/.test(stripped)) indent++;
7218
7224
  return out;
@@ -7301,7 +7307,7 @@ var LinkDialog = class {
7301
7307
  destroy() {
7302
7308
  this._disposers.forEach((d) => d());
7303
7309
  this._disposers = [];
7304
- if (this._dialog && this._dialog.parentNode) this._dialog.parentNode.removeChild(this._dialog);
7310
+ if (this._dialog && this._dialog.parentNode) this._dialog.remove();
7305
7311
  this._dialog = null;
7306
7312
  }
7307
7313
  /**
@@ -7399,7 +7405,7 @@ var LinkDialog = class {
7399
7405
  return overlay;
7400
7406
  }
7401
7407
  _prefill() {
7402
- const sel = window.getSelection();
7408
+ const sel = globalThis.getSelection();
7403
7409
  let anchor = null;
7404
7410
  if (sel && sel.rangeCount > 0) {
7405
7411
  let node = sel.getRangeAt(0).startContainer;
@@ -7486,7 +7492,7 @@ var ImageDialog = class {
7486
7492
  destroy() {
7487
7493
  this._disposers.forEach((d) => d());
7488
7494
  this._disposers = [];
7489
- if (this._dialog && this._dialog.parentNode) this._dialog.parentNode.removeChild(this._dialog);
7495
+ if (this._dialog && this._dialog.parentNode) this._dialog.remove();
7490
7496
  this._dialog = null;
7491
7497
  }
7492
7498
  show() {
@@ -7718,7 +7724,7 @@ var VideoDialog = class {
7718
7724
  destroy() {
7719
7725
  this._disposers.forEach((d) => d());
7720
7726
  this._disposers = [];
7721
- if (this._dialog && this._dialog.parentNode) this._dialog.parentNode.removeChild(this._dialog);
7727
+ if (this._dialog && this._dialog.parentNode) this._dialog.remove();
7722
7728
  this._dialog = null;
7723
7729
  }
7724
7730
  show() {
@@ -7804,7 +7810,7 @@ var VideoDialog = class {
7804
7810
  }
7805
7811
  _onInsert() {
7806
7812
  const rawUrl = this._urlInput.value.trim();
7807
- const width = Math.max(80, parseInt(this._widthInput.value, 10) || 560);
7813
+ const width = Math.max(80, Number.parseInt(this._widthInput.value, 10) || 560);
7808
7814
  if (!rawUrl) {
7809
7815
  this._urlInput.focus();
7810
7816
  return;
@@ -7847,22 +7853,22 @@ var VideoDialog = class {
7847
7853
  } catch {
7848
7854
  return null;
7849
7855
  }
7850
- const ytWatch = url.match(/(?:youtube\.com\/watch\?(?:.*&)?v=|youtube\.com\/embed\/)([a-zA-Z0-9_-]{11})/);
7856
+ const ytWatch = /(?:youtube\.com\/watch\?(?:.*&)?v=|youtube\.com\/embed\/)([a-zA-Z0-9_-]{11})/.exec(url);
7851
7857
  if (ytWatch) return {
7852
7858
  type: "YouTube",
7853
7859
  embedUrl: `https://www.youtube.com/embed/${ytWatch[1]}`
7854
7860
  };
7855
- const ytShort = url.match(/youtu\.be\/([a-zA-Z0-9_-]{11})/);
7861
+ const ytShort = /youtu\.be\/([a-zA-Z0-9_-]{11})/.exec(url);
7856
7862
  if (ytShort) return {
7857
7863
  type: "YouTube",
7858
7864
  embedUrl: `https://www.youtube.com/embed/${ytShort[1]}`
7859
7865
  };
7860
- const ytShorts = url.match(/youtube\.com\/shorts\/([a-zA-Z0-9_-]{11})/);
7866
+ const ytShorts = /youtube\.com\/shorts\/([a-zA-Z0-9_-]{11})/.exec(url);
7861
7867
  if (ytShorts) return {
7862
7868
  type: "YouTube Shorts",
7863
7869
  embedUrl: `https://www.youtube.com/embed/${ytShorts[1]}`
7864
7870
  };
7865
- const vimeo = url.match(/vimeo\.com\/(\d+)/);
7871
+ const vimeo = /vimeo\.com\/(\d+)/.exec(url);
7866
7872
  if (vimeo) return {
7867
7873
  type: "Vimeo",
7868
7874
  embedUrl: `https://player.vimeo.com/video/${vimeo[1]}`
@@ -7886,7 +7892,7 @@ var VideoDialog = class {
7886
7892
  const iframeTitle = `${info.type} video player`;
7887
7893
  return `<div class="an-video-wrapper" style="position:relative;display:block;width:${width}px;max-width:100%"><iframe src="${info.embedUrl}" width="${width}" height="${height}" title="${iframeTitle}" frameborder="0" allowfullscreen allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" style="display:block;max-width:100%"></iframe><div class="an-video-shield"></div></div>`;
7888
7894
  }
7889
- if (info && info.type === "Direct video") return `<div class="an-video-wrapper" style="position:relative;display:block;width:${width}px;max-width:100%"><video src="${info.embedUrl.replace(/"/g, "%22")}" width="${width}" height="${height}" controls style="display:block;max-width:100%"></video><div class="an-video-shield"></div></div>`;
7895
+ if (info && info.type === "Direct video") return `<div class="an-video-wrapper" style="position:relative;display:block;width:${width}px;max-width:100%"><video src="${info.embedUrl.replaceAll("\"", "%22")}" width="${width}" height="${height}" controls style="display:block;max-width:100%"></video><div class="an-video-shield"></div></div>`;
7890
7896
  const safeSrc = (() => {
7891
7897
  try {
7892
7898
  const p = new URL(url);
@@ -7897,7 +7903,7 @@ var VideoDialog = class {
7897
7903
  }
7898
7904
  })();
7899
7905
  if (!safeSrc) return null;
7900
- return `<div class="an-video-wrapper" style="position:relative;display:block;width:${width}px;max-width:100%"><video src="${safeSrc.replace(/"/g, "%22")}" width="${width}" height="${height}" controls style="display:block;max-width:100%"></video><div class="an-video-shield"></div></div>`;
7906
+ return `<div class="an-video-wrapper" style="position:relative;display:block;width:${width}px;max-width:100%"><video src="${safeSrc.replaceAll("\"", "%22")}" width="${width}" height="${height}" controls style="display:block;max-width:100%"></video><div class="an-video-shield"></div></div>`;
7901
7907
  }
7902
7908
  };
7903
7909
  //#endregion
@@ -7968,7 +7974,7 @@ var ImageResizer = class {
7968
7974
  if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
7969
7975
  const img = e.target?.closest("img");
7970
7976
  if (img) this._select(img);
7971
- }), on(document, "click", (e) => this._onDocClick(e)), on(window, "scroll", () => this._updateOverlayPosition(), { passive: true }), on(window, "resize", onWindowResize, { passive: true }), on(editable, "scroll", () => this._updateOverlayPosition(), { passive: true }));
7977
+ }), on(document, "click", (e) => this._onDocClick(e)), on(globalThis, "scroll", () => this._updateOverlayPosition(), { passive: true }), on(globalThis, "resize", onWindowResize, { passive: true }), on(editable, "scroll", () => this._updateOverlayPosition(), { passive: true }));
7972
7978
  return this;
7973
7979
  }
7974
7980
  destroy() {
@@ -7983,7 +7989,7 @@ var ImageResizer = class {
7983
7989
  this._positionRaf = null;
7984
7990
  }
7985
7991
  this._deselect();
7986
- if (this._overlay && this._overlay.parentNode) this._overlay.parentNode.removeChild(this._overlay);
7992
+ if (this._overlay && this._overlay.parentNode) this._overlay.remove();
7987
7993
  this._overlay = null;
7988
7994
  }
7989
7995
  /** @returns {HTMLImageElement|null} */
@@ -8185,7 +8191,7 @@ var VideoResizer = class {
8185
8191
  if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
8186
8192
  const wrapper = this._findWrapper(e.target);
8187
8193
  if (wrapper) this._select(wrapper);
8188
- }), on(document, "click", (e) => this._onDocClick(e)), on(window, "scroll", () => this._updateOverlayPosition(), { passive: true }), on(window, "resize", onWindowResize), on(editable, "scroll", () => this._updateOverlayPosition(), { passive: true }), on(editable, "dragstart", (e) => {
8194
+ }), on(document, "click", (e) => this._onDocClick(e)), on(globalThis, "scroll", () => this._updateOverlayPosition(), { passive: true }), on(globalThis, "resize", onWindowResize), on(editable, "scroll", () => this._updateOverlayPosition(), { passive: true }), on(editable, "dragstart", (e) => {
8189
8195
  if (e.target instanceof Element && e.target.closest(".an-video-wrapper")) e.preventDefault();
8190
8196
  }));
8191
8197
  return this;
@@ -8202,7 +8208,7 @@ var VideoResizer = class {
8202
8208
  this._positionRaf = null;
8203
8209
  }
8204
8210
  this._deselect();
8205
- if (this._overlay && this._overlay.parentNode) this._overlay.parentNode.removeChild(this._overlay);
8211
+ this._overlay?.remove();
8206
8212
  this._overlay = null;
8207
8213
  }
8208
8214
  /** @returns {HTMLElement|null} */
@@ -8223,7 +8229,7 @@ var VideoResizer = class {
8223
8229
  */
8224
8230
  _findWrapper(el) {
8225
8231
  if (!el || !(el instanceof Element)) return null;
8226
- if (el.classList && el.classList.contains("an-video-wrapper")) return el;
8232
+ if (el.classList?.contains("an-video-wrapper")) return el;
8227
8233
  const w = el.closest(".an-video-wrapper");
8228
8234
  if (w) return w;
8229
8235
  return null;
@@ -8256,7 +8262,7 @@ var VideoResizer = class {
8256
8262
  _onDocClick(e) {
8257
8263
  if (!this._activeWrapper) return;
8258
8264
  if (this._activeWrapper.contains(e.target)) return;
8259
- if (this._overlay && this._overlay.contains(e.target)) return;
8265
+ if (this._overlay?.contains(e.target)) return;
8260
8266
  if (e.target.closest(".an-contextmenu")) return;
8261
8267
  this._deselect();
8262
8268
  }
@@ -8381,14 +8387,14 @@ var LinkTooltip = class {
8381
8387
  }), on(editable, "mouseout", (e) => {
8382
8388
  const to = e.relatedTarget;
8383
8389
  if (!to || !editable.contains(to) && !this._el.contains(to)) this._scheduleHide();
8384
- }), on(window, "scroll", () => this._hide(), { passive: true }), on(window, "resize", () => this._hide(), { passive: true }));
8390
+ }), on(globalThis, "scroll", () => this._hide(), { passive: true }), on(globalThis, "resize", () => this._hide(), { passive: true }));
8385
8391
  return this;
8386
8392
  }
8387
8393
  destroy() {
8388
8394
  this._clearTimers();
8389
8395
  this._disposers.forEach((d) => d());
8390
8396
  this._disposers = [];
8391
- if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);
8397
+ if (this._el && this._el.parentNode) this._el.remove();
8392
8398
  this._el = null;
8393
8399
  }
8394
8400
  _buildTooltip() {
@@ -8473,8 +8479,8 @@ var LinkTooltip = class {
8473
8479
  const margin = 6;
8474
8480
  let top = rect.bottom + margin;
8475
8481
  let left = rect.left;
8476
- if (top + tipH > window.innerHeight - margin) top = rect.top - tipH - margin;
8477
- if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;
8482
+ if (top + tipH > globalThis.innerHeight - margin) top = rect.top - tipH - margin;
8483
+ if (left + tipW > globalThis.innerWidth - margin) left = globalThis.innerWidth - tipW - margin;
8478
8484
  if (left < margin) left = margin;
8479
8485
  this._el.style.top = `${top}px`;
8480
8486
  this._el.style.left = `${left}px`;
@@ -8489,12 +8495,12 @@ var LinkTooltip = class {
8489
8495
  }
8490
8496
  }
8491
8497
  _openLink() {
8492
- const url = this._activeAnchor && this._activeAnchor.getAttribute("href");
8493
- if (url) window.open(url, "_blank", "noopener,noreferrer");
8498
+ const url = this._activeAnchor?.getAttribute("href");
8499
+ if (url) globalThis.open(url, "_blank", "noopener,noreferrer");
8494
8500
  this._hide();
8495
8501
  }
8496
8502
  _copyLink() {
8497
- const url = this._activeAnchor && this._activeAnchor.getAttribute("href");
8503
+ const url = this._activeAnchor?.getAttribute("href");
8498
8504
  if (url) navigator.clipboard.writeText(url).catch(() => {
8499
8505
  const ta = document.createElement("textarea");
8500
8506
  ta.value = url;
@@ -8503,7 +8509,7 @@ var LinkTooltip = class {
8503
8509
  document.body.appendChild(ta);
8504
8510
  ta.select();
8505
8511
  document.execCommand("copy");
8506
- document.body.removeChild(ta);
8512
+ ta.remove();
8507
8513
  });
8508
8514
  if (this._copyBtn) {
8509
8515
  this._copyBtn.classList.add("an-link-tooltip-btn--copied");
@@ -8514,7 +8520,7 @@ var LinkTooltip = class {
8514
8520
  const anchor = this._activeAnchor;
8515
8521
  if (!anchor) return;
8516
8522
  this._hide();
8517
- const sel = window.getSelection();
8523
+ const sel = globalThis.getSelection();
8518
8524
  const range = document.createRange();
8519
8525
  range.selectNodeContents(anchor);
8520
8526
  sel.removeAllRanges();
@@ -8525,7 +8531,7 @@ var LinkTooltip = class {
8525
8531
  const anchor = this._activeAnchor;
8526
8532
  if (!anchor) return;
8527
8533
  this._hide();
8528
- const sel = window.getSelection();
8534
+ const sel = globalThis.getSelection();
8529
8535
  const range = document.createRange();
8530
8536
  range.selectNode(anchor);
8531
8537
  sel.removeAllRanges();
@@ -8574,14 +8580,14 @@ var ImageTooltip = class {
8574
8580
  }, { passive: true }), on(document, "click", (e) => {
8575
8581
  const et = e.target;
8576
8582
  if (this._activeImg && !this._activeImg.contains(et) && !this._el.contains(et)) this._hide();
8577
- }), on(window, "scroll", () => this._hide(), { passive: true }), on(window, "resize", () => this._hide(), { passive: true }));
8583
+ }), on(globalThis, "scroll", () => this._hide(), { passive: true }), on(globalThis, "resize", () => this._hide(), { passive: true }));
8578
8584
  return this;
8579
8585
  }
8580
8586
  destroy() {
8581
8587
  this._clearTimers();
8582
8588
  this._disposers.forEach((d) => d());
8583
8589
  this._disposers = [];
8584
- if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);
8590
+ this._el?.remove();
8585
8591
  this._el = null;
8586
8592
  }
8587
8593
  _buildTooltip() {
@@ -8682,8 +8688,8 @@ var ImageTooltip = class {
8682
8688
  const margin = 6;
8683
8689
  let top = rect.bottom + margin;
8684
8690
  let left = rect.left + (rect.width - tipW) / 2;
8685
- if (top + tipH > window.innerHeight - margin) top = rect.top - tipH - margin;
8686
- if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;
8691
+ if (top + tipH > globalThis.innerHeight - margin) top = rect.top - tipH - margin;
8692
+ if (left + tipW > globalThis.innerWidth - margin) left = globalThis.innerWidth - tipW - margin;
8687
8693
  if (left < margin) left = margin;
8688
8694
  this._el.style.top = `${top}px`;
8689
8695
  this._el.style.left = `${left}px`;
@@ -8739,8 +8745,8 @@ var ImageTooltip = class {
8739
8745
  const img = this._activeImg;
8740
8746
  if (!img) return;
8741
8747
  const current = img.style.transform || "";
8742
- const match = current.match(/rotate\((-?[\d.]+)deg\)/);
8743
- const next = ((match ? parseFloat(match[1]) : 0) + delta + 360) % 360;
8748
+ const match = /rotate\((-?[\d.]+)deg\)/.exec(current);
8749
+ const next = ((match ? Number.parseFloat(match[1]) : 0) + delta + 360) % 360;
8744
8750
  const cleaned = current.replace(/rotate\(-?[\d.]+deg\)/, "").trim();
8745
8751
  img.style.transform = cleaned ? `${cleaned} rotate(${next}deg)` : next === 0 ? "" : `rotate(${next}deg)`;
8746
8752
  this.context.invoke("editor.afterCommand");
@@ -8755,8 +8761,8 @@ var ImageTooltip = class {
8755
8761
  this._hide();
8756
8762
  this.context.invoke("imageResizer.deselect");
8757
8763
  const figure = img.closest("figure.an-figure");
8758
- if (figure && figure.parentNode) figure.parentNode.removeChild(figure);
8759
- else if (img.parentNode) img.parentNode.removeChild(img);
8764
+ if (figure) figure.remove();
8765
+ else img.remove();
8760
8766
  this.context.invoke("editor.afterCommand");
8761
8767
  }
8762
8768
  _crop() {
@@ -8775,7 +8781,7 @@ var ImageTooltip = class {
8775
8781
  this._hide();
8776
8782
  const range = document.createRange();
8777
8783
  range.selectNodeContents(cap);
8778
- const sel = window.getSelection();
8784
+ const sel = globalThis.getSelection();
8779
8785
  if (sel) {
8780
8786
  sel.removeAllRanges();
8781
8787
  sel.addRange(range);
@@ -8809,7 +8815,7 @@ var ImageTooltip = class {
8809
8815
  figure.appendChild(figcaption);
8810
8816
  const range = document.createRange();
8811
8817
  range.selectNodeContents(figcaption);
8812
- const sel = window.getSelection();
8818
+ const sel = globalThis.getSelection();
8813
8819
  if (sel) {
8814
8820
  sel.removeAllRanges();
8815
8821
  sel.addRange(range);
@@ -8850,8 +8856,7 @@ var VideoTooltip = class {
8850
8856
  const editable = this.context.layoutInfo.editable;
8851
8857
  this._disposers.push(on(editable, "mouseover", (e) => {
8852
8858
  if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
8853
- const target = e.target;
8854
- const wrapper = target && target.closest ? target.closest(".an-video-wrapper") : null;
8859
+ const wrapper = e.target?.closest(".an-video-wrapper");
8855
8860
  if (wrapper && editable.contains(wrapper)) this._scheduleShow(wrapper);
8856
8861
  }, { passive: true }), on(editable, "mouseout", (e) => {
8857
8862
  const to = e.relatedTarget;
@@ -8859,7 +8864,7 @@ var VideoTooltip = class {
8859
8864
  }, { passive: true }), on(document, "click", (e) => {
8860
8865
  const target = e.target;
8861
8866
  if (this._activeWrapper && !this._activeWrapper.contains(target) && !this._el.contains(target)) this._hide();
8862
- }), on(window, "scroll", () => this._hide(), { passive: true }), on(window, "resize", () => this._hide(), { passive: true }));
8867
+ }), on(globalThis, "scroll", () => this._hide(), { passive: true }), on(globalThis, "resize", () => this._hide(), { passive: true }));
8863
8868
  return this;
8864
8869
  }
8865
8870
  destroy() {
@@ -8867,7 +8872,7 @@ var VideoTooltip = class {
8867
8872
  this._clearTimers();
8868
8873
  this._disposers.forEach((d) => d());
8869
8874
  this._disposers = [];
8870
- if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);
8875
+ this._el?.remove();
8871
8876
  this._el = null;
8872
8877
  }
8873
8878
  _buildTooltip() {
@@ -8964,8 +8969,8 @@ var VideoTooltip = class {
8964
8969
  const margin = 6;
8965
8970
  let top = rect.bottom + margin;
8966
8971
  let left = rect.left + (rect.width - tipW) / 2;
8967
- if (top + tipH > window.innerHeight - margin) top = rect.top - tipH - margin;
8968
- if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;
8972
+ if (top + tipH > globalThis.innerHeight - margin) top = rect.top - tipH - margin;
8973
+ if (left + tipW > globalThis.innerWidth - margin) left = globalThis.innerWidth - tipW - margin;
8969
8974
  if (left < margin) left = margin;
8970
8975
  this._el.style.top = `${top}px`;
8971
8976
  this._el.style.left = `${left}px`;
@@ -9019,7 +9024,7 @@ var VideoTooltip = class {
9019
9024
  if (!wrapper) return;
9020
9025
  this._hide();
9021
9026
  this.context.invoke("videoResizer.deselect");
9022
- if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);
9027
+ wrapper.remove();
9023
9028
  this.context.invoke("editor.afterCommand");
9024
9029
  }
9025
9030
  _togglePreview() {
@@ -9261,12 +9266,12 @@ var TableTooltip = class {
9261
9266
  }, { passive: true }), on(editable, "mouseout", (e) => {
9262
9267
  if (this._selectMode) return;
9263
9268
  const to = e.relatedTarget;
9264
- if (!to || !editable.contains(to) && !this._el.contains(to) && !(this._sizePopover && this._sizePopover.contains(to))) this._scheduleHide();
9269
+ if (!to || !editable.contains(to) && !this._el.contains(to) && !this._sizePopover?.contains(to)) this._scheduleHide();
9265
9270
  }, { passive: true }), on(document, "click", (e) => {
9266
9271
  const et = e.target;
9267
- if (this._selectMode && this._activeTable && this._activeTable.contains(et)) return;
9268
- if (this._activeTable && !this._activeTable.contains(et) && !this._el.contains(et) && !(this._sizePopover && this._sizePopover.contains(et))) this._hide();
9269
- }), on(document, "selectionchange", () => this._syncShadeStrip()), on(window, "scroll", () => this._hide(), { passive: true }), on(window, "resize", () => this._hide(), { passive: true }));
9272
+ if (this._selectMode && this._activeTable?.contains(et)) return;
9273
+ if (this._activeTable && !this._activeTable.contains(et) && !this._el.contains(et) && !this._sizePopover?.contains(et)) this._hide();
9274
+ }), on(document, "selectionchange", () => this._syncShadeStrip()), on(globalThis, "scroll", () => this._hide(), { passive: true }), on(globalThis, "resize", () => this._hide(), { passive: true }));
9270
9275
  this._initResize();
9271
9276
  return this;
9272
9277
  }
@@ -9392,11 +9397,11 @@ var TableTooltip = class {
9392
9397
  this._clearTimers();
9393
9398
  this._disposers.forEach((d) => d());
9394
9399
  this._disposers = [];
9395
- if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);
9400
+ if (this._el && this._el.parentNode) this._el.remove();
9396
9401
  this._el = null;
9397
- if (this._sizePopover && this._sizePopover.parentNode) this._sizePopover.parentNode.removeChild(this._sizePopover);
9402
+ if (this._sizePopover && this._sizePopover.parentNode) this._sizePopover.remove();
9398
9403
  this._sizePopover = null;
9399
- if (this._shadePopover && this._shadePopover.parentNode) this._shadePopover.parentNode.removeChild(this._shadePopover);
9404
+ if (this._shadePopover && this._shadePopover.parentNode) this._shadePopover.remove();
9400
9405
  this._shadePopover = null;
9401
9406
  }
9402
9407
  _buildTooltip() {
@@ -9506,7 +9511,7 @@ var TableTooltip = class {
9506
9511
  _syncShadeStrip() {
9507
9512
  if (!this._shadeColorStrip || !this._el || this._el.style.display === "none") return;
9508
9513
  const cell = this._getCell();
9509
- this._shadeColorStrip.style.background = cell && cell.style.backgroundColor || "transparent";
9514
+ this._shadeColorStrip.style.background = cell?.style.backgroundColor || "transparent";
9510
9515
  }
9511
9516
  _hide() {
9512
9517
  this._el.style.display = "none";
@@ -9536,20 +9541,20 @@ var TableTooltip = class {
9536
9541
  let left = rect.left + (rect.width - tipW) / 2;
9537
9542
  let top = rect.top - tipH - margin;
9538
9543
  if (top < margin) top = rect.bottom + margin;
9539
- if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;
9544
+ if (left + tipW > globalThis.innerWidth - margin) left = globalThis.innerWidth - tipW - margin;
9540
9545
  if (left < margin) left = margin;
9541
9546
  this._el.style.left = `${left}px`;
9542
9547
  this._el.style.top = `${top}px`;
9543
9548
  }
9544
9549
  _getCell() {
9545
- const sel = window.getSelection();
9550
+ const sel = globalThis.getSelection();
9546
9551
  if (sel && sel.rangeCount) {
9547
9552
  let container = sel.getRangeAt(0).commonAncestorContainer;
9548
9553
  if (container.nodeType === 3) container = container.parentElement;
9549
- const cellFromSel = container && container.closest("td, th");
9550
- if (cellFromSel && this._activeTable && this._activeTable.contains(cellFromSel)) return cellFromSel;
9554
+ const cellFromSel = container?.closest("td, th");
9555
+ if (cellFromSel && this._activeTable?.contains(cellFromSel)) return cellFromSel;
9551
9556
  }
9552
- return this._activeCell || this._activeTable && this._activeTable.querySelector("td, th");
9557
+ return this._activeCell || this._activeTable?.querySelector("td, th");
9553
9558
  }
9554
9559
  _toggleSelectMode() {
9555
9560
  this._selectMode = !this._selectMode;
@@ -9648,11 +9653,12 @@ var TableTooltip = class {
9648
9653
  const table = cells[0].closest("table");
9649
9654
  if (!table) return;
9650
9655
  const allRows = Array.from(table.querySelectorAll("tr"));
9651
- const refRow = [...new Set(cells.map((c) => c.closest("tr")).filter(Boolean))].reduce((best, r) => {
9656
+ const selectedRows = [...new Set(cells.map((c) => c.closest("tr")).filter(Boolean))];
9657
+ const refRow = selectedRows.reduce((best, r) => {
9652
9658
  const bi = allRows.indexOf(best);
9653
9659
  const ri = allRows.indexOf(r);
9654
9660
  return position === "above" ? ri < bi ? r : best : ri > bi ? r : best;
9655
- });
9661
+ }, selectedRows[0]);
9656
9662
  const colCount = Array.from(refRow.cells).reduce((sum, c) => sum + (c.colSpan || 1), 0);
9657
9663
  const newRow = document.createElement("tr");
9658
9664
  const refCells = Array.from(refRow.cells);
@@ -9695,7 +9701,7 @@ var TableTooltip = class {
9695
9701
  if (selectedRows.filter((r) => r.closest("tbody")).length >= totalBodyRows) return;
9696
9702
  this._activeCell = null;
9697
9703
  this._clearSelection();
9698
- selectedRows.forEach((r) => r.parentElement?.removeChild(r));
9704
+ selectedRows.forEach((r) => r.remove());
9699
9705
  requestAnimationFrame(() => this._positionNear(this._activeTable));
9700
9706
  this.context.invoke("editor.afterCommand");
9701
9707
  }
@@ -9717,7 +9723,7 @@ var TableTooltip = class {
9717
9723
  });
9718
9724
  this._activeCell = null;
9719
9725
  this._clearSelection();
9720
- cellsToDelete.forEach((c) => c.parentElement?.removeChild(c));
9726
+ cellsToDelete.forEach((c) => c.remove());
9721
9727
  requestAnimationFrame(() => this._positionNear(this._activeTable));
9722
9728
  this.context.invoke("editor.afterCommand");
9723
9729
  }
@@ -9728,7 +9734,7 @@ var TableTooltip = class {
9728
9734
  if (!table) return;
9729
9735
  let selected = this._getSelectedCells().filter((c) => table.contains(c));
9730
9736
  if (selected.length < 2) {
9731
- const sel = window.getSelection();
9737
+ const sel = globalThis.getSelection();
9732
9738
  if (!sel || sel.rangeCount === 0) return;
9733
9739
  const range = sel.getRangeAt(0);
9734
9740
  selected = Array.from(table.querySelectorAll("td, th")).filter((c) => {
@@ -9770,7 +9776,7 @@ var TableTooltip = class {
9770
9776
  first.rowSpan = maxR - minR + 1;
9771
9777
  first.style.verticalAlign = "middle";
9772
9778
  first.innerHTML = rectCells.map((c) => c.innerHTML).join("");
9773
- rectCells.slice(1).forEach((c) => c.parentElement?.removeChild(c));
9779
+ rectCells.slice(1).forEach((c) => c.remove());
9774
9780
  this._clearSelection();
9775
9781
  this.context.invoke("editor.afterCommand");
9776
9782
  }
@@ -9778,7 +9784,7 @@ var TableTooltip = class {
9778
9784
  const table = this._activeTable;
9779
9785
  if (!table) return;
9780
9786
  this._hide();
9781
- if (table.parentNode) table.parentNode.removeChild(table);
9787
+ if (table.parentNode) table.remove();
9782
9788
  this.context.invoke("editor.afterCommand");
9783
9789
  }
9784
9790
  _unmergeCells() {
@@ -9867,7 +9873,7 @@ var TableTooltip = class {
9867
9873
  this._sizeInputEl = inputEl;
9868
9874
  this._sizeApply = null;
9869
9875
  const d1 = on(applyBtn, "click", () => {
9870
- const val = parseInt(this._sizeInputEl.value, 10);
9876
+ const val = Number.parseInt(this._sizeInputEl.value, 10);
9871
9877
  if (val > 0 && typeof this._sizeApply === "function") this._sizeApply(val);
9872
9878
  this._hideSizePopover();
9873
9879
  });
@@ -9896,7 +9902,7 @@ var TableTooltip = class {
9896
9902
  const table = cell.closest("table");
9897
9903
  if (!table) return;
9898
9904
  const firstCell = table.querySelector("td, th");
9899
- const currentPx = firstCell ? parseInt(firstCell.style.borderWidth, 10) || parseInt(window.getComputedStyle(firstCell).borderWidth, 10) || 1 : 1;
9905
+ const currentPx = firstCell ? Number.parseInt(firstCell.style.borderWidth, 10) || Number.parseInt(globalThis.getComputedStyle(firstCell).borderWidth, 10) || 1 : 1;
9900
9906
  this._sizeTitleEl.textContent = this.context.locale.tooltips.table.tableBorderWidthPx;
9901
9907
  this._sizeInputEl.min = "0";
9902
9908
  this._sizeInputEl.max = "10";
@@ -9955,8 +9961,8 @@ var TableTooltip = class {
9955
9961
  const ph = this._sizePopover.offsetHeight || 110;
9956
9962
  let left = tipRect.left;
9957
9963
  let top = tipRect.bottom + 6;
9958
- if (left + pw > window.innerWidth - 8) left = window.innerWidth - pw - 8;
9959
- if (top + ph > window.innerHeight - 8) top = tipRect.top - ph - 6;
9964
+ if (left + pw > globalThis.innerWidth - 8) left = globalThis.innerWidth - pw - 8;
9965
+ if (top + ph > globalThis.innerHeight - 8) top = tipRect.top - ph - 6;
9960
9966
  this._sizePopover.style.left = `${left}px`;
9961
9967
  this._sizePopover.style.top = `${top}px`;
9962
9968
  if (this._sizeInputEl) {
@@ -10010,11 +10016,10 @@ var TableTooltip = class {
10010
10016
  customRow.appendChild(colorInput);
10011
10017
  customRow.appendChild(customLabel);
10012
10018
  pop.appendChild(customRow);
10013
- this._disposers.push(on(pop, "mousedown", (e) => e.preventDefault()));
10014
- this._disposers.push(on(pop, "mouseenter", () => this._clearTimers()), on(pop, "mouseleave", () => this._scheduleHide()));
10019
+ this._disposers.push(on(pop, "mousedown", (e) => e.preventDefault()), on(pop, "mouseenter", () => this._clearTimers()), on(pop, "mouseleave", () => this._scheduleHide()));
10015
10020
  this._disposers.push(on(document, "click", (e) => {
10016
10021
  const et = e.target;
10017
- if (this._shadePopover && this._shadePopover.style.display !== "none" && !this._shadePopover.contains(et) && !(this._el && this._el.contains(et))) this._hideCellShadePopover();
10022
+ if (this._shadePopover && this._shadePopover.style.display !== "none" && !this._shadePopover.contains(et) && !this._el?.contains(et)) this._hideCellShadePopover();
10018
10023
  }));
10019
10024
  return pop;
10020
10025
  }
@@ -10031,8 +10036,8 @@ var TableTooltip = class {
10031
10036
  const tipRect = this._el.getBoundingClientRect();
10032
10037
  let left = tipRect.left;
10033
10038
  let top = tipRect.bottom + 6;
10034
- if (left + pw > window.innerWidth - 8) left = window.innerWidth - pw - 8;
10035
- if (top + ph > window.innerHeight - 8) top = tipRect.top - ph - 6;
10039
+ if (left + pw > globalThis.innerWidth - 8) left = globalThis.innerWidth - pw - 8;
10040
+ if (top + ph > globalThis.innerHeight - 8) top = tipRect.top - ph - 6;
10036
10041
  this._shadePopover.style.left = `${Math.max(8, left)}px`;
10037
10042
  this._shadePopover.style.top = `${Math.max(8, top)}px`;
10038
10043
  });
@@ -10095,7 +10100,7 @@ var CodeTooltip = class {
10095
10100
  this._clearTimers();
10096
10101
  this._disposers.forEach((d) => d());
10097
10102
  this._disposers = [];
10098
- if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);
10103
+ this._el?.remove();
10099
10104
  this._el = null;
10100
10105
  }
10101
10106
  _buildTooltip() {
@@ -10221,21 +10226,21 @@ var CodeTooltip = class {
10221
10226
  let top = rect.top - tipH - margin;
10222
10227
  let left = rect.left + (rect.width - tipW) / 2;
10223
10228
  if (top < margin) top = rect.bottom + margin;
10224
- if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;
10229
+ if (left + tipW > globalThis.innerWidth - margin) left = globalThis.innerWidth - tipW - margin;
10225
10230
  if (left < margin) left = margin;
10226
10231
  this._el.style.top = `${top}px`;
10227
10232
  this._el.style.left = `${left}px`;
10228
10233
  }
10229
10234
  _syncWrapBtn() {
10230
10235
  if (!this._activePre || !this._wrapBtn) return;
10231
- const wrapped = (this._activePre.style.whiteSpace || "").includes("pre-wrap") || window.getComputedStyle(this._activePre).whiteSpace === "pre-wrap";
10236
+ const wrapped = (this._activePre.style.whiteSpace || "").includes("pre-wrap") || globalThis.getComputedStyle(this._activePre).whiteSpace === "pre-wrap";
10232
10237
  this._wrapBtn.classList.toggle("active", wrapped);
10233
10238
  this._wrapBtn.title = wrapped ? this.context.locale.tooltips.code.disableWordWrap : this.context.locale.tooltips.code.enableWordWrap;
10234
10239
  }
10235
10240
  _syncLangSelect() {
10236
10241
  if (!this._activePre || !this._langSelect) return;
10237
10242
  const codeEl = this._activePre.querySelector("code");
10238
- const fromAttr = this._activePre.getAttribute("data-language") || "";
10243
+ const fromAttr = this._activePre.dataset.language || "";
10239
10244
  const fromClass = codeEl ? (_LANG_CLASS_RE.exec(codeEl.className) || [])[1] || "" : "";
10240
10245
  this._langSelect.value = fromAttr || fromClass || "";
10241
10246
  }
@@ -10254,7 +10259,7 @@ var CodeTooltip = class {
10254
10259
  document.execCommand("copy");
10255
10260
  this._flashCopied();
10256
10261
  } catch (_) {}
10257
- document.body.removeChild(ta);
10262
+ ta.remove();
10258
10263
  }
10259
10264
  }
10260
10265
  _flashCopied() {
@@ -10287,7 +10292,6 @@ var CodeTooltip = class {
10287
10292
  applyLanguage(pre, lang) {
10288
10293
  if (!pre || !lang) return;
10289
10294
  const savedPre = this._activePre;
10290
- this._langSelect && this._langSelect.value;
10291
10295
  this._activePre = pre;
10292
10296
  if (this._langSelect) this._langSelect.value = lang;
10293
10297
  this._onLangChange();
@@ -10298,7 +10302,7 @@ var CodeTooltip = class {
10298
10302
  const pre = this._activePre;
10299
10303
  if (!pre) return;
10300
10304
  const lang = this._langSelect.value;
10301
- const _w = window;
10305
+ const _w = globalThis;
10302
10306
  let codeEl = pre.querySelector("code");
10303
10307
  if (!codeEl) {
10304
10308
  codeEl = document.createElement("code");
@@ -10308,15 +10312,15 @@ var CodeTooltip = class {
10308
10312
  }
10309
10313
  codeEl.className = lang ? `language-${lang}` : "";
10310
10314
  pre.className = lang ? `language-${lang}` : "";
10311
- if (lang) pre.setAttribute("data-language", lang);
10312
- else pre.removeAttribute("data-language");
10315
+ if (lang) pre.dataset.language = lang;
10316
+ else delete pre.dataset.language;
10313
10317
  const applyPrism = () => {
10314
10318
  codeEl.querySelectorAll("br").forEach((br) => br.replaceWith("\n"));
10315
10319
  _w.Prism.highlightElement(codeEl);
10316
10320
  this.context.invoke("editor.afterCommand");
10317
10321
  };
10318
10322
  if (lang) {
10319
- if (typeof _w.Prism !== "undefined") {
10323
+ if (_w.Prism !== void 0) {
10320
10324
  if (_w.Prism.languages[lang]) {
10321
10325
  applyPrism();
10322
10326
  return;
@@ -10338,7 +10342,7 @@ var CodeTooltip = class {
10338
10342
  * Called once at initialize time. Fire-and-forget; errors are silent.
10339
10343
  */
10340
10344
  _ensurePrism() {
10341
- const _w = window;
10345
+ const _w = globalThis;
10342
10346
  if (!this.context.options.codeHighlight || _w.Prism) return;
10343
10347
  const cdn = this.context.options.codeHighlightCDN;
10344
10348
  const themeHref = `${cdn}/themes/prism-tomorrow.min.css`;
@@ -10371,11 +10375,11 @@ var CodeTooltip = class {
10371
10375
  * @param {Function} cb – called once the grammar is ready
10372
10376
  */
10373
10377
  _loadPrismComponent(lang, cb) {
10374
- const _w = window;
10378
+ const _w = globalThis;
10375
10379
  const src = `${this.context.options.codeHighlightCDN}/components/prism-${lang}.min.js`;
10376
10380
  if (document.querySelector(`script[src="${src}"]`)) {
10377
10381
  const poll = setInterval(() => {
10378
- if (_w.Prism && _w.Prism.languages[lang]) {
10382
+ if (_w.Prism?.languages[lang]) {
10379
10383
  clearInterval(poll);
10380
10384
  cb();
10381
10385
  }
@@ -10406,7 +10410,7 @@ var CodeTooltip = class {
10406
10410
  const pre = this._activePre;
10407
10411
  if (!pre) return;
10408
10412
  this._hide();
10409
- if (pre.parentNode) pre.parentNode.removeChild(pre);
10413
+ pre.remove();
10410
10414
  this.context.invoke("editor.afterCommand");
10411
10415
  }
10412
10416
  };
@@ -12761,7 +12765,7 @@ var EmojiDialog = class {
12761
12765
  destroy() {
12762
12766
  this._disposers.forEach((d) => d());
12763
12767
  this._disposers = [];
12764
- if (this._dialog && this._dialog.parentNode) this._dialog.parentNode.removeChild(this._dialog);
12768
+ if (this._dialog && this._dialog.parentNode) this._dialog.remove();
12765
12769
  this._dialog = null;
12766
12770
  }
12767
12771
  show() {
@@ -12822,7 +12826,7 @@ var EmojiDialog = class {
12822
12826
  class: "an-icon-cat",
12823
12827
  "data-cat": id
12824
12828
  });
12825
- tab.textContent = L.categories && L.categories[id] || label;
12829
+ tab.textContent = L.categories?.[id] || label;
12826
12830
  catBar.appendChild(tab);
12827
12831
  });
12828
12832
  this._catBar = catBar;
@@ -12903,7 +12907,7 @@ var EmojiDialog = class {
12903
12907
  const savedRange = this._savedRange;
12904
12908
  const editable = this.context.layoutInfo.editable;
12905
12909
  if (savedRange) savedRange.select();
12906
- const sel = window.getSelection();
12910
+ const sel = globalThis.getSelection();
12907
12911
  let range = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;
12908
12912
  if (!range) {
12909
12913
  range = document.createRange();
@@ -12913,7 +12917,7 @@ var EmojiDialog = class {
12913
12917
  const _sc = range.startContainer;
12914
12918
  const _tdAnchor = (_sc.nodeType === 1 ? _sc : _sc.parentElement)?.closest("td, th");
12915
12919
  range.deleteContents();
12916
- if (_tdAnchor && _tdAnchor.isConnected && !_tdAnchor.contains(range.startContainer)) {
12920
+ if (_tdAnchor?.isConnected && !_tdAnchor.contains(range.startContainer)) {
12917
12921
  range.setStart(_tdAnchor, 0);
12918
12922
  range.collapse(true);
12919
12923
  }
@@ -12933,7 +12937,7 @@ var EmojiDialog = class {
12933
12937
  if (this._dialog) {
12934
12938
  this._dialog.style.display = "flex";
12935
12939
  this._removeTrap = trapFocus(this._dialog, () => this._close());
12936
- setTimeout(() => this._searchInput && this._searchInput.focus(), 50);
12940
+ setTimeout(() => this._searchInput?.focus(), 50);
12937
12941
  }
12938
12942
  }
12939
12943
  _close() {
@@ -13240,7 +13244,7 @@ var IconDialog = class {
13240
13244
  destroy() {
13241
13245
  this._disposers.forEach((d) => d());
13242
13246
  this._disposers = [];
13243
- if (this._dialog && this._dialog.parentNode) this._dialog.parentNode.removeChild(this._dialog);
13247
+ this._dialog?.remove();
13244
13248
  this._dialog = null;
13245
13249
  }
13246
13250
  show() {
@@ -13305,7 +13309,7 @@ var IconDialog = class {
13305
13309
  class: "an-icon-cat",
13306
13310
  "data-cat": id
13307
13311
  });
13308
- tab.textContent = L.categories && L.categories[id] || label;
13312
+ tab.textContent = L.categories?.[id] || label;
13309
13313
  catBar.appendChild(tab);
13310
13314
  });
13311
13315
  this._catBar = catBar;
@@ -13473,17 +13477,17 @@ var IconDialog = class {
13473
13477
  this._preview.innerHTML = "<span class=\"an-icon-preview-hint\">Select an icon</span>";
13474
13478
  return;
13475
13479
  }
13476
- const cls = this._styleSelect && this._styleSelect.value || "fa-solid";
13477
- const size = this._sizeSelect && this._sizeSelect.value || "1em";
13478
- const color = (this._useColorCb ? this._useColorCb.checked : false) && this._colorInput ? this._colorInput.value : "";
13480
+ const cls = this._styleSelect?.value || "fa-solid";
13481
+ const size = this._sizeSelect?.value || "1em";
13482
+ const color = this._useColorCb?.checked ?? false ? this._colorInput?.value ?? "" : "";
13479
13483
  const styleAttr = [size ? `font-size:${size}` : "", color ? `color:${color}` : ""].filter(Boolean).join(";");
13480
13484
  this._preview.innerHTML = `<i class="${cls} fa-${name}" aria-hidden="true"${styleAttr ? ` style="${styleAttr}"` : ""}></i><div class="an-icon-preview-name">${cls} fa-${name}</div>`;
13481
13485
  }
13482
13486
  _onInsert() {
13483
13487
  if (!this._selectedIcon) return;
13484
- const cls = this._styleSelect && this._styleSelect.value || "fa-solid";
13485
- const size = this._sizeSelect && this._sizeSelect.value || "";
13486
- const color = (this._useColorCb ? this._useColorCb.checked : false) && this._colorInput ? this._colorInput.value : "";
13488
+ const cls = this._styleSelect?.value || "fa-solid";
13489
+ const size = this._sizeSelect?.value || "";
13490
+ const color = this._useColorCb?.checked ?? false ? this._colorInput?.value ?? "" : "";
13487
13491
  const styleParts = [size ? `font-size:${size}` : "", color ? `color:${color}` : ""].filter(Boolean);
13488
13492
  const iconEl = document.createElement("i");
13489
13493
  iconEl.className = `${cls} fa-${this._selectedIcon}`;
@@ -13493,8 +13497,8 @@ var IconDialog = class {
13493
13497
  const savedRange = this._savedRange;
13494
13498
  const editable = this.context.layoutInfo.editable;
13495
13499
  if (savedRange) savedRange.select();
13496
- const sel = window.getSelection();
13497
- let range = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;
13500
+ const sel = globalThis.getSelection();
13501
+ let range = (sel?.rangeCount ?? 0) > 0 ? sel.getRangeAt(0) : null;
13498
13502
  if (!range) {
13499
13503
  range = document.createRange();
13500
13504
  range.selectNodeContents(editable);
@@ -13533,7 +13537,7 @@ var IconDialog = class {
13533
13537
  if (this._dialog) {
13534
13538
  this._dialog.style.display = "flex";
13535
13539
  this._removeTrap = trapFocus(this._dialog, () => this._close());
13536
- setTimeout(() => this._searchInput && this._searchInput.focus(), 50);
13540
+ setTimeout(() => this._searchInput?.focus(), 50);
13537
13541
  }
13538
13542
  }
13539
13543
  _close() {
@@ -13634,7 +13638,7 @@ var defaultItems = [
13634
13638
  icon: ICONS.paste,
13635
13639
  action: (ctx) => {
13636
13640
  if (!navigator.clipboard) return;
13637
- const editable = ctx.layoutInfo && ctx.layoutInfo.editable;
13641
+ const editable = ctx.layoutInfo?.editable;
13638
13642
  if (!editable) return;
13639
13643
  const doInsert = (html, text) => {
13640
13644
  editable.focus();
@@ -13759,13 +13763,13 @@ var ContextMenu = class {
13759
13763
  this.el.style.display = "none";
13760
13764
  document.body.appendChild(this.el);
13761
13765
  this._renderItems(this._items);
13762
- const editable = this.context.layoutInfo && this.context.layoutInfo.editable;
13766
+ const editable = this.context.layoutInfo?.editable;
13763
13767
  if (editable) this._disposers.push(on(editable, "contextmenu", (e) => this._onContextMenu(e)));
13764
13768
  this._disposers.push(on(document, "click", (e) => this._maybeHide(e)));
13765
13769
  this._disposers.push(on(document, "keydown", (e) => {
13766
13770
  if (e.key === "Escape") this.hide();
13767
13771
  }));
13768
- this._disposers.push(on(window, "scroll", () => this.hide(), { passive: true }));
13772
+ this._disposers.push(on(globalThis, "scroll", () => this.hide(), { passive: true }));
13769
13773
  return this;
13770
13774
  }
13771
13775
  destroy() {
@@ -13781,7 +13785,7 @@ var ContextMenu = class {
13781
13785
  } catch (_e) {}
13782
13786
  });
13783
13787
  this._disposers = [];
13784
- if (this.el && this.el.parentNode) this.el.parentNode.removeChild(this.el);
13788
+ if (this.el) this.el.remove();
13785
13789
  this.el = null;
13786
13790
  }
13787
13791
  _renderItems(items) {
@@ -13809,8 +13813,8 @@ var ContextMenu = class {
13809
13813
  backBtn.appendChild(createElement("span", { class: "an-context-label" }, [backLabel]));
13810
13814
  const off = on(backBtn, "click", (e) => {
13811
13815
  e.stopPropagation();
13812
- const curLeft = parseFloat(this.el.style.left);
13813
- const curTop = parseFloat(this.el.style.top);
13816
+ const curLeft = Number.parseFloat(this.el.style.left);
13817
+ const curTop = Number.parseFloat(this.el.style.top);
13814
13818
  this._renderItems(it.navigate());
13815
13819
  this._reposition(curLeft, curTop);
13816
13820
  });
@@ -13853,8 +13857,8 @@ var ContextMenu = class {
13853
13857
  btn.appendChild(chevron);
13854
13858
  const off = on(btn, "click", (e) => {
13855
13859
  e.stopPropagation();
13856
- const curLeft = parseFloat(this.el.style.left);
13857
- const curTop = parseFloat(this.el.style.top);
13860
+ const curLeft = Number.parseFloat(this.el.style.left);
13861
+ const curTop = Number.parseFloat(this.el.style.top);
13858
13862
  this._renderItems(it.navigate());
13859
13863
  this._reposition(curLeft, curTop);
13860
13864
  });
@@ -13979,10 +13983,10 @@ var ContextMenu = class {
13979
13983
  if (!cell) return;
13980
13984
  const rows = +cell.dataset.row;
13981
13985
  const cols = +cell.dataset.col;
13982
- const editable = this.context.layoutInfo && this.context.layoutInfo.editable;
13986
+ const editable = this.context.layoutInfo?.editable;
13983
13987
  if (editable && this._savedRange) {
13984
13988
  editable.focus();
13985
- const sel = window.getSelection();
13989
+ const sel = globalThis.getSelection();
13986
13990
  sel.removeAllRanges();
13987
13991
  sel.addRange(this._savedRange.cloneRange());
13988
13992
  }
@@ -14024,12 +14028,12 @@ var ContextMenu = class {
14024
14028
  });
14025
14029
  }
14026
14030
  _onContextMenu(event) {
14027
- const editable = this.context.layoutInfo && this.context.layoutInfo.editable;
14031
+ const editable = this.context.layoutInfo?.editable;
14028
14032
  if (!editable) return;
14029
14033
  if (!editable.contains(event.target)) return;
14030
14034
  if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
14031
14035
  event.preventDefault();
14032
- const winSel = window.getSelection();
14036
+ const winSel = globalThis.getSelection();
14033
14037
  this._savedRange = winSel && winSel.rangeCount > 0 ? winSel.getRangeAt(0).cloneRange() : null;
14034
14038
  this._renderItems(this._items);
14035
14039
  const openX = event.clientX;
@@ -14061,9 +14065,9 @@ var ContextMenu = class {
14061
14065
  const h = this.el.offsetHeight;
14062
14066
  let left = rx;
14063
14067
  let top = ry;
14064
- if (left + w > window.innerWidth - 8) left = window.innerWidth - w - 8;
14068
+ if (left + w > globalThis.innerWidth - 8) left = globalThis.innerWidth - w - 8;
14065
14069
  if (left < 8) left = 8;
14066
- if (top + h > window.innerHeight - 8) top = window.innerHeight - h - 8;
14070
+ if (top + h > globalThis.innerHeight - 8) top = globalThis.innerHeight - h - 8;
14067
14071
  if (top < 8) top = 8;
14068
14072
  this.el.style.left = `${left}px`;
14069
14073
  this.el.style.top = `${top}px`;
@@ -14084,17 +14088,17 @@ var ContextMenu = class {
14084
14088
  let node = range.startContainer;
14085
14089
  if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
14086
14090
  if (!node) return type === "foreColor" ? "#000000" : "transparent";
14087
- const cs = window.getComputedStyle(node);
14091
+ const cs = globalThis.getComputedStyle(node);
14088
14092
  if (type === "foreColor") return cs.color || "#000000";
14089
14093
  const bg = cs.backgroundColor;
14090
14094
  return !bg || bg === "rgba(0, 0, 0, 0)" || bg === "transparent" ? "transparent" : bg;
14091
14095
  }
14092
14096
  /** Restore selection, apply a color command, then hide the menu. */
14093
14097
  _applyColor(type, color) {
14094
- const editable = this.context.layoutInfo && this.context.layoutInfo.editable;
14098
+ const editable = this.context.layoutInfo?.editable;
14095
14099
  if (!editable || !this._savedRange) return;
14096
14100
  editable.focus();
14097
- const sel = window.getSelection();
14101
+ const sel = globalThis.getSelection();
14098
14102
  sel.removeAllRanges();
14099
14103
  sel.addRange(this._savedRange.cloneRange());
14100
14104
  document.execCommand(type, false, color);
@@ -14109,15 +14113,15 @@ var ContextMenu = class {
14109
14113
  copyFormat() {
14110
14114
  const range = this._savedRange;
14111
14115
  if (!range) return;
14112
- const editable = this.context.layoutInfo && this.context.layoutInfo.editable;
14116
+ const editable = this.context.layoutInfo?.editable;
14113
14117
  let node = range.startContainer;
14114
14118
  if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
14115
14119
  if (!node || !editable || !editable.contains(node)) return;
14116
- const cs = window.getComputedStyle(node);
14120
+ const cs = globalThis.getComputedStyle(node);
14117
14121
  const explicitFontFamily = this._findExplicitStyle(node, editable, "fontFamily");
14118
14122
  const explicitFontSize = this._findExplicitStyle(node, editable, "fontSize");
14119
14123
  this._copiedFormat = {
14120
- bold: parseInt(cs.fontWeight, 10) >= 700,
14124
+ bold: Number.parseInt(cs.fontWeight, 10) >= 700,
14121
14125
  italic: cs.fontStyle === "italic" || cs.fontStyle === "oblique",
14122
14126
  underline: (cs.textDecorationLine || "").includes("underline"),
14123
14127
  strikethrough: (cs.textDecorationLine || "").includes("line-through"),
@@ -14148,10 +14152,10 @@ var ContextMenu = class {
14148
14152
  pasteFormat() {
14149
14153
  if (!this._copiedFormat || !this._savedRange) return;
14150
14154
  const fmt = this._copiedFormat;
14151
- const editable = this.context.layoutInfo && this.context.layoutInfo.editable;
14155
+ const editable = this.context.layoutInfo?.editable;
14152
14156
  if (!editable) return;
14153
14157
  editable.focus();
14154
- const sel = window.getSelection();
14158
+ const sel = globalThis.getSelection();
14155
14159
  sel.removeAllRanges();
14156
14160
  sel.addRange(this._savedRange.cloneRange());
14157
14161
  document.execCommand("removeFormat");
@@ -14168,14 +14172,14 @@ var ContextMenu = class {
14168
14172
  const preExisting = new Set(editable.querySelectorAll("font[size=\"7\"]"));
14169
14173
  document.execCommand("fontSize", false, "7");
14170
14174
  editable.querySelectorAll("font[size=\"7\"]").forEach((el) => {
14171
- if (!preExisting.has(el)) el.setAttribute("data-an-tmp", marker);
14175
+ if (!preExisting.has(el)) /** @type {HTMLElement} */ el.dataset.anTmp = marker;
14172
14176
  });
14173
14177
  editable.querySelectorAll(`[data-an-tmp="${marker}"]`).forEach((el) => {
14174
14178
  const span = document.createElement("span");
14175
14179
  span.style.fontSize = fmt.fontSize;
14176
14180
  el.parentNode.insertBefore(span, el);
14177
14181
  while (el.firstChild) span.appendChild(el.firstChild);
14178
- el.parentNode.removeChild(el);
14182
+ el.remove();
14179
14183
  });
14180
14184
  }
14181
14185
  this.context.invoke("editor.afterCommand");
@@ -14183,10 +14187,10 @@ var ContextMenu = class {
14183
14187
  /** Strip all inline formatting from the saved selection. */
14184
14188
  removeFormat() {
14185
14189
  if (!this._savedRange) return;
14186
- const editable = this.context.layoutInfo && this.context.layoutInfo.editable;
14190
+ const editable = this.context.layoutInfo?.editable;
14187
14191
  if (!editable) return;
14188
14192
  editable.focus();
14189
- const sel = window.getSelection();
14193
+ const sel = globalThis.getSelection();
14190
14194
  sel.removeAllRanges();
14191
14195
  sel.addRange(this._savedRange.cloneRange());
14192
14196
  document.execCommand("removeFormat");
@@ -14300,14 +14304,14 @@ var ShortcutsDialog = class {
14300
14304
  destroy() {
14301
14305
  this._disposers.forEach((d) => d());
14302
14306
  this._disposers = [];
14303
- if (this._dialog && this._dialog.parentNode) this._dialog.parentNode.removeChild(this._dialog);
14307
+ this._dialog?.remove();
14304
14308
  this._dialog = null;
14305
14309
  }
14306
14310
  show() {
14307
14311
  if (this._dialog) {
14308
14312
  this._dialog.style.display = "flex";
14309
14313
  this._removeTrap = trapFocus(this._dialog, () => this._close());
14310
- setTimeout(() => this._closeBtn && this._closeBtn.focus(), 50);
14314
+ setTimeout(() => this._closeBtn?.focus(), 50);
14311
14315
  }
14312
14316
  }
14313
14317
  _close() {
@@ -14413,7 +14417,7 @@ var FindReplace = class {
14413
14417
  this._clearHighlights();
14414
14418
  this._disposers.forEach((d) => d());
14415
14419
  this._disposers = [];
14416
- if (this._dialog && this._dialog.parentNode) this._dialog.parentNode.removeChild(this._dialog);
14420
+ if (this._dialog && this._dialog.parentNode) this._dialog.remove();
14417
14421
  this._dialog = null;
14418
14422
  }
14419
14423
  /**
@@ -14656,15 +14660,19 @@ var FindReplace = class {
14656
14660
  const re = this._queryRegex;
14657
14661
  const MAX_RESULTS = 500;
14658
14662
  const walker = document.createTreeWalker(root, 4);
14659
- let node;
14660
- while ((node = walker.nextNode()) && results.length < MAX_RESULTS) {
14663
+ let node = walker.nextNode();
14664
+ while (node && results.length < MAX_RESULTS) {
14661
14665
  re.lastIndex = 0;
14662
14666
  let m;
14663
- while ((m = re.exec(node.textContent)) !== null && results.length < MAX_RESULTS) results.push({
14667
+ while ((m = re.exec(
14668
+ /** @type {Text} */
14669
+ node.textContent
14670
+ )) !== null && results.length < MAX_RESULTS) results.push({
14664
14671
  node,
14665
14672
  start: m.index,
14666
14673
  end: m.index + m[0].length
14667
14674
  });
14675
+ node = walker.nextNode();
14668
14676
  }
14669
14677
  return results;
14670
14678
  }
@@ -14699,7 +14707,7 @@ var FindReplace = class {
14699
14707
  const parent = match.mark.parentNode;
14700
14708
  const textNode = document.createTextNode(replacement);
14701
14709
  parent.insertBefore(textNode, match.mark);
14702
- parent.removeChild(match.mark);
14710
+ match.mark.remove();
14703
14711
  parent.normalize();
14704
14712
  this.context.invoke("editor.afterCommand");
14705
14713
  const savedIndex = this._currentIndex;
@@ -14717,7 +14725,7 @@ var FindReplace = class {
14717
14725
  if (!mark || !mark.parentNode) return;
14718
14726
  const textNode = document.createTextNode(replacement);
14719
14727
  mark.parentNode.insertBefore(textNode, mark);
14720
- mark.parentNode.removeChild(mark);
14728
+ mark.remove();
14721
14729
  });
14722
14730
  if (this.context.layoutInfo.editable) this.context.layoutInfo.editable.normalize();
14723
14731
  this._matches = [];
@@ -14736,7 +14744,7 @@ var FindReplace = class {
14736
14744
  const parent = mark.parentNode;
14737
14745
  if (!parent) return;
14738
14746
  while (mark.firstChild) parent.insertBefore(mark.firstChild, mark);
14739
- parent.removeChild(mark);
14747
+ mark.remove();
14740
14748
  });
14741
14749
  editable.normalize();
14742
14750
  this._matches = [];
@@ -14787,7 +14795,7 @@ function drawCropToCanvas(img, naturalRect, renderW, renderH) {
14787
14795
  resolve(null);
14788
14796
  }
14789
14797
  };
14790
- if (img.src.startsWith("data:") || img.src.startsWith("blob:") || img.src.startsWith(window.location.origin)) {
14798
+ if (img.src.startsWith("data:") || img.src.startsWith("blob:") || img.src.startsWith(globalThis.location.origin)) {
14791
14799
  tryDraw(img);
14792
14800
  return;
14793
14801
  }
@@ -15045,8 +15053,8 @@ var ImageCropOverlay = class {
15045
15053
  this._cropBox.style.top = `${y}px`;
15046
15054
  this._cropBox.style.width = `${w}px`;
15047
15055
  this._cropBox.style.height = `${h}px`;
15048
- const vw = window.innerWidth;
15049
- const vh = window.innerHeight;
15056
+ const vw = globalThis.innerWidth;
15057
+ const vh = globalThis.innerHeight;
15050
15058
  this._scrim.style.clipPath = [
15051
15059
  `polygon(`,
15052
15060
  `0 0, ${vw}px 0, ${vw}px ${vh}px, 0 ${vh}px, 0 0,`,
@@ -15070,7 +15078,7 @@ var ImageCropOverlay = class {
15070
15078
  }
15071
15079
  const margin = 8;
15072
15080
  let tbTop = y + h + margin;
15073
- if (tbTop + 40 > window.innerHeight - margin) tbTop = y - 40 - margin;
15081
+ if (tbTop + 40 > globalThis.innerHeight - margin) tbTop = y - 40 - margin;
15074
15082
  this._toolbar.style.left = `${x}px`;
15075
15083
  this._toolbar.style.top = `${tbTop}px`;
15076
15084
  }
@@ -15197,7 +15205,7 @@ var ImageCropOverlay = class {
15197
15205
  this._close(false);
15198
15206
  return;
15199
15207
  }
15200
- const fmt = img.src.match(/^data:image\/(jpe?g)/i) ? "image/jpeg" : "image/png";
15208
+ const fmt = /^data:image\/(jpe?g)/i.exec(img.src) ? "image/jpeg" : "image/png";
15201
15209
  const quality = fmt === "image/jpeg" ? .92 : void 0;
15202
15210
  const newSrc = canvas.toDataURL(fmt, quality);
15203
15211
  this._close(false);
@@ -15237,7 +15245,7 @@ var ImageCropOverlay = class {
15237
15245
  banner.textContent = msg;
15238
15246
  document.body.appendChild(banner);
15239
15247
  setTimeout(() => {
15240
- if (banner.parentNode) banner.parentNode.removeChild(banner);
15248
+ banner.remove();
15241
15249
  }, 4e3);
15242
15250
  }
15243
15251
  /**
@@ -15252,7 +15260,7 @@ var ImageCropOverlay = class {
15252
15260
  this._cropBox,
15253
15261
  this._toolbar
15254
15262
  ].forEach((el) => {
15255
- if (el && el.parentNode) el.parentNode.removeChild(el);
15263
+ el?.remove();
15256
15264
  });
15257
15265
  this._scrim = null;
15258
15266
  this._cropBox = null;
@@ -15273,7 +15281,7 @@ var ImageCropOverlay = class {
15273
15281
  *
15274
15282
  * Activated when both `autoSave` and `autoSaveRestore` options are true.
15275
15283
  * On initialize it checks localStorage for a draft that is within the
15276
- * `autoSaveRestoreTimeout` day window. If one is found a dismissible banner
15284
+ * `autoSaveRestoreTimeout` day globalThis. If one is found a dismissible banner
15277
15285
  * is prepended to the editor container.
15278
15286
  */
15279
15287
  var AutoSaveRestore = class {
@@ -15359,7 +15367,7 @@ var AutoSaveRestore = class {
15359
15367
  this._removeBanner();
15360
15368
  }
15361
15369
  _removeBanner() {
15362
- if (this._banner && this._banner.parentNode) this._banner.parentNode.removeChild(this._banner);
15370
+ this._banner?.remove();
15363
15371
  this._banner = null;
15364
15372
  }
15365
15373
  };
@@ -15422,8 +15430,8 @@ var MarkdownShortcuts = class {
15422
15430
  * @returns {{ text: string, range: Range, lineNode: Node } | null}
15423
15431
  */
15424
15432
  _getLineContext() {
15425
- const sel = window.getSelection();
15426
- if (!sel || !sel.rangeCount) return null;
15433
+ const sel = globalThis.getSelection();
15434
+ if (!sel?.rangeCount) return null;
15427
15435
  const range = sel.getRangeAt(0);
15428
15436
  if (!range.collapsed) return null;
15429
15437
  const editable = this.context.layoutInfo.editable;
@@ -15442,7 +15450,7 @@ var MarkdownShortcuts = class {
15442
15450
  }
15443
15451
  _isBlock(node) {
15444
15452
  if (node.nodeType !== Node.ELEMENT_NODE) return false;
15445
- const display = window.getComputedStyle(node).display;
15453
+ const display = globalThis.getComputedStyle(node).display;
15446
15454
  return display === "block" || display === "list-item" || display === "table-cell";
15447
15455
  }
15448
15456
  /** Applies block rule on Space key. Returns true if a rule fired. */
@@ -15473,7 +15481,7 @@ var MarkdownShortcuts = class {
15473
15481
  }
15474
15482
  ];
15475
15483
  for (const { re, handler } of blockPatterns) {
15476
- const m = text.match(re);
15484
+ const m = re.exec(text);
15477
15485
  if (m) {
15478
15486
  handler(m);
15479
15487
  return true;
@@ -15497,8 +15505,8 @@ var MarkdownShortcuts = class {
15497
15505
  return false;
15498
15506
  }
15499
15507
  _selectLineAndDelete() {
15500
- const sel = window.getSelection();
15501
- if (!sel || !sel.rangeCount) return;
15508
+ const sel = globalThis.getSelection();
15509
+ if (!sel?.rangeCount) return;
15502
15510
  const range = sel.getRangeAt(0);
15503
15511
  const startRange = document.createRange();
15504
15512
  startRange.setStart(range.startContainer.parentNode || range.startContainer, 0);
@@ -15536,8 +15544,8 @@ var MarkdownShortcuts = class {
15536
15544
  this.context.triggerEvent("change", this.context.getHTML());
15537
15545
  }
15538
15546
  _onInput() {
15539
- const sel = window.getSelection();
15540
- if (!sel || !sel.rangeCount) return;
15547
+ const sel = globalThis.getSelection();
15548
+ if (!sel?.rangeCount) return;
15541
15549
  const range = sel.getRangeAt(0);
15542
15550
  if (!range.collapsed) return;
15543
15551
  if (!this.context.layoutInfo.editable.contains(range.startContainer)) return;
@@ -15565,7 +15573,7 @@ var MarkdownShortcuts = class {
15565
15573
  ];
15566
15574
  const upToCursor = text.slice(0, offset);
15567
15575
  for (const { re, tag } of inlineRules) {
15568
- const m = upToCursor.match(re);
15576
+ const m = re.exec(upToCursor);
15569
15577
  if (!m) continue;
15570
15578
  const matchStart = upToCursor.length - m[0].length;
15571
15579
  const matchEnd = offset;
@@ -15576,11 +15584,8 @@ var MarkdownShortcuts = class {
15576
15584
  el.textContent = innerText;
15577
15585
  const beforeNode = document.createTextNode(before);
15578
15586
  const afterNode = document.createTextNode("​" + after);
15579
- const parent = node.parentNode;
15580
- parent.insertBefore(beforeNode, node);
15581
- parent.insertBefore(el, node);
15582
- parent.insertBefore(afterNode, node);
15583
- parent.removeChild(node);
15587
+ /** @type {ChildNode} */ node.before(beforeNode, el, afterNode);
15588
+ /** @type {ChildNode} */ node.remove();
15584
15589
  const newRange = document.createRange();
15585
15590
  newRange.setStart(afterNode, 1);
15586
15591
  newRange.collapse(true);
@@ -15651,12 +15656,12 @@ var _ACTIONS = {
15651
15656
  strikethrough: (ctx) => ctx.invoke("editor.strikethrough"),
15652
15657
  link: (ctx) => ctx.invoke("linkDialog.show"),
15653
15658
  removeFormat: (ctx) => {
15654
- const editable = ctx.layoutInfo && ctx.layoutInfo.editable;
15659
+ const editable = ctx.layoutInfo?.editable;
15655
15660
  if (!editable) return;
15656
15661
  editable.focus();
15657
15662
  document.execCommand("removeFormat");
15658
- const sel = window.getSelection();
15659
- if (sel && sel.rangeCount > 0 && !sel.getRangeAt(0).collapsed) {
15663
+ const sel = globalThis.getSelection();
15664
+ if (sel?.rangeCount > 0 && !sel.getRangeAt(0).collapsed) {
15660
15665
  const range = sel.getRangeAt(0);
15661
15666
  const ancestor = range.commonAncestorContainer;
15662
15667
  const root = ancestor.nodeType === 1 ? ancestor : ancestor.parentElement;
@@ -15714,15 +15719,15 @@ var BubbleToolbar = class {
15714
15719
  const d6 = this.context.on("contextMenu:hide", () => {
15715
15720
  this._contextMenuOpen = false;
15716
15721
  });
15717
- const d7 = on(window, "scroll", () => this._hide(), { passive: true });
15718
- const d8 = on(window, "resize", () => this._hide(), { passive: true });
15722
+ const d7 = on(globalThis, "scroll", () => this._hide(), { passive: true });
15723
+ const d8 = on(globalThis, "resize", () => this._hide(), { passive: true });
15719
15724
  this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8);
15720
15725
  return this;
15721
15726
  }
15722
15727
  destroy() {
15723
- if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);
15728
+ this._el?.remove();
15724
15729
  this._el = null;
15725
- if (this._picker && this._picker.parentNode) this._picker.parentNode.removeChild(this._picker);
15730
+ this._picker?.remove();
15726
15731
  this._picker = null;
15727
15732
  this._disposers.forEach((d) => d());
15728
15733
  this._disposers = [];
@@ -15836,15 +15841,15 @@ var BubbleToolbar = class {
15836
15841
  pickerAny._colorInput = colorInput;
15837
15842
  }
15838
15843
  _openColorPicker(type, anchorBtn) {
15839
- const sel = window.getSelection();
15840
- if (sel && sel.rangeCount > 0) this._savedRange = sel.getRangeAt(0).cloneRange();
15844
+ const sel = globalThis.getSelection();
15845
+ if (sel?.rangeCount > 0) this._savedRange = sel.getRangeAt(0).cloneRange();
15841
15846
  this._pickerType = type;
15842
15847
  const pickerAny = this._picker;
15843
15848
  const palette = pickerAny._paletteEl;
15844
15849
  const noColorBtn = pickerAny._noColorBtn;
15845
15850
  if (type === "hiliteColor") {
15846
15851
  if (!palette.contains(noColorBtn)) palette.appendChild(noColorBtn);
15847
- } else if (palette.contains(noColorBtn)) palette.removeChild(noColorBtn);
15852
+ } else if (palette.contains(noColorBtn)) noColorBtn.remove();
15848
15853
  /** @type {any} */ this._picker._colorInput.value = type === "foreColor" ? "#000000" : "#ffff00";
15849
15854
  this._picker.style.display = "block";
15850
15855
  const pw = this._picker.offsetWidth;
@@ -15853,7 +15858,7 @@ var BubbleToolbar = class {
15853
15858
  let top = toolbarRect.top - ph - 6;
15854
15859
  if (top < 8) top = toolbarRect.bottom + 6;
15855
15860
  let left = anchorBtn.getBoundingClientRect().left;
15856
- left = Math.max(8, Math.min(left, window.innerWidth - pw - 8));
15861
+ left = Math.max(8, Math.min(left, globalThis.innerWidth - pw - 8));
15857
15862
  this._picker.style.left = `${left}px`;
15858
15863
  this._picker.style.top = `${top}px`;
15859
15864
  }
@@ -15863,10 +15868,10 @@ var BubbleToolbar = class {
15863
15868
  }
15864
15869
  /** Restore the saved selection, apply execCommand, update the color strip, then close the picker. */
15865
15870
  _applyColor(type, color) {
15866
- const editable = this.context.layoutInfo && this.context.layoutInfo.editable;
15871
+ const editable = this.context.layoutInfo?.editable;
15867
15872
  if (!editable || !this._savedRange) return;
15868
15873
  editable.focus();
15869
- const sel = window.getSelection();
15874
+ const sel = globalThis.getSelection();
15870
15875
  sel.removeAllRanges();
15871
15876
  try {
15872
15877
  sel.addRange(this._savedRange.cloneRange());
@@ -15877,8 +15882,7 @@ var BubbleToolbar = class {
15877
15882
  if (!document.execCommand(cmd, false, color) && cmd === "hiliteColor") document.execCommand("backColor", false, color);
15878
15883
  this.context.invoke("editor.afterCommand");
15879
15884
  const name = type === "hiliteColor" ? "hiliteColor" : "foreColor";
15880
- const btn = this._el && this._el.querySelector(`[data-name="${name}"]`);
15881
- const strip = btn && btn.querySelector(".an-bubble-color-strip");
15885
+ const strip = (this._el?.querySelector(`[data-name="${name}"]`))?.querySelector(".an-bubble-color-strip");
15882
15886
  if (strip) /** @type {HTMLElement} */ strip.style.background = color === "transparent" ? "transparent" : color;
15883
15887
  this._closeColorPicker();
15884
15888
  this._syncActive();
@@ -15893,14 +15897,14 @@ var BubbleToolbar = class {
15893
15897
  const gap = 8;
15894
15898
  let left = rect.left + rect.width / 2 - bw / 2;
15895
15899
  let top = rect.top - bh - gap;
15896
- left = Math.max(8, Math.min(left, window.innerWidth - bw - 8));
15900
+ left = Math.max(8, Math.min(left, globalThis.innerWidth - bw - 8));
15897
15901
  if (top < 8) top = rect.bottom + gap;
15898
15902
  const tableTooltipEl = document.querySelector(".an-table-tooltip");
15899
15903
  if (tableTooltipEl && tableTooltipEl.style.display !== "none") {
15900
15904
  const ttRect = tableTooltipEl.getBoundingClientRect();
15901
15905
  if (top < ttRect.bottom + gap && top + bh > ttRect.top - gap) {
15902
15906
  top = rect.bottom + gap;
15903
- if (top + bh > window.innerHeight - 8) top = ttRect.bottom + gap;
15907
+ if (top + bh > globalThis.innerHeight - 8) top = ttRect.bottom + gap;
15904
15908
  }
15905
15909
  }
15906
15910
  el.style.top = `${top}px`;
@@ -15926,17 +15930,15 @@ var BubbleToolbar = class {
15926
15930
  /** Read the current selection's color and update the color-strip indicators. */
15927
15931
  _syncColorStrips() {
15928
15932
  if (!this._el) return;
15929
- const sel = window.getSelection();
15933
+ const sel = globalThis.getSelection();
15930
15934
  if (!sel || !sel.rangeCount) return;
15931
15935
  let node = sel.getRangeAt(0).startContainer;
15932
15936
  if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
15933
15937
  if (!node) return;
15934
- const cs = window.getComputedStyle(node);
15935
- const foreBtn = this._el.querySelector("[data-name=\"foreColor\"]");
15936
- const foreStrip = foreBtn && foreBtn.querySelector(".an-bubble-color-strip");
15938
+ const cs = globalThis.getComputedStyle(node);
15939
+ const foreStrip = this._el.querySelector("[data-name=\"foreColor\"]")?.querySelector(".an-bubble-color-strip");
15937
15940
  if (foreStrip) /** @type {HTMLElement} */ foreStrip.style.background = cs.color || "#000000";
15938
- const hiliteBtn = this._el.querySelector("[data-name=\"hiliteColor\"]");
15939
- const hiliteStrip = hiliteBtn && hiliteBtn.querySelector(".an-bubble-color-strip");
15941
+ const hiliteStrip = this._el.querySelector("[data-name=\"hiliteColor\"]")?.querySelector(".an-bubble-color-strip");
15940
15942
  if (hiliteStrip) {
15941
15943
  const bg = cs.backgroundColor;
15942
15944
  /** @type {HTMLElement} */ hiliteStrip.style.background = !bg || bg === "rgba(0, 0, 0, 0)" || bg === "transparent" ? "transparent" : bg;
@@ -15947,7 +15949,7 @@ var BubbleToolbar = class {
15947
15949
  this._rafId = requestAnimationFrame(() => {
15948
15950
  if (this._contextMenuOpen) return;
15949
15951
  if (this._picker && this._picker.style.display !== "none") return;
15950
- const sel = window.getSelection();
15952
+ const sel = globalThis.getSelection();
15951
15953
  if (!sel || sel.isCollapsed || !sel.rangeCount) {
15952
15954
  this._hide();
15953
15955
  return;
@@ -15970,8 +15972,8 @@ var BubbleToolbar = class {
15970
15972
  }
15971
15973
  _onMousedown(e) {
15972
15974
  if (!this._visible) return;
15973
- if (this._el && this._el.contains(e.target)) return;
15974
- if (this._picker && this._picker.contains(e.target)) return;
15975
+ if (this._el?.contains(e.target)) return;
15976
+ if (this._picker?.contains(e.target)) return;
15975
15977
  if (this.context.layoutInfo.editable.contains(e.target)) return;
15976
15978
  this._hide();
15977
15979
  }
@@ -16056,7 +16058,7 @@ var Mention = class {
16056
16058
  }
16057
16059
  destroy() {
16058
16060
  clearTimeout(this._debounceTimer);
16059
- if (this._dropdown && this._dropdown.parentNode) this._dropdown.parentNode.removeChild(this._dropdown);
16061
+ this._dropdown?.remove();
16060
16062
  this._dropdown = null;
16061
16063
  this._disposers.forEach((d) => d());
16062
16064
  this._disposers = [];
@@ -16120,8 +16122,8 @@ var Mention = class {
16120
16122
  const ddw = dd.offsetWidth;
16121
16123
  let top = rect.bottom + 4;
16122
16124
  let left = rect.left;
16123
- if (rect.bottom + ddh + 8 > window.innerHeight) top = rect.top - ddh - 4;
16124
- left = Math.max(8, Math.min(left, window.innerWidth - ddw - 8));
16125
+ if (rect.bottom + ddh + 8 > globalThis.innerHeight) top = rect.top - ddh - 4;
16126
+ left = Math.max(8, Math.min(left, globalThis.innerWidth - ddw - 8));
16125
16127
  dd.style.top = `${top}px`;
16126
16128
  dd.style.left = `${left}px`;
16127
16129
  dd.style.visibility = "";
@@ -16145,7 +16147,7 @@ var Mention = class {
16145
16147
  * collapsed range is reliable at this point but often empty inside async callbacks.
16146
16148
  */
16147
16149
  _captureCaretRect() {
16148
- if (this._triggerNode && this._triggerNode.isConnected) try {
16150
+ if (this._triggerNode?.isConnected) try {
16149
16151
  const r = document.createRange();
16150
16152
  const end = Math.min(this._triggerOffset + 1, this._triggerNode.textContent.length);
16151
16153
  r.setStart(this._triggerNode, this._triggerOffset);
@@ -16156,13 +16158,13 @@ var Mention = class {
16156
16158
  return;
16157
16159
  }
16158
16160
  } catch (_) {}
16159
- const sel = window.getSelection();
16161
+ const sel = globalThis.getSelection();
16160
16162
  if (!sel || !sel.rangeCount) return;
16161
16163
  const rects = sel.getRangeAt(0).getClientRects();
16162
16164
  if (rects.length > 0) this._caretRect = rects[rects.length - 1];
16163
16165
  }
16164
16166
  _getQueryAtCursor() {
16165
- const sel = window.getSelection();
16167
+ const sel = globalThis.getSelection();
16166
16168
  if (!sel || !sel.rangeCount) return null;
16167
16169
  const range = sel.getRangeAt(0);
16168
16170
  if (!range.collapsed) return null;
@@ -16219,7 +16221,7 @@ var Mention = class {
16219
16221
  }
16220
16222
  _onDocClick(e) {
16221
16223
  if (!this._open) return;
16222
- if (this._dropdown && this._dropdown.contains(e.target)) return;
16224
+ if (this._dropdown?.contains(e.target)) return;
16223
16225
  this._hideDropdown();
16224
16226
  }
16225
16227
  _select(index) {
@@ -16228,7 +16230,7 @@ var Mention = class {
16228
16230
  if (this._triggerNode) {
16229
16231
  const node = this._triggerNode;
16230
16232
  node.textContent = node.textContent.slice(0, this._triggerOffset) + node.textContent.slice(this._triggerOffset + this._cfg.trigger.length + this._query.length);
16231
- const sel = window.getSelection();
16233
+ const sel = globalThis.getSelection();
16232
16234
  const range = document.createRange();
16233
16235
  range.setStart(node, this._triggerOffset);
16234
16236
  range.collapse(true);
@@ -16589,23 +16591,27 @@ var Context = class {
16589
16591
  a.style.display = "none";
16590
16592
  document.body.appendChild(a);
16591
16593
  a.click();
16592
- document.body.removeChild(a);
16594
+ a.remove();
16593
16595
  URL.revokeObjectURL(url);
16594
16596
  }
16595
16597
  /**
16596
- * Opens the editor content in a new window and triggers the browser print dialog.
16598
+ * Opens the editor content in a new globalThis and triggers the browser print dialog.
16597
16599
  * @param {string} [title='']
16598
16600
  */
16599
16601
  print(title = "") {
16600
16602
  const content = this.getHTML();
16601
- const safeTitle = (title || "").replace(/</g, "&lt;").replace(/>/g, "&gt;");
16602
- const w = window.open("", "_blank");
16603
- if (!w) return;
16604
- w.document.write(`<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>${safeTitle}</title><style>body{font-family:system-ui,-apple-system,"Segoe UI",Roboto,Arial,sans-serif;font-size:14px;line-height:1.6;padding:20mm;color:#111827;}ul.an-checklist{list-style:none;padding-left:0;}ul.an-checklist li{padding-left:24px;position:relative;margin:2px 0;}ul.an-checklist li input[type="checkbox"]{position:absolute;left:0;top:3px;}code{background:#f3f4f6;border-radius:3px;padding:.1em .35em;font-family:monospace;}pre{background:#f3f4f6;padding:.75em 1em;border-radius:4px;overflow-x:auto;}table{border-collapse:collapse;}td,th{border:1px solid #d1d5db;padding:4px 8px;}</style></head><body>${content}</body></html>`);
16605
- w.document.close();
16606
- w.onload = () => {
16603
+ const markup = `<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>${(title || "").replace(/[<>&"']/g, (c) => `&#${c.charCodeAt(0)};`)}</title><style>body{font-family:system-ui,-apple-system,"Segoe UI",Roboto,Arial,sans-serif;font-size:14px;line-height:1.6;padding:20mm;color:#111827;}ul.an-checklist{list-style:none;padding-left:0;}ul.an-checklist li{padding-left:24px;position:relative;margin:2px 0;}ul.an-checklist li input[type="checkbox"]{position:absolute;left:0;top:3px;}code{background:#f3f4f6;border-radius:3px;padding:.1em .35em;font-family:monospace;}pre{background:#f3f4f6;padding:.75em 1em;border-radius:4px;overflow-x:auto;}table{border-collapse:collapse;}td,th{border:1px solid #d1d5db;padding:4px 8px;}</style></head><body>${content}</body></html>`;
16604
+ const blob = new Blob([markup], { type: "text/html" });
16605
+ const url = URL.createObjectURL(blob);
16606
+ const w = globalThis.open(url, "_blank");
16607
+ if (!w) {
16608
+ URL.revokeObjectURL(url);
16609
+ return;
16610
+ }
16611
+ w.addEventListener("load", () => {
16607
16612
  w.print();
16608
- };
16613
+ URL.revokeObjectURL(url);
16614
+ });
16609
16615
  }
16610
16616
  /**
16611
16617
  * Sets whether the editor is disabled (readonly).
@@ -16643,10 +16649,10 @@ var Context = class {
16643
16649
  this._disposers.forEach((d) => d());
16644
16650
  this._disposers = [];
16645
16651
  const container = this.layoutInfo.container;
16646
- const wasDark = container && container.classList.contains("an-theme-dark");
16647
- if (container && container.parentNode) {
16652
+ const wasDark = container?.classList.contains("an-theme-dark");
16653
+ if (container?.parentNode) {
16648
16654
  this.targetEl.style.display = "";
16649
- container.parentNode.removeChild(container);
16655
+ container.remove();
16650
16656
  }
16651
16657
  if (wasDark && !document.querySelector(".an-container.an-theme-dark")) document.body.classList.remove("an-theme-dark");
16652
16658
  if (typeof this.options.onDestroy === "function") this.options.onDestroy(this);
@@ -16712,7 +16718,7 @@ function tail(arr, n = 1) {
16712
16718
  * @returns {T[]}
16713
16719
  */
16714
16720
  function flatten(arr) {
16715
- return arr.reduce((acc, val) => acc.concat(val), []);
16721
+ return arr.flat();
16716
16722
  }
16717
16723
  /**
16718
16724
  * Returns unique elements of an array (using Set).
@@ -16791,7 +16797,7 @@ var env = {
16791
16797
  /** True if running on mobile */
16792
16798
  isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent),
16793
16799
  /** True if touch is supported */
16794
- isTouch: "ontouchstart" in window || navigator.maxTouchPoints > 0,
16800
+ isTouch: "ontouchstart" in globalThis || navigator.maxTouchPoints > 0,
16795
16801
  /** Modifier key name depending on platform */
16796
16802
  modifierKey: /Macintosh/.test(userAgent) ? "metaKey" : "ctrlKey"
16797
16803
  };