autumnnote 1.5.0 → 1.6.0
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 +6 -4
- package/dist/autumnnote.css +324 -2
- package/dist/autumnnote.es.js +638 -227
- package/dist/autumnnote.es.js.map +1 -1
- package/dist/autumnnote.umd.js +637 -226
- package/dist/autumnnote.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/js/Context.js +8 -3
- package/src/js/core/detectLang.js +98 -0
- package/src/js/core/dom.js +62 -6
- package/src/js/core/markdown.js +14 -13
- package/src/js/core/range.js +2 -2
- package/src/js/editing/History.js +6 -6
- package/src/js/editing/Style.js +19 -19
- package/src/js/editing/Table.js +4 -6
- package/src/js/editing/Typing.js +6 -6
- package/src/js/i18n/en.js +2 -0
- package/src/js/i18n/vi.js +2 -0
- package/src/js/index.js +3 -2
- package/src/js/module/BubbleToolbar.js +30 -13
- package/src/js/module/Buttons.js +16 -14
- package/src/js/module/Clipboard.js +5 -5
- package/src/js/module/CodeTooltip.js +42 -16
- package/src/js/module/Codeview.js +2 -2
- package/src/js/module/ContextMenu.js +12 -12
- package/src/js/module/Editor.js +64 -12
- package/src/js/module/EmojiDialog.js +19 -13
- package/src/js/module/FindReplace.js +85 -59
- package/src/js/module/Fullscreen.js +1 -1
- package/src/js/module/IconDialog.js +26 -20
- package/src/js/module/ImageCropOverlay.js +6 -6
- package/src/js/module/ImageDialog.js +18 -12
- package/src/js/module/ImageResizer.js +1 -1
- package/src/js/module/ImageTooltip.js +8 -4
- package/src/js/module/LinkDialog.js +18 -12
- package/src/js/module/LinkTooltip.js +5 -2
- package/src/js/module/Mention.js +3 -3
- package/src/js/module/Statusbar.js +2 -2
- package/src/js/module/TableTooltip.js +180 -18
- package/src/js/module/Toolbar.js +16 -15
- package/src/js/module/VideoDialog.js +8 -2
- package/src/js/module/VideoResizer.js +3 -3
- package/src/js/module/VideoTooltip.js +11 -6
- package/src/js/renderer.js +4 -2
- package/src/js/settings.js +53 -36
- package/src/styles/autumnnote.scss +332 -4
package/dist/autumnnote.es.js
CHANGED
|
@@ -375,16 +375,60 @@ function trapFocus(container, onEscape) {
|
|
|
375
375
|
if (e.shiftKey) {
|
|
376
376
|
if (document.activeElement === first) {
|
|
377
377
|
e.preventDefault();
|
|
378
|
-
last.focus();
|
|
378
|
+
/** @type {HTMLElement} */ last.focus();
|
|
379
379
|
}
|
|
380
380
|
} else if (document.activeElement === last) {
|
|
381
381
|
e.preventDefault();
|
|
382
|
-
first.focus();
|
|
382
|
+
/** @type {HTMLElement} */ first.focus();
|
|
383
383
|
}
|
|
384
384
|
};
|
|
385
385
|
document.addEventListener("keydown", handler);
|
|
386
386
|
return () => document.removeEventListener("keydown", handler);
|
|
387
387
|
}
|
|
388
|
+
/**
|
|
389
|
+
* Makes a dialog box draggable by its handle element.
|
|
390
|
+
* On first drag the box is pinned to its current viewport coordinates via
|
|
391
|
+
* `position:fixed`, freeing it from the parent flex container's centering.
|
|
392
|
+
* The position is clamped to the visible viewport.
|
|
393
|
+
*
|
|
394
|
+
* @param {HTMLElement} handle Element the user grabs (title bar / header)
|
|
395
|
+
* @param {HTMLElement} box Element that actually moves
|
|
396
|
+
* @returns {Function} Cleanup function (removes the mousedown listener)
|
|
397
|
+
*/
|
|
398
|
+
function makeDraggable(handle, box) {
|
|
399
|
+
handle.style.cursor = "grab";
|
|
400
|
+
const onMousedown = (e) => {
|
|
401
|
+
if (e.button !== 0) return;
|
|
402
|
+
if (e.target.closest("button, input, select, textarea, a")) return;
|
|
403
|
+
e.preventDefault();
|
|
404
|
+
if (!box.dataset.anDragPinned) {
|
|
405
|
+
const r = box.getBoundingClientRect();
|
|
406
|
+
box.style.position = "fixed";
|
|
407
|
+
box.style.margin = "0";
|
|
408
|
+
box.style.left = `${r.left}px`;
|
|
409
|
+
box.style.top = `${r.top}px`;
|
|
410
|
+
box.dataset.anDragPinned = "1";
|
|
411
|
+
}
|
|
412
|
+
const startX = e.clientX - parseFloat(box.style.left);
|
|
413
|
+
const startY = e.clientY - parseFloat(box.style.top);
|
|
414
|
+
handle.style.cursor = "grabbing";
|
|
415
|
+
const onMove = (ev) => {
|
|
416
|
+
const bw = box.offsetWidth;
|
|
417
|
+
const bh = box.offsetHeight;
|
|
418
|
+
box.style.left = `${Math.max(0, Math.min(ev.clientX - startX, window.innerWidth - bw))}px`;
|
|
419
|
+
box.style.top = `${Math.max(0, Math.min(ev.clientY - startY, window.innerHeight - bh))}px`;
|
|
420
|
+
};
|
|
421
|
+
const onUp = () => {
|
|
422
|
+
handle.style.cursor = "grab";
|
|
423
|
+
document.removeEventListener("mousemove", onMove);
|
|
424
|
+
document.removeEventListener("mouseup", onUp);
|
|
425
|
+
};
|
|
426
|
+
document.addEventListener("mousemove", onMove);
|
|
427
|
+
document.addEventListener("mouseup", onUp);
|
|
428
|
+
};
|
|
429
|
+
handle.addEventListener("mousedown", onMousedown);
|
|
430
|
+
return () => handle.removeEventListener("mousedown", onMousedown);
|
|
431
|
+
}
|
|
388
432
|
//#endregion
|
|
389
433
|
//#region src/js/core/range.js
|
|
390
434
|
/**
|
|
@@ -566,7 +610,7 @@ function underline() {
|
|
|
566
610
|
if (!sel || !sel.rangeCount) return;
|
|
567
611
|
let container = sel.getRangeAt(0).commonAncestorContainer;
|
|
568
612
|
if (container.nodeType === 3) container = container.parentElement;
|
|
569
|
-
const uEl = container && container.closest
|
|
613
|
+
const uEl = container && container.closest("u");
|
|
570
614
|
const nativeState = document.queryCommandState("underline");
|
|
571
615
|
if (uEl && !nativeState) {
|
|
572
616
|
const parent = uEl.parentNode;
|
|
@@ -586,7 +630,7 @@ function strikethrough() {
|
|
|
586
630
|
if (!sel || !sel.rangeCount) return;
|
|
587
631
|
let sc = sel.getRangeAt(0).startContainer;
|
|
588
632
|
if (sc.nodeType === 3) sc = sc.parentElement;
|
|
589
|
-
const sEl = sc &&
|
|
633
|
+
const sEl = sc && (sc.closest("s") || sc.closest("strike"));
|
|
590
634
|
const nativeState = document.queryCommandState("strikeThrough");
|
|
591
635
|
if (sEl && !nativeState) {
|
|
592
636
|
const parent = sEl.parentNode;
|
|
@@ -623,7 +667,7 @@ var fontName = (name) => execCommand("fontName", name);
|
|
|
623
667
|
* Sets the font size (in pt or with unit) for the selection.
|
|
624
668
|
* Uses a span-based approach to set px sizes precisely.
|
|
625
669
|
* @param {string} size - e.g. '14px'
|
|
626
|
-
* @param {HTMLElement} [editable] - scoping element to avoid touching nodes outside this editor
|
|
670
|
+
* @param {HTMLElement|Document} [editable] - scoping element to avoid touching nodes outside this editor
|
|
627
671
|
*/
|
|
628
672
|
function fontSize(size, editable = document) {
|
|
629
673
|
const sel = window.getSelection();
|
|
@@ -705,7 +749,7 @@ function outdent() {
|
|
|
705
749
|
if (sel && sel.rangeCount) {
|
|
706
750
|
let container = sel.getRangeAt(0).commonAncestorContainer;
|
|
707
751
|
if (container.nodeType === 3) container = container.parentElement;
|
|
708
|
-
const checkLi = container && container.closest
|
|
752
|
+
const checkLi = container && container.closest(".an-checklist li");
|
|
709
753
|
if (checkLi) {
|
|
710
754
|
_checklistItemToP(checkLi);
|
|
711
755
|
return;
|
|
@@ -827,15 +871,15 @@ function lineHeight(value) {
|
|
|
827
871
|
/**
|
|
828
872
|
* Wraps the selection in an inline <code> element, or unwraps it if the
|
|
829
873
|
* cursor is already inside a <code> that is not inside a <pre>.
|
|
830
|
-
* @param {HTMLElement} [
|
|
874
|
+
* @param {HTMLElement} [_editable]
|
|
831
875
|
*/
|
|
832
|
-
function toggleInlineCode(
|
|
876
|
+
function toggleInlineCode(_editable) {
|
|
833
877
|
const sel = window.getSelection();
|
|
834
878
|
if (!sel || !sel.rangeCount) return;
|
|
835
879
|
const range = sel.getRangeAt(0);
|
|
836
880
|
let container = range.commonAncestorContainer;
|
|
837
881
|
if (container.nodeType === 3) container = container.parentElement;
|
|
838
|
-
const codeEl = container && container.closest
|
|
882
|
+
const codeEl = container && container.closest("code");
|
|
839
883
|
if (codeEl && !codeEl.closest("pre")) {
|
|
840
884
|
const parent = codeEl.parentNode;
|
|
841
885
|
const prevSibling = codeEl.previousSibling;
|
|
@@ -890,7 +934,7 @@ function isInlineCode() {
|
|
|
890
934
|
if (!sel || !sel.rangeCount) return false;
|
|
891
935
|
let sc = sel.getRangeAt(0).startContainer;
|
|
892
936
|
if (sc.nodeType === 3) sc = sc.parentElement;
|
|
893
|
-
const code = sc && sc.closest
|
|
937
|
+
const code = sc && sc.closest("code");
|
|
894
938
|
return !!(code && !code.closest("pre"));
|
|
895
939
|
}
|
|
896
940
|
/**
|
|
@@ -913,11 +957,11 @@ function toggleChecklist() {
|
|
|
913
957
|
const range = sel.getRangeAt(0);
|
|
914
958
|
let container = range.commonAncestorContainer;
|
|
915
959
|
if (container.nodeType === 3) container = container.parentElement;
|
|
916
|
-
const ul = container
|
|
960
|
+
const ul = container && container.closest(".an-checklist");
|
|
917
961
|
if (ul) {
|
|
918
962
|
const selectedLis = Array.from(ul.querySelectorAll("li")).filter((li) => sel.containsNode(li, true));
|
|
919
963
|
if (selectedLis.length > 0) {
|
|
920
|
-
let firstP = null;
|
|
964
|
+
/** @type {HTMLElement|null} */ let firstP = null;
|
|
921
965
|
selectedLis.forEach((li) => {
|
|
922
966
|
const p = document.createElement("p");
|
|
923
967
|
for (const child of li.childNodes) {
|
|
@@ -1015,7 +1059,7 @@ function toggleChecklist() {
|
|
|
1015
1059
|
if (blocks.length === 0) return;
|
|
1016
1060
|
const newUl = document.createElement("ul");
|
|
1017
1061
|
newUl.className = "an-checklist";
|
|
1018
|
-
let lastTextNode = null;
|
|
1062
|
+
/** @type {Text|null} */ let lastTextNode = null;
|
|
1019
1063
|
blocks.forEach((block) => {
|
|
1020
1064
|
const li = document.createElement("li");
|
|
1021
1065
|
const cb = document.createElement("input");
|
|
@@ -1048,7 +1092,7 @@ function isInChecklist() {
|
|
|
1048
1092
|
if (!sel || !sel.rangeCount) return false;
|
|
1049
1093
|
let container = sel.getRangeAt(0).commonAncestorContainer;
|
|
1050
1094
|
if (container.nodeType === 3) container = container.parentElement;
|
|
1051
|
-
return !!(container && container.closest
|
|
1095
|
+
return !!(container && container.closest(".an-checklist li"));
|
|
1052
1096
|
}
|
|
1053
1097
|
//#endregion
|
|
1054
1098
|
//#region src/js/module/Buttons.js
|
|
@@ -1059,12 +1103,14 @@ function isInChecklist() {
|
|
|
1059
1103
|
*/
|
|
1060
1104
|
/**
|
|
1061
1105
|
* @typedef {object} DropdownDef
|
|
1062
|
-
* @property {string} name
|
|
1063
|
-
* @property {'select'} type
|
|
1106
|
+
* @property {string} name - unique identifier
|
|
1107
|
+
* @property {'select'} type - discriminator for Toolbar renderer
|
|
1064
1108
|
* @property {string} tooltip
|
|
1065
|
-
* @property {string
|
|
1066
|
-
* @property {Function} action
|
|
1067
|
-
* @property {Function} [getValue]
|
|
1109
|
+
* @property {Array<string|{value:string,label:string,disabled?:boolean}>} [items] - overridden at render time from options
|
|
1110
|
+
* @property {Function} action - called with (context, value)
|
|
1111
|
+
* @property {Function} [getValue] - called with (context) to get current value
|
|
1112
|
+
* @property {string} [selectClass] - extra CSS class(es) for the <select>
|
|
1113
|
+
* @property {string} [placeholder] - placeholder text for the empty option
|
|
1068
1114
|
*/
|
|
1069
1115
|
/**
|
|
1070
1116
|
* @typedef {object} ButtonDef
|
|
@@ -1132,7 +1178,7 @@ var underlineBtn = btn("underline", "underline", "Underline (Ctrl+U)", () => und
|
|
|
1132
1178
|
if (!sel || !sel.rangeCount) return false;
|
|
1133
1179
|
let sc = sel.getRangeAt(0).startContainer;
|
|
1134
1180
|
if (sc.nodeType === 3) sc = sc.parentElement;
|
|
1135
|
-
return !!(sc && sc.closest
|
|
1181
|
+
return !!(sc && sc.closest("u"));
|
|
1136
1182
|
});
|
|
1137
1183
|
var strikeBtn = btn("strikethrough", "strikethrough", "Strikethrough", () => strikethrough(), () => document.queryCommandState("strikeThrough"));
|
|
1138
1184
|
var superscriptBtn = btn("superscript", "superscript", "Superscript", () => superscript(), () => document.queryCommandState("superscript"));
|
|
@@ -1194,9 +1240,9 @@ var fontSizeBtn = {
|
|
|
1194
1240
|
const sel = window.getSelection();
|
|
1195
1241
|
if (sel && sel.rangeCount) {
|
|
1196
1242
|
let el = sel.getRangeAt(0).startContainer;
|
|
1197
|
-
if (el.nodeType === 3) el = el.parentElement;
|
|
1243
|
+
if (el && el.nodeType === 3) el = el.parentElement;
|
|
1198
1244
|
while (el && el.nodeType === 1 && !el.style.fontSize) el = el.parentElement;
|
|
1199
|
-
const size = el && el.style
|
|
1245
|
+
const size = el && el.style.fontSize ? el.style.fontSize : "";
|
|
1200
1246
|
if (size) return size;
|
|
1201
1247
|
}
|
|
1202
1248
|
const editable = ctx && ctx.layoutInfo && ctx.layoutInfo.editable;
|
|
@@ -1321,8 +1367,11 @@ var lineHeightBtn = {
|
|
|
1321
1367
|
"TH"
|
|
1322
1368
|
]);
|
|
1323
1369
|
let el = sel.getRangeAt(0).startContainer;
|
|
1324
|
-
if (el.nodeType === 3) el = el.parentElement;
|
|
1325
|
-
while (el && !BLOCKS.has(
|
|
1370
|
+
if (el && el.nodeType === 3) el = el.parentElement;
|
|
1371
|
+
while (el && !BLOCKS.has(
|
|
1372
|
+
/** @type {Element} */
|
|
1373
|
+
el.tagName
|
|
1374
|
+
)) el = el.parentElement;
|
|
1326
1375
|
if (!el) return "";
|
|
1327
1376
|
return el.style.lineHeight || getComputedStyle(el).lineHeight || "";
|
|
1328
1377
|
} catch {
|
|
@@ -1416,47 +1465,64 @@ var defaultToolbar = [
|
|
|
1416
1465
|
*/
|
|
1417
1466
|
/**
|
|
1418
1467
|
* @typedef {object} AsnOptions
|
|
1419
|
-
* @property {string} [placeholder]
|
|
1420
|
-
* @property {number} [height]
|
|
1421
|
-
* @property {number} [minHeight]
|
|
1422
|
-
* @property {number} [maxHeight]
|
|
1423
|
-
* @property {boolean} [focus]
|
|
1424
|
-
* @property {boolean} [resizable]
|
|
1425
|
-
* @property {Array} [toolbar]
|
|
1426
|
-
* @property {boolean} [
|
|
1427
|
-
* @property {
|
|
1468
|
+
* @property {string} [placeholder] - Placeholder text when editor is empty
|
|
1469
|
+
* @property {number} [height] - Editor height in px (min)
|
|
1470
|
+
* @property {number} [minHeight] - Minimum height in px
|
|
1471
|
+
* @property {number} [maxHeight] - Maximum height in px (0 = unlimited)
|
|
1472
|
+
* @property {boolean} [focus] - Auto-focus on init
|
|
1473
|
+
* @property {boolean} [resizable] - Show resize handle
|
|
1474
|
+
* @property {Array} [toolbar] - Toolbar button group config
|
|
1475
|
+
* @property {boolean} [useBootstrap] - Use Bootstrap button classes on toolbar buttons
|
|
1476
|
+
* @property {string} [toolbarButtonClass] - CSS classes for Bootstrap toolbar buttons
|
|
1477
|
+
* @property {boolean} [useFontAwesome] - Use Font Awesome icons (default: true)
|
|
1478
|
+
* @property {string} [fontAwesomeClass] - Font Awesome prefix class, e.g. 'fas' or 'fa-solid'
|
|
1479
|
+
* @property {boolean} [pasteAsPlainText] - Force plain-text paste
|
|
1480
|
+
* @property {boolean} [pasteCleanHTML] - Sanitise HTML on paste
|
|
1428
1481
|
* @property {boolean} [pasteStripAttributes] - Strip class/style/data-* from pasted HTML (default: false)
|
|
1429
|
-
* @property {boolean} [allowImageUpload]
|
|
1430
|
-
* @property {number} [maxImageSize]
|
|
1431
|
-
* @property {number} [tabSize]
|
|
1432
|
-
* @property {
|
|
1433
|
-
* @property {
|
|
1434
|
-
* @property {
|
|
1435
|
-
* @property {
|
|
1436
|
-
* @property {
|
|
1437
|
-
* @property {
|
|
1438
|
-
* @property {
|
|
1439
|
-
* @property {
|
|
1440
|
-
* @property {
|
|
1441
|
-
* @property {
|
|
1442
|
-
* @property {boolean} [
|
|
1443
|
-
* @property {
|
|
1444
|
-
* @property {string} [
|
|
1445
|
-
* @property {
|
|
1446
|
-
* @property {
|
|
1447
|
-
* @property {
|
|
1448
|
-
* @property {
|
|
1449
|
-
* @property {
|
|
1450
|
-
* @property {
|
|
1451
|
-
* @property {
|
|
1452
|
-
* @property {
|
|
1453
|
-
* @property {string
|
|
1482
|
+
* @property {boolean} [allowImageUpload] - Allow file upload in image dialog
|
|
1483
|
+
* @property {number} [maxImageSize] - Max upload size in MB
|
|
1484
|
+
* @property {number} [tabSize] - Spaces per tab in non-list context
|
|
1485
|
+
* @property {number} [historyLimit] - Maximum undo/redo history steps
|
|
1486
|
+
* @property {string} [defaultFontFamily] - Default font family applied to the editable area on init
|
|
1487
|
+
* @property {string} [defaultFontSize] - Default font size applied to the editable area on init (e.g. '14px')
|
|
1488
|
+
* @property {string[]} [fontFamilies] - Font families shown in the font-family toolbar dropdown
|
|
1489
|
+
* @property {Function} [onChange] - Callback on content change
|
|
1490
|
+
* @property {Function} [onFocus] - Callback on focus
|
|
1491
|
+
* @property {Function} [onBlur] - Callback on blur
|
|
1492
|
+
* @property {Function} [onInit] - Callback after the editor has initialised
|
|
1493
|
+
* @property {Function} [onImageUpload] - Custom upload handler: (files) => void
|
|
1494
|
+
* @property {Function} [onImageError] - Callback when an image upload error occurs
|
|
1495
|
+
* @property {boolean} [stickyToolbar] - Stick the toolbar to the viewport top when scrolling
|
|
1496
|
+
* @property {number} [stickyToolbarOffset] - Top offset in px for sticky toolbar (e.g. fixed nav height)
|
|
1497
|
+
* @property {string} [theme] - 'light' (default) | 'dark'
|
|
1498
|
+
* @property {boolean} [codeHighlight] - Auto-load Prism.js for syntax highlighting of code blocks
|
|
1499
|
+
* @property {string} [codeHighlightCDN] - CDN base URL for Prism assets (defaults to cdnjs)
|
|
1500
|
+
* @property {boolean} [markdownPaste] - Convert pasted Markdown text to HTML (default: true)
|
|
1501
|
+
* @property {boolean} [readOnly] - Start editor in read-only / non-editable mode
|
|
1502
|
+
* @property {boolean} [spellcheck] - Enable browser spellcheck in the editable area (default: true)
|
|
1503
|
+
* @property {string} [direction] - Text direction: 'ltr' (default) | 'rtl'
|
|
1504
|
+
* @property {string} [toolbarOverflow] - Toolbar overflow strategy: 'wrap' (default) | 'scroll'
|
|
1505
|
+
* @property {boolean} [autoSave] - Auto-save content to localStorage on change
|
|
1506
|
+
* @property {string} [autoSaveKey] - localStorage key used for auto-save (default: 'autumnnote-autosave')
|
|
1507
|
+
* @property {number} [maxChars] - Maximum character count (0 = unlimited). Shows warning in statusbar.
|
|
1508
|
+
* @property {number} [maxWords] - Maximum word count (0 = unlimited). Shows warning in statusbar.
|
|
1509
|
+
* @property {boolean} [tableHeaderRow] - Insert a header row (<thead><th>) when creating tables
|
|
1510
|
+
* @property {Function} [onPaste] - Callback fired on every paste: ({ text, html }) => void
|
|
1511
|
+
* @property {Function} [onSelectionChange] - Callback fired on cursor/selection change: (context) => void
|
|
1512
|
+
* @property {string[]} [colorSwatches] - Custom brand colour swatches prepended to the colour-picker palette
|
|
1454
1513
|
* @property {Function} [onDestroy] - Callback fired when the editor is destroyed: (context) => void
|
|
1455
1514
|
* @property {Function} [onCharLimitReached] - Callback fired when the character limit is hit: (context) => void
|
|
1456
1515
|
* @property {Function} [onWordLimitReached] - Callback fired when the word limit is hit: (context) => void
|
|
1457
|
-
* @property {string} [focusColor]
|
|
1516
|
+
* @property {string} [focusColor] - Custom focus ring colour, e.g. '#f97316'. Overrides the default blue.
|
|
1517
|
+
* @property {boolean} [autoSaveRestore] - Show a restore banner when a previously auto-saved draft exists
|
|
1518
|
+
* @property {number} [autoSaveRestoreTimeout] - Maximum age in days for a draft to be offered for restore (0 = no expiry)
|
|
1519
|
+
* @property {Function} [onAutoSaveRestore] - Callback fired after the user chooses to restore a draft
|
|
1520
|
+
* @property {boolean} [markdownShortcuts] - Convert markdown syntax typed inline to HTML
|
|
1521
|
+
* @property {boolean} [bubbleToolbar] - Show a mini floating toolbar above text selections
|
|
1522
|
+
* @property {string[]} [bubbleToolbarItems] - Button names for the bubble toolbar
|
|
1523
|
+
* @property {object|null} [mention] - @mention configuration (onSearch, minChars, ...)
|
|
1524
|
+
* @property {string} [lang] - Display language or partial locale object override
|
|
1458
1525
|
*/
|
|
1459
|
-
/** @type {AsnOptions} */
|
|
1460
1526
|
var defaultOptions = {
|
|
1461
1527
|
placeholder: "",
|
|
1462
1528
|
height: 200,
|
|
@@ -1855,6 +1921,8 @@ var en = {
|
|
|
1855
1921
|
rowHeight: "Row Height",
|
|
1856
1922
|
tableBorderWidth: "Table Border Width",
|
|
1857
1923
|
deleteTable: "Delete Table",
|
|
1924
|
+
cellBackground: "Cell Background",
|
|
1925
|
+
noShading: "No Shading",
|
|
1858
1926
|
columnWidthPx: "Column Width (px)",
|
|
1859
1927
|
rowHeightPx: "Row Height (px)",
|
|
1860
1928
|
tableBorderWidthPx: "Table Border Width (px)",
|
|
@@ -2210,6 +2278,8 @@ var locales = {
|
|
|
2210
2278
|
rowHeight: "Chiều cao hàng",
|
|
2211
2279
|
tableBorderWidth: "Độ rộng viền bảng",
|
|
2212
2280
|
deleteTable: "Xóa bảng",
|
|
2281
|
+
cellBackground: "Màu Nền Ô",
|
|
2282
|
+
noShading: "Xóa Màu Nền",
|
|
2213
2283
|
columnWidthPx: "Chiều rộng cột (px)",
|
|
2214
2284
|
rowHeightPx: "Chiều cao hàng (px)",
|
|
2215
2285
|
tableBorderWidthPx: "Độ rộng viền bảng (px)",
|
|
@@ -4411,7 +4481,10 @@ function renderLayout(targetEl, options) {
|
|
|
4411
4481
|
else if (options.minHeight) editable.style.minHeight = `${options.minHeight}px`;
|
|
4412
4482
|
if (options.maxHeight) editable.style.maxHeight = `${options.maxHeight}px`;
|
|
4413
4483
|
container.appendChild(editable);
|
|
4414
|
-
if (options.theme === "dark")
|
|
4484
|
+
if (options.theme === "dark") {
|
|
4485
|
+
container.classList.add("an-theme-dark");
|
|
4486
|
+
document.body.classList.add("an-theme-dark");
|
|
4487
|
+
}
|
|
4415
4488
|
if (options.readOnly) {
|
|
4416
4489
|
container.classList.add("an-disabled");
|
|
4417
4490
|
editable.querySelectorAll("ul.an-checklist input[type=\"checkbox\"]").forEach((cb) => {
|
|
@@ -4449,7 +4522,7 @@ var History = class {
|
|
|
4449
4522
|
constructor(editable, limit = 100) {
|
|
4450
4523
|
this.editable = editable;
|
|
4451
4524
|
this._limit = limit;
|
|
4452
|
-
/** @type {Array<{html: string,
|
|
4525
|
+
/** @type {Array<{html: string, images?: Record<string,string>, sel: {start: number, end: number}|null}>} */
|
|
4453
4526
|
this.stack = [];
|
|
4454
4527
|
this.stackOffset = -1;
|
|
4455
4528
|
this._savePoint();
|
|
@@ -4648,8 +4721,7 @@ var History = class {
|
|
|
4648
4721
|
* Build an HTML table with the given number of columns and rows, optionally including a header row.
|
|
4649
4722
|
* @param {number} cols - Number of columns in each row.
|
|
4650
4723
|
* @param {number} rows - Total number of rows to create (including header when `headerRow` is true).
|
|
4651
|
-
* @param {{ headerRow?: boolean }} [opts] - Options
|
|
4652
|
-
* @param {boolean} [opts.headerRow=false] - When true and `rows > 0`, creates a header row (`<thead>`) plus body rows for the remainder.
|
|
4724
|
+
* @param {{ headerRow?: boolean }} [opts] - Options: `headerRow` creates a `<thead>` when true.
|
|
4653
4725
|
* @returns {HTMLTableElement} The constructed `<table>` element with a `<tbody>` and optional `<thead>`; each cell contains a `<br>` placeholder.
|
|
4654
4726
|
*/
|
|
4655
4727
|
function createTable(cols, rows, opts = {}) {
|
|
@@ -4683,7 +4755,6 @@ function createTable(cols, rows, opts = {}) {
|
|
|
4683
4755
|
* @param {number} cols - Number of columns for the new table.
|
|
4684
4756
|
* @param {number} rows - Number of rows for the new table.
|
|
4685
4757
|
* @param {{ headerRow?: boolean }} [opts] - Options for table creation.
|
|
4686
|
-
* @param {boolean} [opts.headerRow=false] - If true, include a header row as the first row.
|
|
4687
4758
|
*/
|
|
4688
4759
|
function insertTable(cols, rows, opts = {}) {
|
|
4689
4760
|
if (cols <= 0 || rows <= 0) return;
|
|
@@ -4706,7 +4777,7 @@ function insertTable(cols, rows, opts = {}) {
|
|
|
4706
4777
|
"PRE"
|
|
4707
4778
|
]);
|
|
4708
4779
|
let anchor = range.startContainer;
|
|
4709
|
-
if (anchor.nodeType === 3) anchor = anchor.parentElement;
|
|
4780
|
+
if (anchor && anchor.nodeType === 3) anchor = anchor.parentElement;
|
|
4710
4781
|
while (anchor && !BLOCK.has(anchor.tagName?.toUpperCase()) && anchor.parentElement) anchor = anchor.parentElement;
|
|
4711
4782
|
if (anchor && BLOCK.has(anchor.tagName?.toUpperCase()) && anchor.parentNode) {
|
|
4712
4783
|
anchor.after(table);
|
|
@@ -4824,7 +4895,7 @@ function handleKeydown(event, editable, options = {}) {
|
|
|
4824
4895
|
const textNode = r.startContainer;
|
|
4825
4896
|
if (r.startOffset === 0 && isFAIcon(textNode.previousSibling)) {
|
|
4826
4897
|
event.preventDefault();
|
|
4827
|
-
textNode.previousSibling.remove();
|
|
4898
|
+
/** @type {ChildNode} */ textNode.previousSibling.remove();
|
|
4828
4899
|
return true;
|
|
4829
4900
|
}
|
|
4830
4901
|
if (r.startOffset === 1 && textNode.textContent === "" && isFAIcon(textNode.previousSibling)) {
|
|
@@ -4970,7 +5041,7 @@ function handleKeydown(event, editable, options = {}) {
|
|
|
4970
5041
|
}
|
|
4971
5042
|
return false;
|
|
4972
5043
|
}
|
|
4973
|
-
const videoWrapper = el && el.closest
|
|
5044
|
+
const videoWrapper = el && el.closest(".an-video-wrapper");
|
|
4974
5045
|
if (videoWrapper) {
|
|
4975
5046
|
event.preventDefault();
|
|
4976
5047
|
const p = document.createElement("p");
|
|
@@ -4984,7 +5055,7 @@ function handleKeydown(event, editable, options = {}) {
|
|
|
4984
5055
|
sel.addRange(nr);
|
|
4985
5056
|
return true;
|
|
4986
5057
|
}
|
|
4987
|
-
const checkLi = el && el.closest
|
|
5058
|
+
const checkLi = el && el.closest(".an-checklist li");
|
|
4988
5059
|
if (checkLi) {
|
|
4989
5060
|
event.preventDefault();
|
|
4990
5061
|
const ul = checkLi.closest(".an-checklist");
|
|
@@ -5084,8 +5155,9 @@ function htmlToMarkdown(html) {
|
|
|
5084
5155
|
function _domToMd(node, depth = 0) {
|
|
5085
5156
|
if (node.nodeType === 3) return node.textContent.replace(/\s+/g, " ");
|
|
5086
5157
|
if (node.nodeType !== 1) return "";
|
|
5087
|
-
const
|
|
5088
|
-
const
|
|
5158
|
+
const el = node;
|
|
5159
|
+
const tag = el.nodeName.toLowerCase();
|
|
5160
|
+
const inner = () => Array.from(el.childNodes).map((n) => _domToMd(n, depth)).join("");
|
|
5089
5161
|
switch (tag) {
|
|
5090
5162
|
case "p":
|
|
5091
5163
|
case "div": return `\n\n${inner()}\n\n`;
|
|
@@ -5103,34 +5175,34 @@ function _domToMd(node, depth = 0) {
|
|
|
5103
5175
|
case "del":
|
|
5104
5176
|
case "s":
|
|
5105
5177
|
case "strike": return `~~${inner()}~~`;
|
|
5106
|
-
case "sup": return `^${inner()}
|
|
5107
|
-
case "sub": return `~${inner()}
|
|
5178
|
+
case "sup": return `^${inner()}^`;
|
|
5179
|
+
case "sub": return `~${inner()}~`;
|
|
5108
5180
|
case "code":
|
|
5109
|
-
if (
|
|
5181
|
+
if (el.closest("pre")) return inner();
|
|
5110
5182
|
return `\`${inner()}\``;
|
|
5111
5183
|
case "pre": {
|
|
5112
|
-
const codeEl =
|
|
5184
|
+
const codeEl = el.querySelector("code");
|
|
5113
5185
|
const langMatch = (codeEl && codeEl.className || "").match(/language-(\S+)/);
|
|
5114
|
-
return `\n\n\`\`\`${langMatch ? langMatch[1] : ""}\n${(codeEl ||
|
|
5186
|
+
return `\n\n\`\`\`${langMatch ? langMatch[1] : ""}\n${(codeEl || el).textContent || ""}\n\`\`\`\n\n`;
|
|
5115
5187
|
}
|
|
5116
5188
|
case "blockquote": return `\n\n${inner().trim().split("\n").map((l) => `> ${l}`).join("\n")}\n\n`;
|
|
5117
5189
|
case "a": {
|
|
5118
|
-
const href =
|
|
5190
|
+
const href = el.getAttribute("href") || "";
|
|
5119
5191
|
return `[${inner()}](${href})`;
|
|
5120
5192
|
}
|
|
5121
5193
|
case "img": {
|
|
5122
|
-
const src =
|
|
5123
|
-
return ``;
|
|
5124
5196
|
}
|
|
5125
5197
|
case "ul": {
|
|
5126
|
-
const items = Array.from(
|
|
5198
|
+
const items = Array.from(el.querySelectorAll(":scope > li"));
|
|
5127
5199
|
if (!items.length) return inner();
|
|
5128
5200
|
const indent = " ".repeat(depth);
|
|
5129
5201
|
const lines = items.map((li) => `${indent}- ${_domToMd(li, depth + 1).trim()}`).join("\n");
|
|
5130
5202
|
return depth === 0 ? `\n\n${lines}\n\n` : `\n${lines}`;
|
|
5131
5203
|
}
|
|
5132
5204
|
case "ol": {
|
|
5133
|
-
const items = Array.from(
|
|
5205
|
+
const items = Array.from(el.querySelectorAll(":scope > li"));
|
|
5134
5206
|
if (!items.length) return inner();
|
|
5135
5207
|
const indent = " ".repeat(depth);
|
|
5136
5208
|
const lines = items.map((li, i) => `${indent}${i + 1}. ${_domToMd(li, depth + 1).trim()}`).join("\n");
|
|
@@ -5139,7 +5211,7 @@ function _domToMd(node, depth = 0) {
|
|
|
5139
5211
|
case "li": return inner();
|
|
5140
5212
|
case "hr": return "\n\n---\n\n";
|
|
5141
5213
|
case "table": {
|
|
5142
|
-
const rows = Array.from(
|
|
5214
|
+
const rows = Array.from(el.querySelectorAll("tr"));
|
|
5143
5215
|
if (!rows.length) return inner();
|
|
5144
5216
|
const cellTexts = rows.map((tr) => Array.from(tr.querySelectorAll("th, td")).map((c) => c.textContent.trim().replace(/\|/g, "\\|")));
|
|
5145
5217
|
const cols = Math.max(...cellTexts.map((r) => r.length));
|
|
@@ -5287,6 +5359,47 @@ function _escAttr(v) {
|
|
|
5287
5359
|
return String(v).replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
5288
5360
|
}
|
|
5289
5361
|
//#endregion
|
|
5362
|
+
//#region src/js/core/detectLang.js
|
|
5363
|
+
/**
|
|
5364
|
+
* detectLang.js — Heuristic programming-language detection for code snippets.
|
|
5365
|
+
*
|
|
5366
|
+
* Returns a Prism.js language identifier or null when no language can be
|
|
5367
|
+
* determined with reasonable confidence.
|
|
5368
|
+
*
|
|
5369
|
+
* Detection order (conflicts in parentheses):
|
|
5370
|
+
* TypeScript → Rust → PHP → Java → Kotlin → Swift → Go
|
|
5371
|
+
* → JavaScript → HTML → CSS → JSON → SQL → Python → Ruby
|
|
5372
|
+
* → Bash → C++ → C# → C → XML
|
|
5373
|
+
*
|
|
5374
|
+
* @param {string} code
|
|
5375
|
+
* @returns {string|null}
|
|
5376
|
+
*/
|
|
5377
|
+
function detectLang(code) {
|
|
5378
|
+
if (!code || !code.trim()) return null;
|
|
5379
|
+
const s = code.trim();
|
|
5380
|
+
if (/(:\s*(string|number|boolean|void|never|any|unknown)\b|interface\s+\w+\s*\{|type\s+\w+\s*[=<(]|<\w+>\s*[;,)]|readonly\s+\w|enum\s+\w+\s*\{|\?\s*:\s*\w|as\s+\w+\s*[;,)\]])/.test(s)) return "typescript";
|
|
5381
|
+
if (/\bprintln!\s*\(|\bprint!\s*\(|\bfn\s+\w+\s*(<[^>]*>)?\s*\(|\blet\s+mut\s|\bpub\s+fn\s|\buse\s+std::|\bimpl\s+\w+|\bOption<|\bResult<\w+/.test(s)) return "rust";
|
|
5382
|
+
if (/(<\?php\b|<\?=|\becho\s+.*\$\w|\$this->|\$\w+\s*=\s*\w|\bforeach\s*\(\s*\$|Illuminate\\)/.test(s)) return "php";
|
|
5383
|
+
if (/\bpublic\s+(class|static|void|int|String)\s+\w|System\.out\.(print|println)\s*\(|@(Override|Autowired|Component|Service|Controller)\b|import\s+java\.(util|io|lang|net)\.|throws\s+\w+Exception/.test(s)) return "java";
|
|
5384
|
+
if (/\bfun\s+\w+\s*\(|\bdata\s+class\s+\w+|\bcompanion\s+object\b|\bval\s+\w+\s*:\s*\w|\bprintln\s*\(/.test(s)) return "kotlin";
|
|
5385
|
+
if (/\bguard\s+(let|var)\b|\bprotocol\s+\w+\s*\{|\bextension\s+\w+|\bfunc\s+\w+[^(]*\([^)]*\)\s*->\s*\w|\blet\s+\w+\s*:\s*[A-Z]\w*|\bSwiftUI\b/.test(s)) return "swift";
|
|
5386
|
+
if (/\bpackage\s+\w+\b|\bfmt\.(Print|Println|Sprintf|Errorf|Fprintf)\s*\(|:=\s*\w|\bgoroutine\b|\bchan\s+\w|\bgo\s+func\b/.test(s)) return "go";
|
|
5387
|
+
if (/\b(const\s+\w|let\s+\w+\s*=|var\s+\w+\s*=|function\s+\w|\=>\s*[{(]|import\s+.*\bfrom\b\s*['"]|require\s*\(|console\.(log|error|warn|info)|document\.\w|window\.\w|async\s+function|\bPromise\b|React\.|useState\s*\(|\.then\s*\()/.test(s)) return "javascript";
|
|
5388
|
+
if (/^<!DOCTYPE html/i.test(s) || /<(html|head|body|div|section|article|nav|p|a|img|ul|ol|li|table|form|input|button|script|style)\b[^>]*>/i.test(s)) return "html";
|
|
5389
|
+
if (/(^|\n)\s*(\/\/\s+\S|&[:.[\w]|\$\w+\s*:|@(mixin|include|extend|each|if|for|use|forward)\b|#\{)/.test(s) && /[\w#.*&[\]:(),>+~ -]+\s*\{/.test(s)) return "scss";
|
|
5390
|
+
if (/(^|\n)\s*[\w#.*:[\]&, +-]+\s*\{[^}]*[\w-]+\s*:[^{}:;]+[;}\n]/m.test(s) && !/<\w|function\s|def\s|:\s*(string|number)/.test(s)) return "css";
|
|
5391
|
+
if (/^\s*[{[]/.test(s) && /"\w[\w\s-]*"\s*:/.test(s) && !/\bfunction\b|\bdef\b/.test(s)) return "json";
|
|
5392
|
+
if (/(^|\n)\s*(SELECT\s|INSERT\s+INTO|UPDATE\s+\w|DELETE\s+FROM|CREATE\s+(TABLE|DATABASE|INDEX|VIEW)|DROP\s+(TABLE|DATABASE)|ALTER\s+TABLE|WITH\s+\w+\s+AS\s*\()/im.test(s)) return "sql";
|
|
5393
|
+
if (/\bdef\s+\w+\s*\([^)]*\)\s*:|(^|\n)\s*class\s+\w+.*:\s*$|(^|\n)\s*import\s+\w|(^|\n)\s*from\s+\w+\s+import\s+|\bprint\s*\(|if\s+__name__\s*==\s*['"]__main__['"]/m.test(s)) return "python";
|
|
5394
|
+
if (/\bputs\s+\S|\battr_(accessor|reader|writer)\s|\.each\s+do\s*\|\w+\s*\||\bdo\s*\|\w+\s*\|.*\bend\b|\bdef\s+\w+[^:]*\n[\s\S]*?\bend\b/.test(s)) return "ruby";
|
|
5395
|
+
if (/^#!.*\/(ba|z|da|fi|k)?sh\b/m.test(s) || /\b(echo\s+["']|grep\s+|awk\s+|sed\s+['"\\/-]|chmod\s+|sudo\s+|apt(-get)?\s+install|brew\s+install|npm\s+(install|run|start|build)|pip\s+(install|3\s)|docker\s+(run|build|compose)|kubectl\s+|git\s+(clone|add|commit|push|pull|checkout))\b/.test(s)) return "bash";
|
|
5396
|
+
if (/\bcout\s*<<|\bcin\s*>>|using\s+namespace\s+std\b|std::\w|\btemplate\s*<\w|\b#include\s*<(iostream|vector|map|set|algorithm|string|memory)>/.test(s)) return "cpp";
|
|
5397
|
+
if (/\busing\s+System\b|Console\.(Write|WriteLine)\s*\(|\bget;\s*set;|\basync\s+Task[<\s]|IEnumerable<|\bLINQ\b|\.Select\s*\(|\.Where\s*\(/.test(s)) return "csharp";
|
|
5398
|
+
if (/\b#include\s*<(stdio|stdlib|string|math|time|ctype)\.h>|\bprintf\s*\(|\bscanf\s*\(|int\s+main\s*\(\s*(void|int\s+argc)|\bmalloc\s*\(|\bfree\s*\(/.test(s) && !/namespace|cout|cin|std::/.test(s)) return "c";
|
|
5399
|
+
if (/^<\?xml\s/i.test(s) || /xmlns:|<\/[\w:]+>/.test(s)) return "xml";
|
|
5400
|
+
return null;
|
|
5401
|
+
}
|
|
5402
|
+
//#endregion
|
|
5290
5403
|
//#region src/js/module/Editor.js
|
|
5291
5404
|
/**
|
|
5292
5405
|
* Editor.js - Core editing command module
|
|
@@ -5341,7 +5454,8 @@ var Editor = class {
|
|
|
5341
5454
|
if (!r.collapsed) return;
|
|
5342
5455
|
const sc = r.startContainer;
|
|
5343
5456
|
if (sc.nodeType !== Node.ELEMENT_NODE) return;
|
|
5344
|
-
const
|
|
5457
|
+
const scEl = sc;
|
|
5458
|
+
const li = scEl.matches(".an-checklist li") ? scEl : null;
|
|
5345
5459
|
if (!li) return;
|
|
5346
5460
|
const cb = li.querySelector("input[type=\"checkbox\"]");
|
|
5347
5461
|
if (!cb) return;
|
|
@@ -5381,7 +5495,7 @@ var Editor = class {
|
|
|
5381
5495
|
return;
|
|
5382
5496
|
}
|
|
5383
5497
|
const target = e.target;
|
|
5384
|
-
if (target && (target.nodeName === "IFRAME" || target.closest
|
|
5498
|
+
if (target && (target.nodeName === "IFRAME" || target.closest(".an-video-wrapper"))) e.preventDefault();
|
|
5385
5499
|
}), on(editable, "drop", (e) => {
|
|
5386
5500
|
if (isReadOnly()) e.preventDefault();
|
|
5387
5501
|
}));
|
|
@@ -5395,9 +5509,12 @@ var Editor = class {
|
|
|
5395
5509
|
}
|
|
5396
5510
|
let node = sel.getRangeAt(0).startContainer;
|
|
5397
5511
|
if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
|
|
5398
|
-
if (node
|
|
5399
|
-
|
|
5400
|
-
|
|
5512
|
+
if (node) {
|
|
5513
|
+
const el = node;
|
|
5514
|
+
if (el.closest("sup")) _compositionSupSub = "superscript";
|
|
5515
|
+
else if (el.closest("sub")) _compositionSupSub = "subscript";
|
|
5516
|
+
else _compositionSupSub = null;
|
|
5517
|
+
}
|
|
5401
5518
|
};
|
|
5402
5519
|
const onCompositionEnd = () => {
|
|
5403
5520
|
const tag = _compositionSupSub;
|
|
@@ -5407,7 +5524,8 @@ var Editor = class {
|
|
|
5407
5524
|
if (!sel || !sel.rangeCount) return;
|
|
5408
5525
|
let node = sel.getRangeAt(0).startContainer;
|
|
5409
5526
|
if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
|
|
5410
|
-
|
|
5527
|
+
const el = node;
|
|
5528
|
+
if (!(el && (tag === "superscript" ? el.closest("sup") : el.closest("sub")))) document.execCommand(tag);
|
|
5411
5529
|
};
|
|
5412
5530
|
this._disposers.push(on(editable, "compositionstart", onCompositionStart), on(editable, "compositionend", onCompositionEnd));
|
|
5413
5531
|
}
|
|
@@ -5496,6 +5614,7 @@ var Editor = class {
|
|
|
5496
5614
|
}
|
|
5497
5615
|
afterCommand() {
|
|
5498
5616
|
this._cleanOrphanedFigures();
|
|
5617
|
+
this._ensureTrailingParagraph();
|
|
5499
5618
|
this.context.invoke("toolbar.refresh");
|
|
5500
5619
|
this.context.invoke("statusbar.update");
|
|
5501
5620
|
this._scheduleSnapshot();
|
|
@@ -5522,6 +5641,31 @@ var Editor = class {
|
|
|
5522
5641
|
if (!fig.querySelector("img")) fig.parentNode.removeChild(fig);
|
|
5523
5642
|
});
|
|
5524
5643
|
}
|
|
5644
|
+
/**
|
|
5645
|
+
* Ensures the editable always ends with a plain paragraph so the cursor can
|
|
5646
|
+
* be placed after block elements that do not naturally allow it
|
|
5647
|
+
* (pre, blockquote, table, figure, ul, ol, hr).
|
|
5648
|
+
* Without this, clicking below the last such element does nothing.
|
|
5649
|
+
*/
|
|
5650
|
+
_ensureTrailingParagraph() {
|
|
5651
|
+
const editable = this.context.layoutInfo.editable;
|
|
5652
|
+
if (!editable) return;
|
|
5653
|
+
const last = editable.lastElementChild;
|
|
5654
|
+
if (!last) return;
|
|
5655
|
+
if (new Set([
|
|
5656
|
+
"PRE",
|
|
5657
|
+
"BLOCKQUOTE",
|
|
5658
|
+
"TABLE",
|
|
5659
|
+
"FIGURE",
|
|
5660
|
+
"UL",
|
|
5661
|
+
"OL",
|
|
5662
|
+
"HR"
|
|
5663
|
+
]).has(last.nodeName)) {
|
|
5664
|
+
const p = document.createElement("p");
|
|
5665
|
+
p.innerHTML = "<br>";
|
|
5666
|
+
editable.appendChild(p);
|
|
5667
|
+
}
|
|
5668
|
+
}
|
|
5525
5669
|
focus() {
|
|
5526
5670
|
this.context.layoutInfo.editable.focus();
|
|
5527
5671
|
}
|
|
@@ -5705,10 +5849,24 @@ var Editor = class {
|
|
|
5705
5849
|
this.context.print();
|
|
5706
5850
|
}
|
|
5707
5851
|
/**
|
|
5708
|
-
* @param {string} tagName - e.g. 'h1', 'p', 'blockquote'
|
|
5852
|
+
* @param {string} tagName - e.g. 'h1', 'p', 'blockquote', 'pre'
|
|
5709
5853
|
*/
|
|
5710
5854
|
formatBlock(tagName) {
|
|
5711
5855
|
formatBlock(tagName);
|
|
5856
|
+
if (tagName === "pre") {
|
|
5857
|
+
const sel = window.getSelection();
|
|
5858
|
+
if (sel && sel.rangeCount > 0) {
|
|
5859
|
+
const container = sel.getRangeAt(0).commonAncestorContainer;
|
|
5860
|
+
const pre = container.nodeType === 1 ? container.closest("pre") : container.parentElement?.closest("pre");
|
|
5861
|
+
if (pre && !pre.getAttribute("data-language")) {
|
|
5862
|
+
const lang = detectLang(pre.textContent || "");
|
|
5863
|
+
if (lang) {
|
|
5864
|
+
this.context.invoke("codeTooltip.applyLanguage", pre, lang);
|
|
5865
|
+
return;
|
|
5866
|
+
}
|
|
5867
|
+
}
|
|
5868
|
+
}
|
|
5869
|
+
}
|
|
5712
5870
|
this.afterCommand();
|
|
5713
5871
|
}
|
|
5714
5872
|
/**
|
|
@@ -5765,8 +5923,8 @@ var Editor = class {
|
|
|
5765
5923
|
if (openInNewTab) {
|
|
5766
5924
|
const link = this._getClosestAnchor();
|
|
5767
5925
|
if (link) {
|
|
5768
|
-
link.setAttribute("target", "_blank");
|
|
5769
|
-
link.setAttribute("rel", "noopener noreferrer");
|
|
5926
|
+
/** @type {Element} */ link.setAttribute("target", "_blank");
|
|
5927
|
+
/** @type {Element} */ link.setAttribute("rel", "noopener noreferrer");
|
|
5770
5928
|
}
|
|
5771
5929
|
}
|
|
5772
5930
|
}
|
|
@@ -6048,13 +6206,13 @@ var Toolbar = class {
|
|
|
6048
6206
|
else openPopup();
|
|
6049
6207
|
});
|
|
6050
6208
|
const d2 = on(grid, "mouseover", (e) => {
|
|
6051
|
-
const cell = e.target
|
|
6209
|
+
const cell = e.target?.closest(".an-table-cell");
|
|
6052
6210
|
if (!cell) return;
|
|
6053
6211
|
setHighlight(+cell.getAttribute("data-row"), +cell.getAttribute("data-col"));
|
|
6054
6212
|
});
|
|
6055
6213
|
const d3 = on(grid, "mouseleave", () => setHighlight(0, 0));
|
|
6056
6214
|
const d4 = on(grid, "click", (e) => {
|
|
6057
|
-
const cell = e.target
|
|
6215
|
+
const cell = e.target?.closest(".an-table-cell");
|
|
6058
6216
|
if (!cell) return;
|
|
6059
6217
|
const rows = +cell.getAttribute("data-row");
|
|
6060
6218
|
const cols = +cell.getAttribute("data-col");
|
|
@@ -6217,11 +6375,17 @@ var Toolbar = class {
|
|
|
6217
6375
|
e.preventDefault();
|
|
6218
6376
|
});
|
|
6219
6377
|
const d3b = on(swatches, "click", (e) => {
|
|
6220
|
-
const sw = e.target
|
|
6221
|
-
if (sw) applyColor(
|
|
6378
|
+
const sw = e.target?.closest(".an-color-swatch");
|
|
6379
|
+
if (sw) applyColor(
|
|
6380
|
+
/** @type {HTMLElement} */
|
|
6381
|
+
sw.dataset.color
|
|
6382
|
+
);
|
|
6222
6383
|
});
|
|
6223
6384
|
const d4 = on(colorInput, "change", (e) => {
|
|
6224
|
-
applyColor(
|
|
6385
|
+
applyColor(
|
|
6386
|
+
/** @type {HTMLInputElement} */
|
|
6387
|
+
e.target.value
|
|
6388
|
+
);
|
|
6225
6389
|
});
|
|
6226
6390
|
const d5 = on(document, "click", (e) => {
|
|
6227
6391
|
if (isOpen && !wrap.contains(e.target) && !popup.contains(e.target)) closePopup();
|
|
@@ -6356,15 +6520,17 @@ var Toolbar = class {
|
|
|
6356
6520
|
this.el.querySelectorAll("button[data-btn]").forEach((btn) => {
|
|
6357
6521
|
const def = btnMap.get(btn.getAttribute("data-btn"));
|
|
6358
6522
|
if (def && typeof def.isActive === "function") btn.classList.toggle("active", !!def.isActive(this.context));
|
|
6359
|
-
if (def && typeof def.isDisabled === "function")
|
|
6523
|
+
if (def && typeof def.isDisabled === "function")
|
|
6524
|
+
/** @type {HTMLButtonElement} */ btn.disabled = !!def.isDisabled(this.context);
|
|
6360
6525
|
});
|
|
6361
6526
|
this.el.querySelectorAll("select[data-btn]").forEach((select) => {
|
|
6362
6527
|
const def = btnMap.get(select.getAttribute("data-btn"));
|
|
6363
6528
|
if (!def || typeof def.getValue !== "function") return;
|
|
6364
6529
|
let raw = (def.getValue(this.context) || "").replace(/["']/g, "").trim();
|
|
6365
6530
|
if (!raw) raw = this.options.defaultFontFamily || this.options.fontFamilies && this.options.fontFamilies[0] || "";
|
|
6366
|
-
const
|
|
6367
|
-
|
|
6531
|
+
const sel = select;
|
|
6532
|
+
const matched = Array.from(sel.options).find((opt) => opt.value && opt.value.toLowerCase() === raw.toLowerCase());
|
|
6533
|
+
sel.value = matched ? matched.value : "";
|
|
6368
6534
|
});
|
|
6369
6535
|
}
|
|
6370
6536
|
/**
|
|
@@ -7158,8 +7324,13 @@ var LinkDialog = class {
|
|
|
7158
7324
|
"aria-label": L.ariaLabel
|
|
7159
7325
|
});
|
|
7160
7326
|
const box = createElement("div", { class: "an-dialog-box" });
|
|
7327
|
+
const header = createElement("div", { class: "an-dialog-header" });
|
|
7328
|
+
const iconEl = createElement("span", { class: "an-dialog-icon" });
|
|
7329
|
+
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"><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>`;
|
|
7161
7330
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7162
7331
|
title.textContent = L.title;
|
|
7332
|
+
header.appendChild(iconEl);
|
|
7333
|
+
header.appendChild(title);
|
|
7163
7334
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7164
7335
|
urlLabel.textContent = L.url;
|
|
7165
7336
|
const urlInput = createElement("input", {
|
|
@@ -7204,8 +7375,9 @@ var LinkDialog = class {
|
|
|
7204
7375
|
cancelBtn.textContent = L.cancelBtn;
|
|
7205
7376
|
btnRow.appendChild(insertBtn);
|
|
7206
7377
|
btnRow.appendChild(cancelBtn);
|
|
7207
|
-
box.append(
|
|
7378
|
+
box.append(header, urlLabel, urlInput, textLabel, textInput, tabLabel, btnRow);
|
|
7208
7379
|
overlay.appendChild(box);
|
|
7380
|
+
makeDraggable(header, box);
|
|
7209
7381
|
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7210
7382
|
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7211
7383
|
const d3 = on(overlay, "click", (e) => {
|
|
@@ -7335,8 +7507,13 @@ var ImageDialog = class {
|
|
|
7335
7507
|
"aria-label": L.ariaLabel
|
|
7336
7508
|
});
|
|
7337
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>`;
|
|
7338
7513
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7339
7514
|
title.textContent = L.title;
|
|
7515
|
+
header.appendChild(iconEl);
|
|
7516
|
+
header.appendChild(title);
|
|
7340
7517
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7341
7518
|
urlLabel.textContent = L.imageUrl;
|
|
7342
7519
|
const urlInput = createElement("input", {
|
|
@@ -7355,7 +7532,7 @@ var ImageDialog = class {
|
|
|
7355
7532
|
autocomplete: "off"
|
|
7356
7533
|
});
|
|
7357
7534
|
this._altInput = altInput;
|
|
7358
|
-
box.append(
|
|
7535
|
+
box.append(header, urlLabel, urlInput, altLabel, altInput);
|
|
7359
7536
|
const alignLabel = createElement("label", { class: "an-label" });
|
|
7360
7537
|
alignLabel.textContent = L.alignment;
|
|
7361
7538
|
const alignRow = createElement("div", { class: "an-align-row" });
|
|
@@ -7424,6 +7601,7 @@ var ImageDialog = class {
|
|
|
7424
7601
|
btnRow.appendChild(cancelBtn);
|
|
7425
7602
|
box.append(btnRow);
|
|
7426
7603
|
overlay.appendChild(box);
|
|
7604
|
+
makeDraggable(header, box);
|
|
7427
7605
|
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7428
7606
|
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7429
7607
|
const d3 = on(overlay, "click", (e) => {
|
|
@@ -7561,8 +7739,13 @@ var VideoDialog = class {
|
|
|
7561
7739
|
"aria-label": L.ariaLabel
|
|
7562
7740
|
});
|
|
7563
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>`;
|
|
7564
7745
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7565
7746
|
title.textContent = L.title;
|
|
7747
|
+
header.appendChild(iconEl);
|
|
7748
|
+
header.appendChild(title);
|
|
7566
7749
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7567
7750
|
urlLabel.textContent = L.videoUrl;
|
|
7568
7751
|
const urlInput = createElement("input", {
|
|
@@ -7598,8 +7781,9 @@ var VideoDialog = class {
|
|
|
7598
7781
|
cancelBtn.textContent = L.cancelBtn;
|
|
7599
7782
|
btnRow.appendChild(insertBtn);
|
|
7600
7783
|
btnRow.appendChild(cancelBtn);
|
|
7601
|
-
box.append(
|
|
7784
|
+
box.append(header, urlLabel, urlInput, hintEl, widthLabel, widthInput, btnRow);
|
|
7602
7785
|
overlay.appendChild(box);
|
|
7786
|
+
makeDraggable(header, box);
|
|
7603
7787
|
const d0 = on(urlInput, "input", () => {
|
|
7604
7788
|
const info = this._parseVideoUrl(urlInput.value.trim());
|
|
7605
7789
|
hintEl.textContent = info ? this.context.locale.videoDialog.detected(info.type) : urlInput.value ? this.context.locale.videoDialog.unknownFormat : "";
|
|
@@ -7782,7 +7966,7 @@ var ImageResizer = class {
|
|
|
7782
7966
|
};
|
|
7783
7967
|
this._disposers.push(on(editable, "click", (e) => this._onEditorClick(e)), on(editable, "contextmenu", (e) => {
|
|
7784
7968
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
7785
|
-
const img = e.target
|
|
7969
|
+
const img = e.target?.closest("img");
|
|
7786
7970
|
if (img) this._select(img);
|
|
7787
7971
|
}), on(document, "click", (e) => this._onDocClick(e)), on(window, "scroll", () => this._updateOverlayPosition(), { passive: true }), on(window, "resize", onWindowResize, { passive: true }), on(editable, "scroll", () => this._updateOverlayPosition(), { passive: true }));
|
|
7788
7972
|
return this;
|
|
@@ -8192,12 +8376,12 @@ var LinkTooltip = class {
|
|
|
8192
8376
|
document.body.appendChild(this._el);
|
|
8193
8377
|
const editable = this.context.layoutInfo.editable;
|
|
8194
8378
|
this._disposers.push(on(editable, "mouseover", (e) => {
|
|
8195
|
-
const anchor = e.target
|
|
8379
|
+
const anchor = e.target?.closest("a[href]");
|
|
8196
8380
|
if (anchor && editable.contains(anchor)) this._scheduleShow(anchor);
|
|
8197
8381
|
}), on(editable, "mouseout", (e) => {
|
|
8198
8382
|
const to = e.relatedTarget;
|
|
8199
8383
|
if (!to || !editable.contains(to) && !this._el.contains(to)) this._scheduleHide();
|
|
8200
|
-
}));
|
|
8384
|
+
}), on(window, "scroll", () => this._hide(), { passive: true }), on(window, "resize", () => this._hide(), { passive: true }));
|
|
8201
8385
|
return this;
|
|
8202
8386
|
}
|
|
8203
8387
|
destroy() {
|
|
@@ -8382,14 +8566,15 @@ var ImageTooltip = class {
|
|
|
8382
8566
|
const editable = this.context.layoutInfo.editable;
|
|
8383
8567
|
this._disposers.push(on(editable, "mouseover", (e) => {
|
|
8384
8568
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
8385
|
-
const img = e.target
|
|
8569
|
+
const img = e.target?.closest("img");
|
|
8386
8570
|
if (img && editable.contains(img) && !img.closest("a[href]")) this._scheduleShow(img);
|
|
8387
8571
|
}, { passive: true }), on(editable, "mouseout", (e) => {
|
|
8388
8572
|
const to = e.relatedTarget;
|
|
8389
8573
|
if (!to || !editable.contains(to) && !this._el.contains(to)) this._scheduleHide();
|
|
8390
8574
|
}, { passive: true }), on(document, "click", (e) => {
|
|
8391
|
-
|
|
8392
|
-
|
|
8575
|
+
const et = e.target;
|
|
8576
|
+
if (this._activeImg && !this._activeImg.contains(et) && !this._el.contains(et)) this._hide();
|
|
8577
|
+
}), on(window, "scroll", () => this._hide(), { passive: true }), on(window, "resize", () => this._hide(), { passive: true }));
|
|
8393
8578
|
return this;
|
|
8394
8579
|
}
|
|
8395
8580
|
destroy() {
|
|
@@ -8473,7 +8658,7 @@ var ImageTooltip = class {
|
|
|
8473
8658
|
clearTimeout(this._hideTimer);
|
|
8474
8659
|
this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY$3);
|
|
8475
8660
|
}
|
|
8476
|
-
_show(
|
|
8661
|
+
_show(_img) {
|
|
8477
8662
|
this._el.style.display = "flex";
|
|
8478
8663
|
requestAnimationFrame(() => {
|
|
8479
8664
|
if (this._activeImg) this._positionNear(this._activeImg);
|
|
@@ -8665,14 +8850,16 @@ var VideoTooltip = class {
|
|
|
8665
8850
|
const editable = this.context.layoutInfo.editable;
|
|
8666
8851
|
this._disposers.push(on(editable, "mouseover", (e) => {
|
|
8667
8852
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
8668
|
-
const
|
|
8853
|
+
const target = e.target;
|
|
8854
|
+
const wrapper = target && target.closest ? target.closest(".an-video-wrapper") : null;
|
|
8669
8855
|
if (wrapper && editable.contains(wrapper)) this._scheduleShow(wrapper);
|
|
8670
8856
|
}, { passive: true }), on(editable, "mouseout", (e) => {
|
|
8671
8857
|
const to = e.relatedTarget;
|
|
8672
8858
|
if (!to || !editable.contains(to) && !this._el.contains(to)) this._scheduleHide();
|
|
8673
8859
|
}, { passive: true }), on(document, "click", (e) => {
|
|
8674
|
-
|
|
8675
|
-
|
|
8860
|
+
const target = e.target;
|
|
8861
|
+
if (this._activeWrapper && !this._activeWrapper.contains(target) && !this._el.contains(target)) this._hide();
|
|
8862
|
+
}), on(window, "scroll", () => this._hide(), { passive: true }), on(window, "resize", () => this._hide(), { passive: true }));
|
|
8676
8863
|
return this;
|
|
8677
8864
|
}
|
|
8678
8865
|
destroy() {
|
|
@@ -8752,7 +8939,7 @@ var VideoTooltip = class {
|
|
|
8752
8939
|
if (this._hideTimer) return;
|
|
8753
8940
|
this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY$2);
|
|
8754
8941
|
}
|
|
8755
|
-
_show(
|
|
8942
|
+
_show(_wrapper) {
|
|
8756
8943
|
this._el.style.display = "flex";
|
|
8757
8944
|
requestAnimationFrame(() => {
|
|
8758
8945
|
if (this._activeWrapper) this._positionNear(this._activeWrapper);
|
|
@@ -8976,8 +9163,35 @@ var ICONS$2 = {
|
|
|
8976
9163
|
rowHeight: `<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" y1="7" x2="20" y2="7"/><line x1="4" y1="17" x2="20" y2="17"/><line x1="12" y1="7" x2="12" y2="17"/><path d="M9 10l3-3 3 3"/><path d="M9 14l3 3 3-3"/></svg>`,
|
|
8977
9164
|
tableBorder: `<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round"><line x1="3" y1="6" x2="21" y2="6" stroke-width="1"/><line x1="3" y1="13" x2="21" y2="13" stroke-width="2"/><line x1="3" y1="20" x2="21" y2="20" stroke-width="3"/></svg>`,
|
|
8978
9165
|
deleteTable: `<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" 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="1"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="3" y1="15" x2="21" y2="15"/><line x1="9" y1="3" x2="9" y2="21"/><line x1="15" y1="3" x2="15" y2="21"/><line x1="16" y1="16" x2="22" y2="22" stroke="#ef4444"/><line x1="22" y1="16" x2="16" y2="22" stroke="#ef4444"/></svg>`,
|
|
8979
|
-
selectCells: `<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4 L4 20 L9 15 L12 21 L14 20 L11 14 L17 14 Z" fill="currentColor" opacity="0.15"/><path d="M4 4 L4 20 L9 15 L12 21 L14 20 L11 14 L17 14 Z"/></svg
|
|
9166
|
+
selectCells: `<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4 L4 20 L9 15 L12 21 L14 20 L11 14 L17 14 Z" fill="currentColor" opacity="0.15"/><path d="M4 4 L4 20 L9 15 L12 21 L14 20 L11 14 L17 14 Z"/></svg>`,
|
|
9167
|
+
cellShade: `<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 11L8.93 3.36a1 1 0 0 0-1.29.08L3.22 7.8a1 1 0 0 0-.07 1.29L11 20"/><path d="m5 14 5-5"/><path d="M22 22a2 2 0 0 1-2 2h-3a2 2 0 0 1-2-2c0-1.5 2.5-5 3.5-5s3.5 3.5 3.5 5z"/></svg>`
|
|
8980
9168
|
};
|
|
9169
|
+
var SHADE_PRESETS = [
|
|
9170
|
+
"#000000",
|
|
9171
|
+
"#434343",
|
|
9172
|
+
"#666666",
|
|
9173
|
+
"#999999",
|
|
9174
|
+
"#b7b7b7",
|
|
9175
|
+
"#cccccc",
|
|
9176
|
+
"#efefef",
|
|
9177
|
+
"#ffffff",
|
|
9178
|
+
"#ff0000",
|
|
9179
|
+
"#ff9900",
|
|
9180
|
+
"#ffff00",
|
|
9181
|
+
"#00ff00",
|
|
9182
|
+
"#00ffff",
|
|
9183
|
+
"#4a86e8",
|
|
9184
|
+
"#9900ff",
|
|
9185
|
+
"#ff00ff",
|
|
9186
|
+
"#f4cccc",
|
|
9187
|
+
"#fce5cd",
|
|
9188
|
+
"#fff2cc",
|
|
9189
|
+
"#d9ead3",
|
|
9190
|
+
"#d0e0e3",
|
|
9191
|
+
"#c9daf8",
|
|
9192
|
+
"#d9d2e9",
|
|
9193
|
+
"#ead1dc"
|
|
9194
|
+
];
|
|
8981
9195
|
var TableTooltip = class {
|
|
8982
9196
|
/** @param {import('../Context.js').Context} context */
|
|
8983
9197
|
constructor(context) {
|
|
@@ -8992,6 +9206,9 @@ var TableTooltip = class {
|
|
|
8992
9206
|
this._sizeApply = null;
|
|
8993
9207
|
this._sizeTitleEl = null;
|
|
8994
9208
|
this._sizeInputEl = null;
|
|
9209
|
+
this._shadePopover = null;
|
|
9210
|
+
this._shadeTitleEl = null;
|
|
9211
|
+
this._shadeColorStrip = null;
|
|
8995
9212
|
this._selectMode = false;
|
|
8996
9213
|
this._selectedCells = [];
|
|
8997
9214
|
this._selectStart = null;
|
|
@@ -9004,6 +9221,8 @@ var TableTooltip = class {
|
|
|
9004
9221
|
document.body.appendChild(this._el);
|
|
9005
9222
|
this._sizePopover = this._buildSizePopover();
|
|
9006
9223
|
document.body.appendChild(this._sizePopover);
|
|
9224
|
+
this._shadePopover = this._buildCellShadePopover();
|
|
9225
|
+
document.body.appendChild(this._shadePopover);
|
|
9007
9226
|
const editable = this.context.layoutInfo.editable;
|
|
9008
9227
|
this._editable = editable;
|
|
9009
9228
|
const onSelMousedown = (e) => {
|
|
@@ -9030,10 +9249,13 @@ var TableTooltip = class {
|
|
|
9030
9249
|
this._disposers.push(on(editable, "mousedown", onSelMousedown), on(editable, "mousemove", onSelMousemove), on(document, "mouseup", onSelMouseup));
|
|
9031
9250
|
this._disposers.push(on(editable, "mouseover", (e) => {
|
|
9032
9251
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
9033
|
-
const table = e.target
|
|
9252
|
+
const table = e.target?.closest("table");
|
|
9034
9253
|
if (table && editable.contains(table)) {
|
|
9035
|
-
const cell = e.target
|
|
9036
|
-
if (cell)
|
|
9254
|
+
const cell = e.target?.closest("td, th");
|
|
9255
|
+
if (cell) {
|
|
9256
|
+
this._activeCell = cell;
|
|
9257
|
+
this._syncShadeStrip();
|
|
9258
|
+
}
|
|
9037
9259
|
this._scheduleShow(table);
|
|
9038
9260
|
}
|
|
9039
9261
|
}, { passive: true }), on(editable, "mouseout", (e) => {
|
|
@@ -9041,9 +9263,10 @@ var TableTooltip = class {
|
|
|
9041
9263
|
const to = e.relatedTarget;
|
|
9042
9264
|
if (!to || !editable.contains(to) && !this._el.contains(to) && !(this._sizePopover && this._sizePopover.contains(to))) this._scheduleHide();
|
|
9043
9265
|
}, { passive: true }), on(document, "click", (e) => {
|
|
9044
|
-
|
|
9045
|
-
if (this.
|
|
9046
|
-
|
|
9266
|
+
const et = e.target;
|
|
9267
|
+
if (this._selectMode && this._activeTable && this._activeTable.contains(et)) return;
|
|
9268
|
+
if (this._activeTable && !this._activeTable.contains(et) && !this._el.contains(et) && !(this._sizePopover && this._sizePopover.contains(et))) this._hide();
|
|
9269
|
+
}), on(document, "selectionchange", () => this._syncShadeStrip()), on(window, "scroll", () => this._hide(), { passive: true }), on(window, "resize", () => this._hide(), { passive: true }));
|
|
9047
9270
|
this._initResize();
|
|
9048
9271
|
return this;
|
|
9049
9272
|
}
|
|
@@ -9173,6 +9396,8 @@ var TableTooltip = class {
|
|
|
9173
9396
|
this._el = null;
|
|
9174
9397
|
if (this._sizePopover && this._sizePopover.parentNode) this._sizePopover.parentNode.removeChild(this._sizePopover);
|
|
9175
9398
|
this._sizePopover = null;
|
|
9399
|
+
if (this._shadePopover && this._shadePopover.parentNode) this._shadePopover.parentNode.removeChild(this._shadePopover);
|
|
9400
|
+
this._shadePopover = null;
|
|
9176
9401
|
}
|
|
9177
9402
|
_buildTooltip() {
|
|
9178
9403
|
const L = this.context.locale.tooltips.table;
|
|
@@ -9200,6 +9425,24 @@ var TableTooltip = class {
|
|
|
9200
9425
|
el.appendChild(this._makeBtn(ICONS$2.mergeCells, L.mergeCells, () => this._mergeCells()));
|
|
9201
9426
|
el.appendChild(this._makeBtn(ICONS$2.unmergeCells, L.unmergeCells, () => this._unmergeCells()));
|
|
9202
9427
|
el.appendChild(this._sep());
|
|
9428
|
+
const shadeBtn = createElement("button", {
|
|
9429
|
+
type: "button",
|
|
9430
|
+
class: "an-link-tooltip-btn an-link-tooltip-btn--shade",
|
|
9431
|
+
title: L.cellBackground
|
|
9432
|
+
});
|
|
9433
|
+
const shadeSvgWrap = createElement("span", { class: "an-bubble-btn-svg" });
|
|
9434
|
+
shadeSvgWrap.innerHTML = ICONS$2.cellShade;
|
|
9435
|
+
const shadeStrip = createElement("span", { class: "an-link-tooltip-color-strip" });
|
|
9436
|
+
shadeBtn.appendChild(shadeSvgWrap);
|
|
9437
|
+
shadeBtn.appendChild(shadeStrip);
|
|
9438
|
+
this._shadeColorStrip = shadeStrip;
|
|
9439
|
+
this._disposers.push(on(shadeBtn, "click", (e) => {
|
|
9440
|
+
e.preventDefault();
|
|
9441
|
+
e.stopPropagation();
|
|
9442
|
+
this._openCellShadePopover();
|
|
9443
|
+
}));
|
|
9444
|
+
el.appendChild(shadeBtn);
|
|
9445
|
+
el.appendChild(this._sep());
|
|
9203
9446
|
el.appendChild(this._makeBtn(ICONS$2.colWidth, L.columnWidth, () => this._openSizePopover("col")));
|
|
9204
9447
|
el.appendChild(this._makeBtn(ICONS$2.rowHeight, L.rowHeight, () => this._openSizePopover("row")));
|
|
9205
9448
|
el.appendChild(this._makeBtn(ICONS$2.tableBorder, L.tableBorderWidth, () => this._openSizePopover("border")));
|
|
@@ -9208,6 +9451,7 @@ var TableTooltip = class {
|
|
|
9208
9451
|
this._disposers.push(on(el, "mouseenter", () => this._clearTimers()), on(el, "mouseleave", () => {
|
|
9209
9452
|
if (this._selectMode) return;
|
|
9210
9453
|
if (this._sizePopover && this._sizePopover.style.display !== "none") return;
|
|
9454
|
+
if (this._shadePopover && this._shadePopover.style.display !== "none") return;
|
|
9211
9455
|
this._scheduleHide();
|
|
9212
9456
|
}));
|
|
9213
9457
|
return el;
|
|
@@ -9254,10 +9498,16 @@ var TableTooltip = class {
|
|
|
9254
9498
|
_show() {
|
|
9255
9499
|
if (!this._activeTable) return;
|
|
9256
9500
|
this._el.style.display = "flex";
|
|
9501
|
+
this._syncShadeStrip();
|
|
9257
9502
|
requestAnimationFrame(() => {
|
|
9258
9503
|
if (this._activeTable) this._positionNear(this._activeTable);
|
|
9259
9504
|
});
|
|
9260
9505
|
}
|
|
9506
|
+
_syncShadeStrip() {
|
|
9507
|
+
if (!this._shadeColorStrip || !this._el || this._el.style.display === "none") return;
|
|
9508
|
+
const cell = this._getCell();
|
|
9509
|
+
this._shadeColorStrip.style.background = cell && cell.style.backgroundColor || "transparent";
|
|
9510
|
+
}
|
|
9261
9511
|
_hide() {
|
|
9262
9512
|
this._el.style.display = "none";
|
|
9263
9513
|
this._activeTable = null;
|
|
@@ -9296,7 +9546,7 @@ var TableTooltip = class {
|
|
|
9296
9546
|
if (sel && sel.rangeCount) {
|
|
9297
9547
|
let container = sel.getRangeAt(0).commonAncestorContainer;
|
|
9298
9548
|
if (container.nodeType === 3) container = container.parentElement;
|
|
9299
|
-
const cellFromSel = container && container.closest
|
|
9549
|
+
const cellFromSel = container && container.closest("td, th");
|
|
9300
9550
|
if (cellFromSel && this._activeTable && this._activeTable.contains(cellFromSel)) return cellFromSel;
|
|
9301
9551
|
}
|
|
9302
9552
|
return this._activeCell || this._activeTable && this._activeTable.querySelector("td, th");
|
|
@@ -9623,14 +9873,16 @@ var TableTooltip = class {
|
|
|
9623
9873
|
});
|
|
9624
9874
|
const d2 = on(cancelBtn, "click", () => this._hideSizePopover());
|
|
9625
9875
|
const d3 = on(inputEl, "keydown", (e) => {
|
|
9626
|
-
|
|
9876
|
+
const ke = e;
|
|
9877
|
+
if (ke.key === "Enter") {
|
|
9627
9878
|
e.preventDefault();
|
|
9628
9879
|
applyBtn.click();
|
|
9629
9880
|
}
|
|
9630
|
-
if (
|
|
9881
|
+
if (ke.key === "Escape") this._hideSizePopover();
|
|
9631
9882
|
});
|
|
9632
9883
|
const d4 = on(document, "click", (e) => {
|
|
9633
|
-
|
|
9884
|
+
const et = e.target;
|
|
9885
|
+
if (this._sizePopover && this._sizePopover.style.display !== "none" && !this._sizePopover.contains(et) && !this._el.contains(et)) this._hideSizePopover();
|
|
9634
9886
|
});
|
|
9635
9887
|
const d5 = on(popover, "mouseenter", () => this._clearTimers());
|
|
9636
9888
|
const d6 = on(popover, "mouseleave", () => this._scheduleHide());
|
|
@@ -9648,7 +9900,7 @@ var TableTooltip = class {
|
|
|
9648
9900
|
this._sizeTitleEl.textContent = this.context.locale.tooltips.table.tableBorderWidthPx;
|
|
9649
9901
|
this._sizeInputEl.min = "0";
|
|
9650
9902
|
this._sizeInputEl.max = "10";
|
|
9651
|
-
this._sizeInputEl.value = currentPx;
|
|
9903
|
+
this._sizeInputEl.value = String(currentPx);
|
|
9652
9904
|
this._sizeApply = (val) => {
|
|
9653
9905
|
const cells = Array.from(table.querySelectorAll("td, th"));
|
|
9654
9906
|
if (val === 0) cells.forEach((c) => {
|
|
@@ -9717,6 +9969,85 @@ var TableTooltip = class {
|
|
|
9717
9969
|
if (this._sizePopover) this._sizePopover.style.display = "none";
|
|
9718
9970
|
this._sizeApply = null;
|
|
9719
9971
|
}
|
|
9972
|
+
_buildCellShadePopover() {
|
|
9973
|
+
const pop = createElement("div", { class: "an-cell-shade-popover" });
|
|
9974
|
+
pop.style.display = "none";
|
|
9975
|
+
const title = createElement("div", { class: "an-size-popover-title" });
|
|
9976
|
+
pop.appendChild(title);
|
|
9977
|
+
this._shadeTitleEl = title;
|
|
9978
|
+
const palette = createElement("div", { class: "an-context-color-palette" });
|
|
9979
|
+
SHADE_PRESETS.forEach((color) => {
|
|
9980
|
+
const sw = createElement("div", {
|
|
9981
|
+
class: "an-context-color-swatch",
|
|
9982
|
+
title: color
|
|
9983
|
+
});
|
|
9984
|
+
sw.style.background = color;
|
|
9985
|
+
this._disposers.push(on(sw, "click", (e) => {
|
|
9986
|
+
e.stopPropagation();
|
|
9987
|
+
this._applyCellShade(color);
|
|
9988
|
+
}));
|
|
9989
|
+
palette.appendChild(sw);
|
|
9990
|
+
});
|
|
9991
|
+
pop.appendChild(palette);
|
|
9992
|
+
const noShadeRow = createElement("div", { class: "an-context-color-custom" });
|
|
9993
|
+
const noShadeBtn = createElement("button", {
|
|
9994
|
+
type: "button",
|
|
9995
|
+
class: "an-shade-no-color"
|
|
9996
|
+
});
|
|
9997
|
+
this._disposers.push(on(noShadeBtn, "click", () => this._applyCellShade("")));
|
|
9998
|
+
noShadeRow.appendChild(noShadeBtn);
|
|
9999
|
+
pop.appendChild(noShadeRow);
|
|
10000
|
+
this._shadeNoBtn = noShadeBtn;
|
|
10001
|
+
const customRow = createElement("div", { class: "an-context-color-custom" });
|
|
10002
|
+
const colorInput = createElement("input", {
|
|
10003
|
+
type: "color",
|
|
10004
|
+
class: "an-shade-color-input",
|
|
10005
|
+
value: "#ffffff"
|
|
10006
|
+
});
|
|
10007
|
+
const customLabel = createElement("span");
|
|
10008
|
+
customLabel.textContent = "Custom…";
|
|
10009
|
+
this._disposers.push(on(colorInput, "change", () => this._applyCellShade(colorInput.value)));
|
|
10010
|
+
customRow.appendChild(colorInput);
|
|
10011
|
+
customRow.appendChild(customLabel);
|
|
10012
|
+
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()));
|
|
10015
|
+
this._disposers.push(on(document, "click", (e) => {
|
|
10016
|
+
const et = e.target;
|
|
10017
|
+
if (this._shadePopover && this._shadePopover.style.display !== "none" && !this._shadePopover.contains(et) && !(this._el && this._el.contains(et))) this._hideCellShadePopover();
|
|
10018
|
+
}));
|
|
10019
|
+
return pop;
|
|
10020
|
+
}
|
|
10021
|
+
_openCellShadePopover() {
|
|
10022
|
+
if (!this._shadePopover) return;
|
|
10023
|
+
const L = this.context.locale.tooltips.table;
|
|
10024
|
+
if (this._shadeTitleEl) this._shadeTitleEl.textContent = L.cellBackground;
|
|
10025
|
+
if (this._shadeNoBtn) this._shadeNoBtn.textContent = L.noShading;
|
|
10026
|
+
this._shadePopover.style.display = "block";
|
|
10027
|
+
requestAnimationFrame(() => {
|
|
10028
|
+
if (!this._shadePopover || !this._el) return;
|
|
10029
|
+
const pw = this._shadePopover.offsetWidth || 170;
|
|
10030
|
+
const ph = this._shadePopover.offsetHeight || 120;
|
|
10031
|
+
const tipRect = this._el.getBoundingClientRect();
|
|
10032
|
+
let left = tipRect.left;
|
|
10033
|
+
let top = tipRect.bottom + 6;
|
|
10034
|
+
if (left + pw > window.innerWidth - 8) left = window.innerWidth - pw - 8;
|
|
10035
|
+
if (top + ph > window.innerHeight - 8) top = tipRect.top - ph - 6;
|
|
10036
|
+
this._shadePopover.style.left = `${Math.max(8, left)}px`;
|
|
10037
|
+
this._shadePopover.style.top = `${Math.max(8, top)}px`;
|
|
10038
|
+
});
|
|
10039
|
+
}
|
|
10040
|
+
_hideCellShadePopover() {
|
|
10041
|
+
if (this._shadePopover) this._shadePopover.style.display = "none";
|
|
10042
|
+
}
|
|
10043
|
+
_applyCellShade(color) {
|
|
10044
|
+
(this._selectMode ? this._selectedCells : [this._getCell()]).forEach((cell) => {
|
|
10045
|
+
if (cell) cell.style.backgroundColor = color;
|
|
10046
|
+
});
|
|
10047
|
+
if (this._shadeColorStrip) this._shadeColorStrip.style.background = color || "transparent";
|
|
10048
|
+
this._hideCellShadePopover();
|
|
10049
|
+
this.context.invoke("editor.afterCommand");
|
|
10050
|
+
}
|
|
9720
10051
|
};
|
|
9721
10052
|
//#endregion
|
|
9722
10053
|
//#region src/js/module/CodeTooltip.js
|
|
@@ -9749,13 +10080,14 @@ var CodeTooltip = class {
|
|
|
9749
10080
|
const editable = this.context.layoutInfo.editable;
|
|
9750
10081
|
this._disposers.push(on(editable, "mouseover", (e) => {
|
|
9751
10082
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
9752
|
-
const pre = e.target
|
|
10083
|
+
const pre = e.target?.closest("pre");
|
|
9753
10084
|
if (pre && editable.contains(pre)) this._scheduleShow(pre);
|
|
9754
10085
|
}), on(editable, "mouseout", (e) => {
|
|
9755
10086
|
const to = e.relatedTarget;
|
|
9756
10087
|
if (!to || !editable.contains(to) && !this._el.contains(to)) this._scheduleHide();
|
|
9757
10088
|
}), on(document, "click", (e) => {
|
|
9758
|
-
|
|
10089
|
+
const et = e.target;
|
|
10090
|
+
if (this._activePre && !this._activePre.contains(et) && !this._el.contains(et)) this._hide();
|
|
9759
10091
|
}));
|
|
9760
10092
|
return this;
|
|
9761
10093
|
}
|
|
@@ -9790,6 +10122,7 @@ var CodeTooltip = class {
|
|
|
9790
10122
|
["python", "Python"],
|
|
9791
10123
|
["html", "HTML"],
|
|
9792
10124
|
["css", "CSS"],
|
|
10125
|
+
["scss", "SCSS"],
|
|
9793
10126
|
["json", "JSON"],
|
|
9794
10127
|
["xml", "XML"],
|
|
9795
10128
|
["bash", "Bash / Shell"],
|
|
@@ -9945,10 +10278,27 @@ var CodeTooltip = class {
|
|
|
9945
10278
|
this.context.invoke("editor.afterCommand");
|
|
9946
10279
|
this._positionNear(pre);
|
|
9947
10280
|
}
|
|
10281
|
+
/**
|
|
10282
|
+
* Applies a language to a given <pre> element: sets classes, data-language,
|
|
10283
|
+
* and triggers Prism highlighting. Called by the auto-detect flow.
|
|
10284
|
+
* @param {HTMLElement} pre
|
|
10285
|
+
* @param {string} lang - Prism language identifier, e.g. 'javascript'
|
|
10286
|
+
*/
|
|
10287
|
+
applyLanguage(pre, lang) {
|
|
10288
|
+
if (!pre || !lang) return;
|
|
10289
|
+
const savedPre = this._activePre;
|
|
10290
|
+
this._langSelect && this._langSelect.value;
|
|
10291
|
+
this._activePre = pre;
|
|
10292
|
+
if (this._langSelect) this._langSelect.value = lang;
|
|
10293
|
+
this._onLangChange();
|
|
10294
|
+
if (this._langSelect) this._langSelect.value = lang;
|
|
10295
|
+
this._activePre = savedPre || pre;
|
|
10296
|
+
}
|
|
9948
10297
|
_onLangChange() {
|
|
9949
10298
|
const pre = this._activePre;
|
|
9950
10299
|
if (!pre) return;
|
|
9951
10300
|
const lang = this._langSelect.value;
|
|
10301
|
+
const _w = window;
|
|
9952
10302
|
let codeEl = pre.querySelector("code");
|
|
9953
10303
|
if (!codeEl) {
|
|
9954
10304
|
codeEl = document.createElement("code");
|
|
@@ -9962,12 +10312,12 @@ var CodeTooltip = class {
|
|
|
9962
10312
|
else pre.removeAttribute("data-language");
|
|
9963
10313
|
const applyPrism = () => {
|
|
9964
10314
|
codeEl.querySelectorAll("br").forEach((br) => br.replaceWith("\n"));
|
|
9965
|
-
|
|
10315
|
+
_w.Prism.highlightElement(codeEl);
|
|
9966
10316
|
this.context.invoke("editor.afterCommand");
|
|
9967
10317
|
};
|
|
9968
10318
|
if (lang) {
|
|
9969
|
-
if (typeof
|
|
9970
|
-
if (
|
|
10319
|
+
if (typeof _w.Prism !== "undefined") {
|
|
10320
|
+
if (_w.Prism.languages[lang]) {
|
|
9971
10321
|
applyPrism();
|
|
9972
10322
|
return;
|
|
9973
10323
|
}
|
|
@@ -9975,7 +10325,7 @@ var CodeTooltip = class {
|
|
|
9975
10325
|
return;
|
|
9976
10326
|
} else if (this._prismScript) {
|
|
9977
10327
|
this._prismScript.addEventListener("load", () => {
|
|
9978
|
-
if (
|
|
10328
|
+
if (_w.Prism.languages[lang]) applyPrism();
|
|
9979
10329
|
else this._loadPrismComponent(lang, applyPrism);
|
|
9980
10330
|
}, { once: true });
|
|
9981
10331
|
return;
|
|
@@ -9988,7 +10338,8 @@ var CodeTooltip = class {
|
|
|
9988
10338
|
* Called once at initialize time. Fire-and-forget; errors are silent.
|
|
9989
10339
|
*/
|
|
9990
10340
|
_ensurePrism() {
|
|
9991
|
-
|
|
10341
|
+
const _w = window;
|
|
10342
|
+
if (!this.context.options.codeHighlight || _w.Prism) return;
|
|
9992
10343
|
const cdn = this.context.options.codeHighlightCDN;
|
|
9993
10344
|
const themeHref = `${cdn}/themes/prism-tomorrow.min.css`;
|
|
9994
10345
|
const scriptSrc = `${cdn}/prism.min.js`;
|
|
@@ -10000,7 +10351,7 @@ var CodeTooltip = class {
|
|
|
10000
10351
|
}
|
|
10001
10352
|
const existingScript = document.querySelector(`script[src="${scriptSrc}"]`);
|
|
10002
10353
|
if (existingScript) {
|
|
10003
|
-
this._prismScript =
|
|
10354
|
+
this._prismScript = _w.Prism ? null : existingScript;
|
|
10004
10355
|
return;
|
|
10005
10356
|
}
|
|
10006
10357
|
const script = document.createElement("script");
|
|
@@ -10020,10 +10371,11 @@ var CodeTooltip = class {
|
|
|
10020
10371
|
* @param {Function} cb – called once the grammar is ready
|
|
10021
10372
|
*/
|
|
10022
10373
|
_loadPrismComponent(lang, cb) {
|
|
10374
|
+
const _w = window;
|
|
10023
10375
|
const src = `${this.context.options.codeHighlightCDN}/components/prism-${lang}.min.js`;
|
|
10024
10376
|
if (document.querySelector(`script[src="${src}"]`)) {
|
|
10025
10377
|
const poll = setInterval(() => {
|
|
10026
|
-
if (
|
|
10378
|
+
if (_w.Prism && _w.Prism.languages[lang]) {
|
|
10027
10379
|
clearInterval(poll);
|
|
10028
10380
|
cb();
|
|
10029
10381
|
}
|
|
@@ -12436,15 +12788,19 @@ var EmojiDialog = class {
|
|
|
12436
12788
|
});
|
|
12437
12789
|
const box = createElement("div", { class: "an-dialog-box an-emoji-box" });
|
|
12438
12790
|
const titleRow = createElement("div", { class: "an-icon-title-row" });
|
|
12791
|
+
const titleGroup = createElement("div", { class: "an-dialog-title-group" });
|
|
12792
|
+
const iconEl = createElement("span", { class: "an-dialog-icon an-dialog-icon--sm" });
|
|
12793
|
+
iconEl.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M8 13s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>`;
|
|
12439
12794
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
12440
12795
|
title.textContent = L.title;
|
|
12796
|
+
titleGroup.append(iconEl, title);
|
|
12441
12797
|
const closeBtn = createElement("button", {
|
|
12442
12798
|
type: "button",
|
|
12443
12799
|
class: "an-icon-close",
|
|
12444
12800
|
"aria-label": L.close
|
|
12445
12801
|
});
|
|
12446
12802
|
closeBtn.innerHTML = "×";
|
|
12447
|
-
titleRow.append(
|
|
12803
|
+
titleRow.append(titleGroup, closeBtn);
|
|
12448
12804
|
const searchInput = createElement("input", {
|
|
12449
12805
|
type: "search",
|
|
12450
12806
|
class: "an-input an-icon-search",
|
|
@@ -12493,6 +12849,7 @@ var EmojiDialog = class {
|
|
|
12493
12849
|
btnRow.appendChild(cancelBtn);
|
|
12494
12850
|
box.append(titleRow, searchInput, catBar, grid, btnRow);
|
|
12495
12851
|
overlay.appendChild(box);
|
|
12852
|
+
makeDraggable(titleRow, box);
|
|
12496
12853
|
const d1 = on(closeBtn, "click", () => this._close());
|
|
12497
12854
|
const d2 = on(cancelBtn, "click", () => this._close());
|
|
12498
12855
|
const d3 = on(overlay, "click", (e) => {
|
|
@@ -12500,7 +12857,7 @@ var EmojiDialog = class {
|
|
|
12500
12857
|
});
|
|
12501
12858
|
const d4 = on(searchInput, "input", () => this._filterEmojis(searchInput.value, this._activeCat));
|
|
12502
12859
|
const d5 = on(catBar, "click", (e) => {
|
|
12503
|
-
const tab = e.target
|
|
12860
|
+
const tab = e.target?.closest("[data-cat]");
|
|
12504
12861
|
if (tab) {
|
|
12505
12862
|
this._activeCat = tab.dataset.cat;
|
|
12506
12863
|
this._updateCatTabs();
|
|
@@ -12508,7 +12865,7 @@ var EmojiDialog = class {
|
|
|
12508
12865
|
}
|
|
12509
12866
|
});
|
|
12510
12867
|
const d6 = on(grid, "click", (e) => {
|
|
12511
|
-
const cell = e.target
|
|
12868
|
+
const cell = e.target?.closest(".an-emoji-cell");
|
|
12512
12869
|
if (cell) this._onEmojiClick(cell.dataset.char);
|
|
12513
12870
|
});
|
|
12514
12871
|
this._disposers.push(d1, d2, d3, d4, d5, d6);
|
|
@@ -12516,17 +12873,22 @@ var EmojiDialog = class {
|
|
|
12516
12873
|
}
|
|
12517
12874
|
_updateCatTabs() {
|
|
12518
12875
|
this._catBar.querySelectorAll(".an-icon-cat").forEach((tab) => {
|
|
12519
|
-
tab.classList.toggle(
|
|
12876
|
+
tab.classList.toggle(
|
|
12877
|
+
"active",
|
|
12878
|
+
/** @type {HTMLElement} */
|
|
12879
|
+
tab.dataset.cat === this._activeCat
|
|
12880
|
+
);
|
|
12520
12881
|
});
|
|
12521
12882
|
}
|
|
12522
12883
|
_filterEmojis(query, cat) {
|
|
12523
12884
|
const q = (query || "").trim().toLowerCase();
|
|
12524
12885
|
let count = 0;
|
|
12525
12886
|
this._grid.querySelectorAll(".an-emoji-cell").forEach((cell) => {
|
|
12526
|
-
const
|
|
12527
|
-
const
|
|
12887
|
+
const hCell = cell;
|
|
12888
|
+
const matchCat = !cat || cat === "all" || hCell.dataset.cat === cat;
|
|
12889
|
+
const matchQuery = !q || hCell.dataset.keywords.includes(q) || hCell.dataset.char === q;
|
|
12528
12890
|
const visible = matchCat && matchQuery;
|
|
12529
|
-
|
|
12891
|
+
hCell.style.display = visible ? "" : "none";
|
|
12530
12892
|
if (visible) count++;
|
|
12531
12893
|
});
|
|
12532
12894
|
let empty = this._grid.querySelector(".an-icon-empty");
|
|
@@ -12535,7 +12897,7 @@ var EmojiDialog = class {
|
|
|
12535
12897
|
empty.textContent = "No emojis found";
|
|
12536
12898
|
this._grid.appendChild(empty);
|
|
12537
12899
|
}
|
|
12538
|
-
empty.style.display = count > 0 ? "none" : "";
|
|
12900
|
+
/** @type {HTMLElement} */ empty.style.display = count > 0 ? "none" : "";
|
|
12539
12901
|
}
|
|
12540
12902
|
_onEmojiClick(char) {
|
|
12541
12903
|
const savedRange = this._savedRange;
|
|
@@ -12549,7 +12911,7 @@ var EmojiDialog = class {
|
|
|
12549
12911
|
range.collapse(false);
|
|
12550
12912
|
}
|
|
12551
12913
|
const _sc = range.startContainer;
|
|
12552
|
-
const _tdAnchor = (_sc.nodeType === 1 ? _sc : _sc.parentElement)?.closest
|
|
12914
|
+
const _tdAnchor = (_sc.nodeType === 1 ? _sc : _sc.parentElement)?.closest("td, th");
|
|
12553
12915
|
range.deleteContents();
|
|
12554
12916
|
if (_tdAnchor && _tdAnchor.isConnected && !_tdAnchor.contains(range.startContainer)) {
|
|
12555
12917
|
range.setStart(_tdAnchor, 0);
|
|
@@ -12909,15 +13271,19 @@ var IconDialog = class {
|
|
|
12909
13271
|
});
|
|
12910
13272
|
const box = createElement("div", { class: "an-dialog-box an-icon-box" });
|
|
12911
13273
|
const titleRow = createElement("div", { class: "an-icon-title-row" });
|
|
13274
|
+
const titleGroup = createElement("div", { class: "an-dialog-title-group" });
|
|
13275
|
+
const iconEl = createElement("span", { class: "an-dialog-icon an-dialog-icon--sm" });
|
|
13276
|
+
iconEl.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>`;
|
|
12912
13277
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
12913
13278
|
title.textContent = L.title;
|
|
13279
|
+
titleGroup.append(iconEl, title);
|
|
12914
13280
|
const closeBtn = createElement("button", {
|
|
12915
13281
|
type: "button",
|
|
12916
13282
|
class: "an-icon-close",
|
|
12917
13283
|
"aria-label": L.close
|
|
12918
13284
|
});
|
|
12919
13285
|
closeBtn.innerHTML = "×";
|
|
12920
|
-
titleRow.append(
|
|
13286
|
+
titleRow.append(titleGroup, closeBtn);
|
|
12921
13287
|
const searchInput = createElement("input", {
|
|
12922
13288
|
type: "search",
|
|
12923
13289
|
class: "an-input an-icon-search",
|
|
@@ -13032,6 +13398,7 @@ var IconDialog = class {
|
|
|
13032
13398
|
this._insertBtn = insertBtn;
|
|
13033
13399
|
box.append(titleRow, searchInput, catBar, grid, optRow, preview, btnRow);
|
|
13034
13400
|
overlay.appendChild(box);
|
|
13401
|
+
makeDraggable(titleRow, box);
|
|
13035
13402
|
const d1 = on(closeBtn, "click", () => this._close());
|
|
13036
13403
|
const d2 = on(cancelBtn, "click", () => this._close());
|
|
13037
13404
|
const d3 = on(insertBtn, "click", () => this._onInsert());
|
|
@@ -13040,7 +13407,7 @@ var IconDialog = class {
|
|
|
13040
13407
|
});
|
|
13041
13408
|
const d5 = on(searchInput, "input", () => this._filterIcons(searchInput.value, this._activeCat));
|
|
13042
13409
|
const d6 = on(catBar, "click", (e) => {
|
|
13043
|
-
const tab = e.target
|
|
13410
|
+
const tab = e.target?.closest("[data-cat]");
|
|
13044
13411
|
if (tab) {
|
|
13045
13412
|
this._activeCat = tab.dataset.cat;
|
|
13046
13413
|
this._updateCatTabs();
|
|
@@ -13048,7 +13415,7 @@ var IconDialog = class {
|
|
|
13048
13415
|
}
|
|
13049
13416
|
});
|
|
13050
13417
|
const d7 = on(grid, "click", (e) => {
|
|
13051
|
-
const cell = e.target
|
|
13418
|
+
const cell = e.target?.closest(".an-icon-cell");
|
|
13052
13419
|
if (cell) this._selectIcon(cell.dataset.name);
|
|
13053
13420
|
});
|
|
13054
13421
|
const d8 = on(styleSelect, "change", () => this._updatePreview(this._selectedIcon));
|
|
@@ -13060,19 +13427,24 @@ var IconDialog = class {
|
|
|
13060
13427
|
}
|
|
13061
13428
|
_updateCatTabs() {
|
|
13062
13429
|
this._catBar.querySelectorAll(".an-icon-cat").forEach((tab) => {
|
|
13063
|
-
tab.classList.toggle(
|
|
13430
|
+
tab.classList.toggle(
|
|
13431
|
+
"active",
|
|
13432
|
+
/** @type {HTMLElement} */
|
|
13433
|
+
tab.dataset.cat === this._activeCat
|
|
13434
|
+
);
|
|
13064
13435
|
});
|
|
13065
13436
|
}
|
|
13066
13437
|
_filterIcons(query, cat) {
|
|
13067
13438
|
const q = (query || "").trim().toLowerCase();
|
|
13068
13439
|
let visibleCount = 0;
|
|
13069
13440
|
this._grid.querySelectorAll(".an-icon-cell").forEach((cell) => {
|
|
13070
|
-
const
|
|
13071
|
-
const
|
|
13441
|
+
const hCell = cell;
|
|
13442
|
+
const name = hCell.dataset.name;
|
|
13443
|
+
const cellCat = hCell.dataset.cat;
|
|
13072
13444
|
const matchesCat = !cat || cat === "all" || cellCat === cat;
|
|
13073
13445
|
const matchesQuery = !q || name.includes(q);
|
|
13074
13446
|
const visible = matchesCat && matchesQuery;
|
|
13075
|
-
|
|
13447
|
+
hCell.style.display = visible ? "" : "none";
|
|
13076
13448
|
if (visible) visibleCount++;
|
|
13077
13449
|
});
|
|
13078
13450
|
let empty = this._grid.querySelector(".an-icon-empty");
|
|
@@ -13081,12 +13453,16 @@ var IconDialog = class {
|
|
|
13081
13453
|
empty.textContent = "No icons found";
|
|
13082
13454
|
this._grid.appendChild(empty);
|
|
13083
13455
|
}
|
|
13084
|
-
empty.style.display = visibleCount > 0 ? "none" : "";
|
|
13456
|
+
/** @type {HTMLElement} */ empty.style.display = visibleCount > 0 ? "none" : "";
|
|
13085
13457
|
}
|
|
13086
13458
|
_selectIcon(name) {
|
|
13087
13459
|
this._selectedIcon = name;
|
|
13088
13460
|
this._grid.querySelectorAll(".an-icon-cell").forEach((cell) => {
|
|
13089
|
-
cell.classList.toggle(
|
|
13461
|
+
cell.classList.toggle(
|
|
13462
|
+
"active",
|
|
13463
|
+
/** @type {HTMLElement} */
|
|
13464
|
+
cell.dataset.name === name
|
|
13465
|
+
);
|
|
13090
13466
|
});
|
|
13091
13467
|
this._insertBtn.removeAttribute("disabled");
|
|
13092
13468
|
this._updatePreview(name);
|
|
@@ -13125,7 +13501,7 @@ var IconDialog = class {
|
|
|
13125
13501
|
range.collapse(false);
|
|
13126
13502
|
}
|
|
13127
13503
|
const _sc = range.startContainer;
|
|
13128
|
-
const _tdAnchor = (_sc.nodeType === 1 ? _sc : _sc.parentElement)?.closest
|
|
13504
|
+
const _tdAnchor = (_sc.nodeType === 1 ? _sc : _sc.parentElement)?.closest("td, th");
|
|
13129
13505
|
range.deleteContents();
|
|
13130
13506
|
if (_tdAnchor && _tdAnchor.isConnected && !_tdAnchor.contains(range.startContainer)) {
|
|
13131
13507
|
range.setStart(_tdAnchor, 0);
|
|
@@ -13396,13 +13772,13 @@ var ContextMenu = class {
|
|
|
13396
13772
|
this._menuDisposers.forEach((d) => {
|
|
13397
13773
|
try {
|
|
13398
13774
|
d();
|
|
13399
|
-
} catch (
|
|
13775
|
+
} catch (_e) {}
|
|
13400
13776
|
});
|
|
13401
13777
|
this._menuDisposers = [];
|
|
13402
13778
|
this._disposers.forEach((d) => {
|
|
13403
13779
|
try {
|
|
13404
13780
|
d();
|
|
13405
|
-
} catch (
|
|
13781
|
+
} catch (_e) {}
|
|
13406
13782
|
});
|
|
13407
13783
|
this._disposers = [];
|
|
13408
13784
|
if (this.el && this.el.parentNode) this.el.parentNode.removeChild(this.el);
|
|
@@ -13593,13 +13969,13 @@ var ContextMenu = class {
|
|
|
13593
13969
|
});
|
|
13594
13970
|
this._menuDisposers.push(offHeader);
|
|
13595
13971
|
const offMove = on(gridEl, "mousemove", (e) => {
|
|
13596
|
-
const cell = e.target
|
|
13972
|
+
const cell = e.target?.closest("[data-row]");
|
|
13597
13973
|
if (!cell) return;
|
|
13598
13974
|
setHighlight(+cell.dataset.row, +cell.dataset.col);
|
|
13599
13975
|
});
|
|
13600
13976
|
const offLeave = on(gridEl, "mouseleave", () => setHighlight(0, 0));
|
|
13601
13977
|
const offClick = on(gridEl, "click", (e) => {
|
|
13602
|
-
const cell = e.target
|
|
13978
|
+
const cell = e.target?.closest("[data-row]");
|
|
13603
13979
|
if (!cell) return;
|
|
13604
13980
|
const rows = +cell.dataset.row;
|
|
13605
13981
|
const cols = +cell.dataset.col;
|
|
@@ -13624,7 +14000,7 @@ var ContextMenu = class {
|
|
|
13624
14000
|
class: "an-context-item",
|
|
13625
14001
|
"data-name": it.name || ""
|
|
13626
14002
|
});
|
|
13627
|
-
if (typeof it.disabled === "function" ? it.disabled(this.context) : !!it.disabled) btn.disabled = true;
|
|
14003
|
+
if (typeof it.disabled === "function" ? it.disabled(this.context) : !!it.disabled) /** @type {HTMLButtonElement} */ btn.disabled = true;
|
|
13628
14004
|
if (it.icon) {
|
|
13629
14005
|
const iconSpan = createElement("span", {
|
|
13630
14006
|
class: "an-context-icon",
|
|
@@ -13656,7 +14032,7 @@ var ContextMenu = class {
|
|
|
13656
14032
|
const winSel = window.getSelection();
|
|
13657
14033
|
this._savedRange = winSel && winSel.rangeCount > 0 ? winSel.getRangeAt(0).cloneRange() : null;
|
|
13658
14034
|
this._renderItems(this._items);
|
|
13659
|
-
|
|
14035
|
+
const openX = event.clientX;
|
|
13660
14036
|
let openY = event.clientY;
|
|
13661
14037
|
if (this._savedRange && !this._savedRange.collapsed) try {
|
|
13662
14038
|
const selRect = this._savedRange.getBoundingClientRect();
|
|
@@ -13822,7 +14198,7 @@ var ContextMenu = class {
|
|
|
13822
14198
|
while (el = iter.nextNode()) {
|
|
13823
14199
|
if (!editable.contains(el) || el === editable) continue;
|
|
13824
14200
|
try {
|
|
13825
|
-
if (range.intersectsNode(el)) el.removeAttribute("style");
|
|
14201
|
+
if (range.intersectsNode(el)) /** @type {Element} */ el.removeAttribute("style");
|
|
13826
14202
|
} catch {}
|
|
13827
14203
|
}
|
|
13828
14204
|
this.context.invoke("editor.afterCommand");
|
|
@@ -14084,8 +14460,8 @@ var FindReplace = class {
|
|
|
14084
14460
|
const replaceActions = this._dialog.querySelector(".an-fr-replace-actions");
|
|
14085
14461
|
const title = this._dialog.querySelector(".an-dialog-title");
|
|
14086
14462
|
const isReplace = this._mode === "replace";
|
|
14087
|
-
if (replaceRow) replaceRow.style.display = isReplace ? "" : "none";
|
|
14088
|
-
if (replaceActions) replaceActions.style.display = isReplace ? "" : "none";
|
|
14463
|
+
if (replaceRow) /** @type {HTMLElement} */ replaceRow.style.display = isReplace ? "" : "none";
|
|
14464
|
+
if (replaceActions) /** @type {HTMLElement} */ replaceActions.style.display = isReplace ? "" : "none";
|
|
14089
14465
|
if (title) title.textContent = isReplace ? this.context.locale.findReplace.findReplaceTitle : this.context.locale.findReplace.findTitle;
|
|
14090
14466
|
}
|
|
14091
14467
|
_buildDialog() {
|
|
@@ -14096,106 +14472,123 @@ var FindReplace = class {
|
|
|
14096
14472
|
"aria-modal": "true",
|
|
14097
14473
|
"aria-label": L.findReplaceTitle
|
|
14098
14474
|
});
|
|
14099
|
-
const box = createElement("div", { class: "an-dialog-box" });
|
|
14100
|
-
const
|
|
14475
|
+
const box = createElement("div", { class: "an-dialog-box an-fr-box" });
|
|
14476
|
+
const header = createElement("div", { class: "an-fr-header" });
|
|
14477
|
+
const titleGroup = createElement("div", { class: "an-dialog-title-group" });
|
|
14478
|
+
const iconEl = createElement("span", { class: "an-dialog-icon an-dialog-icon--sm" });
|
|
14479
|
+
iconEl.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>`;
|
|
14101
14480
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
14102
14481
|
title.textContent = L.findTitle;
|
|
14482
|
+
titleGroup.append(iconEl, title);
|
|
14103
14483
|
const closeBtn = createElement("button", {
|
|
14104
14484
|
type: "button",
|
|
14105
14485
|
class: "an-icon-close",
|
|
14106
|
-
|
|
14486
|
+
title: L.close,
|
|
14487
|
+
"aria-label": L.close
|
|
14107
14488
|
});
|
|
14108
|
-
closeBtn.
|
|
14489
|
+
closeBtn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>`;
|
|
14109
14490
|
this._closeBtn = closeBtn;
|
|
14110
|
-
|
|
14111
|
-
box.appendChild(
|
|
14112
|
-
const
|
|
14491
|
+
header.append(titleGroup, closeBtn);
|
|
14492
|
+
box.appendChild(header);
|
|
14493
|
+
const searchBar = createElement("div", { class: "an-fr-search-bar" });
|
|
14113
14494
|
const findInput = createElement("input", {
|
|
14114
14495
|
type: "text",
|
|
14115
|
-
class: "an-input",
|
|
14496
|
+
class: "an-input an-fr-input",
|
|
14116
14497
|
placeholder: L.findPlaceholder,
|
|
14117
14498
|
"aria-label": L.searchAriaLabel
|
|
14118
14499
|
});
|
|
14119
14500
|
this._findInput = findInput;
|
|
14120
|
-
findRow.appendChild(findInput);
|
|
14121
|
-
box.appendChild(findRow);
|
|
14122
|
-
const optRow = createElement("div", { class: "an-fr-options-row" });
|
|
14123
|
-
const caseLabel = createElement("label", { class: "an-label an-label-inline" });
|
|
14124
14501
|
const caseCheckbox = createElement("input", {
|
|
14125
14502
|
type: "checkbox",
|
|
14126
|
-
|
|
14503
|
+
style: "display:none",
|
|
14504
|
+
"aria-hidden": "true"
|
|
14127
14505
|
});
|
|
14128
14506
|
this._caseCheckbox = caseCheckbox;
|
|
14129
|
-
|
|
14130
|
-
|
|
14131
|
-
|
|
14132
|
-
|
|
14133
|
-
|
|
14134
|
-
|
|
14507
|
+
const caseBtn = createElement("button", {
|
|
14508
|
+
type: "button",
|
|
14509
|
+
class: "an-fr-icon-btn",
|
|
14510
|
+
title: "Case sensitive",
|
|
14511
|
+
"aria-label": "Case sensitive"
|
|
14512
|
+
});
|
|
14513
|
+
caseBtn.textContent = "Aa";
|
|
14135
14514
|
const prevBtn = createElement("button", {
|
|
14136
14515
|
type: "button",
|
|
14137
|
-
class: "an-btn"
|
|
14516
|
+
class: "an-fr-icon-btn",
|
|
14517
|
+
title: "Previous (Shift+Enter)",
|
|
14518
|
+
"aria-label": "Previous"
|
|
14138
14519
|
});
|
|
14139
|
-
prevBtn.
|
|
14520
|
+
prevBtn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 15 12 9 6 15"/></svg>`;
|
|
14140
14521
|
const nextBtn = createElement("button", {
|
|
14141
14522
|
type: "button",
|
|
14142
|
-
class: "an-
|
|
14523
|
+
class: "an-fr-icon-btn",
|
|
14524
|
+
title: "Next (Enter)",
|
|
14525
|
+
"aria-label": "Next"
|
|
14143
14526
|
});
|
|
14144
|
-
nextBtn.
|
|
14145
|
-
|
|
14146
|
-
|
|
14527
|
+
nextBtn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>`;
|
|
14528
|
+
const counter = createElement("span", { class: "an-fr-counter" });
|
|
14529
|
+
this._counterEl = counter;
|
|
14530
|
+
searchBar.append(findInput, caseCheckbox, caseBtn, prevBtn, nextBtn, counter);
|
|
14531
|
+
box.appendChild(searchBar);
|
|
14147
14532
|
const replaceRow = createElement("div", { class: "an-fr-replace-row" });
|
|
14148
14533
|
replaceRow.style.display = "none";
|
|
14149
14534
|
const replaceInput = createElement("input", {
|
|
14150
14535
|
type: "text",
|
|
14151
|
-
class: "an-input",
|
|
14536
|
+
class: "an-input an-fr-input",
|
|
14152
14537
|
placeholder: L.replacePlaceholder,
|
|
14153
14538
|
"aria-label": L.replaceAriaLabel
|
|
14154
14539
|
});
|
|
14155
14540
|
this._replaceInput = replaceInput;
|
|
14156
|
-
replaceRow.appendChild(replaceInput);
|
|
14157
|
-
box.appendChild(replaceRow);
|
|
14158
|
-
const replaceActions = createElement("div", { class: "an-dialog-actions an-fr-replace-actions" });
|
|
14159
|
-
replaceActions.style.display = "none";
|
|
14160
14541
|
const replaceBtn = createElement("button", {
|
|
14161
14542
|
type: "button",
|
|
14162
|
-
class: "an-btn"
|
|
14543
|
+
class: "an-btn an-fr-replace-btn"
|
|
14163
14544
|
});
|
|
14164
14545
|
replaceBtn.textContent = L.replaceBtn;
|
|
14165
14546
|
const replaceAllBtn = createElement("button", {
|
|
14166
14547
|
type: "button",
|
|
14167
|
-
class: "an-btn an-btn-primary"
|
|
14548
|
+
class: "an-btn an-btn-primary an-fr-replace-btn"
|
|
14168
14549
|
});
|
|
14169
14550
|
replaceAllBtn.textContent = L.replaceAllBtn;
|
|
14170
|
-
|
|
14551
|
+
replaceRow.append(replaceInput, replaceBtn, replaceAllBtn);
|
|
14552
|
+
box.appendChild(replaceRow);
|
|
14553
|
+
const replaceActions = createElement("div", { class: "an-fr-replace-actions" });
|
|
14554
|
+
replaceActions.style.display = "none";
|
|
14171
14555
|
box.appendChild(replaceActions);
|
|
14172
14556
|
overlay.appendChild(box);
|
|
14557
|
+
makeDraggable(header, box);
|
|
14173
14558
|
const d1 = on(closeBtn, "click", () => this._close());
|
|
14174
14559
|
const d2 = on(overlay, "click", (e) => {
|
|
14175
14560
|
if (e.target === overlay) this._close();
|
|
14176
14561
|
});
|
|
14177
14562
|
const d3 = on(findInput, "input", () => this._onSearch());
|
|
14178
|
-
const d4 = on(
|
|
14563
|
+
const d4 = on(caseBtn, "click", () => {
|
|
14564
|
+
this._caseSensitive = !this._caseSensitive;
|
|
14565
|
+
caseCheckbox.checked = this._caseSensitive;
|
|
14566
|
+
caseBtn.classList.toggle("an-fr-icon-btn--active", this._caseSensitive);
|
|
14567
|
+
this._onSearch();
|
|
14568
|
+
});
|
|
14569
|
+
const d5 = on(caseCheckbox, "change", () => {
|
|
14179
14570
|
this._caseSensitive = caseCheckbox.checked;
|
|
14571
|
+
caseBtn.classList.toggle("an-fr-icon-btn--active", this._caseSensitive);
|
|
14180
14572
|
this._onSearch();
|
|
14181
14573
|
});
|
|
14182
|
-
const
|
|
14183
|
-
const
|
|
14184
|
-
const
|
|
14185
|
-
const
|
|
14186
|
-
const
|
|
14187
|
-
|
|
14574
|
+
const d6 = on(nextBtn, "click", () => this._next());
|
|
14575
|
+
const d7 = on(prevBtn, "click", () => this._prev());
|
|
14576
|
+
const d8 = on(replaceBtn, "click", () => this._replace());
|
|
14577
|
+
const d9 = on(replaceAllBtn, "click", () => this._replaceAll());
|
|
14578
|
+
const d10 = on(findInput, "keydown", (e) => {
|
|
14579
|
+
const ke = e;
|
|
14580
|
+
if (ke.key === "Enter") {
|
|
14188
14581
|
e.preventDefault();
|
|
14189
|
-
|
|
14582
|
+
ke.shiftKey ? this._prev() : this._next();
|
|
14190
14583
|
}
|
|
14191
14584
|
});
|
|
14192
|
-
const
|
|
14585
|
+
const d11 = on(replaceInput, "keydown", (e) => {
|
|
14193
14586
|
if (e.key === "Enter") {
|
|
14194
14587
|
e.preventDefault();
|
|
14195
14588
|
this._replace();
|
|
14196
14589
|
}
|
|
14197
14590
|
});
|
|
14198
|
-
this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10);
|
|
14591
|
+
this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
|
|
14199
14592
|
return overlay;
|
|
14200
14593
|
}
|
|
14201
14594
|
_onSearch() {
|
|
@@ -14556,9 +14949,10 @@ var ImageCropOverlay = class {
|
|
|
14556
14949
|
}), on(h, "touchstart", (e) => {
|
|
14557
14950
|
e.preventDefault();
|
|
14558
14951
|
e.stopPropagation();
|
|
14952
|
+
const te = e;
|
|
14559
14953
|
this._startHandleDrag({
|
|
14560
|
-
clientX:
|
|
14561
|
-
clientY:
|
|
14954
|
+
clientX: te.touches[0].clientX,
|
|
14955
|
+
clientY: te.touches[0].clientY
|
|
14562
14956
|
}, id);
|
|
14563
14957
|
}, { passive: false }));
|
|
14564
14958
|
this._handles[id] = h;
|
|
@@ -14575,9 +14969,10 @@ var ImageCropOverlay = class {
|
|
|
14575
14969
|
if (e.target !== cropBox && e.target !== grid) return;
|
|
14576
14970
|
e.preventDefault();
|
|
14577
14971
|
e.stopPropagation();
|
|
14972
|
+
const te2 = e;
|
|
14578
14973
|
this._startBoxMove({
|
|
14579
|
-
clientX:
|
|
14580
|
-
clientY:
|
|
14974
|
+
clientX: te2.touches[0].clientX,
|
|
14975
|
+
clientY: te2.touches[0].clientY
|
|
14581
14976
|
});
|
|
14582
14977
|
}, { passive: false }));
|
|
14583
14978
|
const infoEl = document.createElement("div");
|
|
@@ -14739,9 +15134,10 @@ var ImageCropOverlay = class {
|
|
|
14739
15134
|
_attachDocDrag(onMove) {
|
|
14740
15135
|
const onTouchMove = (e) => {
|
|
14741
15136
|
e.preventDefault();
|
|
15137
|
+
const te3 = e;
|
|
14742
15138
|
onMove({
|
|
14743
|
-
clientX:
|
|
14744
|
-
clientY:
|
|
15139
|
+
clientX: te3.touches[0].clientX,
|
|
15140
|
+
clientY: te3.touches[0].clientY
|
|
14745
15141
|
});
|
|
14746
15142
|
};
|
|
14747
15143
|
const cleanup = () => {
|
|
@@ -15318,7 +15714,9 @@ var BubbleToolbar = class {
|
|
|
15318
15714
|
const d6 = this.context.on("contextMenu:hide", () => {
|
|
15319
15715
|
this._contextMenuOpen = false;
|
|
15320
15716
|
});
|
|
15321
|
-
|
|
15717
|
+
const d7 = on(window, "scroll", () => this._hide(), { passive: true });
|
|
15718
|
+
const d8 = on(window, "resize", () => this._hide(), { passive: true });
|
|
15719
|
+
this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8);
|
|
15322
15720
|
return this;
|
|
15323
15721
|
}
|
|
15324
15722
|
destroy() {
|
|
@@ -15432,20 +15830,22 @@ var BubbleToolbar = class {
|
|
|
15432
15830
|
picker.appendChild(customRow);
|
|
15433
15831
|
document.body.appendChild(picker);
|
|
15434
15832
|
this._picker = picker;
|
|
15435
|
-
|
|
15436
|
-
|
|
15437
|
-
|
|
15833
|
+
const pickerAny = picker;
|
|
15834
|
+
pickerAny._paletteEl = palette;
|
|
15835
|
+
pickerAny._noColorBtn = noColorBtn;
|
|
15836
|
+
pickerAny._colorInput = colorInput;
|
|
15438
15837
|
}
|
|
15439
15838
|
_openColorPicker(type, anchorBtn) {
|
|
15440
15839
|
const sel = window.getSelection();
|
|
15441
15840
|
if (sel && sel.rangeCount > 0) this._savedRange = sel.getRangeAt(0).cloneRange();
|
|
15442
15841
|
this._pickerType = type;
|
|
15443
|
-
const
|
|
15444
|
-
const
|
|
15842
|
+
const pickerAny = this._picker;
|
|
15843
|
+
const palette = pickerAny._paletteEl;
|
|
15844
|
+
const noColorBtn = pickerAny._noColorBtn;
|
|
15445
15845
|
if (type === "hiliteColor") {
|
|
15446
15846
|
if (!palette.contains(noColorBtn)) palette.appendChild(noColorBtn);
|
|
15447
15847
|
} else if (palette.contains(noColorBtn)) palette.removeChild(noColorBtn);
|
|
15448
|
-
this._picker._colorInput.value = type === "foreColor" ? "#000000" : "#ffff00";
|
|
15848
|
+
/** @type {any} */ this._picker._colorInput.value = type === "foreColor" ? "#000000" : "#ffff00";
|
|
15449
15849
|
this._picker.style.display = "block";
|
|
15450
15850
|
const pw = this._picker.offsetWidth;
|
|
15451
15851
|
const ph = this._picker.offsetHeight;
|
|
@@ -15479,7 +15879,7 @@ var BubbleToolbar = class {
|
|
|
15479
15879
|
const name = type === "hiliteColor" ? "hiliteColor" : "foreColor";
|
|
15480
15880
|
const btn = this._el && this._el.querySelector(`[data-name="${name}"]`);
|
|
15481
15881
|
const strip = btn && btn.querySelector(".an-bubble-color-strip");
|
|
15482
|
-
if (strip) strip.style.background = color === "transparent" ? "transparent" : color;
|
|
15882
|
+
if (strip) /** @type {HTMLElement} */ strip.style.background = color === "transparent" ? "transparent" : color;
|
|
15483
15883
|
this._closeColorPicker();
|
|
15484
15884
|
this._syncActive();
|
|
15485
15885
|
}
|
|
@@ -15495,6 +15895,14 @@ var BubbleToolbar = class {
|
|
|
15495
15895
|
let top = rect.top - bh - gap;
|
|
15496
15896
|
left = Math.max(8, Math.min(left, window.innerWidth - bw - 8));
|
|
15497
15897
|
if (top < 8) top = rect.bottom + gap;
|
|
15898
|
+
const tableTooltipEl = document.querySelector(".an-table-tooltip");
|
|
15899
|
+
if (tableTooltipEl && tableTooltipEl.style.display !== "none") {
|
|
15900
|
+
const ttRect = tableTooltipEl.getBoundingClientRect();
|
|
15901
|
+
if (top < ttRect.bottom + gap && top + bh > ttRect.top - gap) {
|
|
15902
|
+
top = rect.bottom + gap;
|
|
15903
|
+
if (top + bh > window.innerHeight - 8) top = ttRect.bottom + gap;
|
|
15904
|
+
}
|
|
15905
|
+
}
|
|
15498
15906
|
el.style.top = `${top}px`;
|
|
15499
15907
|
el.style.left = `${left}px`;
|
|
15500
15908
|
el.style.visibility = "";
|
|
@@ -15526,12 +15934,12 @@ var BubbleToolbar = class {
|
|
|
15526
15934
|
const cs = window.getComputedStyle(node);
|
|
15527
15935
|
const foreBtn = this._el.querySelector("[data-name=\"foreColor\"]");
|
|
15528
15936
|
const foreStrip = foreBtn && foreBtn.querySelector(".an-bubble-color-strip");
|
|
15529
|
-
if (foreStrip) foreStrip.style.background = cs.color || "#000000";
|
|
15937
|
+
if (foreStrip) /** @type {HTMLElement} */ foreStrip.style.background = cs.color || "#000000";
|
|
15530
15938
|
const hiliteBtn = this._el.querySelector("[data-name=\"hiliteColor\"]");
|
|
15531
15939
|
const hiliteStrip = hiliteBtn && hiliteBtn.querySelector(".an-bubble-color-strip");
|
|
15532
15940
|
if (hiliteStrip) {
|
|
15533
15941
|
const bg = cs.backgroundColor;
|
|
15534
|
-
hiliteStrip.style.background = !bg || bg === "rgba(0, 0, 0, 0)" || bg === "transparent" ? "transparent" : bg;
|
|
15942
|
+
/** @type {HTMLElement} */ hiliteStrip.style.background = !bg || bg === "rgba(0, 0, 0, 0)" || bg === "transparent" ? "transparent" : bg;
|
|
15535
15943
|
}
|
|
15536
15944
|
}
|
|
15537
15945
|
_onSelectionChange() {
|
|
@@ -15659,11 +16067,11 @@ var Mention = class {
|
|
|
15659
16067
|
el.setAttribute("role", "listbox");
|
|
15660
16068
|
el.addEventListener("mousedown", (e) => e.preventDefault());
|
|
15661
16069
|
el.addEventListener("click", (e) => {
|
|
15662
|
-
const item = e.target
|
|
16070
|
+
const item = e.target?.closest(".an-mention-item");
|
|
15663
16071
|
if (item) this._select(+item.dataset.index);
|
|
15664
16072
|
});
|
|
15665
16073
|
el.addEventListener("mousemove", (e) => {
|
|
15666
|
-
const item = e.target
|
|
16074
|
+
const item = e.target?.closest(".an-mention-item");
|
|
15667
16075
|
if (item) this._highlightItem(+item.dataset.index);
|
|
15668
16076
|
});
|
|
15669
16077
|
document.body.appendChild(el);
|
|
@@ -15678,7 +16086,7 @@ var Mention = class {
|
|
|
15678
16086
|
const li = document.createElement("div");
|
|
15679
16087
|
li.className = "an-mention-item";
|
|
15680
16088
|
li.setAttribute("role", "option");
|
|
15681
|
-
li.dataset.index = i;
|
|
16089
|
+
li.dataset.index = String(i);
|
|
15682
16090
|
if (item.avatar) {
|
|
15683
16091
|
const img = document.createElement("img");
|
|
15684
16092
|
img.src = item.avatar;
|
|
@@ -15928,7 +16336,7 @@ var Context = class {
|
|
|
15928
16336
|
/**
|
|
15929
16337
|
* Registers and initialises a custom module on this instance.
|
|
15930
16338
|
* @param {string} name
|
|
15931
|
-
* @param {
|
|
16339
|
+
* @param {new (ctx: this) => any} ModuleClass
|
|
15932
16340
|
* @returns {this}
|
|
15933
16341
|
*/
|
|
15934
16342
|
registerModule(name, ModuleClass) {
|
|
@@ -16235,10 +16643,12 @@ var Context = class {
|
|
|
16235
16643
|
this._disposers.forEach((d) => d());
|
|
16236
16644
|
this._disposers = [];
|
|
16237
16645
|
const container = this.layoutInfo.container;
|
|
16646
|
+
const wasDark = container && container.classList.contains("an-theme-dark");
|
|
16238
16647
|
if (container && container.parentNode) {
|
|
16239
16648
|
this.targetEl.style.display = "";
|
|
16240
16649
|
container.parentNode.removeChild(container);
|
|
16241
16650
|
}
|
|
16651
|
+
if (wasDark && !document.querySelector(".an-container.an-theme-dark")) document.body.classList.remove("an-theme-dark");
|
|
16242
16652
|
if (typeof this.options.onDestroy === "function") this.options.onDestroy(this);
|
|
16243
16653
|
this._alive = false;
|
|
16244
16654
|
this._listeners.clear();
|
|
@@ -16247,7 +16657,8 @@ var Context = class {
|
|
|
16247
16657
|
* Syncs editor HTML back into the original textarea/input for form submission.
|
|
16248
16658
|
*/
|
|
16249
16659
|
_syncToTarget() {
|
|
16250
|
-
if (this.targetEl.tagName === "TEXTAREA" || this.targetEl.tagName === "INPUT")
|
|
16660
|
+
if (this.targetEl.tagName === "TEXTAREA" || this.targetEl.tagName === "INPUT")
|
|
16661
|
+
/** @type {HTMLInputElement} */ this.targetEl.value = this.getHTML();
|
|
16251
16662
|
}
|
|
16252
16663
|
};
|
|
16253
16664
|
//#endregion
|
|
@@ -16504,6 +16915,6 @@ function resolveElements(selector) {
|
|
|
16504
16915
|
return [];
|
|
16505
16916
|
}
|
|
16506
16917
|
//#endregion
|
|
16507
|
-
export { Context, ELEMENT_NODE, TEXT_NODE, WrappedRange, _buttonRegistry, alignCenterBtn, alignJustifyBtn, alignLeftBtn, alignRightBtn, all, ancestors, any, backColorBtn, boldBtn, checklistBtn, children, chunk, clamp, closest, closestPara, codeviewBtn, collapsedRange, compose, createElement, currentRange, debounce, AutumnNote as default, defaultOptions, defaultToolbar, directionBtn, emojiBtn, env, findBtn, findReplaceBtn, first, flatten, fontFamilyBtn, fontSizeBtn, foreColorBtn, fromNativeRange, fullscreenBtn, getButton, groupBy, hrBtn, iconBtn, identity, imageBtn, indentBtn, initial, inlineCodeBtn, insertAfter, isAnchor, isEditable, isElement, isEmpty, isFunction, isImage, isInline, isInsideEditable, isKey, isLi, isList, isModifier, isNil, isPara, isPlainObject, isSelectionInside, isString, isTable, isText, isVoid, italicBtn, key, last, lineHeightBtn, linkBtn, locales, mergeDeep, nextElement, nodeValue, olBtn, on, outdentBtn, outerHtml, paragraphStyleBtn, placeCaret, prevElement, printBtn, rangeFromElement, rect2bnd, redoBtn, registerButton, remove, removeFormatBtn, resolveLocale, sanitiseHTML, sanitiseUrl, shortcutsBtn, splitText, strikeBtn, subscriptBtn, superscriptBtn, tableBtn, tail, throttle, trapFocus, ulBtn, underlineBtn, undoBtn, unique, unwrap, videoBtn, withSavedRange, wrap };
|
|
16918
|
+
export { Context, ELEMENT_NODE, TEXT_NODE, WrappedRange, _buttonRegistry, alignCenterBtn, alignJustifyBtn, alignLeftBtn, alignRightBtn, all, ancestors, any, backColorBtn, boldBtn, checklistBtn, children, chunk, clamp, closest, closestPara, codeviewBtn, collapsedRange, compose, createElement, currentRange, debounce, AutumnNote as default, defaultOptions, defaultToolbar, directionBtn, emojiBtn, env, findBtn, findReplaceBtn, first, flatten, fontFamilyBtn, fontSizeBtn, foreColorBtn, fromNativeRange, fullscreenBtn, getButton, groupBy, hrBtn, iconBtn, identity, imageBtn, indentBtn, initial, inlineCodeBtn, insertAfter, isAnchor, isEditable, isElement, isEmpty, isFunction, isImage, isInline, isInsideEditable, isKey, isLi, isList, isModifier, isNil, isPara, isPlainObject, isSelectionInside, isString, isTable, isText, isVoid, italicBtn, key, last, lineHeightBtn, linkBtn, locales, makeDraggable, mergeDeep, nextElement, nodeValue, olBtn, on, outdentBtn, outerHtml, paragraphStyleBtn, placeCaret, prevElement, printBtn, rangeFromElement, rect2bnd, redoBtn, registerButton, remove, removeFormatBtn, resolveLocale, sanitiseHTML, sanitiseUrl, shortcutsBtn, splitText, strikeBtn, subscriptBtn, superscriptBtn, tableBtn, tail, throttle, trapFocus, ulBtn, underlineBtn, undoBtn, unique, unwrap, videoBtn, withSavedRange, wrap };
|
|
16508
16919
|
|
|
16509
16920
|
//# sourceMappingURL=autumnnote.es.js.map
|