autumnnote 1.6.0 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/autumnnote.css +0 -2
- package/dist/autumnnote.es.js +468 -552
- package/dist/autumnnote.es.js.map +1 -1
- package/dist/autumnnote.umd.js +461 -546
- package/dist/autumnnote.umd.js.map +1 -1
- package/package.json +21 -3
- package/src/js/Context.js +21 -16
- package/src/js/core/dom.js +9 -9
- package/src/js/core/env.js +1 -1
- package/src/js/core/func.js +1 -1
- package/src/js/core/lists.js +1 -1
- package/src/js/core/markdown.js +18 -18
- package/src/js/core/range.js +6 -6
- package/src/js/editing/History.js +4 -4
- package/src/js/editing/Style.js +32 -32
- package/src/js/editing/Table.js +2 -2
- package/src/js/editing/Typing.js +15 -15
- package/src/js/index.js +1 -1
- package/src/js/module/AutoSaveRestore.js +2 -4
- package/src/js/module/BaseDialog.js +126 -0
- package/src/js/module/BubbleToolbar.js +25 -25
- package/src/js/module/Buttons.js +4 -4
- package/src/js/module/Clipboard.js +12 -13
- package/src/js/module/CodeTooltip.js +14 -16
- package/src/js/module/Codeview.js +3 -5
- package/src/js/module/ContextMenu.js +27 -27
- package/src/js/module/Editor.js +17 -18
- package/src/js/module/EmojiDialog.js +5 -5
- package/src/js/module/FindReplace.js +8 -7
- package/src/js/module/IconDialog.js +13 -15
- package/src/js/module/ImageCropOverlay.js +7 -7
- package/src/js/module/ImageDialog.js +12 -82
- package/src/js/module/ImageResizer.js +4 -4
- package/src/js/module/ImageTooltip.js +14 -14
- package/src/js/module/LinkDialog.js +13 -79
- package/src/js/module/LinkTooltip.js +12 -12
- package/src/js/module/MarkdownShortcuts.js +11 -14
- package/src/js/module/Mention.js +8 -10
- package/src/js/module/Placeholder.js +1 -1
- package/src/js/module/ShortcutsDialog.js +2 -4
- package/src/js/module/Statusbar.js +3 -5
- package/src/js/module/TableTooltip.js +30 -32
- package/src/js/module/Toolbar.js +21 -21
- package/src/js/module/VideoDialog.js +17 -87
- package/src/js/module/VideoResizer.js +5 -7
- package/src/js/module/VideoTooltip.js +7 -7
- package/src/js/renderer.js +1 -1
- package/src/styles/autumnnote.scss +0 -3
package/dist/autumnnote.es.js
CHANGED
|
@@ -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
|
|
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)
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
|
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,
|
|
419
|
-
box.style.top = `${Math.max(0, Math.min(ev.clientY - startY,
|
|
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
|
|
466
|
+
* Select this wrapped range in the globalThis.
|
|
466
467
|
*/
|
|
467
468
|
select() {
|
|
468
|
-
const sel =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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.
|
|
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
|
|
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 =
|
|
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
|
|
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.
|
|
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
|
-
|
|
795
|
-
if (checkUl.children.length === 0) 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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
889
|
-
|
|
889
|
+
codeEl.remove();
|
|
890
|
+
parent?.normalize();
|
|
890
891
|
if (movedChildren.length > 0) try {
|
|
891
892
|
const firstMoved = movedChildren[0];
|
|
892
|
-
const lastMoved = movedChildren
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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.
|
|
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
|
-
|
|
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("").
|
|
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.
|
|
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 =
|
|
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 !!
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
|
4871
|
-
var isZwsAnchor = (n) => !!(n
|
|
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 =
|
|
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 =
|
|
4892
|
-
if (sel
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
5053
|
+
const sel = globalThis.getSelection();
|
|
5054
5054
|
sel.removeAllRanges();
|
|
5055
5055
|
sel.addRange(nr);
|
|
5056
5056
|
return true;
|
|
5057
5057
|
}
|
|
5058
|
-
const checkLi = el
|
|
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 =
|
|
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
|
|
5106
|
+
if (para?.nodeName.toUpperCase() === "PRE") {
|
|
5107
5107
|
event.preventDefault();
|
|
5108
5108
|
execCommand("insertText", "\n");
|
|
5109
5109
|
return true;
|
|
5110
5110
|
}
|
|
5111
|
-
if (para
|
|
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 || "")
|
|
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().
|
|
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.
|
|
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 =
|
|
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 =
|
|
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
|
|
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).
|
|
5357
|
+
return String(v).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
5357
5358
|
}
|
|
5358
5359
|
function _escAttr(v) {
|
|
5359
|
-
return String(v).
|
|
5360
|
+
return String(v).replaceAll("&", "&").replaceAll("\"", """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 (!(
|
|
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.
|
|
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.
|
|
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.
|
|
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().
|
|
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 =
|
|
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.
|
|
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 =
|
|
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 =
|
|
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 ?? "").
|
|
5993
|
+
return String(str ?? "").replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<").replaceAll(">", ">");
|
|
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.
|
|
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.
|
|
6176
|
-
const c = +cell.
|
|
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 >
|
|
6191
|
-
if (top + ph >
|
|
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.
|
|
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.
|
|
6218
|
-
const cols = +cell.
|
|
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.
|
|
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 =
|
|
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 =
|
|
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 >
|
|
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
|
-
|
|
6402
|
-
this._disposers.push(d1, d2, d2b, d3, d3b, d4, d5, d6, () => document.removeEventListener("scroll", onScrollResize, { capture: true }), () =>
|
|
6403
|
-
if (popup.parentNode) 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 =
|
|
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 =
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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 || "").
|
|
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
|
-
|
|
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 ||
|
|
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.
|
|
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 =
|
|
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.
|
|
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 =
|
|
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.
|
|
7101
|
+
return str.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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 (
|
|
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;
|
|
@@ -7276,15 +7282,13 @@ var Fullscreen = class {
|
|
|
7276
7282
|
}
|
|
7277
7283
|
};
|
|
7278
7284
|
//#endregion
|
|
7279
|
-
//#region src/js/module/
|
|
7285
|
+
//#region src/js/module/BaseDialog.js
|
|
7280
7286
|
/**
|
|
7281
|
-
*
|
|
7282
|
-
*
|
|
7287
|
+
* Shared lifecycle and shell-building logic for all modal dialogs.
|
|
7288
|
+
* Subclasses implement _buildDialog() for their specific form fields.
|
|
7283
7289
|
*/
|
|
7284
|
-
var
|
|
7285
|
-
/**
|
|
7286
|
-
* @param {import('../Context.js').Context} context
|
|
7287
|
-
*/
|
|
7290
|
+
var BaseDialog = class {
|
|
7291
|
+
/** @param {import('../Context.js').Context} context */
|
|
7288
7292
|
constructor(context) {
|
|
7289
7293
|
this.context = context;
|
|
7290
7294
|
this.options = context.options;
|
|
@@ -7292,6 +7296,9 @@ var LinkDialog = class {
|
|
|
7292
7296
|
this._dialog = null;
|
|
7293
7297
|
this._disposers = [];
|
|
7294
7298
|
this._savedRange = null;
|
|
7299
|
+
/** @type {HTMLElement|null} First focusable input; set by subclass in _buildDialog(). */
|
|
7300
|
+
this._firstInput = null;
|
|
7301
|
+
this._removeTrap = null;
|
|
7295
7302
|
}
|
|
7296
7303
|
initialize() {
|
|
7297
7304
|
this._dialog = this._buildDialog();
|
|
@@ -7301,36 +7308,113 @@ var LinkDialog = class {
|
|
|
7301
7308
|
destroy() {
|
|
7302
7309
|
this._disposers.forEach((d) => d());
|
|
7303
7310
|
this._disposers = [];
|
|
7304
|
-
if (this._dialog
|
|
7311
|
+
if (this._dialog?.parentNode) this._dialog.remove();
|
|
7305
7312
|
this._dialog = null;
|
|
7306
7313
|
}
|
|
7307
|
-
/**
|
|
7308
|
-
|
|
7309
|
-
* Pre-fills with the currently selected link if present.
|
|
7310
|
-
*/
|
|
7311
|
-
show() {
|
|
7314
|
+
/** Saves the current selection range before opening the dialog. */
|
|
7315
|
+
_saveRange() {
|
|
7312
7316
|
withSavedRange((range) => {
|
|
7313
7317
|
this._savedRange = range;
|
|
7314
7318
|
});
|
|
7315
|
-
this._prefill();
|
|
7316
|
-
this._open();
|
|
7317
7319
|
}
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
+
_open() {
|
|
7321
|
+
if (this._dialog) {
|
|
7322
|
+
this._dialog.style.display = "flex";
|
|
7323
|
+
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7324
|
+
setTimeout(() => this._firstInput && this._firstInput.focus(), 50);
|
|
7325
|
+
}
|
|
7326
|
+
}
|
|
7327
|
+
_close() {
|
|
7328
|
+
if (this._dialog) this._dialog.style.display = "none";
|
|
7329
|
+
if (this._removeTrap) {
|
|
7330
|
+
this._removeTrap();
|
|
7331
|
+
this._removeTrap = null;
|
|
7332
|
+
}
|
|
7333
|
+
this._savedRange = null;
|
|
7334
|
+
}
|
|
7335
|
+
/**
|
|
7336
|
+
* Builds the overlay + box + header shell common to all dialogs.
|
|
7337
|
+
* Also wires up draggable and overlay-click-to-close.
|
|
7338
|
+
* @param {string} ariaLabel
|
|
7339
|
+
* @param {string} iconHtml Raw SVG string for the dialog icon
|
|
7340
|
+
* @param {string} titleText
|
|
7341
|
+
* @returns {{ overlay: HTMLElement, box: HTMLElement }}
|
|
7342
|
+
*/
|
|
7343
|
+
_buildDialogShell(ariaLabel, iconHtml, titleText) {
|
|
7320
7344
|
const overlay = createElement("div", {
|
|
7321
7345
|
class: "an-dialog-overlay",
|
|
7322
7346
|
role: "dialog",
|
|
7323
7347
|
"aria-modal": "true",
|
|
7324
|
-
"aria-label":
|
|
7348
|
+
"aria-label": ariaLabel
|
|
7325
7349
|
});
|
|
7326
7350
|
const box = createElement("div", { class: "an-dialog-box" });
|
|
7327
7351
|
const header = createElement("div", { class: "an-dialog-header" });
|
|
7328
7352
|
const iconEl = createElement("span", { class: "an-dialog-icon" });
|
|
7329
|
-
iconEl.innerHTML =
|
|
7330
|
-
const
|
|
7331
|
-
|
|
7353
|
+
iconEl.innerHTML = iconHtml;
|
|
7354
|
+
const titleEl = createElement("h3", { class: "an-dialog-title" });
|
|
7355
|
+
titleEl.textContent = titleText;
|
|
7332
7356
|
header.appendChild(iconEl);
|
|
7333
|
-
header.appendChild(
|
|
7357
|
+
header.appendChild(titleEl);
|
|
7358
|
+
box.appendChild(header);
|
|
7359
|
+
overlay.appendChild(box);
|
|
7360
|
+
makeDraggable(header, box);
|
|
7361
|
+
const d = on(overlay, "click", (e) => {
|
|
7362
|
+
if (e.target === overlay) this._close();
|
|
7363
|
+
});
|
|
7364
|
+
this._disposers.push(d);
|
|
7365
|
+
return {
|
|
7366
|
+
overlay,
|
|
7367
|
+
box
|
|
7368
|
+
};
|
|
7369
|
+
}
|
|
7370
|
+
/**
|
|
7371
|
+
* Builds an action button row with a primary insert button and a cancel button.
|
|
7372
|
+
* Disposers are registered automatically.
|
|
7373
|
+
* @param {string} insertLabel
|
|
7374
|
+
* @param {string} cancelLabel
|
|
7375
|
+
* @param {() => void} onInsert
|
|
7376
|
+
* @returns {HTMLElement}
|
|
7377
|
+
*/
|
|
7378
|
+
_buildButtonRow(insertLabel, cancelLabel, onInsert) {
|
|
7379
|
+
const btnRow = createElement("div", { class: "an-dialog-actions" });
|
|
7380
|
+
const insertBtn = createElement("button", {
|
|
7381
|
+
type: "button",
|
|
7382
|
+
class: "an-btn an-btn-primary"
|
|
7383
|
+
});
|
|
7384
|
+
insertBtn.textContent = insertLabel;
|
|
7385
|
+
const cancelBtn = createElement("button", {
|
|
7386
|
+
type: "button",
|
|
7387
|
+
class: "an-btn"
|
|
7388
|
+
});
|
|
7389
|
+
cancelBtn.textContent = cancelLabel;
|
|
7390
|
+
btnRow.appendChild(insertBtn);
|
|
7391
|
+
btnRow.appendChild(cancelBtn);
|
|
7392
|
+
const d1 = on(insertBtn, "click", onInsert);
|
|
7393
|
+
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7394
|
+
this._disposers.push(d1, d2);
|
|
7395
|
+
return btnRow;
|
|
7396
|
+
}
|
|
7397
|
+
};
|
|
7398
|
+
//#endregion
|
|
7399
|
+
//#region src/js/module/LinkDialog.js
|
|
7400
|
+
/**
|
|
7401
|
+
* LinkDialog.js - Dialog for inserting / editing hyperlinks
|
|
7402
|
+
* Inspired by Summernote's LinkDialog — rewritten without jQuery
|
|
7403
|
+
*/
|
|
7404
|
+
var ICON_SVG$2 = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>`;
|
|
7405
|
+
var LinkDialog = class extends BaseDialog {
|
|
7406
|
+
/**
|
|
7407
|
+
* Opens the link dialog.
|
|
7408
|
+
* Pre-fills with the currently selected link if present.
|
|
7409
|
+
*/
|
|
7410
|
+
show() {
|
|
7411
|
+
this._saveRange();
|
|
7412
|
+
this._prefill();
|
|
7413
|
+
this._open();
|
|
7414
|
+
}
|
|
7415
|
+
_buildDialog() {
|
|
7416
|
+
const L = this.context.locale.linkDialog;
|
|
7417
|
+
const { overlay, box } = this._buildDialogShell(L.ariaLabel, ICON_SVG$2, L.title);
|
|
7334
7418
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7335
7419
|
urlLabel.textContent = L.url;
|
|
7336
7420
|
const urlInput = createElement("input", {
|
|
@@ -7342,6 +7426,7 @@ var LinkDialog = class {
|
|
|
7342
7426
|
autocomplete: "off"
|
|
7343
7427
|
});
|
|
7344
7428
|
this._urlInput = urlInput;
|
|
7429
|
+
this._firstInput = urlInput;
|
|
7345
7430
|
const textLabel = createElement("label", { class: "an-label" });
|
|
7346
7431
|
textLabel.textContent = L.displayText;
|
|
7347
7432
|
const textInput = createElement("input", {
|
|
@@ -7362,27 +7447,8 @@ var LinkDialog = class {
|
|
|
7362
7447
|
this._tabCheckbox = tabCheckbox;
|
|
7363
7448
|
tabLabel.appendChild(tabCheckbox);
|
|
7364
7449
|
tabLabel.appendChild(document.createTextNode(" " + L.openInNewTab));
|
|
7365
|
-
const btnRow =
|
|
7366
|
-
|
|
7367
|
-
type: "button",
|
|
7368
|
-
class: "an-btn an-btn-primary"
|
|
7369
|
-
});
|
|
7370
|
-
insertBtn.textContent = L.insertBtn;
|
|
7371
|
-
const cancelBtn = createElement("button", {
|
|
7372
|
-
type: "button",
|
|
7373
|
-
class: "an-btn"
|
|
7374
|
-
});
|
|
7375
|
-
cancelBtn.textContent = L.cancelBtn;
|
|
7376
|
-
btnRow.appendChild(insertBtn);
|
|
7377
|
-
btnRow.appendChild(cancelBtn);
|
|
7378
|
-
box.append(header, urlLabel, urlInput, textLabel, textInput, tabLabel, btnRow);
|
|
7379
|
-
overlay.appendChild(box);
|
|
7380
|
-
makeDraggable(header, box);
|
|
7381
|
-
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7382
|
-
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7383
|
-
const d3 = on(overlay, "click", (e) => {
|
|
7384
|
-
if (e.target === overlay) this._close();
|
|
7385
|
-
});
|
|
7450
|
+
const btnRow = this._buildButtonRow(L.insertBtn, L.cancelBtn, () => this._onInsert());
|
|
7451
|
+
box.append(urlLabel, urlInput, textLabel, textInput, tabLabel, btnRow);
|
|
7386
7452
|
const d4 = on(urlInput, "keydown", (e) => {
|
|
7387
7453
|
if (e.key === "Enter") {
|
|
7388
7454
|
e.preventDefault();
|
|
@@ -7395,11 +7461,11 @@ var LinkDialog = class {
|
|
|
7395
7461
|
this._onInsert();
|
|
7396
7462
|
}
|
|
7397
7463
|
});
|
|
7398
|
-
this._disposers.push(
|
|
7464
|
+
this._disposers.push(d4, d5);
|
|
7399
7465
|
return overlay;
|
|
7400
7466
|
}
|
|
7401
7467
|
_prefill() {
|
|
7402
|
-
const sel =
|
|
7468
|
+
const sel = globalThis.getSelection();
|
|
7403
7469
|
let anchor = null;
|
|
7404
7470
|
if (sel && sel.rangeCount > 0) {
|
|
7405
7471
|
let node = sel.getRangeAt(0).startContainer;
|
|
@@ -7444,21 +7510,6 @@ var LinkDialog = class {
|
|
|
7444
7510
|
this.context.invoke("editor.insertLink", url, text, newTab);
|
|
7445
7511
|
this._close();
|
|
7446
7512
|
}
|
|
7447
|
-
_open() {
|
|
7448
|
-
if (this._dialog) {
|
|
7449
|
-
this._dialog.style.display = "flex";
|
|
7450
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7451
|
-
setTimeout(() => this._urlInput && this._urlInput.focus(), 50);
|
|
7452
|
-
}
|
|
7453
|
-
}
|
|
7454
|
-
_close() {
|
|
7455
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
7456
|
-
if (this._removeTrap) {
|
|
7457
|
-
this._removeTrap();
|
|
7458
|
-
this._removeTrap = null;
|
|
7459
|
-
}
|
|
7460
|
-
this._savedRange = null;
|
|
7461
|
-
}
|
|
7462
7513
|
};
|
|
7463
7514
|
//#endregion
|
|
7464
7515
|
//#region src/js/module/ImageDialog.js
|
|
@@ -7466,33 +7517,10 @@ var LinkDialog = class {
|
|
|
7466
7517
|
* ImageDialog.js - Dialog for inserting images (by URL or file upload)
|
|
7467
7518
|
* Inspired by Summernote's ImageDialog — rewritten without jQuery
|
|
7468
7519
|
*/
|
|
7469
|
-
var
|
|
7470
|
-
|
|
7471
|
-
* @param {import('../Context.js').Context} context
|
|
7472
|
-
*/
|
|
7473
|
-
constructor(context) {
|
|
7474
|
-
this.context = context;
|
|
7475
|
-
this.options = context.options;
|
|
7476
|
-
/** @type {HTMLElement|null} */
|
|
7477
|
-
this._dialog = null;
|
|
7478
|
-
this._disposers = [];
|
|
7479
|
-
this._savedRange = null;
|
|
7480
|
-
}
|
|
7481
|
-
initialize() {
|
|
7482
|
-
this._dialog = this._buildDialog();
|
|
7483
|
-
document.body.appendChild(this._dialog);
|
|
7484
|
-
return this;
|
|
7485
|
-
}
|
|
7486
|
-
destroy() {
|
|
7487
|
-
this._disposers.forEach((d) => d());
|
|
7488
|
-
this._disposers = [];
|
|
7489
|
-
if (this._dialog && this._dialog.parentNode) this._dialog.parentNode.removeChild(this._dialog);
|
|
7490
|
-
this._dialog = null;
|
|
7491
|
-
}
|
|
7520
|
+
var ICON_SVG$1 = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>`;
|
|
7521
|
+
var ImageDialog = class extends BaseDialog {
|
|
7492
7522
|
show() {
|
|
7493
|
-
|
|
7494
|
-
this._savedRange = range;
|
|
7495
|
-
});
|
|
7523
|
+
this._saveRange();
|
|
7496
7524
|
this._urlInput.value = "";
|
|
7497
7525
|
this._altInput.value = "";
|
|
7498
7526
|
if (this._fileInput) this._fileInput.value = "";
|
|
@@ -7500,20 +7528,7 @@ var ImageDialog = class {
|
|
|
7500
7528
|
}
|
|
7501
7529
|
_buildDialog() {
|
|
7502
7530
|
const L = this.context.locale.imageDialog;
|
|
7503
|
-
const overlay =
|
|
7504
|
-
class: "an-dialog-overlay",
|
|
7505
|
-
role: "dialog",
|
|
7506
|
-
"aria-modal": "true",
|
|
7507
|
-
"aria-label": L.ariaLabel
|
|
7508
|
-
});
|
|
7509
|
-
const box = createElement("div", { class: "an-dialog-box" });
|
|
7510
|
-
const header = createElement("div", { class: "an-dialog-header" });
|
|
7511
|
-
const iconEl = createElement("span", { class: "an-dialog-icon" });
|
|
7512
|
-
iconEl.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>`;
|
|
7513
|
-
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7514
|
-
title.textContent = L.title;
|
|
7515
|
-
header.appendChild(iconEl);
|
|
7516
|
-
header.appendChild(title);
|
|
7531
|
+
const { overlay, box } = this._buildDialogShell(L.ariaLabel, ICON_SVG$1, L.title);
|
|
7517
7532
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7518
7533
|
urlLabel.textContent = L.imageUrl;
|
|
7519
7534
|
const urlInput = createElement("input", {
|
|
@@ -7523,6 +7538,7 @@ var ImageDialog = class {
|
|
|
7523
7538
|
autocomplete: "off"
|
|
7524
7539
|
});
|
|
7525
7540
|
this._urlInput = urlInput;
|
|
7541
|
+
this._firstInput = urlInput;
|
|
7526
7542
|
const altLabel = createElement("label", { class: "an-label" });
|
|
7527
7543
|
altLabel.textContent = L.altText;
|
|
7528
7544
|
const altInput = createElement("input", {
|
|
@@ -7532,7 +7548,7 @@ var ImageDialog = class {
|
|
|
7532
7548
|
autocomplete: "off"
|
|
7533
7549
|
});
|
|
7534
7550
|
this._altInput = altInput;
|
|
7535
|
-
box.append(
|
|
7551
|
+
box.append(urlLabel, urlInput, altLabel, altInput);
|
|
7536
7552
|
const alignLabel = createElement("label", { class: "an-label" });
|
|
7537
7553
|
alignLabel.textContent = L.alignment;
|
|
7538
7554
|
const alignRow = createElement("div", { class: "an-align-row" });
|
|
@@ -7586,27 +7602,8 @@ var ImageDialog = class {
|
|
|
7586
7602
|
this._disposers.push(d);
|
|
7587
7603
|
box.append(fileLabel, fileInput, fileHint);
|
|
7588
7604
|
}
|
|
7589
|
-
const btnRow =
|
|
7590
|
-
const insertBtn = createElement("button", {
|
|
7591
|
-
type: "button",
|
|
7592
|
-
class: "an-btn an-btn-primary"
|
|
7593
|
-
});
|
|
7594
|
-
insertBtn.textContent = L.insertBtn;
|
|
7595
|
-
const cancelBtn = createElement("button", {
|
|
7596
|
-
type: "button",
|
|
7597
|
-
class: "an-btn"
|
|
7598
|
-
});
|
|
7599
|
-
cancelBtn.textContent = L.cancelBtn;
|
|
7600
|
-
btnRow.appendChild(insertBtn);
|
|
7601
|
-
btnRow.appendChild(cancelBtn);
|
|
7605
|
+
const btnRow = this._buildButtonRow(L.insertBtn, L.cancelBtn, () => this._onInsert());
|
|
7602
7606
|
box.append(btnRow);
|
|
7603
|
-
overlay.appendChild(box);
|
|
7604
|
-
makeDraggable(header, box);
|
|
7605
|
-
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7606
|
-
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7607
|
-
const d3 = on(overlay, "click", (e) => {
|
|
7608
|
-
if (e.target === overlay) this._close();
|
|
7609
|
-
});
|
|
7610
7607
|
const d4 = on(urlInput, "keydown", (e) => {
|
|
7611
7608
|
if (e.key === "Enter") {
|
|
7612
7609
|
e.preventDefault();
|
|
@@ -7619,7 +7616,7 @@ var ImageDialog = class {
|
|
|
7619
7616
|
this._onInsert();
|
|
7620
7617
|
}
|
|
7621
7618
|
});
|
|
7622
|
-
this._disposers.push(
|
|
7619
|
+
this._disposers.push(d4, d5);
|
|
7623
7620
|
return overlay;
|
|
7624
7621
|
}
|
|
7625
7622
|
_onFileChange() {
|
|
@@ -7674,21 +7671,6 @@ var ImageDialog = class {
|
|
|
7674
7671
|
this.context.invoke("editor.insertImage", src, alt, align);
|
|
7675
7672
|
this._close();
|
|
7676
7673
|
}
|
|
7677
|
-
_open() {
|
|
7678
|
-
if (this._dialog) {
|
|
7679
|
-
this._dialog.style.display = "flex";
|
|
7680
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7681
|
-
setTimeout(() => this._urlInput && this._urlInput.focus(), 50);
|
|
7682
|
-
}
|
|
7683
|
-
}
|
|
7684
|
-
_close() {
|
|
7685
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
7686
|
-
if (this._removeTrap) {
|
|
7687
|
-
this._removeTrap();
|
|
7688
|
-
this._removeTrap = null;
|
|
7689
|
-
}
|
|
7690
|
-
this._savedRange = null;
|
|
7691
|
-
}
|
|
7692
7674
|
};
|
|
7693
7675
|
//#endregion
|
|
7694
7676
|
//#region src/js/module/VideoDialog.js
|
|
@@ -7700,31 +7682,10 @@ var ImageDialog = class {
|
|
|
7700
7682
|
* • Vimeo URLs → <iframe> embed
|
|
7701
7683
|
* • Direct video URLs → <video> element (.mp4 / .webm / .ogg)
|
|
7702
7684
|
*/
|
|
7703
|
-
var
|
|
7704
|
-
|
|
7705
|
-
constructor(context) {
|
|
7706
|
-
this.context = context;
|
|
7707
|
-
this.options = context.options;
|
|
7708
|
-
/** @type {HTMLElement|null} */
|
|
7709
|
-
this._dialog = null;
|
|
7710
|
-
this._disposers = [];
|
|
7711
|
-
this._savedRange = null;
|
|
7712
|
-
}
|
|
7713
|
-
initialize() {
|
|
7714
|
-
this._dialog = this._buildDialog();
|
|
7715
|
-
document.body.appendChild(this._dialog);
|
|
7716
|
-
return this;
|
|
7717
|
-
}
|
|
7718
|
-
destroy() {
|
|
7719
|
-
this._disposers.forEach((d) => d());
|
|
7720
|
-
this._disposers = [];
|
|
7721
|
-
if (this._dialog && this._dialog.parentNode) this._dialog.parentNode.removeChild(this._dialog);
|
|
7722
|
-
this._dialog = null;
|
|
7723
|
-
}
|
|
7685
|
+
var ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2"/></svg>`;
|
|
7686
|
+
var VideoDialog = class extends BaseDialog {
|
|
7724
7687
|
show() {
|
|
7725
|
-
|
|
7726
|
-
this._savedRange = range;
|
|
7727
|
-
});
|
|
7688
|
+
this._saveRange();
|
|
7728
7689
|
this._urlInput.value = "";
|
|
7729
7690
|
this._widthInput.value = "560";
|
|
7730
7691
|
this._hintEl.textContent = "";
|
|
@@ -7732,20 +7693,7 @@ var VideoDialog = class {
|
|
|
7732
7693
|
}
|
|
7733
7694
|
_buildDialog() {
|
|
7734
7695
|
const L = this.context.locale.videoDialog;
|
|
7735
|
-
const overlay =
|
|
7736
|
-
class: "an-dialog-overlay",
|
|
7737
|
-
role: "dialog",
|
|
7738
|
-
"aria-modal": "true",
|
|
7739
|
-
"aria-label": L.ariaLabel
|
|
7740
|
-
});
|
|
7741
|
-
const box = createElement("div", { class: "an-dialog-box" });
|
|
7742
|
-
const header = createElement("div", { class: "an-dialog-header" });
|
|
7743
|
-
const iconEl = createElement("span", { class: "an-dialog-icon" });
|
|
7744
|
-
iconEl.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2"/></svg>`;
|
|
7745
|
-
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7746
|
-
title.textContent = L.title;
|
|
7747
|
-
header.appendChild(iconEl);
|
|
7748
|
-
header.appendChild(title);
|
|
7696
|
+
const { overlay, box } = this._buildDialogShell(L.ariaLabel, ICON_SVG, L.title);
|
|
7749
7697
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7750
7698
|
urlLabel.textContent = L.videoUrl;
|
|
7751
7699
|
const urlInput = createElement("input", {
|
|
@@ -7755,6 +7703,7 @@ var VideoDialog = class {
|
|
|
7755
7703
|
autocomplete: "off"
|
|
7756
7704
|
});
|
|
7757
7705
|
this._urlInput = urlInput;
|
|
7706
|
+
this._firstInput = urlInput;
|
|
7758
7707
|
const hintEl = createElement("p", { class: "an-dialog-hint" });
|
|
7759
7708
|
this._hintEl = hintEl;
|
|
7760
7709
|
const widthLabel = createElement("label", { class: "an-label" });
|
|
@@ -7768,43 +7717,24 @@ var VideoDialog = class {
|
|
|
7768
7717
|
value: "560"
|
|
7769
7718
|
});
|
|
7770
7719
|
this._widthInput = widthInput;
|
|
7771
|
-
const btnRow =
|
|
7772
|
-
|
|
7773
|
-
type: "button",
|
|
7774
|
-
class: "an-btn an-btn-primary"
|
|
7775
|
-
});
|
|
7776
|
-
insertBtn.textContent = L.insertBtn;
|
|
7777
|
-
const cancelBtn = createElement("button", {
|
|
7778
|
-
type: "button",
|
|
7779
|
-
class: "an-btn"
|
|
7780
|
-
});
|
|
7781
|
-
cancelBtn.textContent = L.cancelBtn;
|
|
7782
|
-
btnRow.appendChild(insertBtn);
|
|
7783
|
-
btnRow.appendChild(cancelBtn);
|
|
7784
|
-
box.append(header, urlLabel, urlInput, hintEl, widthLabel, widthInput, btnRow);
|
|
7785
|
-
overlay.appendChild(box);
|
|
7786
|
-
makeDraggable(header, box);
|
|
7720
|
+
const btnRow = this._buildButtonRow(L.insertBtn, L.cancelBtn, () => this._onInsert());
|
|
7721
|
+
box.append(urlLabel, urlInput, hintEl, widthLabel, widthInput, btnRow);
|
|
7787
7722
|
const d0 = on(urlInput, "input", () => {
|
|
7788
7723
|
const info = this._parseVideoUrl(urlInput.value.trim());
|
|
7789
7724
|
hintEl.textContent = info ? this.context.locale.videoDialog.detected(info.type) : urlInput.value ? this.context.locale.videoDialog.unknownFormat : "";
|
|
7790
7725
|
});
|
|
7791
|
-
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7792
|
-
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7793
|
-
const d3 = on(overlay, "click", (e) => {
|
|
7794
|
-
if (e.target === overlay) this._close();
|
|
7795
|
-
});
|
|
7796
7726
|
const d4 = on(urlInput, "keydown", (e) => {
|
|
7797
7727
|
if (e.key === "Enter") {
|
|
7798
7728
|
e.preventDefault();
|
|
7799
7729
|
this._onInsert();
|
|
7800
7730
|
}
|
|
7801
7731
|
});
|
|
7802
|
-
this._disposers.push(d0,
|
|
7732
|
+
this._disposers.push(d0, d4);
|
|
7803
7733
|
return overlay;
|
|
7804
7734
|
}
|
|
7805
7735
|
_onInsert() {
|
|
7806
7736
|
const rawUrl = this._urlInput.value.trim();
|
|
7807
|
-
const width = Math.max(80, parseInt(this._widthInput.value, 10) || 560);
|
|
7737
|
+
const width = Math.max(80, Number.parseInt(this._widthInput.value, 10) || 560);
|
|
7808
7738
|
if (!rawUrl) {
|
|
7809
7739
|
this._urlInput.focus();
|
|
7810
7740
|
return;
|
|
@@ -7819,21 +7749,6 @@ var VideoDialog = class {
|
|
|
7819
7749
|
this.context.invoke("editor.insertVideo", html);
|
|
7820
7750
|
this._close();
|
|
7821
7751
|
}
|
|
7822
|
-
_open() {
|
|
7823
|
-
if (this._dialog) {
|
|
7824
|
-
this._dialog.style.display = "flex";
|
|
7825
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7826
|
-
setTimeout(() => this._urlInput && this._urlInput.focus(), 50);
|
|
7827
|
-
}
|
|
7828
|
-
}
|
|
7829
|
-
_close() {
|
|
7830
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
7831
|
-
if (this._removeTrap) {
|
|
7832
|
-
this._removeTrap();
|
|
7833
|
-
this._removeTrap = null;
|
|
7834
|
-
}
|
|
7835
|
-
this._savedRange = null;
|
|
7836
|
-
}
|
|
7837
7752
|
/**
|
|
7838
7753
|
* Parses a video URL and returns { type, embedUrl } or null.
|
|
7839
7754
|
* @param {string} url
|
|
@@ -7847,22 +7762,22 @@ var VideoDialog = class {
|
|
|
7847
7762
|
} catch {
|
|
7848
7763
|
return null;
|
|
7849
7764
|
}
|
|
7850
|
-
const ytWatch =
|
|
7765
|
+
const ytWatch = /(?:youtube\.com\/watch\?(?:.*&)?v=|youtube\.com\/embed\/)([a-zA-Z0-9_-]{11})/.exec(url);
|
|
7851
7766
|
if (ytWatch) return {
|
|
7852
7767
|
type: "YouTube",
|
|
7853
7768
|
embedUrl: `https://www.youtube.com/embed/${ytWatch[1]}`
|
|
7854
7769
|
};
|
|
7855
|
-
const ytShort =
|
|
7770
|
+
const ytShort = /youtu\.be\/([a-zA-Z0-9_-]{11})/.exec(url);
|
|
7856
7771
|
if (ytShort) return {
|
|
7857
7772
|
type: "YouTube",
|
|
7858
7773
|
embedUrl: `https://www.youtube.com/embed/${ytShort[1]}`
|
|
7859
7774
|
};
|
|
7860
|
-
const ytShorts =
|
|
7775
|
+
const ytShorts = /youtube\.com\/shorts\/([a-zA-Z0-9_-]{11})/.exec(url);
|
|
7861
7776
|
if (ytShorts) return {
|
|
7862
7777
|
type: "YouTube Shorts",
|
|
7863
7778
|
embedUrl: `https://www.youtube.com/embed/${ytShorts[1]}`
|
|
7864
7779
|
};
|
|
7865
|
-
const vimeo =
|
|
7780
|
+
const vimeo = /vimeo\.com\/(\d+)/.exec(url);
|
|
7866
7781
|
if (vimeo) return {
|
|
7867
7782
|
type: "Vimeo",
|
|
7868
7783
|
embedUrl: `https://player.vimeo.com/video/${vimeo[1]}`
|
|
@@ -7886,7 +7801,7 @@ var VideoDialog = class {
|
|
|
7886
7801
|
const iframeTitle = `${info.type} video player`;
|
|
7887
7802
|
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
7803
|
}
|
|
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.
|
|
7804
|
+
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
7805
|
const safeSrc = (() => {
|
|
7891
7806
|
try {
|
|
7892
7807
|
const p = new URL(url);
|
|
@@ -7897,7 +7812,7 @@ var VideoDialog = class {
|
|
|
7897
7812
|
}
|
|
7898
7813
|
})();
|
|
7899
7814
|
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.
|
|
7815
|
+
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
7816
|
}
|
|
7902
7817
|
};
|
|
7903
7818
|
//#endregion
|
|
@@ -7968,7 +7883,7 @@ var ImageResizer = class {
|
|
|
7968
7883
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
7969
7884
|
const img = e.target?.closest("img");
|
|
7970
7885
|
if (img) this._select(img);
|
|
7971
|
-
}), on(document, "click", (e) => this._onDocClick(e)), on(
|
|
7886
|
+
}), 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
7887
|
return this;
|
|
7973
7888
|
}
|
|
7974
7889
|
destroy() {
|
|
@@ -7983,7 +7898,7 @@ var ImageResizer = class {
|
|
|
7983
7898
|
this._positionRaf = null;
|
|
7984
7899
|
}
|
|
7985
7900
|
this._deselect();
|
|
7986
|
-
if (this._overlay && this._overlay.parentNode) this._overlay.
|
|
7901
|
+
if (this._overlay && this._overlay.parentNode) this._overlay.remove();
|
|
7987
7902
|
this._overlay = null;
|
|
7988
7903
|
}
|
|
7989
7904
|
/** @returns {HTMLImageElement|null} */
|
|
@@ -8185,7 +8100,7 @@ var VideoResizer = class {
|
|
|
8185
8100
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
8186
8101
|
const wrapper = this._findWrapper(e.target);
|
|
8187
8102
|
if (wrapper) this._select(wrapper);
|
|
8188
|
-
}), on(document, "click", (e) => this._onDocClick(e)), on(
|
|
8103
|
+
}), 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
8104
|
if (e.target instanceof Element && e.target.closest(".an-video-wrapper")) e.preventDefault();
|
|
8190
8105
|
}));
|
|
8191
8106
|
return this;
|
|
@@ -8202,7 +8117,7 @@ var VideoResizer = class {
|
|
|
8202
8117
|
this._positionRaf = null;
|
|
8203
8118
|
}
|
|
8204
8119
|
this._deselect();
|
|
8205
|
-
|
|
8120
|
+
this._overlay?.remove();
|
|
8206
8121
|
this._overlay = null;
|
|
8207
8122
|
}
|
|
8208
8123
|
/** @returns {HTMLElement|null} */
|
|
@@ -8223,7 +8138,7 @@ var VideoResizer = class {
|
|
|
8223
8138
|
*/
|
|
8224
8139
|
_findWrapper(el) {
|
|
8225
8140
|
if (!el || !(el instanceof Element)) return null;
|
|
8226
|
-
if (el.classList
|
|
8141
|
+
if (el.classList?.contains("an-video-wrapper")) return el;
|
|
8227
8142
|
const w = el.closest(".an-video-wrapper");
|
|
8228
8143
|
if (w) return w;
|
|
8229
8144
|
return null;
|
|
@@ -8256,7 +8171,7 @@ var VideoResizer = class {
|
|
|
8256
8171
|
_onDocClick(e) {
|
|
8257
8172
|
if (!this._activeWrapper) return;
|
|
8258
8173
|
if (this._activeWrapper.contains(e.target)) return;
|
|
8259
|
-
if (this._overlay
|
|
8174
|
+
if (this._overlay?.contains(e.target)) return;
|
|
8260
8175
|
if (e.target.closest(".an-contextmenu")) return;
|
|
8261
8176
|
this._deselect();
|
|
8262
8177
|
}
|
|
@@ -8381,14 +8296,14 @@ var LinkTooltip = class {
|
|
|
8381
8296
|
}), on(editable, "mouseout", (e) => {
|
|
8382
8297
|
const to = e.relatedTarget;
|
|
8383
8298
|
if (!to || !editable.contains(to) && !this._el.contains(to)) this._scheduleHide();
|
|
8384
|
-
}), on(
|
|
8299
|
+
}), on(globalThis, "scroll", () => this._hide(), { passive: true }), on(globalThis, "resize", () => this._hide(), { passive: true }));
|
|
8385
8300
|
return this;
|
|
8386
8301
|
}
|
|
8387
8302
|
destroy() {
|
|
8388
8303
|
this._clearTimers();
|
|
8389
8304
|
this._disposers.forEach((d) => d());
|
|
8390
8305
|
this._disposers = [];
|
|
8391
|
-
if (this._el && this._el.parentNode) this._el.
|
|
8306
|
+
if (this._el && this._el.parentNode) this._el.remove();
|
|
8392
8307
|
this._el = null;
|
|
8393
8308
|
}
|
|
8394
8309
|
_buildTooltip() {
|
|
@@ -8473,8 +8388,8 @@ var LinkTooltip = class {
|
|
|
8473
8388
|
const margin = 6;
|
|
8474
8389
|
let top = rect.bottom + margin;
|
|
8475
8390
|
let left = rect.left;
|
|
8476
|
-
if (top + tipH >
|
|
8477
|
-
if (left + tipW >
|
|
8391
|
+
if (top + tipH > globalThis.innerHeight - margin) top = rect.top - tipH - margin;
|
|
8392
|
+
if (left + tipW > globalThis.innerWidth - margin) left = globalThis.innerWidth - tipW - margin;
|
|
8478
8393
|
if (left < margin) left = margin;
|
|
8479
8394
|
this._el.style.top = `${top}px`;
|
|
8480
8395
|
this._el.style.left = `${left}px`;
|
|
@@ -8489,12 +8404,12 @@ var LinkTooltip = class {
|
|
|
8489
8404
|
}
|
|
8490
8405
|
}
|
|
8491
8406
|
_openLink() {
|
|
8492
|
-
const url = this._activeAnchor
|
|
8493
|
-
if (url)
|
|
8407
|
+
const url = this._activeAnchor?.getAttribute("href");
|
|
8408
|
+
if (url) globalThis.open(url, "_blank", "noopener,noreferrer");
|
|
8494
8409
|
this._hide();
|
|
8495
8410
|
}
|
|
8496
8411
|
_copyLink() {
|
|
8497
|
-
const url = this._activeAnchor
|
|
8412
|
+
const url = this._activeAnchor?.getAttribute("href");
|
|
8498
8413
|
if (url) navigator.clipboard.writeText(url).catch(() => {
|
|
8499
8414
|
const ta = document.createElement("textarea");
|
|
8500
8415
|
ta.value = url;
|
|
@@ -8503,7 +8418,7 @@ var LinkTooltip = class {
|
|
|
8503
8418
|
document.body.appendChild(ta);
|
|
8504
8419
|
ta.select();
|
|
8505
8420
|
document.execCommand("copy");
|
|
8506
|
-
|
|
8421
|
+
ta.remove();
|
|
8507
8422
|
});
|
|
8508
8423
|
if (this._copyBtn) {
|
|
8509
8424
|
this._copyBtn.classList.add("an-link-tooltip-btn--copied");
|
|
@@ -8514,7 +8429,7 @@ var LinkTooltip = class {
|
|
|
8514
8429
|
const anchor = this._activeAnchor;
|
|
8515
8430
|
if (!anchor) return;
|
|
8516
8431
|
this._hide();
|
|
8517
|
-
const sel =
|
|
8432
|
+
const sel = globalThis.getSelection();
|
|
8518
8433
|
const range = document.createRange();
|
|
8519
8434
|
range.selectNodeContents(anchor);
|
|
8520
8435
|
sel.removeAllRanges();
|
|
@@ -8525,7 +8440,7 @@ var LinkTooltip = class {
|
|
|
8525
8440
|
const anchor = this._activeAnchor;
|
|
8526
8441
|
if (!anchor) return;
|
|
8527
8442
|
this._hide();
|
|
8528
|
-
const sel =
|
|
8443
|
+
const sel = globalThis.getSelection();
|
|
8529
8444
|
const range = document.createRange();
|
|
8530
8445
|
range.selectNode(anchor);
|
|
8531
8446
|
sel.removeAllRanges();
|
|
@@ -8574,14 +8489,14 @@ var ImageTooltip = class {
|
|
|
8574
8489
|
}, { passive: true }), on(document, "click", (e) => {
|
|
8575
8490
|
const et = e.target;
|
|
8576
8491
|
if (this._activeImg && !this._activeImg.contains(et) && !this._el.contains(et)) this._hide();
|
|
8577
|
-
}), on(
|
|
8492
|
+
}), on(globalThis, "scroll", () => this._hide(), { passive: true }), on(globalThis, "resize", () => this._hide(), { passive: true }));
|
|
8578
8493
|
return this;
|
|
8579
8494
|
}
|
|
8580
8495
|
destroy() {
|
|
8581
8496
|
this._clearTimers();
|
|
8582
8497
|
this._disposers.forEach((d) => d());
|
|
8583
8498
|
this._disposers = [];
|
|
8584
|
-
|
|
8499
|
+
this._el?.remove();
|
|
8585
8500
|
this._el = null;
|
|
8586
8501
|
}
|
|
8587
8502
|
_buildTooltip() {
|
|
@@ -8682,8 +8597,8 @@ var ImageTooltip = class {
|
|
|
8682
8597
|
const margin = 6;
|
|
8683
8598
|
let top = rect.bottom + margin;
|
|
8684
8599
|
let left = rect.left + (rect.width - tipW) / 2;
|
|
8685
|
-
if (top + tipH >
|
|
8686
|
-
if (left + tipW >
|
|
8600
|
+
if (top + tipH > globalThis.innerHeight - margin) top = rect.top - tipH - margin;
|
|
8601
|
+
if (left + tipW > globalThis.innerWidth - margin) left = globalThis.innerWidth - tipW - margin;
|
|
8687
8602
|
if (left < margin) left = margin;
|
|
8688
8603
|
this._el.style.top = `${top}px`;
|
|
8689
8604
|
this._el.style.left = `${left}px`;
|
|
@@ -8739,8 +8654,8 @@ var ImageTooltip = class {
|
|
|
8739
8654
|
const img = this._activeImg;
|
|
8740
8655
|
if (!img) return;
|
|
8741
8656
|
const current = img.style.transform || "";
|
|
8742
|
-
const match =
|
|
8743
|
-
const next = ((match ? parseFloat(match[1]) : 0) + delta + 360) % 360;
|
|
8657
|
+
const match = /rotate\((-?[\d.]+)deg\)/.exec(current);
|
|
8658
|
+
const next = ((match ? Number.parseFloat(match[1]) : 0) + delta + 360) % 360;
|
|
8744
8659
|
const cleaned = current.replace(/rotate\(-?[\d.]+deg\)/, "").trim();
|
|
8745
8660
|
img.style.transform = cleaned ? `${cleaned} rotate(${next}deg)` : next === 0 ? "" : `rotate(${next}deg)`;
|
|
8746
8661
|
this.context.invoke("editor.afterCommand");
|
|
@@ -8755,8 +8670,8 @@ var ImageTooltip = class {
|
|
|
8755
8670
|
this._hide();
|
|
8756
8671
|
this.context.invoke("imageResizer.deselect");
|
|
8757
8672
|
const figure = img.closest("figure.an-figure");
|
|
8758
|
-
if (figure
|
|
8759
|
-
else
|
|
8673
|
+
if (figure) figure.remove();
|
|
8674
|
+
else img.remove();
|
|
8760
8675
|
this.context.invoke("editor.afterCommand");
|
|
8761
8676
|
}
|
|
8762
8677
|
_crop() {
|
|
@@ -8775,7 +8690,7 @@ var ImageTooltip = class {
|
|
|
8775
8690
|
this._hide();
|
|
8776
8691
|
const range = document.createRange();
|
|
8777
8692
|
range.selectNodeContents(cap);
|
|
8778
|
-
const sel =
|
|
8693
|
+
const sel = globalThis.getSelection();
|
|
8779
8694
|
if (sel) {
|
|
8780
8695
|
sel.removeAllRanges();
|
|
8781
8696
|
sel.addRange(range);
|
|
@@ -8809,7 +8724,7 @@ var ImageTooltip = class {
|
|
|
8809
8724
|
figure.appendChild(figcaption);
|
|
8810
8725
|
const range = document.createRange();
|
|
8811
8726
|
range.selectNodeContents(figcaption);
|
|
8812
|
-
const sel =
|
|
8727
|
+
const sel = globalThis.getSelection();
|
|
8813
8728
|
if (sel) {
|
|
8814
8729
|
sel.removeAllRanges();
|
|
8815
8730
|
sel.addRange(range);
|
|
@@ -8850,8 +8765,7 @@ var VideoTooltip = class {
|
|
|
8850
8765
|
const editable = this.context.layoutInfo.editable;
|
|
8851
8766
|
this._disposers.push(on(editable, "mouseover", (e) => {
|
|
8852
8767
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
8853
|
-
const
|
|
8854
|
-
const wrapper = target && target.closest ? target.closest(".an-video-wrapper") : null;
|
|
8768
|
+
const wrapper = e.target?.closest(".an-video-wrapper");
|
|
8855
8769
|
if (wrapper && editable.contains(wrapper)) this._scheduleShow(wrapper);
|
|
8856
8770
|
}, { passive: true }), on(editable, "mouseout", (e) => {
|
|
8857
8771
|
const to = e.relatedTarget;
|
|
@@ -8859,7 +8773,7 @@ var VideoTooltip = class {
|
|
|
8859
8773
|
}, { passive: true }), on(document, "click", (e) => {
|
|
8860
8774
|
const target = e.target;
|
|
8861
8775
|
if (this._activeWrapper && !this._activeWrapper.contains(target) && !this._el.contains(target)) this._hide();
|
|
8862
|
-
}), on(
|
|
8776
|
+
}), on(globalThis, "scroll", () => this._hide(), { passive: true }), on(globalThis, "resize", () => this._hide(), { passive: true }));
|
|
8863
8777
|
return this;
|
|
8864
8778
|
}
|
|
8865
8779
|
destroy() {
|
|
@@ -8867,7 +8781,7 @@ var VideoTooltip = class {
|
|
|
8867
8781
|
this._clearTimers();
|
|
8868
8782
|
this._disposers.forEach((d) => d());
|
|
8869
8783
|
this._disposers = [];
|
|
8870
|
-
|
|
8784
|
+
this._el?.remove();
|
|
8871
8785
|
this._el = null;
|
|
8872
8786
|
}
|
|
8873
8787
|
_buildTooltip() {
|
|
@@ -8964,8 +8878,8 @@ var VideoTooltip = class {
|
|
|
8964
8878
|
const margin = 6;
|
|
8965
8879
|
let top = rect.bottom + margin;
|
|
8966
8880
|
let left = rect.left + (rect.width - tipW) / 2;
|
|
8967
|
-
if (top + tipH >
|
|
8968
|
-
if (left + tipW >
|
|
8881
|
+
if (top + tipH > globalThis.innerHeight - margin) top = rect.top - tipH - margin;
|
|
8882
|
+
if (left + tipW > globalThis.innerWidth - margin) left = globalThis.innerWidth - tipW - margin;
|
|
8969
8883
|
if (left < margin) left = margin;
|
|
8970
8884
|
this._el.style.top = `${top}px`;
|
|
8971
8885
|
this._el.style.left = `${left}px`;
|
|
@@ -9019,7 +8933,7 @@ var VideoTooltip = class {
|
|
|
9019
8933
|
if (!wrapper) return;
|
|
9020
8934
|
this._hide();
|
|
9021
8935
|
this.context.invoke("videoResizer.deselect");
|
|
9022
|
-
|
|
8936
|
+
wrapper.remove();
|
|
9023
8937
|
this.context.invoke("editor.afterCommand");
|
|
9024
8938
|
}
|
|
9025
8939
|
_togglePreview() {
|
|
@@ -9261,12 +9175,12 @@ var TableTooltip = class {
|
|
|
9261
9175
|
}, { passive: true }), on(editable, "mouseout", (e) => {
|
|
9262
9176
|
if (this._selectMode) return;
|
|
9263
9177
|
const to = e.relatedTarget;
|
|
9264
|
-
if (!to || !editable.contains(to) && !this._el.contains(to) && !
|
|
9178
|
+
if (!to || !editable.contains(to) && !this._el.contains(to) && !this._sizePopover?.contains(to)) this._scheduleHide();
|
|
9265
9179
|
}, { passive: true }), on(document, "click", (e) => {
|
|
9266
9180
|
const et = e.target;
|
|
9267
|
-
if (this._selectMode && this._activeTable
|
|
9268
|
-
if (this._activeTable && !this._activeTable.contains(et) && !this._el.contains(et) && !
|
|
9269
|
-
}), on(document, "selectionchange", () => this._syncShadeStrip()), on(
|
|
9181
|
+
if (this._selectMode && this._activeTable?.contains(et)) return;
|
|
9182
|
+
if (this._activeTable && !this._activeTable.contains(et) && !this._el.contains(et) && !this._sizePopover?.contains(et)) this._hide();
|
|
9183
|
+
}), on(document, "selectionchange", () => this._syncShadeStrip()), on(globalThis, "scroll", () => this._hide(), { passive: true }), on(globalThis, "resize", () => this._hide(), { passive: true }));
|
|
9270
9184
|
this._initResize();
|
|
9271
9185
|
return this;
|
|
9272
9186
|
}
|
|
@@ -9392,11 +9306,11 @@ var TableTooltip = class {
|
|
|
9392
9306
|
this._clearTimers();
|
|
9393
9307
|
this._disposers.forEach((d) => d());
|
|
9394
9308
|
this._disposers = [];
|
|
9395
|
-
if (this._el && this._el.parentNode) this._el.
|
|
9309
|
+
if (this._el && this._el.parentNode) this._el.remove();
|
|
9396
9310
|
this._el = null;
|
|
9397
|
-
if (this._sizePopover && this._sizePopover.parentNode) this._sizePopover.
|
|
9311
|
+
if (this._sizePopover && this._sizePopover.parentNode) this._sizePopover.remove();
|
|
9398
9312
|
this._sizePopover = null;
|
|
9399
|
-
if (this._shadePopover && this._shadePopover.parentNode) this._shadePopover.
|
|
9313
|
+
if (this._shadePopover && this._shadePopover.parentNode) this._shadePopover.remove();
|
|
9400
9314
|
this._shadePopover = null;
|
|
9401
9315
|
}
|
|
9402
9316
|
_buildTooltip() {
|
|
@@ -9506,7 +9420,7 @@ var TableTooltip = class {
|
|
|
9506
9420
|
_syncShadeStrip() {
|
|
9507
9421
|
if (!this._shadeColorStrip || !this._el || this._el.style.display === "none") return;
|
|
9508
9422
|
const cell = this._getCell();
|
|
9509
|
-
this._shadeColorStrip.style.background = cell
|
|
9423
|
+
this._shadeColorStrip.style.background = cell?.style.backgroundColor || "transparent";
|
|
9510
9424
|
}
|
|
9511
9425
|
_hide() {
|
|
9512
9426
|
this._el.style.display = "none";
|
|
@@ -9536,20 +9450,20 @@ var TableTooltip = class {
|
|
|
9536
9450
|
let left = rect.left + (rect.width - tipW) / 2;
|
|
9537
9451
|
let top = rect.top - tipH - margin;
|
|
9538
9452
|
if (top < margin) top = rect.bottom + margin;
|
|
9539
|
-
if (left + tipW >
|
|
9453
|
+
if (left + tipW > globalThis.innerWidth - margin) left = globalThis.innerWidth - tipW - margin;
|
|
9540
9454
|
if (left < margin) left = margin;
|
|
9541
9455
|
this._el.style.left = `${left}px`;
|
|
9542
9456
|
this._el.style.top = `${top}px`;
|
|
9543
9457
|
}
|
|
9544
9458
|
_getCell() {
|
|
9545
|
-
const sel =
|
|
9459
|
+
const sel = globalThis.getSelection();
|
|
9546
9460
|
if (sel && sel.rangeCount) {
|
|
9547
9461
|
let container = sel.getRangeAt(0).commonAncestorContainer;
|
|
9548
9462
|
if (container.nodeType === 3) container = container.parentElement;
|
|
9549
|
-
const cellFromSel = container
|
|
9550
|
-
if (cellFromSel && this._activeTable
|
|
9463
|
+
const cellFromSel = container?.closest("td, th");
|
|
9464
|
+
if (cellFromSel && this._activeTable?.contains(cellFromSel)) return cellFromSel;
|
|
9551
9465
|
}
|
|
9552
|
-
return this._activeCell || this._activeTable
|
|
9466
|
+
return this._activeCell || this._activeTable?.querySelector("td, th");
|
|
9553
9467
|
}
|
|
9554
9468
|
_toggleSelectMode() {
|
|
9555
9469
|
this._selectMode = !this._selectMode;
|
|
@@ -9648,11 +9562,12 @@ var TableTooltip = class {
|
|
|
9648
9562
|
const table = cells[0].closest("table");
|
|
9649
9563
|
if (!table) return;
|
|
9650
9564
|
const allRows = Array.from(table.querySelectorAll("tr"));
|
|
9651
|
-
const
|
|
9565
|
+
const selectedRows = [...new Set(cells.map((c) => c.closest("tr")).filter(Boolean))];
|
|
9566
|
+
const refRow = selectedRows.reduce((best, r) => {
|
|
9652
9567
|
const bi = allRows.indexOf(best);
|
|
9653
9568
|
const ri = allRows.indexOf(r);
|
|
9654
9569
|
return position === "above" ? ri < bi ? r : best : ri > bi ? r : best;
|
|
9655
|
-
});
|
|
9570
|
+
}, selectedRows[0]);
|
|
9656
9571
|
const colCount = Array.from(refRow.cells).reduce((sum, c) => sum + (c.colSpan || 1), 0);
|
|
9657
9572
|
const newRow = document.createElement("tr");
|
|
9658
9573
|
const refCells = Array.from(refRow.cells);
|
|
@@ -9695,7 +9610,7 @@ var TableTooltip = class {
|
|
|
9695
9610
|
if (selectedRows.filter((r) => r.closest("tbody")).length >= totalBodyRows) return;
|
|
9696
9611
|
this._activeCell = null;
|
|
9697
9612
|
this._clearSelection();
|
|
9698
|
-
selectedRows.forEach((r) => r.
|
|
9613
|
+
selectedRows.forEach((r) => r.remove());
|
|
9699
9614
|
requestAnimationFrame(() => this._positionNear(this._activeTable));
|
|
9700
9615
|
this.context.invoke("editor.afterCommand");
|
|
9701
9616
|
}
|
|
@@ -9717,7 +9632,7 @@ var TableTooltip = class {
|
|
|
9717
9632
|
});
|
|
9718
9633
|
this._activeCell = null;
|
|
9719
9634
|
this._clearSelection();
|
|
9720
|
-
cellsToDelete.forEach((c) => c.
|
|
9635
|
+
cellsToDelete.forEach((c) => c.remove());
|
|
9721
9636
|
requestAnimationFrame(() => this._positionNear(this._activeTable));
|
|
9722
9637
|
this.context.invoke("editor.afterCommand");
|
|
9723
9638
|
}
|
|
@@ -9728,7 +9643,7 @@ var TableTooltip = class {
|
|
|
9728
9643
|
if (!table) return;
|
|
9729
9644
|
let selected = this._getSelectedCells().filter((c) => table.contains(c));
|
|
9730
9645
|
if (selected.length < 2) {
|
|
9731
|
-
const sel =
|
|
9646
|
+
const sel = globalThis.getSelection();
|
|
9732
9647
|
if (!sel || sel.rangeCount === 0) return;
|
|
9733
9648
|
const range = sel.getRangeAt(0);
|
|
9734
9649
|
selected = Array.from(table.querySelectorAll("td, th")).filter((c) => {
|
|
@@ -9770,7 +9685,7 @@ var TableTooltip = class {
|
|
|
9770
9685
|
first.rowSpan = maxR - minR + 1;
|
|
9771
9686
|
first.style.verticalAlign = "middle";
|
|
9772
9687
|
first.innerHTML = rectCells.map((c) => c.innerHTML).join("");
|
|
9773
|
-
rectCells.slice(1).forEach((c) => c.
|
|
9688
|
+
rectCells.slice(1).forEach((c) => c.remove());
|
|
9774
9689
|
this._clearSelection();
|
|
9775
9690
|
this.context.invoke("editor.afterCommand");
|
|
9776
9691
|
}
|
|
@@ -9778,7 +9693,7 @@ var TableTooltip = class {
|
|
|
9778
9693
|
const table = this._activeTable;
|
|
9779
9694
|
if (!table) return;
|
|
9780
9695
|
this._hide();
|
|
9781
|
-
if (table.parentNode) table.
|
|
9696
|
+
if (table.parentNode) table.remove();
|
|
9782
9697
|
this.context.invoke("editor.afterCommand");
|
|
9783
9698
|
}
|
|
9784
9699
|
_unmergeCells() {
|
|
@@ -9867,7 +9782,7 @@ var TableTooltip = class {
|
|
|
9867
9782
|
this._sizeInputEl = inputEl;
|
|
9868
9783
|
this._sizeApply = null;
|
|
9869
9784
|
const d1 = on(applyBtn, "click", () => {
|
|
9870
|
-
const val = parseInt(this._sizeInputEl.value, 10);
|
|
9785
|
+
const val = Number.parseInt(this._sizeInputEl.value, 10);
|
|
9871
9786
|
if (val > 0 && typeof this._sizeApply === "function") this._sizeApply(val);
|
|
9872
9787
|
this._hideSizePopover();
|
|
9873
9788
|
});
|
|
@@ -9896,7 +9811,7 @@ var TableTooltip = class {
|
|
|
9896
9811
|
const table = cell.closest("table");
|
|
9897
9812
|
if (!table) return;
|
|
9898
9813
|
const firstCell = table.querySelector("td, th");
|
|
9899
|
-
const currentPx = firstCell ? parseInt(firstCell.style.borderWidth, 10) || parseInt(
|
|
9814
|
+
const currentPx = firstCell ? Number.parseInt(firstCell.style.borderWidth, 10) || Number.parseInt(globalThis.getComputedStyle(firstCell).borderWidth, 10) || 1 : 1;
|
|
9900
9815
|
this._sizeTitleEl.textContent = this.context.locale.tooltips.table.tableBorderWidthPx;
|
|
9901
9816
|
this._sizeInputEl.min = "0";
|
|
9902
9817
|
this._sizeInputEl.max = "10";
|
|
@@ -9955,8 +9870,8 @@ var TableTooltip = class {
|
|
|
9955
9870
|
const ph = this._sizePopover.offsetHeight || 110;
|
|
9956
9871
|
let left = tipRect.left;
|
|
9957
9872
|
let top = tipRect.bottom + 6;
|
|
9958
|
-
if (left + pw >
|
|
9959
|
-
if (top + ph >
|
|
9873
|
+
if (left + pw > globalThis.innerWidth - 8) left = globalThis.innerWidth - pw - 8;
|
|
9874
|
+
if (top + ph > globalThis.innerHeight - 8) top = tipRect.top - ph - 6;
|
|
9960
9875
|
this._sizePopover.style.left = `${left}px`;
|
|
9961
9876
|
this._sizePopover.style.top = `${top}px`;
|
|
9962
9877
|
if (this._sizeInputEl) {
|
|
@@ -10010,11 +9925,10 @@ var TableTooltip = class {
|
|
|
10010
9925
|
customRow.appendChild(colorInput);
|
|
10011
9926
|
customRow.appendChild(customLabel);
|
|
10012
9927
|
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()));
|
|
9928
|
+
this._disposers.push(on(pop, "mousedown", (e) => e.preventDefault()), on(pop, "mouseenter", () => this._clearTimers()), on(pop, "mouseleave", () => this._scheduleHide()));
|
|
10015
9929
|
this._disposers.push(on(document, "click", (e) => {
|
|
10016
9930
|
const et = e.target;
|
|
10017
|
-
if (this._shadePopover && this._shadePopover.style.display !== "none" && !this._shadePopover.contains(et) && !
|
|
9931
|
+
if (this._shadePopover && this._shadePopover.style.display !== "none" && !this._shadePopover.contains(et) && !this._el?.contains(et)) this._hideCellShadePopover();
|
|
10018
9932
|
}));
|
|
10019
9933
|
return pop;
|
|
10020
9934
|
}
|
|
@@ -10031,8 +9945,8 @@ var TableTooltip = class {
|
|
|
10031
9945
|
const tipRect = this._el.getBoundingClientRect();
|
|
10032
9946
|
let left = tipRect.left;
|
|
10033
9947
|
let top = tipRect.bottom + 6;
|
|
10034
|
-
if (left + pw >
|
|
10035
|
-
if (top + ph >
|
|
9948
|
+
if (left + pw > globalThis.innerWidth - 8) left = globalThis.innerWidth - pw - 8;
|
|
9949
|
+
if (top + ph > globalThis.innerHeight - 8) top = tipRect.top - ph - 6;
|
|
10036
9950
|
this._shadePopover.style.left = `${Math.max(8, left)}px`;
|
|
10037
9951
|
this._shadePopover.style.top = `${Math.max(8, top)}px`;
|
|
10038
9952
|
});
|
|
@@ -10095,7 +10009,7 @@ var CodeTooltip = class {
|
|
|
10095
10009
|
this._clearTimers();
|
|
10096
10010
|
this._disposers.forEach((d) => d());
|
|
10097
10011
|
this._disposers = [];
|
|
10098
|
-
|
|
10012
|
+
this._el?.remove();
|
|
10099
10013
|
this._el = null;
|
|
10100
10014
|
}
|
|
10101
10015
|
_buildTooltip() {
|
|
@@ -10221,21 +10135,21 @@ var CodeTooltip = class {
|
|
|
10221
10135
|
let top = rect.top - tipH - margin;
|
|
10222
10136
|
let left = rect.left + (rect.width - tipW) / 2;
|
|
10223
10137
|
if (top < margin) top = rect.bottom + margin;
|
|
10224
|
-
if (left + tipW >
|
|
10138
|
+
if (left + tipW > globalThis.innerWidth - margin) left = globalThis.innerWidth - tipW - margin;
|
|
10225
10139
|
if (left < margin) left = margin;
|
|
10226
10140
|
this._el.style.top = `${top}px`;
|
|
10227
10141
|
this._el.style.left = `${left}px`;
|
|
10228
10142
|
}
|
|
10229
10143
|
_syncWrapBtn() {
|
|
10230
10144
|
if (!this._activePre || !this._wrapBtn) return;
|
|
10231
|
-
const wrapped = (this._activePre.style.whiteSpace || "").includes("pre-wrap") ||
|
|
10145
|
+
const wrapped = (this._activePre.style.whiteSpace || "").includes("pre-wrap") || globalThis.getComputedStyle(this._activePre).whiteSpace === "pre-wrap";
|
|
10232
10146
|
this._wrapBtn.classList.toggle("active", wrapped);
|
|
10233
10147
|
this._wrapBtn.title = wrapped ? this.context.locale.tooltips.code.disableWordWrap : this.context.locale.tooltips.code.enableWordWrap;
|
|
10234
10148
|
}
|
|
10235
10149
|
_syncLangSelect() {
|
|
10236
10150
|
if (!this._activePre || !this._langSelect) return;
|
|
10237
10151
|
const codeEl = this._activePre.querySelector("code");
|
|
10238
|
-
const fromAttr = this._activePre.
|
|
10152
|
+
const fromAttr = this._activePre.dataset.language || "";
|
|
10239
10153
|
const fromClass = codeEl ? (_LANG_CLASS_RE.exec(codeEl.className) || [])[1] || "" : "";
|
|
10240
10154
|
this._langSelect.value = fromAttr || fromClass || "";
|
|
10241
10155
|
}
|
|
@@ -10254,7 +10168,7 @@ var CodeTooltip = class {
|
|
|
10254
10168
|
document.execCommand("copy");
|
|
10255
10169
|
this._flashCopied();
|
|
10256
10170
|
} catch (_) {}
|
|
10257
|
-
|
|
10171
|
+
ta.remove();
|
|
10258
10172
|
}
|
|
10259
10173
|
}
|
|
10260
10174
|
_flashCopied() {
|
|
@@ -10287,7 +10201,6 @@ var CodeTooltip = class {
|
|
|
10287
10201
|
applyLanguage(pre, lang) {
|
|
10288
10202
|
if (!pre || !lang) return;
|
|
10289
10203
|
const savedPre = this._activePre;
|
|
10290
|
-
this._langSelect && this._langSelect.value;
|
|
10291
10204
|
this._activePre = pre;
|
|
10292
10205
|
if (this._langSelect) this._langSelect.value = lang;
|
|
10293
10206
|
this._onLangChange();
|
|
@@ -10298,7 +10211,7 @@ var CodeTooltip = class {
|
|
|
10298
10211
|
const pre = this._activePre;
|
|
10299
10212
|
if (!pre) return;
|
|
10300
10213
|
const lang = this._langSelect.value;
|
|
10301
|
-
const _w =
|
|
10214
|
+
const _w = globalThis;
|
|
10302
10215
|
let codeEl = pre.querySelector("code");
|
|
10303
10216
|
if (!codeEl) {
|
|
10304
10217
|
codeEl = document.createElement("code");
|
|
@@ -10308,15 +10221,15 @@ var CodeTooltip = class {
|
|
|
10308
10221
|
}
|
|
10309
10222
|
codeEl.className = lang ? `language-${lang}` : "";
|
|
10310
10223
|
pre.className = lang ? `language-${lang}` : "";
|
|
10311
|
-
if (lang) pre.
|
|
10312
|
-
else pre.
|
|
10224
|
+
if (lang) pre.dataset.language = lang;
|
|
10225
|
+
else delete pre.dataset.language;
|
|
10313
10226
|
const applyPrism = () => {
|
|
10314
10227
|
codeEl.querySelectorAll("br").forEach((br) => br.replaceWith("\n"));
|
|
10315
10228
|
_w.Prism.highlightElement(codeEl);
|
|
10316
10229
|
this.context.invoke("editor.afterCommand");
|
|
10317
10230
|
};
|
|
10318
10231
|
if (lang) {
|
|
10319
|
-
if (
|
|
10232
|
+
if (_w.Prism !== void 0) {
|
|
10320
10233
|
if (_w.Prism.languages[lang]) {
|
|
10321
10234
|
applyPrism();
|
|
10322
10235
|
return;
|
|
@@ -10338,7 +10251,7 @@ var CodeTooltip = class {
|
|
|
10338
10251
|
* Called once at initialize time. Fire-and-forget; errors are silent.
|
|
10339
10252
|
*/
|
|
10340
10253
|
_ensurePrism() {
|
|
10341
|
-
const _w =
|
|
10254
|
+
const _w = globalThis;
|
|
10342
10255
|
if (!this.context.options.codeHighlight || _w.Prism) return;
|
|
10343
10256
|
const cdn = this.context.options.codeHighlightCDN;
|
|
10344
10257
|
const themeHref = `${cdn}/themes/prism-tomorrow.min.css`;
|
|
@@ -10371,11 +10284,11 @@ var CodeTooltip = class {
|
|
|
10371
10284
|
* @param {Function} cb – called once the grammar is ready
|
|
10372
10285
|
*/
|
|
10373
10286
|
_loadPrismComponent(lang, cb) {
|
|
10374
|
-
const _w =
|
|
10287
|
+
const _w = globalThis;
|
|
10375
10288
|
const src = `${this.context.options.codeHighlightCDN}/components/prism-${lang}.min.js`;
|
|
10376
10289
|
if (document.querySelector(`script[src="${src}"]`)) {
|
|
10377
10290
|
const poll = setInterval(() => {
|
|
10378
|
-
if (_w.Prism
|
|
10291
|
+
if (_w.Prism?.languages[lang]) {
|
|
10379
10292
|
clearInterval(poll);
|
|
10380
10293
|
cb();
|
|
10381
10294
|
}
|
|
@@ -10406,7 +10319,7 @@ var CodeTooltip = class {
|
|
|
10406
10319
|
const pre = this._activePre;
|
|
10407
10320
|
if (!pre) return;
|
|
10408
10321
|
this._hide();
|
|
10409
|
-
|
|
10322
|
+
pre.remove();
|
|
10410
10323
|
this.context.invoke("editor.afterCommand");
|
|
10411
10324
|
}
|
|
10412
10325
|
};
|
|
@@ -12761,7 +12674,7 @@ var EmojiDialog = class {
|
|
|
12761
12674
|
destroy() {
|
|
12762
12675
|
this._disposers.forEach((d) => d());
|
|
12763
12676
|
this._disposers = [];
|
|
12764
|
-
if (this._dialog && this._dialog.parentNode) this._dialog.
|
|
12677
|
+
if (this._dialog && this._dialog.parentNode) this._dialog.remove();
|
|
12765
12678
|
this._dialog = null;
|
|
12766
12679
|
}
|
|
12767
12680
|
show() {
|
|
@@ -12822,7 +12735,7 @@ var EmojiDialog = class {
|
|
|
12822
12735
|
class: "an-icon-cat",
|
|
12823
12736
|
"data-cat": id
|
|
12824
12737
|
});
|
|
12825
|
-
tab.textContent = L.categories
|
|
12738
|
+
tab.textContent = L.categories?.[id] || label;
|
|
12826
12739
|
catBar.appendChild(tab);
|
|
12827
12740
|
});
|
|
12828
12741
|
this._catBar = catBar;
|
|
@@ -12903,7 +12816,7 @@ var EmojiDialog = class {
|
|
|
12903
12816
|
const savedRange = this._savedRange;
|
|
12904
12817
|
const editable = this.context.layoutInfo.editable;
|
|
12905
12818
|
if (savedRange) savedRange.select();
|
|
12906
|
-
const sel =
|
|
12819
|
+
const sel = globalThis.getSelection();
|
|
12907
12820
|
let range = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;
|
|
12908
12821
|
if (!range) {
|
|
12909
12822
|
range = document.createRange();
|
|
@@ -12913,7 +12826,7 @@ var EmojiDialog = class {
|
|
|
12913
12826
|
const _sc = range.startContainer;
|
|
12914
12827
|
const _tdAnchor = (_sc.nodeType === 1 ? _sc : _sc.parentElement)?.closest("td, th");
|
|
12915
12828
|
range.deleteContents();
|
|
12916
|
-
if (_tdAnchor
|
|
12829
|
+
if (_tdAnchor?.isConnected && !_tdAnchor.contains(range.startContainer)) {
|
|
12917
12830
|
range.setStart(_tdAnchor, 0);
|
|
12918
12831
|
range.collapse(true);
|
|
12919
12832
|
}
|
|
@@ -12933,7 +12846,7 @@ var EmojiDialog = class {
|
|
|
12933
12846
|
if (this._dialog) {
|
|
12934
12847
|
this._dialog.style.display = "flex";
|
|
12935
12848
|
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
12936
|
-
setTimeout(() => this._searchInput
|
|
12849
|
+
setTimeout(() => this._searchInput?.focus(), 50);
|
|
12937
12850
|
}
|
|
12938
12851
|
}
|
|
12939
12852
|
_close() {
|
|
@@ -13240,7 +13153,7 @@ var IconDialog = class {
|
|
|
13240
13153
|
destroy() {
|
|
13241
13154
|
this._disposers.forEach((d) => d());
|
|
13242
13155
|
this._disposers = [];
|
|
13243
|
-
|
|
13156
|
+
this._dialog?.remove();
|
|
13244
13157
|
this._dialog = null;
|
|
13245
13158
|
}
|
|
13246
13159
|
show() {
|
|
@@ -13305,7 +13218,7 @@ var IconDialog = class {
|
|
|
13305
13218
|
class: "an-icon-cat",
|
|
13306
13219
|
"data-cat": id
|
|
13307
13220
|
});
|
|
13308
|
-
tab.textContent = L.categories
|
|
13221
|
+
tab.textContent = L.categories?.[id] || label;
|
|
13309
13222
|
catBar.appendChild(tab);
|
|
13310
13223
|
});
|
|
13311
13224
|
this._catBar = catBar;
|
|
@@ -13473,17 +13386,17 @@ var IconDialog = class {
|
|
|
13473
13386
|
this._preview.innerHTML = "<span class=\"an-icon-preview-hint\">Select an icon</span>";
|
|
13474
13387
|
return;
|
|
13475
13388
|
}
|
|
13476
|
-
const cls = this._styleSelect
|
|
13477
|
-
const size = this._sizeSelect
|
|
13478
|
-
const color =
|
|
13389
|
+
const cls = this._styleSelect?.value || "fa-solid";
|
|
13390
|
+
const size = this._sizeSelect?.value || "1em";
|
|
13391
|
+
const color = this._useColorCb?.checked ?? false ? this._colorInput?.value ?? "" : "";
|
|
13479
13392
|
const styleAttr = [size ? `font-size:${size}` : "", color ? `color:${color}` : ""].filter(Boolean).join(";");
|
|
13480
13393
|
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
13394
|
}
|
|
13482
13395
|
_onInsert() {
|
|
13483
13396
|
if (!this._selectedIcon) return;
|
|
13484
|
-
const cls = this._styleSelect
|
|
13485
|
-
const size = this._sizeSelect
|
|
13486
|
-
const color =
|
|
13397
|
+
const cls = this._styleSelect?.value || "fa-solid";
|
|
13398
|
+
const size = this._sizeSelect?.value || "";
|
|
13399
|
+
const color = this._useColorCb?.checked ?? false ? this._colorInput?.value ?? "" : "";
|
|
13487
13400
|
const styleParts = [size ? `font-size:${size}` : "", color ? `color:${color}` : ""].filter(Boolean);
|
|
13488
13401
|
const iconEl = document.createElement("i");
|
|
13489
13402
|
iconEl.className = `${cls} fa-${this._selectedIcon}`;
|
|
@@ -13493,8 +13406,8 @@ var IconDialog = class {
|
|
|
13493
13406
|
const savedRange = this._savedRange;
|
|
13494
13407
|
const editable = this.context.layoutInfo.editable;
|
|
13495
13408
|
if (savedRange) savedRange.select();
|
|
13496
|
-
const sel =
|
|
13497
|
-
let range = sel
|
|
13409
|
+
const sel = globalThis.getSelection();
|
|
13410
|
+
let range = (sel?.rangeCount ?? 0) > 0 ? sel.getRangeAt(0) : null;
|
|
13498
13411
|
if (!range) {
|
|
13499
13412
|
range = document.createRange();
|
|
13500
13413
|
range.selectNodeContents(editable);
|
|
@@ -13533,7 +13446,7 @@ var IconDialog = class {
|
|
|
13533
13446
|
if (this._dialog) {
|
|
13534
13447
|
this._dialog.style.display = "flex";
|
|
13535
13448
|
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
13536
|
-
setTimeout(() => this._searchInput
|
|
13449
|
+
setTimeout(() => this._searchInput?.focus(), 50);
|
|
13537
13450
|
}
|
|
13538
13451
|
}
|
|
13539
13452
|
_close() {
|
|
@@ -13634,7 +13547,7 @@ var defaultItems = [
|
|
|
13634
13547
|
icon: ICONS.paste,
|
|
13635
13548
|
action: (ctx) => {
|
|
13636
13549
|
if (!navigator.clipboard) return;
|
|
13637
|
-
const editable = ctx.layoutInfo
|
|
13550
|
+
const editable = ctx.layoutInfo?.editable;
|
|
13638
13551
|
if (!editable) return;
|
|
13639
13552
|
const doInsert = (html, text) => {
|
|
13640
13553
|
editable.focus();
|
|
@@ -13759,13 +13672,13 @@ var ContextMenu = class {
|
|
|
13759
13672
|
this.el.style.display = "none";
|
|
13760
13673
|
document.body.appendChild(this.el);
|
|
13761
13674
|
this._renderItems(this._items);
|
|
13762
|
-
const editable = this.context.layoutInfo
|
|
13675
|
+
const editable = this.context.layoutInfo?.editable;
|
|
13763
13676
|
if (editable) this._disposers.push(on(editable, "contextmenu", (e) => this._onContextMenu(e)));
|
|
13764
13677
|
this._disposers.push(on(document, "click", (e) => this._maybeHide(e)));
|
|
13765
13678
|
this._disposers.push(on(document, "keydown", (e) => {
|
|
13766
13679
|
if (e.key === "Escape") this.hide();
|
|
13767
13680
|
}));
|
|
13768
|
-
this._disposers.push(on(
|
|
13681
|
+
this._disposers.push(on(globalThis, "scroll", () => this.hide(), { passive: true }));
|
|
13769
13682
|
return this;
|
|
13770
13683
|
}
|
|
13771
13684
|
destroy() {
|
|
@@ -13781,7 +13694,7 @@ var ContextMenu = class {
|
|
|
13781
13694
|
} catch (_e) {}
|
|
13782
13695
|
});
|
|
13783
13696
|
this._disposers = [];
|
|
13784
|
-
if (this.el
|
|
13697
|
+
if (this.el) this.el.remove();
|
|
13785
13698
|
this.el = null;
|
|
13786
13699
|
}
|
|
13787
13700
|
_renderItems(items) {
|
|
@@ -13809,8 +13722,8 @@ var ContextMenu = class {
|
|
|
13809
13722
|
backBtn.appendChild(createElement("span", { class: "an-context-label" }, [backLabel]));
|
|
13810
13723
|
const off = on(backBtn, "click", (e) => {
|
|
13811
13724
|
e.stopPropagation();
|
|
13812
|
-
const curLeft = parseFloat(this.el.style.left);
|
|
13813
|
-
const curTop = parseFloat(this.el.style.top);
|
|
13725
|
+
const curLeft = Number.parseFloat(this.el.style.left);
|
|
13726
|
+
const curTop = Number.parseFloat(this.el.style.top);
|
|
13814
13727
|
this._renderItems(it.navigate());
|
|
13815
13728
|
this._reposition(curLeft, curTop);
|
|
13816
13729
|
});
|
|
@@ -13853,8 +13766,8 @@ var ContextMenu = class {
|
|
|
13853
13766
|
btn.appendChild(chevron);
|
|
13854
13767
|
const off = on(btn, "click", (e) => {
|
|
13855
13768
|
e.stopPropagation();
|
|
13856
|
-
const curLeft = parseFloat(this.el.style.left);
|
|
13857
|
-
const curTop = parseFloat(this.el.style.top);
|
|
13769
|
+
const curLeft = Number.parseFloat(this.el.style.left);
|
|
13770
|
+
const curTop = Number.parseFloat(this.el.style.top);
|
|
13858
13771
|
this._renderItems(it.navigate());
|
|
13859
13772
|
this._reposition(curLeft, curTop);
|
|
13860
13773
|
});
|
|
@@ -13979,10 +13892,10 @@ var ContextMenu = class {
|
|
|
13979
13892
|
if (!cell) return;
|
|
13980
13893
|
const rows = +cell.dataset.row;
|
|
13981
13894
|
const cols = +cell.dataset.col;
|
|
13982
|
-
const editable = this.context.layoutInfo
|
|
13895
|
+
const editable = this.context.layoutInfo?.editable;
|
|
13983
13896
|
if (editable && this._savedRange) {
|
|
13984
13897
|
editable.focus();
|
|
13985
|
-
const sel =
|
|
13898
|
+
const sel = globalThis.getSelection();
|
|
13986
13899
|
sel.removeAllRanges();
|
|
13987
13900
|
sel.addRange(this._savedRange.cloneRange());
|
|
13988
13901
|
}
|
|
@@ -14024,12 +13937,12 @@ var ContextMenu = class {
|
|
|
14024
13937
|
});
|
|
14025
13938
|
}
|
|
14026
13939
|
_onContextMenu(event) {
|
|
14027
|
-
const editable = this.context.layoutInfo
|
|
13940
|
+
const editable = this.context.layoutInfo?.editable;
|
|
14028
13941
|
if (!editable) return;
|
|
14029
13942
|
if (!editable.contains(event.target)) return;
|
|
14030
13943
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
14031
13944
|
event.preventDefault();
|
|
14032
|
-
const winSel =
|
|
13945
|
+
const winSel = globalThis.getSelection();
|
|
14033
13946
|
this._savedRange = winSel && winSel.rangeCount > 0 ? winSel.getRangeAt(0).cloneRange() : null;
|
|
14034
13947
|
this._renderItems(this._items);
|
|
14035
13948
|
const openX = event.clientX;
|
|
@@ -14061,9 +13974,9 @@ var ContextMenu = class {
|
|
|
14061
13974
|
const h = this.el.offsetHeight;
|
|
14062
13975
|
let left = rx;
|
|
14063
13976
|
let top = ry;
|
|
14064
|
-
if (left + w >
|
|
13977
|
+
if (left + w > globalThis.innerWidth - 8) left = globalThis.innerWidth - w - 8;
|
|
14065
13978
|
if (left < 8) left = 8;
|
|
14066
|
-
if (top + h >
|
|
13979
|
+
if (top + h > globalThis.innerHeight - 8) top = globalThis.innerHeight - h - 8;
|
|
14067
13980
|
if (top < 8) top = 8;
|
|
14068
13981
|
this.el.style.left = `${left}px`;
|
|
14069
13982
|
this.el.style.top = `${top}px`;
|
|
@@ -14084,17 +13997,17 @@ var ContextMenu = class {
|
|
|
14084
13997
|
let node = range.startContainer;
|
|
14085
13998
|
if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
|
|
14086
13999
|
if (!node) return type === "foreColor" ? "#000000" : "transparent";
|
|
14087
|
-
const cs =
|
|
14000
|
+
const cs = globalThis.getComputedStyle(node);
|
|
14088
14001
|
if (type === "foreColor") return cs.color || "#000000";
|
|
14089
14002
|
const bg = cs.backgroundColor;
|
|
14090
14003
|
return !bg || bg === "rgba(0, 0, 0, 0)" || bg === "transparent" ? "transparent" : bg;
|
|
14091
14004
|
}
|
|
14092
14005
|
/** Restore selection, apply a color command, then hide the menu. */
|
|
14093
14006
|
_applyColor(type, color) {
|
|
14094
|
-
const editable = this.context.layoutInfo
|
|
14007
|
+
const editable = this.context.layoutInfo?.editable;
|
|
14095
14008
|
if (!editable || !this._savedRange) return;
|
|
14096
14009
|
editable.focus();
|
|
14097
|
-
const sel =
|
|
14010
|
+
const sel = globalThis.getSelection();
|
|
14098
14011
|
sel.removeAllRanges();
|
|
14099
14012
|
sel.addRange(this._savedRange.cloneRange());
|
|
14100
14013
|
document.execCommand(type, false, color);
|
|
@@ -14109,15 +14022,15 @@ var ContextMenu = class {
|
|
|
14109
14022
|
copyFormat() {
|
|
14110
14023
|
const range = this._savedRange;
|
|
14111
14024
|
if (!range) return;
|
|
14112
|
-
const editable = this.context.layoutInfo
|
|
14025
|
+
const editable = this.context.layoutInfo?.editable;
|
|
14113
14026
|
let node = range.startContainer;
|
|
14114
14027
|
if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
|
|
14115
14028
|
if (!node || !editable || !editable.contains(node)) return;
|
|
14116
|
-
const cs =
|
|
14029
|
+
const cs = globalThis.getComputedStyle(node);
|
|
14117
14030
|
const explicitFontFamily = this._findExplicitStyle(node, editable, "fontFamily");
|
|
14118
14031
|
const explicitFontSize = this._findExplicitStyle(node, editable, "fontSize");
|
|
14119
14032
|
this._copiedFormat = {
|
|
14120
|
-
bold: parseInt(cs.fontWeight, 10) >= 700,
|
|
14033
|
+
bold: Number.parseInt(cs.fontWeight, 10) >= 700,
|
|
14121
14034
|
italic: cs.fontStyle === "italic" || cs.fontStyle === "oblique",
|
|
14122
14035
|
underline: (cs.textDecorationLine || "").includes("underline"),
|
|
14123
14036
|
strikethrough: (cs.textDecorationLine || "").includes("line-through"),
|
|
@@ -14148,10 +14061,10 @@ var ContextMenu = class {
|
|
|
14148
14061
|
pasteFormat() {
|
|
14149
14062
|
if (!this._copiedFormat || !this._savedRange) return;
|
|
14150
14063
|
const fmt = this._copiedFormat;
|
|
14151
|
-
const editable = this.context.layoutInfo
|
|
14064
|
+
const editable = this.context.layoutInfo?.editable;
|
|
14152
14065
|
if (!editable) return;
|
|
14153
14066
|
editable.focus();
|
|
14154
|
-
const sel =
|
|
14067
|
+
const sel = globalThis.getSelection();
|
|
14155
14068
|
sel.removeAllRanges();
|
|
14156
14069
|
sel.addRange(this._savedRange.cloneRange());
|
|
14157
14070
|
document.execCommand("removeFormat");
|
|
@@ -14168,14 +14081,14 @@ var ContextMenu = class {
|
|
|
14168
14081
|
const preExisting = new Set(editable.querySelectorAll("font[size=\"7\"]"));
|
|
14169
14082
|
document.execCommand("fontSize", false, "7");
|
|
14170
14083
|
editable.querySelectorAll("font[size=\"7\"]").forEach((el) => {
|
|
14171
|
-
if (!preExisting.has(el)) el.
|
|
14084
|
+
if (!preExisting.has(el)) /** @type {HTMLElement} */ el.dataset.anTmp = marker;
|
|
14172
14085
|
});
|
|
14173
14086
|
editable.querySelectorAll(`[data-an-tmp="${marker}"]`).forEach((el) => {
|
|
14174
14087
|
const span = document.createElement("span");
|
|
14175
14088
|
span.style.fontSize = fmt.fontSize;
|
|
14176
14089
|
el.parentNode.insertBefore(span, el);
|
|
14177
14090
|
while (el.firstChild) span.appendChild(el.firstChild);
|
|
14178
|
-
el.
|
|
14091
|
+
el.remove();
|
|
14179
14092
|
});
|
|
14180
14093
|
}
|
|
14181
14094
|
this.context.invoke("editor.afterCommand");
|
|
@@ -14183,10 +14096,10 @@ var ContextMenu = class {
|
|
|
14183
14096
|
/** Strip all inline formatting from the saved selection. */
|
|
14184
14097
|
removeFormat() {
|
|
14185
14098
|
if (!this._savedRange) return;
|
|
14186
|
-
const editable = this.context.layoutInfo
|
|
14099
|
+
const editable = this.context.layoutInfo?.editable;
|
|
14187
14100
|
if (!editable) return;
|
|
14188
14101
|
editable.focus();
|
|
14189
|
-
const sel =
|
|
14102
|
+
const sel = globalThis.getSelection();
|
|
14190
14103
|
sel.removeAllRanges();
|
|
14191
14104
|
sel.addRange(this._savedRange.cloneRange());
|
|
14192
14105
|
document.execCommand("removeFormat");
|
|
@@ -14300,14 +14213,14 @@ var ShortcutsDialog = class {
|
|
|
14300
14213
|
destroy() {
|
|
14301
14214
|
this._disposers.forEach((d) => d());
|
|
14302
14215
|
this._disposers = [];
|
|
14303
|
-
|
|
14216
|
+
this._dialog?.remove();
|
|
14304
14217
|
this._dialog = null;
|
|
14305
14218
|
}
|
|
14306
14219
|
show() {
|
|
14307
14220
|
if (this._dialog) {
|
|
14308
14221
|
this._dialog.style.display = "flex";
|
|
14309
14222
|
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
14310
|
-
setTimeout(() => this._closeBtn
|
|
14223
|
+
setTimeout(() => this._closeBtn?.focus(), 50);
|
|
14311
14224
|
}
|
|
14312
14225
|
}
|
|
14313
14226
|
_close() {
|
|
@@ -14413,7 +14326,7 @@ var FindReplace = class {
|
|
|
14413
14326
|
this._clearHighlights();
|
|
14414
14327
|
this._disposers.forEach((d) => d());
|
|
14415
14328
|
this._disposers = [];
|
|
14416
|
-
if (this._dialog && this._dialog.parentNode) this._dialog.
|
|
14329
|
+
if (this._dialog && this._dialog.parentNode) this._dialog.remove();
|
|
14417
14330
|
this._dialog = null;
|
|
14418
14331
|
}
|
|
14419
14332
|
/**
|
|
@@ -14656,15 +14569,19 @@ var FindReplace = class {
|
|
|
14656
14569
|
const re = this._queryRegex;
|
|
14657
14570
|
const MAX_RESULTS = 500;
|
|
14658
14571
|
const walker = document.createTreeWalker(root, 4);
|
|
14659
|
-
let node;
|
|
14660
|
-
while (
|
|
14572
|
+
let node = walker.nextNode();
|
|
14573
|
+
while (node && results.length < MAX_RESULTS) {
|
|
14661
14574
|
re.lastIndex = 0;
|
|
14662
14575
|
let m;
|
|
14663
|
-
while ((m = re.exec(
|
|
14576
|
+
while ((m = re.exec(
|
|
14577
|
+
/** @type {Text} */
|
|
14578
|
+
node.textContent
|
|
14579
|
+
)) !== null && results.length < MAX_RESULTS) results.push({
|
|
14664
14580
|
node,
|
|
14665
14581
|
start: m.index,
|
|
14666
14582
|
end: m.index + m[0].length
|
|
14667
14583
|
});
|
|
14584
|
+
node = walker.nextNode();
|
|
14668
14585
|
}
|
|
14669
14586
|
return results;
|
|
14670
14587
|
}
|
|
@@ -14699,7 +14616,7 @@ var FindReplace = class {
|
|
|
14699
14616
|
const parent = match.mark.parentNode;
|
|
14700
14617
|
const textNode = document.createTextNode(replacement);
|
|
14701
14618
|
parent.insertBefore(textNode, match.mark);
|
|
14702
|
-
|
|
14619
|
+
match.mark.remove();
|
|
14703
14620
|
parent.normalize();
|
|
14704
14621
|
this.context.invoke("editor.afterCommand");
|
|
14705
14622
|
const savedIndex = this._currentIndex;
|
|
@@ -14717,7 +14634,7 @@ var FindReplace = class {
|
|
|
14717
14634
|
if (!mark || !mark.parentNode) return;
|
|
14718
14635
|
const textNode = document.createTextNode(replacement);
|
|
14719
14636
|
mark.parentNode.insertBefore(textNode, mark);
|
|
14720
|
-
mark.
|
|
14637
|
+
mark.remove();
|
|
14721
14638
|
});
|
|
14722
14639
|
if (this.context.layoutInfo.editable) this.context.layoutInfo.editable.normalize();
|
|
14723
14640
|
this._matches = [];
|
|
@@ -14736,7 +14653,7 @@ var FindReplace = class {
|
|
|
14736
14653
|
const parent = mark.parentNode;
|
|
14737
14654
|
if (!parent) return;
|
|
14738
14655
|
while (mark.firstChild) parent.insertBefore(mark.firstChild, mark);
|
|
14739
|
-
|
|
14656
|
+
mark.remove();
|
|
14740
14657
|
});
|
|
14741
14658
|
editable.normalize();
|
|
14742
14659
|
this._matches = [];
|
|
@@ -14787,7 +14704,7 @@ function drawCropToCanvas(img, naturalRect, renderW, renderH) {
|
|
|
14787
14704
|
resolve(null);
|
|
14788
14705
|
}
|
|
14789
14706
|
};
|
|
14790
|
-
if (img.src.startsWith("data:") || img.src.startsWith("blob:") || img.src.startsWith(
|
|
14707
|
+
if (img.src.startsWith("data:") || img.src.startsWith("blob:") || img.src.startsWith(globalThis.location.origin)) {
|
|
14791
14708
|
tryDraw(img);
|
|
14792
14709
|
return;
|
|
14793
14710
|
}
|
|
@@ -15045,8 +14962,8 @@ var ImageCropOverlay = class {
|
|
|
15045
14962
|
this._cropBox.style.top = `${y}px`;
|
|
15046
14963
|
this._cropBox.style.width = `${w}px`;
|
|
15047
14964
|
this._cropBox.style.height = `${h}px`;
|
|
15048
|
-
const vw =
|
|
15049
|
-
const vh =
|
|
14965
|
+
const vw = globalThis.innerWidth;
|
|
14966
|
+
const vh = globalThis.innerHeight;
|
|
15050
14967
|
this._scrim.style.clipPath = [
|
|
15051
14968
|
`polygon(`,
|
|
15052
14969
|
`0 0, ${vw}px 0, ${vw}px ${vh}px, 0 ${vh}px, 0 0,`,
|
|
@@ -15070,7 +14987,7 @@ var ImageCropOverlay = class {
|
|
|
15070
14987
|
}
|
|
15071
14988
|
const margin = 8;
|
|
15072
14989
|
let tbTop = y + h + margin;
|
|
15073
|
-
if (tbTop + 40 >
|
|
14990
|
+
if (tbTop + 40 > globalThis.innerHeight - margin) tbTop = y - 40 - margin;
|
|
15074
14991
|
this._toolbar.style.left = `${x}px`;
|
|
15075
14992
|
this._toolbar.style.top = `${tbTop}px`;
|
|
15076
14993
|
}
|
|
@@ -15197,7 +15114,7 @@ var ImageCropOverlay = class {
|
|
|
15197
15114
|
this._close(false);
|
|
15198
15115
|
return;
|
|
15199
15116
|
}
|
|
15200
|
-
const fmt =
|
|
15117
|
+
const fmt = /^data:image\/(jpe?g)/i.exec(img.src) ? "image/jpeg" : "image/png";
|
|
15201
15118
|
const quality = fmt === "image/jpeg" ? .92 : void 0;
|
|
15202
15119
|
const newSrc = canvas.toDataURL(fmt, quality);
|
|
15203
15120
|
this._close(false);
|
|
@@ -15237,7 +15154,7 @@ var ImageCropOverlay = class {
|
|
|
15237
15154
|
banner.textContent = msg;
|
|
15238
15155
|
document.body.appendChild(banner);
|
|
15239
15156
|
setTimeout(() => {
|
|
15240
|
-
|
|
15157
|
+
banner.remove();
|
|
15241
15158
|
}, 4e3);
|
|
15242
15159
|
}
|
|
15243
15160
|
/**
|
|
@@ -15252,7 +15169,7 @@ var ImageCropOverlay = class {
|
|
|
15252
15169
|
this._cropBox,
|
|
15253
15170
|
this._toolbar
|
|
15254
15171
|
].forEach((el) => {
|
|
15255
|
-
|
|
15172
|
+
el?.remove();
|
|
15256
15173
|
});
|
|
15257
15174
|
this._scrim = null;
|
|
15258
15175
|
this._cropBox = null;
|
|
@@ -15273,7 +15190,7 @@ var ImageCropOverlay = class {
|
|
|
15273
15190
|
*
|
|
15274
15191
|
* Activated when both `autoSave` and `autoSaveRestore` options are true.
|
|
15275
15192
|
* On initialize it checks localStorage for a draft that is within the
|
|
15276
|
-
* `autoSaveRestoreTimeout` day
|
|
15193
|
+
* `autoSaveRestoreTimeout` day globalThis. If one is found a dismissible banner
|
|
15277
15194
|
* is prepended to the editor container.
|
|
15278
15195
|
*/
|
|
15279
15196
|
var AutoSaveRestore = class {
|
|
@@ -15359,7 +15276,7 @@ var AutoSaveRestore = class {
|
|
|
15359
15276
|
this._removeBanner();
|
|
15360
15277
|
}
|
|
15361
15278
|
_removeBanner() {
|
|
15362
|
-
|
|
15279
|
+
this._banner?.remove();
|
|
15363
15280
|
this._banner = null;
|
|
15364
15281
|
}
|
|
15365
15282
|
};
|
|
@@ -15422,8 +15339,8 @@ var MarkdownShortcuts = class {
|
|
|
15422
15339
|
* @returns {{ text: string, range: Range, lineNode: Node } | null}
|
|
15423
15340
|
*/
|
|
15424
15341
|
_getLineContext() {
|
|
15425
|
-
const sel =
|
|
15426
|
-
if (!sel
|
|
15342
|
+
const sel = globalThis.getSelection();
|
|
15343
|
+
if (!sel?.rangeCount) return null;
|
|
15427
15344
|
const range = sel.getRangeAt(0);
|
|
15428
15345
|
if (!range.collapsed) return null;
|
|
15429
15346
|
const editable = this.context.layoutInfo.editable;
|
|
@@ -15442,7 +15359,7 @@ var MarkdownShortcuts = class {
|
|
|
15442
15359
|
}
|
|
15443
15360
|
_isBlock(node) {
|
|
15444
15361
|
if (node.nodeType !== Node.ELEMENT_NODE) return false;
|
|
15445
|
-
const display =
|
|
15362
|
+
const display = globalThis.getComputedStyle(node).display;
|
|
15446
15363
|
return display === "block" || display === "list-item" || display === "table-cell";
|
|
15447
15364
|
}
|
|
15448
15365
|
/** Applies block rule on Space key. Returns true if a rule fired. */
|
|
@@ -15473,7 +15390,7 @@ var MarkdownShortcuts = class {
|
|
|
15473
15390
|
}
|
|
15474
15391
|
];
|
|
15475
15392
|
for (const { re, handler } of blockPatterns) {
|
|
15476
|
-
const m =
|
|
15393
|
+
const m = re.exec(text);
|
|
15477
15394
|
if (m) {
|
|
15478
15395
|
handler(m);
|
|
15479
15396
|
return true;
|
|
@@ -15497,8 +15414,8 @@ var MarkdownShortcuts = class {
|
|
|
15497
15414
|
return false;
|
|
15498
15415
|
}
|
|
15499
15416
|
_selectLineAndDelete() {
|
|
15500
|
-
const sel =
|
|
15501
|
-
if (!sel
|
|
15417
|
+
const sel = globalThis.getSelection();
|
|
15418
|
+
if (!sel?.rangeCount) return;
|
|
15502
15419
|
const range = sel.getRangeAt(0);
|
|
15503
15420
|
const startRange = document.createRange();
|
|
15504
15421
|
startRange.setStart(range.startContainer.parentNode || range.startContainer, 0);
|
|
@@ -15536,8 +15453,8 @@ var MarkdownShortcuts = class {
|
|
|
15536
15453
|
this.context.triggerEvent("change", this.context.getHTML());
|
|
15537
15454
|
}
|
|
15538
15455
|
_onInput() {
|
|
15539
|
-
const sel =
|
|
15540
|
-
if (!sel
|
|
15456
|
+
const sel = globalThis.getSelection();
|
|
15457
|
+
if (!sel?.rangeCount) return;
|
|
15541
15458
|
const range = sel.getRangeAt(0);
|
|
15542
15459
|
if (!range.collapsed) return;
|
|
15543
15460
|
if (!this.context.layoutInfo.editable.contains(range.startContainer)) return;
|
|
@@ -15565,7 +15482,7 @@ var MarkdownShortcuts = class {
|
|
|
15565
15482
|
];
|
|
15566
15483
|
const upToCursor = text.slice(0, offset);
|
|
15567
15484
|
for (const { re, tag } of inlineRules) {
|
|
15568
|
-
const m =
|
|
15485
|
+
const m = re.exec(upToCursor);
|
|
15569
15486
|
if (!m) continue;
|
|
15570
15487
|
const matchStart = upToCursor.length - m[0].length;
|
|
15571
15488
|
const matchEnd = offset;
|
|
@@ -15576,11 +15493,8 @@ var MarkdownShortcuts = class {
|
|
|
15576
15493
|
el.textContent = innerText;
|
|
15577
15494
|
const beforeNode = document.createTextNode(before);
|
|
15578
15495
|
const afterNode = document.createTextNode("" + after);
|
|
15579
|
-
|
|
15580
|
-
|
|
15581
|
-
parent.insertBefore(el, node);
|
|
15582
|
-
parent.insertBefore(afterNode, node);
|
|
15583
|
-
parent.removeChild(node);
|
|
15496
|
+
/** @type {ChildNode} */ node.before(beforeNode, el, afterNode);
|
|
15497
|
+
/** @type {ChildNode} */ node.remove();
|
|
15584
15498
|
const newRange = document.createRange();
|
|
15585
15499
|
newRange.setStart(afterNode, 1);
|
|
15586
15500
|
newRange.collapse(true);
|
|
@@ -15651,12 +15565,12 @@ var _ACTIONS = {
|
|
|
15651
15565
|
strikethrough: (ctx) => ctx.invoke("editor.strikethrough"),
|
|
15652
15566
|
link: (ctx) => ctx.invoke("linkDialog.show"),
|
|
15653
15567
|
removeFormat: (ctx) => {
|
|
15654
|
-
const editable = ctx.layoutInfo
|
|
15568
|
+
const editable = ctx.layoutInfo?.editable;
|
|
15655
15569
|
if (!editable) return;
|
|
15656
15570
|
editable.focus();
|
|
15657
15571
|
document.execCommand("removeFormat");
|
|
15658
|
-
const sel =
|
|
15659
|
-
if (sel
|
|
15572
|
+
const sel = globalThis.getSelection();
|
|
15573
|
+
if (sel?.rangeCount > 0 && !sel.getRangeAt(0).collapsed) {
|
|
15660
15574
|
const range = sel.getRangeAt(0);
|
|
15661
15575
|
const ancestor = range.commonAncestorContainer;
|
|
15662
15576
|
const root = ancestor.nodeType === 1 ? ancestor : ancestor.parentElement;
|
|
@@ -15714,15 +15628,15 @@ var BubbleToolbar = class {
|
|
|
15714
15628
|
const d6 = this.context.on("contextMenu:hide", () => {
|
|
15715
15629
|
this._contextMenuOpen = false;
|
|
15716
15630
|
});
|
|
15717
|
-
const d7 = on(
|
|
15718
|
-
const d8 = on(
|
|
15631
|
+
const d7 = on(globalThis, "scroll", () => this._hide(), { passive: true });
|
|
15632
|
+
const d8 = on(globalThis, "resize", () => this._hide(), { passive: true });
|
|
15719
15633
|
this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8);
|
|
15720
15634
|
return this;
|
|
15721
15635
|
}
|
|
15722
15636
|
destroy() {
|
|
15723
|
-
|
|
15637
|
+
this._el?.remove();
|
|
15724
15638
|
this._el = null;
|
|
15725
|
-
|
|
15639
|
+
this._picker?.remove();
|
|
15726
15640
|
this._picker = null;
|
|
15727
15641
|
this._disposers.forEach((d) => d());
|
|
15728
15642
|
this._disposers = [];
|
|
@@ -15836,15 +15750,15 @@ var BubbleToolbar = class {
|
|
|
15836
15750
|
pickerAny._colorInput = colorInput;
|
|
15837
15751
|
}
|
|
15838
15752
|
_openColorPicker(type, anchorBtn) {
|
|
15839
|
-
const sel =
|
|
15840
|
-
if (sel
|
|
15753
|
+
const sel = globalThis.getSelection();
|
|
15754
|
+
if (sel?.rangeCount > 0) this._savedRange = sel.getRangeAt(0).cloneRange();
|
|
15841
15755
|
this._pickerType = type;
|
|
15842
15756
|
const pickerAny = this._picker;
|
|
15843
15757
|
const palette = pickerAny._paletteEl;
|
|
15844
15758
|
const noColorBtn = pickerAny._noColorBtn;
|
|
15845
15759
|
if (type === "hiliteColor") {
|
|
15846
15760
|
if (!palette.contains(noColorBtn)) palette.appendChild(noColorBtn);
|
|
15847
|
-
} else if (palette.contains(noColorBtn))
|
|
15761
|
+
} else if (palette.contains(noColorBtn)) noColorBtn.remove();
|
|
15848
15762
|
/** @type {any} */ this._picker._colorInput.value = type === "foreColor" ? "#000000" : "#ffff00";
|
|
15849
15763
|
this._picker.style.display = "block";
|
|
15850
15764
|
const pw = this._picker.offsetWidth;
|
|
@@ -15853,7 +15767,7 @@ var BubbleToolbar = class {
|
|
|
15853
15767
|
let top = toolbarRect.top - ph - 6;
|
|
15854
15768
|
if (top < 8) top = toolbarRect.bottom + 6;
|
|
15855
15769
|
let left = anchorBtn.getBoundingClientRect().left;
|
|
15856
|
-
left = Math.max(8, Math.min(left,
|
|
15770
|
+
left = Math.max(8, Math.min(left, globalThis.innerWidth - pw - 8));
|
|
15857
15771
|
this._picker.style.left = `${left}px`;
|
|
15858
15772
|
this._picker.style.top = `${top}px`;
|
|
15859
15773
|
}
|
|
@@ -15863,10 +15777,10 @@ var BubbleToolbar = class {
|
|
|
15863
15777
|
}
|
|
15864
15778
|
/** Restore the saved selection, apply execCommand, update the color strip, then close the picker. */
|
|
15865
15779
|
_applyColor(type, color) {
|
|
15866
|
-
const editable = this.context.layoutInfo
|
|
15780
|
+
const editable = this.context.layoutInfo?.editable;
|
|
15867
15781
|
if (!editable || !this._savedRange) return;
|
|
15868
15782
|
editable.focus();
|
|
15869
|
-
const sel =
|
|
15783
|
+
const sel = globalThis.getSelection();
|
|
15870
15784
|
sel.removeAllRanges();
|
|
15871
15785
|
try {
|
|
15872
15786
|
sel.addRange(this._savedRange.cloneRange());
|
|
@@ -15877,8 +15791,7 @@ var BubbleToolbar = class {
|
|
|
15877
15791
|
if (!document.execCommand(cmd, false, color) && cmd === "hiliteColor") document.execCommand("backColor", false, color);
|
|
15878
15792
|
this.context.invoke("editor.afterCommand");
|
|
15879
15793
|
const name = type === "hiliteColor" ? "hiliteColor" : "foreColor";
|
|
15880
|
-
const
|
|
15881
|
-
const strip = btn && btn.querySelector(".an-bubble-color-strip");
|
|
15794
|
+
const strip = (this._el?.querySelector(`[data-name="${name}"]`))?.querySelector(".an-bubble-color-strip");
|
|
15882
15795
|
if (strip) /** @type {HTMLElement} */ strip.style.background = color === "transparent" ? "transparent" : color;
|
|
15883
15796
|
this._closeColorPicker();
|
|
15884
15797
|
this._syncActive();
|
|
@@ -15893,14 +15806,14 @@ var BubbleToolbar = class {
|
|
|
15893
15806
|
const gap = 8;
|
|
15894
15807
|
let left = rect.left + rect.width / 2 - bw / 2;
|
|
15895
15808
|
let top = rect.top - bh - gap;
|
|
15896
|
-
left = Math.max(8, Math.min(left,
|
|
15809
|
+
left = Math.max(8, Math.min(left, globalThis.innerWidth - bw - 8));
|
|
15897
15810
|
if (top < 8) top = rect.bottom + gap;
|
|
15898
15811
|
const tableTooltipEl = document.querySelector(".an-table-tooltip");
|
|
15899
15812
|
if (tableTooltipEl && tableTooltipEl.style.display !== "none") {
|
|
15900
15813
|
const ttRect = tableTooltipEl.getBoundingClientRect();
|
|
15901
15814
|
if (top < ttRect.bottom + gap && top + bh > ttRect.top - gap) {
|
|
15902
15815
|
top = rect.bottom + gap;
|
|
15903
|
-
if (top + bh >
|
|
15816
|
+
if (top + bh > globalThis.innerHeight - 8) top = ttRect.bottom + gap;
|
|
15904
15817
|
}
|
|
15905
15818
|
}
|
|
15906
15819
|
el.style.top = `${top}px`;
|
|
@@ -15926,17 +15839,15 @@ var BubbleToolbar = class {
|
|
|
15926
15839
|
/** Read the current selection's color and update the color-strip indicators. */
|
|
15927
15840
|
_syncColorStrips() {
|
|
15928
15841
|
if (!this._el) return;
|
|
15929
|
-
const sel =
|
|
15842
|
+
const sel = globalThis.getSelection();
|
|
15930
15843
|
if (!sel || !sel.rangeCount) return;
|
|
15931
15844
|
let node = sel.getRangeAt(0).startContainer;
|
|
15932
15845
|
if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
|
|
15933
15846
|
if (!node) return;
|
|
15934
|
-
const cs =
|
|
15935
|
-
const
|
|
15936
|
-
const foreStrip = foreBtn && foreBtn.querySelector(".an-bubble-color-strip");
|
|
15847
|
+
const cs = globalThis.getComputedStyle(node);
|
|
15848
|
+
const foreStrip = this._el.querySelector("[data-name=\"foreColor\"]")?.querySelector(".an-bubble-color-strip");
|
|
15937
15849
|
if (foreStrip) /** @type {HTMLElement} */ foreStrip.style.background = cs.color || "#000000";
|
|
15938
|
-
const
|
|
15939
|
-
const hiliteStrip = hiliteBtn && hiliteBtn.querySelector(".an-bubble-color-strip");
|
|
15850
|
+
const hiliteStrip = this._el.querySelector("[data-name=\"hiliteColor\"]")?.querySelector(".an-bubble-color-strip");
|
|
15940
15851
|
if (hiliteStrip) {
|
|
15941
15852
|
const bg = cs.backgroundColor;
|
|
15942
15853
|
/** @type {HTMLElement} */ hiliteStrip.style.background = !bg || bg === "rgba(0, 0, 0, 0)" || bg === "transparent" ? "transparent" : bg;
|
|
@@ -15947,7 +15858,7 @@ var BubbleToolbar = class {
|
|
|
15947
15858
|
this._rafId = requestAnimationFrame(() => {
|
|
15948
15859
|
if (this._contextMenuOpen) return;
|
|
15949
15860
|
if (this._picker && this._picker.style.display !== "none") return;
|
|
15950
|
-
const sel =
|
|
15861
|
+
const sel = globalThis.getSelection();
|
|
15951
15862
|
if (!sel || sel.isCollapsed || !sel.rangeCount) {
|
|
15952
15863
|
this._hide();
|
|
15953
15864
|
return;
|
|
@@ -15970,8 +15881,8 @@ var BubbleToolbar = class {
|
|
|
15970
15881
|
}
|
|
15971
15882
|
_onMousedown(e) {
|
|
15972
15883
|
if (!this._visible) return;
|
|
15973
|
-
if (this._el
|
|
15974
|
-
if (this._picker
|
|
15884
|
+
if (this._el?.contains(e.target)) return;
|
|
15885
|
+
if (this._picker?.contains(e.target)) return;
|
|
15975
15886
|
if (this.context.layoutInfo.editable.contains(e.target)) return;
|
|
15976
15887
|
this._hide();
|
|
15977
15888
|
}
|
|
@@ -16056,7 +15967,7 @@ var Mention = class {
|
|
|
16056
15967
|
}
|
|
16057
15968
|
destroy() {
|
|
16058
15969
|
clearTimeout(this._debounceTimer);
|
|
16059
|
-
|
|
15970
|
+
this._dropdown?.remove();
|
|
16060
15971
|
this._dropdown = null;
|
|
16061
15972
|
this._disposers.forEach((d) => d());
|
|
16062
15973
|
this._disposers = [];
|
|
@@ -16120,8 +16031,8 @@ var Mention = class {
|
|
|
16120
16031
|
const ddw = dd.offsetWidth;
|
|
16121
16032
|
let top = rect.bottom + 4;
|
|
16122
16033
|
let left = rect.left;
|
|
16123
|
-
if (rect.bottom + ddh + 8 >
|
|
16124
|
-
left = Math.max(8, Math.min(left,
|
|
16034
|
+
if (rect.bottom + ddh + 8 > globalThis.innerHeight) top = rect.top - ddh - 4;
|
|
16035
|
+
left = Math.max(8, Math.min(left, globalThis.innerWidth - ddw - 8));
|
|
16125
16036
|
dd.style.top = `${top}px`;
|
|
16126
16037
|
dd.style.left = `${left}px`;
|
|
16127
16038
|
dd.style.visibility = "";
|
|
@@ -16145,7 +16056,7 @@ var Mention = class {
|
|
|
16145
16056
|
* collapsed range is reliable at this point but often empty inside async callbacks.
|
|
16146
16057
|
*/
|
|
16147
16058
|
_captureCaretRect() {
|
|
16148
|
-
if (this._triggerNode
|
|
16059
|
+
if (this._triggerNode?.isConnected) try {
|
|
16149
16060
|
const r = document.createRange();
|
|
16150
16061
|
const end = Math.min(this._triggerOffset + 1, this._triggerNode.textContent.length);
|
|
16151
16062
|
r.setStart(this._triggerNode, this._triggerOffset);
|
|
@@ -16156,13 +16067,13 @@ var Mention = class {
|
|
|
16156
16067
|
return;
|
|
16157
16068
|
}
|
|
16158
16069
|
} catch (_) {}
|
|
16159
|
-
const sel =
|
|
16070
|
+
const sel = globalThis.getSelection();
|
|
16160
16071
|
if (!sel || !sel.rangeCount) return;
|
|
16161
16072
|
const rects = sel.getRangeAt(0).getClientRects();
|
|
16162
16073
|
if (rects.length > 0) this._caretRect = rects[rects.length - 1];
|
|
16163
16074
|
}
|
|
16164
16075
|
_getQueryAtCursor() {
|
|
16165
|
-
const sel =
|
|
16076
|
+
const sel = globalThis.getSelection();
|
|
16166
16077
|
if (!sel || !sel.rangeCount) return null;
|
|
16167
16078
|
const range = sel.getRangeAt(0);
|
|
16168
16079
|
if (!range.collapsed) return null;
|
|
@@ -16219,7 +16130,7 @@ var Mention = class {
|
|
|
16219
16130
|
}
|
|
16220
16131
|
_onDocClick(e) {
|
|
16221
16132
|
if (!this._open) return;
|
|
16222
|
-
if (this._dropdown
|
|
16133
|
+
if (this._dropdown?.contains(e.target)) return;
|
|
16223
16134
|
this._hideDropdown();
|
|
16224
16135
|
}
|
|
16225
16136
|
_select(index) {
|
|
@@ -16228,7 +16139,7 @@ var Mention = class {
|
|
|
16228
16139
|
if (this._triggerNode) {
|
|
16229
16140
|
const node = this._triggerNode;
|
|
16230
16141
|
node.textContent = node.textContent.slice(0, this._triggerOffset) + node.textContent.slice(this._triggerOffset + this._cfg.trigger.length + this._query.length);
|
|
16231
|
-
const sel =
|
|
16142
|
+
const sel = globalThis.getSelection();
|
|
16232
16143
|
const range = document.createRange();
|
|
16233
16144
|
range.setStart(node, this._triggerOffset);
|
|
16234
16145
|
range.collapse(true);
|
|
@@ -16331,7 +16242,7 @@ var Context = class {
|
|
|
16331
16242
|
register("markdownShortcuts", MarkdownShortcuts);
|
|
16332
16243
|
register("bubbleToolbar", BubbleToolbar);
|
|
16333
16244
|
register("mention", Mention);
|
|
16334
|
-
for (const [name, ModuleClass] of _customModules) register(name, ModuleClass);
|
|
16245
|
+
if (_customModules.size > 0) for (const [name, ModuleClass] of _customModules) register(name, ModuleClass);
|
|
16335
16246
|
}
|
|
16336
16247
|
/**
|
|
16337
16248
|
* Registers and initialises a custom module on this instance.
|
|
@@ -16384,6 +16295,7 @@ var Context = class {
|
|
|
16384
16295
|
});
|
|
16385
16296
|
}
|
|
16386
16297
|
_applyGlobalPlugins() {
|
|
16298
|
+
if (_globalPlugins.size === 0) return;
|
|
16387
16299
|
for (const { plugin, options } of _globalPlugins.values()) this._installPlugin(plugin, options);
|
|
16388
16300
|
}
|
|
16389
16301
|
_bindEditorEvents(editable) {
|
|
@@ -16589,23 +16501,27 @@ var Context = class {
|
|
|
16589
16501
|
a.style.display = "none";
|
|
16590
16502
|
document.body.appendChild(a);
|
|
16591
16503
|
a.click();
|
|
16592
|
-
|
|
16504
|
+
a.remove();
|
|
16593
16505
|
URL.revokeObjectURL(url);
|
|
16594
16506
|
}
|
|
16595
16507
|
/**
|
|
16596
|
-
* Opens the editor content in a new
|
|
16508
|
+
* Opens the editor content in a new globalThis and triggers the browser print dialog.
|
|
16597
16509
|
* @param {string} [title='']
|
|
16598
16510
|
*/
|
|
16599
16511
|
print(title = "") {
|
|
16600
16512
|
const content = this.getHTML();
|
|
16601
|
-
const
|
|
16602
|
-
const
|
|
16603
|
-
|
|
16604
|
-
w
|
|
16605
|
-
w
|
|
16606
|
-
|
|
16513
|
+
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>`;
|
|
16514
|
+
const blob = new Blob([markup], { type: "text/html" });
|
|
16515
|
+
const url = URL.createObjectURL(blob);
|
|
16516
|
+
const w = globalThis.open(url, "_blank");
|
|
16517
|
+
if (!w) {
|
|
16518
|
+
URL.revokeObjectURL(url);
|
|
16519
|
+
return;
|
|
16520
|
+
}
|
|
16521
|
+
w.addEventListener("load", () => {
|
|
16607
16522
|
w.print();
|
|
16608
|
-
|
|
16523
|
+
URL.revokeObjectURL(url);
|
|
16524
|
+
});
|
|
16609
16525
|
}
|
|
16610
16526
|
/**
|
|
16611
16527
|
* Sets whether the editor is disabled (readonly).
|
|
@@ -16643,10 +16559,10 @@ var Context = class {
|
|
|
16643
16559
|
this._disposers.forEach((d) => d());
|
|
16644
16560
|
this._disposers = [];
|
|
16645
16561
|
const container = this.layoutInfo.container;
|
|
16646
|
-
const wasDark = container
|
|
16647
|
-
if (container
|
|
16562
|
+
const wasDark = container?.classList.contains("an-theme-dark");
|
|
16563
|
+
if (container?.parentNode) {
|
|
16648
16564
|
this.targetEl.style.display = "";
|
|
16649
|
-
container.
|
|
16565
|
+
container.remove();
|
|
16650
16566
|
}
|
|
16651
16567
|
if (wasDark && !document.querySelector(".an-container.an-theme-dark")) document.body.classList.remove("an-theme-dark");
|
|
16652
16568
|
if (typeof this.options.onDestroy === "function") this.options.onDestroy(this);
|
|
@@ -16712,7 +16628,7 @@ function tail(arr, n = 1) {
|
|
|
16712
16628
|
* @returns {T[]}
|
|
16713
16629
|
*/
|
|
16714
16630
|
function flatten(arr) {
|
|
16715
|
-
return arr.
|
|
16631
|
+
return arr.flat();
|
|
16716
16632
|
}
|
|
16717
16633
|
/**
|
|
16718
16634
|
* Returns unique elements of an array (using Set).
|
|
@@ -16791,7 +16707,7 @@ var env = {
|
|
|
16791
16707
|
/** True if running on mobile */
|
|
16792
16708
|
isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent),
|
|
16793
16709
|
/** True if touch is supported */
|
|
16794
|
-
isTouch: "ontouchstart" in
|
|
16710
|
+
isTouch: "ontouchstart" in globalThis || navigator.maxTouchPoints > 0,
|
|
16795
16711
|
/** Modifier key name depending on platform */
|
|
16796
16712
|
modifierKey: /Macintosh/.test(userAgent) ? "metaKey" : "ctrlKey"
|
|
16797
16713
|
};
|
|
@@ -16902,7 +16818,7 @@ var AutumnNote = {
|
|
|
16902
16818
|
return this;
|
|
16903
16819
|
},
|
|
16904
16820
|
/** Library version */
|
|
16905
|
-
version: "1.
|
|
16821
|
+
version: "1.6.2"
|
|
16906
16822
|
};
|
|
16907
16823
|
/**
|
|
16908
16824
|
* @param {string|Element|NodeList|Element[]} selector
|