autumnnote 1.4.2 → 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 +102 -21
- package/dist/autumnnote.css +324 -2
- package/dist/autumnnote.es.js +700 -228
- package/dist/autumnnote.es.js.map +1 -1
- package/dist/autumnnote.umd.js +691 -235
- package/dist/autumnnote.umd.js.map +1 -1
- package/package.json +8 -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 +4 -3
- 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,
|
|
@@ -1590,6 +1656,7 @@ var en = {
|
|
|
1590
1656
|
chooseHighlightColor: "Choose highlight color",
|
|
1591
1657
|
customColor: "Custom color",
|
|
1592
1658
|
insertTableLabel: "Insert Table",
|
|
1659
|
+
/** Map of paragraph-style value → label (only values needing translation) */
|
|
1593
1660
|
paragraphItems: {
|
|
1594
1661
|
p: "Normal",
|
|
1595
1662
|
blockquote: "Quote",
|
|
@@ -1632,6 +1699,7 @@ var en = {
|
|
|
1632
1699
|
widthPlaceholder: "560",
|
|
1633
1700
|
insertBtn: "Insert",
|
|
1634
1701
|
cancelBtn: "Cancel",
|
|
1702
|
+
/** @param {string} type */
|
|
1635
1703
|
detected: (type) => `Detected: ${type}`,
|
|
1636
1704
|
unknownFormat: "Unknown format — will try direct video embed",
|
|
1637
1705
|
invalidUrl: "Invalid URL — please enter a valid video link."
|
|
@@ -1794,9 +1862,13 @@ var en = {
|
|
|
1794
1862
|
},
|
|
1795
1863
|
statusbar: {
|
|
1796
1864
|
resizeHandle: "Resize editor",
|
|
1865
|
+
/** @param {number} n */
|
|
1797
1866
|
words: (n) => `Words: ${n}`,
|
|
1867
|
+
/** @param {number} n @param {number} max */
|
|
1798
1868
|
wordsLimit: (n, max) => `Words: ${n}/${max}`,
|
|
1869
|
+
/** @param {number} n */
|
|
1799
1870
|
chars: (n) => `Chars: ${n}`,
|
|
1871
|
+
/** @param {number} n @param {number} max */
|
|
1800
1872
|
charsLimit: (n, max) => `Chars: ${n}/${max}`
|
|
1801
1873
|
},
|
|
1802
1874
|
tooltips: {
|
|
@@ -1849,6 +1921,8 @@ var en = {
|
|
|
1849
1921
|
rowHeight: "Row Height",
|
|
1850
1922
|
tableBorderWidth: "Table Border Width",
|
|
1851
1923
|
deleteTable: "Delete Table",
|
|
1924
|
+
cellBackground: "Cell Background",
|
|
1925
|
+
noShading: "No Shading",
|
|
1852
1926
|
columnWidthPx: "Column Width (px)",
|
|
1853
1927
|
rowHeightPx: "Row Height (px)",
|
|
1854
1928
|
tableBorderWidthPx: "Table Border Width (px)",
|
|
@@ -1869,7 +1943,9 @@ var en = {
|
|
|
1869
1943
|
}
|
|
1870
1944
|
},
|
|
1871
1945
|
errors: {
|
|
1946
|
+
/** @param {string} type */
|
|
1872
1947
|
imageFormat: (type) => `Format "${type}" is not supported for display in web browsers. Please convert to JPEG, PNG, or WebP first.`,
|
|
1948
|
+
/** @param {number} maxSize */
|
|
1873
1949
|
imageSize: (maxSize) => `Image file is too large. Maximum allowed size is ${maxSize} MB.`
|
|
1874
1950
|
}
|
|
1875
1951
|
};
|
|
@@ -2202,6 +2278,8 @@ var locales = {
|
|
|
2202
2278
|
rowHeight: "Chiều cao hàng",
|
|
2203
2279
|
tableBorderWidth: "Độ rộng viền bảng",
|
|
2204
2280
|
deleteTable: "Xóa bảng",
|
|
2281
|
+
cellBackground: "Màu Nền Ô",
|
|
2282
|
+
noShading: "Xóa Màu Nền",
|
|
2205
2283
|
columnWidthPx: "Chiều rộng cột (px)",
|
|
2206
2284
|
rowHeightPx: "Chiều cao hàng (px)",
|
|
2207
2285
|
tableBorderWidthPx: "Độ rộng viền bảng (px)",
|
|
@@ -4403,7 +4481,10 @@ function renderLayout(targetEl, options) {
|
|
|
4403
4481
|
else if (options.minHeight) editable.style.minHeight = `${options.minHeight}px`;
|
|
4404
4482
|
if (options.maxHeight) editable.style.maxHeight = `${options.maxHeight}px`;
|
|
4405
4483
|
container.appendChild(editable);
|
|
4406
|
-
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
|
+
}
|
|
4407
4488
|
if (options.readOnly) {
|
|
4408
4489
|
container.classList.add("an-disabled");
|
|
4409
4490
|
editable.querySelectorAll("ul.an-checklist input[type=\"checkbox\"]").forEach((cb) => {
|
|
@@ -4441,7 +4522,7 @@ var History = class {
|
|
|
4441
4522
|
constructor(editable, limit = 100) {
|
|
4442
4523
|
this.editable = editable;
|
|
4443
4524
|
this._limit = limit;
|
|
4444
|
-
/** @type {Array<{html: string,
|
|
4525
|
+
/** @type {Array<{html: string, images?: Record<string,string>, sel: {start: number, end: number}|null}>} */
|
|
4445
4526
|
this.stack = [];
|
|
4446
4527
|
this.stackOffset = -1;
|
|
4447
4528
|
this._savePoint();
|
|
@@ -4640,8 +4721,7 @@ var History = class {
|
|
|
4640
4721
|
* Build an HTML table with the given number of columns and rows, optionally including a header row.
|
|
4641
4722
|
* @param {number} cols - Number of columns in each row.
|
|
4642
4723
|
* @param {number} rows - Total number of rows to create (including header when `headerRow` is true).
|
|
4643
|
-
* @param {{ headerRow?: boolean }} [opts] - Options
|
|
4644
|
-
* @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.
|
|
4645
4725
|
* @returns {HTMLTableElement} The constructed `<table>` element with a `<tbody>` and optional `<thead>`; each cell contains a `<br>` placeholder.
|
|
4646
4726
|
*/
|
|
4647
4727
|
function createTable(cols, rows, opts = {}) {
|
|
@@ -4675,7 +4755,6 @@ function createTable(cols, rows, opts = {}) {
|
|
|
4675
4755
|
* @param {number} cols - Number of columns for the new table.
|
|
4676
4756
|
* @param {number} rows - Number of rows for the new table.
|
|
4677
4757
|
* @param {{ headerRow?: boolean }} [opts] - Options for table creation.
|
|
4678
|
-
* @param {boolean} [opts.headerRow=false] - If true, include a header row as the first row.
|
|
4679
4758
|
*/
|
|
4680
4759
|
function insertTable(cols, rows, opts = {}) {
|
|
4681
4760
|
if (cols <= 0 || rows <= 0) return;
|
|
@@ -4698,7 +4777,7 @@ function insertTable(cols, rows, opts = {}) {
|
|
|
4698
4777
|
"PRE"
|
|
4699
4778
|
]);
|
|
4700
4779
|
let anchor = range.startContainer;
|
|
4701
|
-
if (anchor.nodeType === 3) anchor = anchor.parentElement;
|
|
4780
|
+
if (anchor && anchor.nodeType === 3) anchor = anchor.parentElement;
|
|
4702
4781
|
while (anchor && !BLOCK.has(anchor.tagName?.toUpperCase()) && anchor.parentElement) anchor = anchor.parentElement;
|
|
4703
4782
|
if (anchor && BLOCK.has(anchor.tagName?.toUpperCase()) && anchor.parentNode) {
|
|
4704
4783
|
anchor.after(table);
|
|
@@ -4816,7 +4895,7 @@ function handleKeydown(event, editable, options = {}) {
|
|
|
4816
4895
|
const textNode = r.startContainer;
|
|
4817
4896
|
if (r.startOffset === 0 && isFAIcon(textNode.previousSibling)) {
|
|
4818
4897
|
event.preventDefault();
|
|
4819
|
-
textNode.previousSibling.remove();
|
|
4898
|
+
/** @type {ChildNode} */ textNode.previousSibling.remove();
|
|
4820
4899
|
return true;
|
|
4821
4900
|
}
|
|
4822
4901
|
if (r.startOffset === 1 && textNode.textContent === "" && isFAIcon(textNode.previousSibling)) {
|
|
@@ -4962,7 +5041,7 @@ function handleKeydown(event, editable, options = {}) {
|
|
|
4962
5041
|
}
|
|
4963
5042
|
return false;
|
|
4964
5043
|
}
|
|
4965
|
-
const videoWrapper = el && el.closest
|
|
5044
|
+
const videoWrapper = el && el.closest(".an-video-wrapper");
|
|
4966
5045
|
if (videoWrapper) {
|
|
4967
5046
|
event.preventDefault();
|
|
4968
5047
|
const p = document.createElement("p");
|
|
@@ -4976,7 +5055,7 @@ function handleKeydown(event, editable, options = {}) {
|
|
|
4976
5055
|
sel.addRange(nr);
|
|
4977
5056
|
return true;
|
|
4978
5057
|
}
|
|
4979
|
-
const checkLi = el && el.closest
|
|
5058
|
+
const checkLi = el && el.closest(".an-checklist li");
|
|
4980
5059
|
if (checkLi) {
|
|
4981
5060
|
event.preventDefault();
|
|
4982
5061
|
const ul = checkLi.closest(".an-checklist");
|
|
@@ -5076,8 +5155,9 @@ function htmlToMarkdown(html) {
|
|
|
5076
5155
|
function _domToMd(node, depth = 0) {
|
|
5077
5156
|
if (node.nodeType === 3) return node.textContent.replace(/\s+/g, " ");
|
|
5078
5157
|
if (node.nodeType !== 1) return "";
|
|
5079
|
-
const
|
|
5080
|
-
const
|
|
5158
|
+
const el = node;
|
|
5159
|
+
const tag = el.nodeName.toLowerCase();
|
|
5160
|
+
const inner = () => Array.from(el.childNodes).map((n) => _domToMd(n, depth)).join("");
|
|
5081
5161
|
switch (tag) {
|
|
5082
5162
|
case "p":
|
|
5083
5163
|
case "div": return `\n\n${inner()}\n\n`;
|
|
@@ -5095,34 +5175,34 @@ function _domToMd(node, depth = 0) {
|
|
|
5095
5175
|
case "del":
|
|
5096
5176
|
case "s":
|
|
5097
5177
|
case "strike": return `~~${inner()}~~`;
|
|
5098
|
-
case "sup": return `^${inner()}
|
|
5099
|
-
case "sub": return `~${inner()}
|
|
5178
|
+
case "sup": return `^${inner()}^`;
|
|
5179
|
+
case "sub": return `~${inner()}~`;
|
|
5100
5180
|
case "code":
|
|
5101
|
-
if (
|
|
5181
|
+
if (el.closest("pre")) return inner();
|
|
5102
5182
|
return `\`${inner()}\``;
|
|
5103
5183
|
case "pre": {
|
|
5104
|
-
const codeEl =
|
|
5184
|
+
const codeEl = el.querySelector("code");
|
|
5105
5185
|
const langMatch = (codeEl && codeEl.className || "").match(/language-(\S+)/);
|
|
5106
|
-
return `\n\n\`\`\`${langMatch ? langMatch[1] : ""}\n${(codeEl ||
|
|
5186
|
+
return `\n\n\`\`\`${langMatch ? langMatch[1] : ""}\n${(codeEl || el).textContent || ""}\n\`\`\`\n\n`;
|
|
5107
5187
|
}
|
|
5108
5188
|
case "blockquote": return `\n\n${inner().trim().split("\n").map((l) => `> ${l}`).join("\n")}\n\n`;
|
|
5109
5189
|
case "a": {
|
|
5110
|
-
const href =
|
|
5190
|
+
const href = el.getAttribute("href") || "";
|
|
5111
5191
|
return `[${inner()}](${href})`;
|
|
5112
5192
|
}
|
|
5113
5193
|
case "img": {
|
|
5114
|
-
const src =
|
|
5115
|
-
return ``;
|
|
5116
5196
|
}
|
|
5117
5197
|
case "ul": {
|
|
5118
|
-
const items = Array.from(
|
|
5198
|
+
const items = Array.from(el.querySelectorAll(":scope > li"));
|
|
5119
5199
|
if (!items.length) return inner();
|
|
5120
5200
|
const indent = " ".repeat(depth);
|
|
5121
5201
|
const lines = items.map((li) => `${indent}- ${_domToMd(li, depth + 1).trim()}`).join("\n");
|
|
5122
5202
|
return depth === 0 ? `\n\n${lines}\n\n` : `\n${lines}`;
|
|
5123
5203
|
}
|
|
5124
5204
|
case "ol": {
|
|
5125
|
-
const items = Array.from(
|
|
5205
|
+
const items = Array.from(el.querySelectorAll(":scope > li"));
|
|
5126
5206
|
if (!items.length) return inner();
|
|
5127
5207
|
const indent = " ".repeat(depth);
|
|
5128
5208
|
const lines = items.map((li, i) => `${indent}${i + 1}. ${_domToMd(li, depth + 1).trim()}`).join("\n");
|
|
@@ -5131,7 +5211,7 @@ function _domToMd(node, depth = 0) {
|
|
|
5131
5211
|
case "li": return inner();
|
|
5132
5212
|
case "hr": return "\n\n---\n\n";
|
|
5133
5213
|
case "table": {
|
|
5134
|
-
const rows = Array.from(
|
|
5214
|
+
const rows = Array.from(el.querySelectorAll("tr"));
|
|
5135
5215
|
if (!rows.length) return inner();
|
|
5136
5216
|
const cellTexts = rows.map((tr) => Array.from(tr.querySelectorAll("th, td")).map((c) => c.textContent.trim().replace(/\|/g, "\\|")));
|
|
5137
5217
|
const cols = Math.max(...cellTexts.map((r) => r.length));
|
|
@@ -5279,6 +5359,47 @@ function _escAttr(v) {
|
|
|
5279
5359
|
return String(v).replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
5280
5360
|
}
|
|
5281
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
|
|
5282
5403
|
//#region src/js/module/Editor.js
|
|
5283
5404
|
/**
|
|
5284
5405
|
* Editor.js - Core editing command module
|
|
@@ -5333,7 +5454,8 @@ var Editor = class {
|
|
|
5333
5454
|
if (!r.collapsed) return;
|
|
5334
5455
|
const sc = r.startContainer;
|
|
5335
5456
|
if (sc.nodeType !== Node.ELEMENT_NODE) return;
|
|
5336
|
-
const
|
|
5457
|
+
const scEl = sc;
|
|
5458
|
+
const li = scEl.matches(".an-checklist li") ? scEl : null;
|
|
5337
5459
|
if (!li) return;
|
|
5338
5460
|
const cb = li.querySelector("input[type=\"checkbox\"]");
|
|
5339
5461
|
if (!cb) return;
|
|
@@ -5373,7 +5495,7 @@ var Editor = class {
|
|
|
5373
5495
|
return;
|
|
5374
5496
|
}
|
|
5375
5497
|
const target = e.target;
|
|
5376
|
-
if (target && (target.nodeName === "IFRAME" || target.closest
|
|
5498
|
+
if (target && (target.nodeName === "IFRAME" || target.closest(".an-video-wrapper"))) e.preventDefault();
|
|
5377
5499
|
}), on(editable, "drop", (e) => {
|
|
5378
5500
|
if (isReadOnly()) e.preventDefault();
|
|
5379
5501
|
}));
|
|
@@ -5387,9 +5509,12 @@ var Editor = class {
|
|
|
5387
5509
|
}
|
|
5388
5510
|
let node = sel.getRangeAt(0).startContainer;
|
|
5389
5511
|
if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
|
|
5390
|
-
if (node
|
|
5391
|
-
|
|
5392
|
-
|
|
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
|
+
}
|
|
5393
5518
|
};
|
|
5394
5519
|
const onCompositionEnd = () => {
|
|
5395
5520
|
const tag = _compositionSupSub;
|
|
@@ -5399,7 +5524,8 @@ var Editor = class {
|
|
|
5399
5524
|
if (!sel || !sel.rangeCount) return;
|
|
5400
5525
|
let node = sel.getRangeAt(0).startContainer;
|
|
5401
5526
|
if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
|
|
5402
|
-
|
|
5527
|
+
const el = node;
|
|
5528
|
+
if (!(el && (tag === "superscript" ? el.closest("sup") : el.closest("sub")))) document.execCommand(tag);
|
|
5403
5529
|
};
|
|
5404
5530
|
this._disposers.push(on(editable, "compositionstart", onCompositionStart), on(editable, "compositionend", onCompositionEnd));
|
|
5405
5531
|
}
|
|
@@ -5488,6 +5614,7 @@ var Editor = class {
|
|
|
5488
5614
|
}
|
|
5489
5615
|
afterCommand() {
|
|
5490
5616
|
this._cleanOrphanedFigures();
|
|
5617
|
+
this._ensureTrailingParagraph();
|
|
5491
5618
|
this.context.invoke("toolbar.refresh");
|
|
5492
5619
|
this.context.invoke("statusbar.update");
|
|
5493
5620
|
this._scheduleSnapshot();
|
|
@@ -5514,6 +5641,31 @@ var Editor = class {
|
|
|
5514
5641
|
if (!fig.querySelector("img")) fig.parentNode.removeChild(fig);
|
|
5515
5642
|
});
|
|
5516
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
|
+
}
|
|
5517
5669
|
focus() {
|
|
5518
5670
|
this.context.layoutInfo.editable.focus();
|
|
5519
5671
|
}
|
|
@@ -5697,10 +5849,24 @@ var Editor = class {
|
|
|
5697
5849
|
this.context.print();
|
|
5698
5850
|
}
|
|
5699
5851
|
/**
|
|
5700
|
-
* @param {string} tagName - e.g. 'h1', 'p', 'blockquote'
|
|
5852
|
+
* @param {string} tagName - e.g. 'h1', 'p', 'blockquote', 'pre'
|
|
5701
5853
|
*/
|
|
5702
5854
|
formatBlock(tagName) {
|
|
5703
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
|
+
}
|
|
5704
5870
|
this.afterCommand();
|
|
5705
5871
|
}
|
|
5706
5872
|
/**
|
|
@@ -5757,8 +5923,8 @@ var Editor = class {
|
|
|
5757
5923
|
if (openInNewTab) {
|
|
5758
5924
|
const link = this._getClosestAnchor();
|
|
5759
5925
|
if (link) {
|
|
5760
|
-
link.setAttribute("target", "_blank");
|
|
5761
|
-
link.setAttribute("rel", "noopener noreferrer");
|
|
5926
|
+
/** @type {Element} */ link.setAttribute("target", "_blank");
|
|
5927
|
+
/** @type {Element} */ link.setAttribute("rel", "noopener noreferrer");
|
|
5762
5928
|
}
|
|
5763
5929
|
}
|
|
5764
5930
|
}
|
|
@@ -6040,13 +6206,13 @@ var Toolbar = class {
|
|
|
6040
6206
|
else openPopup();
|
|
6041
6207
|
});
|
|
6042
6208
|
const d2 = on(grid, "mouseover", (e) => {
|
|
6043
|
-
const cell = e.target
|
|
6209
|
+
const cell = e.target?.closest(".an-table-cell");
|
|
6044
6210
|
if (!cell) return;
|
|
6045
6211
|
setHighlight(+cell.getAttribute("data-row"), +cell.getAttribute("data-col"));
|
|
6046
6212
|
});
|
|
6047
6213
|
const d3 = on(grid, "mouseleave", () => setHighlight(0, 0));
|
|
6048
6214
|
const d4 = on(grid, "click", (e) => {
|
|
6049
|
-
const cell = e.target
|
|
6215
|
+
const cell = e.target?.closest(".an-table-cell");
|
|
6050
6216
|
if (!cell) return;
|
|
6051
6217
|
const rows = +cell.getAttribute("data-row");
|
|
6052
6218
|
const cols = +cell.getAttribute("data-col");
|
|
@@ -6209,11 +6375,17 @@ var Toolbar = class {
|
|
|
6209
6375
|
e.preventDefault();
|
|
6210
6376
|
});
|
|
6211
6377
|
const d3b = on(swatches, "click", (e) => {
|
|
6212
|
-
const sw = e.target
|
|
6213
|
-
if (sw) applyColor(
|
|
6378
|
+
const sw = e.target?.closest(".an-color-swatch");
|
|
6379
|
+
if (sw) applyColor(
|
|
6380
|
+
/** @type {HTMLElement} */
|
|
6381
|
+
sw.dataset.color
|
|
6382
|
+
);
|
|
6214
6383
|
});
|
|
6215
6384
|
const d4 = on(colorInput, "change", (e) => {
|
|
6216
|
-
applyColor(
|
|
6385
|
+
applyColor(
|
|
6386
|
+
/** @type {HTMLInputElement} */
|
|
6387
|
+
e.target.value
|
|
6388
|
+
);
|
|
6217
6389
|
});
|
|
6218
6390
|
const d5 = on(document, "click", (e) => {
|
|
6219
6391
|
if (isOpen && !wrap.contains(e.target) && !popup.contains(e.target)) closePopup();
|
|
@@ -6348,15 +6520,17 @@ var Toolbar = class {
|
|
|
6348
6520
|
this.el.querySelectorAll("button[data-btn]").forEach((btn) => {
|
|
6349
6521
|
const def = btnMap.get(btn.getAttribute("data-btn"));
|
|
6350
6522
|
if (def && typeof def.isActive === "function") btn.classList.toggle("active", !!def.isActive(this.context));
|
|
6351
|
-
if (def && typeof def.isDisabled === "function")
|
|
6523
|
+
if (def && typeof def.isDisabled === "function")
|
|
6524
|
+
/** @type {HTMLButtonElement} */ btn.disabled = !!def.isDisabled(this.context);
|
|
6352
6525
|
});
|
|
6353
6526
|
this.el.querySelectorAll("select[data-btn]").forEach((select) => {
|
|
6354
6527
|
const def = btnMap.get(select.getAttribute("data-btn"));
|
|
6355
6528
|
if (!def || typeof def.getValue !== "function") return;
|
|
6356
6529
|
let raw = (def.getValue(this.context) || "").replace(/["']/g, "").trim();
|
|
6357
6530
|
if (!raw) raw = this.options.defaultFontFamily || this.options.fontFamilies && this.options.fontFamilies[0] || "";
|
|
6358
|
-
const
|
|
6359
|
-
|
|
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 : "";
|
|
6360
6534
|
});
|
|
6361
6535
|
}
|
|
6362
6536
|
/**
|
|
@@ -7150,8 +7324,13 @@ var LinkDialog = class {
|
|
|
7150
7324
|
"aria-label": L.ariaLabel
|
|
7151
7325
|
});
|
|
7152
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>`;
|
|
7153
7330
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7154
7331
|
title.textContent = L.title;
|
|
7332
|
+
header.appendChild(iconEl);
|
|
7333
|
+
header.appendChild(title);
|
|
7155
7334
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7156
7335
|
urlLabel.textContent = L.url;
|
|
7157
7336
|
const urlInput = createElement("input", {
|
|
@@ -7196,8 +7375,9 @@ var LinkDialog = class {
|
|
|
7196
7375
|
cancelBtn.textContent = L.cancelBtn;
|
|
7197
7376
|
btnRow.appendChild(insertBtn);
|
|
7198
7377
|
btnRow.appendChild(cancelBtn);
|
|
7199
|
-
box.append(
|
|
7378
|
+
box.append(header, urlLabel, urlInput, textLabel, textInput, tabLabel, btnRow);
|
|
7200
7379
|
overlay.appendChild(box);
|
|
7380
|
+
makeDraggable(header, box);
|
|
7201
7381
|
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7202
7382
|
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7203
7383
|
const d3 = on(overlay, "click", (e) => {
|
|
@@ -7327,8 +7507,13 @@ var ImageDialog = class {
|
|
|
7327
7507
|
"aria-label": L.ariaLabel
|
|
7328
7508
|
});
|
|
7329
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>`;
|
|
7330
7513
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7331
7514
|
title.textContent = L.title;
|
|
7515
|
+
header.appendChild(iconEl);
|
|
7516
|
+
header.appendChild(title);
|
|
7332
7517
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7333
7518
|
urlLabel.textContent = L.imageUrl;
|
|
7334
7519
|
const urlInput = createElement("input", {
|
|
@@ -7347,7 +7532,7 @@ var ImageDialog = class {
|
|
|
7347
7532
|
autocomplete: "off"
|
|
7348
7533
|
});
|
|
7349
7534
|
this._altInput = altInput;
|
|
7350
|
-
box.append(
|
|
7535
|
+
box.append(header, urlLabel, urlInput, altLabel, altInput);
|
|
7351
7536
|
const alignLabel = createElement("label", { class: "an-label" });
|
|
7352
7537
|
alignLabel.textContent = L.alignment;
|
|
7353
7538
|
const alignRow = createElement("div", { class: "an-align-row" });
|
|
@@ -7416,6 +7601,7 @@ var ImageDialog = class {
|
|
|
7416
7601
|
btnRow.appendChild(cancelBtn);
|
|
7417
7602
|
box.append(btnRow);
|
|
7418
7603
|
overlay.appendChild(box);
|
|
7604
|
+
makeDraggable(header, box);
|
|
7419
7605
|
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7420
7606
|
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7421
7607
|
const d3 = on(overlay, "click", (e) => {
|
|
@@ -7553,8 +7739,13 @@ var VideoDialog = class {
|
|
|
7553
7739
|
"aria-label": L.ariaLabel
|
|
7554
7740
|
});
|
|
7555
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>`;
|
|
7556
7745
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7557
7746
|
title.textContent = L.title;
|
|
7747
|
+
header.appendChild(iconEl);
|
|
7748
|
+
header.appendChild(title);
|
|
7558
7749
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7559
7750
|
urlLabel.textContent = L.videoUrl;
|
|
7560
7751
|
const urlInput = createElement("input", {
|
|
@@ -7590,8 +7781,9 @@ var VideoDialog = class {
|
|
|
7590
7781
|
cancelBtn.textContent = L.cancelBtn;
|
|
7591
7782
|
btnRow.appendChild(insertBtn);
|
|
7592
7783
|
btnRow.appendChild(cancelBtn);
|
|
7593
|
-
box.append(
|
|
7784
|
+
box.append(header, urlLabel, urlInput, hintEl, widthLabel, widthInput, btnRow);
|
|
7594
7785
|
overlay.appendChild(box);
|
|
7786
|
+
makeDraggable(header, box);
|
|
7595
7787
|
const d0 = on(urlInput, "input", () => {
|
|
7596
7788
|
const info = this._parseVideoUrl(urlInput.value.trim());
|
|
7597
7789
|
hintEl.textContent = info ? this.context.locale.videoDialog.detected(info.type) : urlInput.value ? this.context.locale.videoDialog.unknownFormat : "";
|
|
@@ -7774,7 +7966,7 @@ var ImageResizer = class {
|
|
|
7774
7966
|
};
|
|
7775
7967
|
this._disposers.push(on(editable, "click", (e) => this._onEditorClick(e)), on(editable, "contextmenu", (e) => {
|
|
7776
7968
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
7777
|
-
const img = e.target
|
|
7969
|
+
const img = e.target?.closest("img");
|
|
7778
7970
|
if (img) this._select(img);
|
|
7779
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 }));
|
|
7780
7972
|
return this;
|
|
@@ -8184,12 +8376,12 @@ var LinkTooltip = class {
|
|
|
8184
8376
|
document.body.appendChild(this._el);
|
|
8185
8377
|
const editable = this.context.layoutInfo.editable;
|
|
8186
8378
|
this._disposers.push(on(editable, "mouseover", (e) => {
|
|
8187
|
-
const anchor = e.target
|
|
8379
|
+
const anchor = e.target?.closest("a[href]");
|
|
8188
8380
|
if (anchor && editable.contains(anchor)) this._scheduleShow(anchor);
|
|
8189
8381
|
}), on(editable, "mouseout", (e) => {
|
|
8190
8382
|
const to = e.relatedTarget;
|
|
8191
8383
|
if (!to || !editable.contains(to) && !this._el.contains(to)) this._scheduleHide();
|
|
8192
|
-
}));
|
|
8384
|
+
}), on(window, "scroll", () => this._hide(), { passive: true }), on(window, "resize", () => this._hide(), { passive: true }));
|
|
8193
8385
|
return this;
|
|
8194
8386
|
}
|
|
8195
8387
|
destroy() {
|
|
@@ -8374,14 +8566,15 @@ var ImageTooltip = class {
|
|
|
8374
8566
|
const editable = this.context.layoutInfo.editable;
|
|
8375
8567
|
this._disposers.push(on(editable, "mouseover", (e) => {
|
|
8376
8568
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
8377
|
-
const img = e.target
|
|
8569
|
+
const img = e.target?.closest("img");
|
|
8378
8570
|
if (img && editable.contains(img) && !img.closest("a[href]")) this._scheduleShow(img);
|
|
8379
8571
|
}, { passive: true }), on(editable, "mouseout", (e) => {
|
|
8380
8572
|
const to = e.relatedTarget;
|
|
8381
8573
|
if (!to || !editable.contains(to) && !this._el.contains(to)) this._scheduleHide();
|
|
8382
8574
|
}, { passive: true }), on(document, "click", (e) => {
|
|
8383
|
-
|
|
8384
|
-
|
|
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 }));
|
|
8385
8578
|
return this;
|
|
8386
8579
|
}
|
|
8387
8580
|
destroy() {
|
|
@@ -8465,7 +8658,7 @@ var ImageTooltip = class {
|
|
|
8465
8658
|
clearTimeout(this._hideTimer);
|
|
8466
8659
|
this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY$3);
|
|
8467
8660
|
}
|
|
8468
|
-
_show(
|
|
8661
|
+
_show(_img) {
|
|
8469
8662
|
this._el.style.display = "flex";
|
|
8470
8663
|
requestAnimationFrame(() => {
|
|
8471
8664
|
if (this._activeImg) this._positionNear(this._activeImg);
|
|
@@ -8657,14 +8850,16 @@ var VideoTooltip = class {
|
|
|
8657
8850
|
const editable = this.context.layoutInfo.editable;
|
|
8658
8851
|
this._disposers.push(on(editable, "mouseover", (e) => {
|
|
8659
8852
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
8660
|
-
const
|
|
8853
|
+
const target = e.target;
|
|
8854
|
+
const wrapper = target && target.closest ? target.closest(".an-video-wrapper") : null;
|
|
8661
8855
|
if (wrapper && editable.contains(wrapper)) this._scheduleShow(wrapper);
|
|
8662
8856
|
}, { passive: true }), on(editable, "mouseout", (e) => {
|
|
8663
8857
|
const to = e.relatedTarget;
|
|
8664
8858
|
if (!to || !editable.contains(to) && !this._el.contains(to)) this._scheduleHide();
|
|
8665
8859
|
}, { passive: true }), on(document, "click", (e) => {
|
|
8666
|
-
|
|
8667
|
-
|
|
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 }));
|
|
8668
8863
|
return this;
|
|
8669
8864
|
}
|
|
8670
8865
|
destroy() {
|
|
@@ -8744,7 +8939,7 @@ var VideoTooltip = class {
|
|
|
8744
8939
|
if (this._hideTimer) return;
|
|
8745
8940
|
this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY$2);
|
|
8746
8941
|
}
|
|
8747
|
-
_show(
|
|
8942
|
+
_show(_wrapper) {
|
|
8748
8943
|
this._el.style.display = "flex";
|
|
8749
8944
|
requestAnimationFrame(() => {
|
|
8750
8945
|
if (this._activeWrapper) this._positionNear(this._activeWrapper);
|
|
@@ -8968,8 +9163,35 @@ var ICONS$2 = {
|
|
|
8968
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>`,
|
|
8969
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>`,
|
|
8970
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>`,
|
|
8971
|
-
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>`
|
|
8972
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
|
+
];
|
|
8973
9195
|
var TableTooltip = class {
|
|
8974
9196
|
/** @param {import('../Context.js').Context} context */
|
|
8975
9197
|
constructor(context) {
|
|
@@ -8984,6 +9206,9 @@ var TableTooltip = class {
|
|
|
8984
9206
|
this._sizeApply = null;
|
|
8985
9207
|
this._sizeTitleEl = null;
|
|
8986
9208
|
this._sizeInputEl = null;
|
|
9209
|
+
this._shadePopover = null;
|
|
9210
|
+
this._shadeTitleEl = null;
|
|
9211
|
+
this._shadeColorStrip = null;
|
|
8987
9212
|
this._selectMode = false;
|
|
8988
9213
|
this._selectedCells = [];
|
|
8989
9214
|
this._selectStart = null;
|
|
@@ -8996,6 +9221,8 @@ var TableTooltip = class {
|
|
|
8996
9221
|
document.body.appendChild(this._el);
|
|
8997
9222
|
this._sizePopover = this._buildSizePopover();
|
|
8998
9223
|
document.body.appendChild(this._sizePopover);
|
|
9224
|
+
this._shadePopover = this._buildCellShadePopover();
|
|
9225
|
+
document.body.appendChild(this._shadePopover);
|
|
8999
9226
|
const editable = this.context.layoutInfo.editable;
|
|
9000
9227
|
this._editable = editable;
|
|
9001
9228
|
const onSelMousedown = (e) => {
|
|
@@ -9022,10 +9249,13 @@ var TableTooltip = class {
|
|
|
9022
9249
|
this._disposers.push(on(editable, "mousedown", onSelMousedown), on(editable, "mousemove", onSelMousemove), on(document, "mouseup", onSelMouseup));
|
|
9023
9250
|
this._disposers.push(on(editable, "mouseover", (e) => {
|
|
9024
9251
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
9025
|
-
const table = e.target
|
|
9252
|
+
const table = e.target?.closest("table");
|
|
9026
9253
|
if (table && editable.contains(table)) {
|
|
9027
|
-
const cell = e.target
|
|
9028
|
-
if (cell)
|
|
9254
|
+
const cell = e.target?.closest("td, th");
|
|
9255
|
+
if (cell) {
|
|
9256
|
+
this._activeCell = cell;
|
|
9257
|
+
this._syncShadeStrip();
|
|
9258
|
+
}
|
|
9029
9259
|
this._scheduleShow(table);
|
|
9030
9260
|
}
|
|
9031
9261
|
}, { passive: true }), on(editable, "mouseout", (e) => {
|
|
@@ -9033,9 +9263,10 @@ var TableTooltip = class {
|
|
|
9033
9263
|
const to = e.relatedTarget;
|
|
9034
9264
|
if (!to || !editable.contains(to) && !this._el.contains(to) && !(this._sizePopover && this._sizePopover.contains(to))) this._scheduleHide();
|
|
9035
9265
|
}, { passive: true }), on(document, "click", (e) => {
|
|
9036
|
-
|
|
9037
|
-
if (this.
|
|
9038
|
-
|
|
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 }));
|
|
9039
9270
|
this._initResize();
|
|
9040
9271
|
return this;
|
|
9041
9272
|
}
|
|
@@ -9165,6 +9396,8 @@ var TableTooltip = class {
|
|
|
9165
9396
|
this._el = null;
|
|
9166
9397
|
if (this._sizePopover && this._sizePopover.parentNode) this._sizePopover.parentNode.removeChild(this._sizePopover);
|
|
9167
9398
|
this._sizePopover = null;
|
|
9399
|
+
if (this._shadePopover && this._shadePopover.parentNode) this._shadePopover.parentNode.removeChild(this._shadePopover);
|
|
9400
|
+
this._shadePopover = null;
|
|
9168
9401
|
}
|
|
9169
9402
|
_buildTooltip() {
|
|
9170
9403
|
const L = this.context.locale.tooltips.table;
|
|
@@ -9192,6 +9425,24 @@ var TableTooltip = class {
|
|
|
9192
9425
|
el.appendChild(this._makeBtn(ICONS$2.mergeCells, L.mergeCells, () => this._mergeCells()));
|
|
9193
9426
|
el.appendChild(this._makeBtn(ICONS$2.unmergeCells, L.unmergeCells, () => this._unmergeCells()));
|
|
9194
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());
|
|
9195
9446
|
el.appendChild(this._makeBtn(ICONS$2.colWidth, L.columnWidth, () => this._openSizePopover("col")));
|
|
9196
9447
|
el.appendChild(this._makeBtn(ICONS$2.rowHeight, L.rowHeight, () => this._openSizePopover("row")));
|
|
9197
9448
|
el.appendChild(this._makeBtn(ICONS$2.tableBorder, L.tableBorderWidth, () => this._openSizePopover("border")));
|
|
@@ -9200,6 +9451,7 @@ var TableTooltip = class {
|
|
|
9200
9451
|
this._disposers.push(on(el, "mouseenter", () => this._clearTimers()), on(el, "mouseleave", () => {
|
|
9201
9452
|
if (this._selectMode) return;
|
|
9202
9453
|
if (this._sizePopover && this._sizePopover.style.display !== "none") return;
|
|
9454
|
+
if (this._shadePopover && this._shadePopover.style.display !== "none") return;
|
|
9203
9455
|
this._scheduleHide();
|
|
9204
9456
|
}));
|
|
9205
9457
|
return el;
|
|
@@ -9246,10 +9498,16 @@ var TableTooltip = class {
|
|
|
9246
9498
|
_show() {
|
|
9247
9499
|
if (!this._activeTable) return;
|
|
9248
9500
|
this._el.style.display = "flex";
|
|
9501
|
+
this._syncShadeStrip();
|
|
9249
9502
|
requestAnimationFrame(() => {
|
|
9250
9503
|
if (this._activeTable) this._positionNear(this._activeTable);
|
|
9251
9504
|
});
|
|
9252
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
|
+
}
|
|
9253
9511
|
_hide() {
|
|
9254
9512
|
this._el.style.display = "none";
|
|
9255
9513
|
this._activeTable = null;
|
|
@@ -9288,7 +9546,7 @@ var TableTooltip = class {
|
|
|
9288
9546
|
if (sel && sel.rangeCount) {
|
|
9289
9547
|
let container = sel.getRangeAt(0).commonAncestorContainer;
|
|
9290
9548
|
if (container.nodeType === 3) container = container.parentElement;
|
|
9291
|
-
const cellFromSel = container && container.closest
|
|
9549
|
+
const cellFromSel = container && container.closest("td, th");
|
|
9292
9550
|
if (cellFromSel && this._activeTable && this._activeTable.contains(cellFromSel)) return cellFromSel;
|
|
9293
9551
|
}
|
|
9294
9552
|
return this._activeCell || this._activeTable && this._activeTable.querySelector("td, th");
|
|
@@ -9615,14 +9873,16 @@ var TableTooltip = class {
|
|
|
9615
9873
|
});
|
|
9616
9874
|
const d2 = on(cancelBtn, "click", () => this._hideSizePopover());
|
|
9617
9875
|
const d3 = on(inputEl, "keydown", (e) => {
|
|
9618
|
-
|
|
9876
|
+
const ke = e;
|
|
9877
|
+
if (ke.key === "Enter") {
|
|
9619
9878
|
e.preventDefault();
|
|
9620
9879
|
applyBtn.click();
|
|
9621
9880
|
}
|
|
9622
|
-
if (
|
|
9881
|
+
if (ke.key === "Escape") this._hideSizePopover();
|
|
9623
9882
|
});
|
|
9624
9883
|
const d4 = on(document, "click", (e) => {
|
|
9625
|
-
|
|
9884
|
+
const et = e.target;
|
|
9885
|
+
if (this._sizePopover && this._sizePopover.style.display !== "none" && !this._sizePopover.contains(et) && !this._el.contains(et)) this._hideSizePopover();
|
|
9626
9886
|
});
|
|
9627
9887
|
const d5 = on(popover, "mouseenter", () => this._clearTimers());
|
|
9628
9888
|
const d6 = on(popover, "mouseleave", () => this._scheduleHide());
|
|
@@ -9640,7 +9900,7 @@ var TableTooltip = class {
|
|
|
9640
9900
|
this._sizeTitleEl.textContent = this.context.locale.tooltips.table.tableBorderWidthPx;
|
|
9641
9901
|
this._sizeInputEl.min = "0";
|
|
9642
9902
|
this._sizeInputEl.max = "10";
|
|
9643
|
-
this._sizeInputEl.value = currentPx;
|
|
9903
|
+
this._sizeInputEl.value = String(currentPx);
|
|
9644
9904
|
this._sizeApply = (val) => {
|
|
9645
9905
|
const cells = Array.from(table.querySelectorAll("td, th"));
|
|
9646
9906
|
if (val === 0) cells.forEach((c) => {
|
|
@@ -9709,6 +9969,85 @@ var TableTooltip = class {
|
|
|
9709
9969
|
if (this._sizePopover) this._sizePopover.style.display = "none";
|
|
9710
9970
|
this._sizeApply = null;
|
|
9711
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
|
+
}
|
|
9712
10051
|
};
|
|
9713
10052
|
//#endregion
|
|
9714
10053
|
//#region src/js/module/CodeTooltip.js
|
|
@@ -9741,13 +10080,14 @@ var CodeTooltip = class {
|
|
|
9741
10080
|
const editable = this.context.layoutInfo.editable;
|
|
9742
10081
|
this._disposers.push(on(editable, "mouseover", (e) => {
|
|
9743
10082
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
9744
|
-
const pre = e.target
|
|
10083
|
+
const pre = e.target?.closest("pre");
|
|
9745
10084
|
if (pre && editable.contains(pre)) this._scheduleShow(pre);
|
|
9746
10085
|
}), on(editable, "mouseout", (e) => {
|
|
9747
10086
|
const to = e.relatedTarget;
|
|
9748
10087
|
if (!to || !editable.contains(to) && !this._el.contains(to)) this._scheduleHide();
|
|
9749
10088
|
}), on(document, "click", (e) => {
|
|
9750
|
-
|
|
10089
|
+
const et = e.target;
|
|
10090
|
+
if (this._activePre && !this._activePre.contains(et) && !this._el.contains(et)) this._hide();
|
|
9751
10091
|
}));
|
|
9752
10092
|
return this;
|
|
9753
10093
|
}
|
|
@@ -9782,6 +10122,7 @@ var CodeTooltip = class {
|
|
|
9782
10122
|
["python", "Python"],
|
|
9783
10123
|
["html", "HTML"],
|
|
9784
10124
|
["css", "CSS"],
|
|
10125
|
+
["scss", "SCSS"],
|
|
9785
10126
|
["json", "JSON"],
|
|
9786
10127
|
["xml", "XML"],
|
|
9787
10128
|
["bash", "Bash / Shell"],
|
|
@@ -9937,10 +10278,27 @@ var CodeTooltip = class {
|
|
|
9937
10278
|
this.context.invoke("editor.afterCommand");
|
|
9938
10279
|
this._positionNear(pre);
|
|
9939
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
|
+
}
|
|
9940
10297
|
_onLangChange() {
|
|
9941
10298
|
const pre = this._activePre;
|
|
9942
10299
|
if (!pre) return;
|
|
9943
10300
|
const lang = this._langSelect.value;
|
|
10301
|
+
const _w = window;
|
|
9944
10302
|
let codeEl = pre.querySelector("code");
|
|
9945
10303
|
if (!codeEl) {
|
|
9946
10304
|
codeEl = document.createElement("code");
|
|
@@ -9954,12 +10312,12 @@ var CodeTooltip = class {
|
|
|
9954
10312
|
else pre.removeAttribute("data-language");
|
|
9955
10313
|
const applyPrism = () => {
|
|
9956
10314
|
codeEl.querySelectorAll("br").forEach((br) => br.replaceWith("\n"));
|
|
9957
|
-
|
|
10315
|
+
_w.Prism.highlightElement(codeEl);
|
|
9958
10316
|
this.context.invoke("editor.afterCommand");
|
|
9959
10317
|
};
|
|
9960
10318
|
if (lang) {
|
|
9961
|
-
if (typeof
|
|
9962
|
-
if (
|
|
10319
|
+
if (typeof _w.Prism !== "undefined") {
|
|
10320
|
+
if (_w.Prism.languages[lang]) {
|
|
9963
10321
|
applyPrism();
|
|
9964
10322
|
return;
|
|
9965
10323
|
}
|
|
@@ -9967,7 +10325,7 @@ var CodeTooltip = class {
|
|
|
9967
10325
|
return;
|
|
9968
10326
|
} else if (this._prismScript) {
|
|
9969
10327
|
this._prismScript.addEventListener("load", () => {
|
|
9970
|
-
if (
|
|
10328
|
+
if (_w.Prism.languages[lang]) applyPrism();
|
|
9971
10329
|
else this._loadPrismComponent(lang, applyPrism);
|
|
9972
10330
|
}, { once: true });
|
|
9973
10331
|
return;
|
|
@@ -9980,7 +10338,8 @@ var CodeTooltip = class {
|
|
|
9980
10338
|
* Called once at initialize time. Fire-and-forget; errors are silent.
|
|
9981
10339
|
*/
|
|
9982
10340
|
_ensurePrism() {
|
|
9983
|
-
|
|
10341
|
+
const _w = window;
|
|
10342
|
+
if (!this.context.options.codeHighlight || _w.Prism) return;
|
|
9984
10343
|
const cdn = this.context.options.codeHighlightCDN;
|
|
9985
10344
|
const themeHref = `${cdn}/themes/prism-tomorrow.min.css`;
|
|
9986
10345
|
const scriptSrc = `${cdn}/prism.min.js`;
|
|
@@ -9992,7 +10351,7 @@ var CodeTooltip = class {
|
|
|
9992
10351
|
}
|
|
9993
10352
|
const existingScript = document.querySelector(`script[src="${scriptSrc}"]`);
|
|
9994
10353
|
if (existingScript) {
|
|
9995
|
-
this._prismScript =
|
|
10354
|
+
this._prismScript = _w.Prism ? null : existingScript;
|
|
9996
10355
|
return;
|
|
9997
10356
|
}
|
|
9998
10357
|
const script = document.createElement("script");
|
|
@@ -10012,10 +10371,11 @@ var CodeTooltip = class {
|
|
|
10012
10371
|
* @param {Function} cb – called once the grammar is ready
|
|
10013
10372
|
*/
|
|
10014
10373
|
_loadPrismComponent(lang, cb) {
|
|
10374
|
+
const _w = window;
|
|
10015
10375
|
const src = `${this.context.options.codeHighlightCDN}/components/prism-${lang}.min.js`;
|
|
10016
10376
|
if (document.querySelector(`script[src="${src}"]`)) {
|
|
10017
10377
|
const poll = setInterval(() => {
|
|
10018
|
-
if (
|
|
10378
|
+
if (_w.Prism && _w.Prism.languages[lang]) {
|
|
10019
10379
|
clearInterval(poll);
|
|
10020
10380
|
cb();
|
|
10021
10381
|
}
|
|
@@ -12428,15 +12788,19 @@ var EmojiDialog = class {
|
|
|
12428
12788
|
});
|
|
12429
12789
|
const box = createElement("div", { class: "an-dialog-box an-emoji-box" });
|
|
12430
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>`;
|
|
12431
12794
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
12432
12795
|
title.textContent = L.title;
|
|
12796
|
+
titleGroup.append(iconEl, title);
|
|
12433
12797
|
const closeBtn = createElement("button", {
|
|
12434
12798
|
type: "button",
|
|
12435
12799
|
class: "an-icon-close",
|
|
12436
12800
|
"aria-label": L.close
|
|
12437
12801
|
});
|
|
12438
12802
|
closeBtn.innerHTML = "×";
|
|
12439
|
-
titleRow.append(
|
|
12803
|
+
titleRow.append(titleGroup, closeBtn);
|
|
12440
12804
|
const searchInput = createElement("input", {
|
|
12441
12805
|
type: "search",
|
|
12442
12806
|
class: "an-input an-icon-search",
|
|
@@ -12485,6 +12849,7 @@ var EmojiDialog = class {
|
|
|
12485
12849
|
btnRow.appendChild(cancelBtn);
|
|
12486
12850
|
box.append(titleRow, searchInput, catBar, grid, btnRow);
|
|
12487
12851
|
overlay.appendChild(box);
|
|
12852
|
+
makeDraggable(titleRow, box);
|
|
12488
12853
|
const d1 = on(closeBtn, "click", () => this._close());
|
|
12489
12854
|
const d2 = on(cancelBtn, "click", () => this._close());
|
|
12490
12855
|
const d3 = on(overlay, "click", (e) => {
|
|
@@ -12492,7 +12857,7 @@ var EmojiDialog = class {
|
|
|
12492
12857
|
});
|
|
12493
12858
|
const d4 = on(searchInput, "input", () => this._filterEmojis(searchInput.value, this._activeCat));
|
|
12494
12859
|
const d5 = on(catBar, "click", (e) => {
|
|
12495
|
-
const tab = e.target
|
|
12860
|
+
const tab = e.target?.closest("[data-cat]");
|
|
12496
12861
|
if (tab) {
|
|
12497
12862
|
this._activeCat = tab.dataset.cat;
|
|
12498
12863
|
this._updateCatTabs();
|
|
@@ -12500,7 +12865,7 @@ var EmojiDialog = class {
|
|
|
12500
12865
|
}
|
|
12501
12866
|
});
|
|
12502
12867
|
const d6 = on(grid, "click", (e) => {
|
|
12503
|
-
const cell = e.target
|
|
12868
|
+
const cell = e.target?.closest(".an-emoji-cell");
|
|
12504
12869
|
if (cell) this._onEmojiClick(cell.dataset.char);
|
|
12505
12870
|
});
|
|
12506
12871
|
this._disposers.push(d1, d2, d3, d4, d5, d6);
|
|
@@ -12508,17 +12873,22 @@ var EmojiDialog = class {
|
|
|
12508
12873
|
}
|
|
12509
12874
|
_updateCatTabs() {
|
|
12510
12875
|
this._catBar.querySelectorAll(".an-icon-cat").forEach((tab) => {
|
|
12511
|
-
tab.classList.toggle(
|
|
12876
|
+
tab.classList.toggle(
|
|
12877
|
+
"active",
|
|
12878
|
+
/** @type {HTMLElement} */
|
|
12879
|
+
tab.dataset.cat === this._activeCat
|
|
12880
|
+
);
|
|
12512
12881
|
});
|
|
12513
12882
|
}
|
|
12514
12883
|
_filterEmojis(query, cat) {
|
|
12515
12884
|
const q = (query || "").trim().toLowerCase();
|
|
12516
12885
|
let count = 0;
|
|
12517
12886
|
this._grid.querySelectorAll(".an-emoji-cell").forEach((cell) => {
|
|
12518
|
-
const
|
|
12519
|
-
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;
|
|
12520
12890
|
const visible = matchCat && matchQuery;
|
|
12521
|
-
|
|
12891
|
+
hCell.style.display = visible ? "" : "none";
|
|
12522
12892
|
if (visible) count++;
|
|
12523
12893
|
});
|
|
12524
12894
|
let empty = this._grid.querySelector(".an-icon-empty");
|
|
@@ -12527,7 +12897,7 @@ var EmojiDialog = class {
|
|
|
12527
12897
|
empty.textContent = "No emojis found";
|
|
12528
12898
|
this._grid.appendChild(empty);
|
|
12529
12899
|
}
|
|
12530
|
-
empty.style.display = count > 0 ? "none" : "";
|
|
12900
|
+
/** @type {HTMLElement} */ empty.style.display = count > 0 ? "none" : "";
|
|
12531
12901
|
}
|
|
12532
12902
|
_onEmojiClick(char) {
|
|
12533
12903
|
const savedRange = this._savedRange;
|
|
@@ -12541,7 +12911,7 @@ var EmojiDialog = class {
|
|
|
12541
12911
|
range.collapse(false);
|
|
12542
12912
|
}
|
|
12543
12913
|
const _sc = range.startContainer;
|
|
12544
|
-
const _tdAnchor = (_sc.nodeType === 1 ? _sc : _sc.parentElement)?.closest
|
|
12914
|
+
const _tdAnchor = (_sc.nodeType === 1 ? _sc : _sc.parentElement)?.closest("td, th");
|
|
12545
12915
|
range.deleteContents();
|
|
12546
12916
|
if (_tdAnchor && _tdAnchor.isConnected && !_tdAnchor.contains(range.startContainer)) {
|
|
12547
12917
|
range.setStart(_tdAnchor, 0);
|
|
@@ -12901,15 +13271,19 @@ var IconDialog = class {
|
|
|
12901
13271
|
});
|
|
12902
13272
|
const box = createElement("div", { class: "an-dialog-box an-icon-box" });
|
|
12903
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>`;
|
|
12904
13277
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
12905
13278
|
title.textContent = L.title;
|
|
13279
|
+
titleGroup.append(iconEl, title);
|
|
12906
13280
|
const closeBtn = createElement("button", {
|
|
12907
13281
|
type: "button",
|
|
12908
13282
|
class: "an-icon-close",
|
|
12909
13283
|
"aria-label": L.close
|
|
12910
13284
|
});
|
|
12911
13285
|
closeBtn.innerHTML = "×";
|
|
12912
|
-
titleRow.append(
|
|
13286
|
+
titleRow.append(titleGroup, closeBtn);
|
|
12913
13287
|
const searchInput = createElement("input", {
|
|
12914
13288
|
type: "search",
|
|
12915
13289
|
class: "an-input an-icon-search",
|
|
@@ -13024,6 +13398,7 @@ var IconDialog = class {
|
|
|
13024
13398
|
this._insertBtn = insertBtn;
|
|
13025
13399
|
box.append(titleRow, searchInput, catBar, grid, optRow, preview, btnRow);
|
|
13026
13400
|
overlay.appendChild(box);
|
|
13401
|
+
makeDraggable(titleRow, box);
|
|
13027
13402
|
const d1 = on(closeBtn, "click", () => this._close());
|
|
13028
13403
|
const d2 = on(cancelBtn, "click", () => this._close());
|
|
13029
13404
|
const d3 = on(insertBtn, "click", () => this._onInsert());
|
|
@@ -13032,7 +13407,7 @@ var IconDialog = class {
|
|
|
13032
13407
|
});
|
|
13033
13408
|
const d5 = on(searchInput, "input", () => this._filterIcons(searchInput.value, this._activeCat));
|
|
13034
13409
|
const d6 = on(catBar, "click", (e) => {
|
|
13035
|
-
const tab = e.target
|
|
13410
|
+
const tab = e.target?.closest("[data-cat]");
|
|
13036
13411
|
if (tab) {
|
|
13037
13412
|
this._activeCat = tab.dataset.cat;
|
|
13038
13413
|
this._updateCatTabs();
|
|
@@ -13040,7 +13415,7 @@ var IconDialog = class {
|
|
|
13040
13415
|
}
|
|
13041
13416
|
});
|
|
13042
13417
|
const d7 = on(grid, "click", (e) => {
|
|
13043
|
-
const cell = e.target
|
|
13418
|
+
const cell = e.target?.closest(".an-icon-cell");
|
|
13044
13419
|
if (cell) this._selectIcon(cell.dataset.name);
|
|
13045
13420
|
});
|
|
13046
13421
|
const d8 = on(styleSelect, "change", () => this._updatePreview(this._selectedIcon));
|
|
@@ -13052,19 +13427,24 @@ var IconDialog = class {
|
|
|
13052
13427
|
}
|
|
13053
13428
|
_updateCatTabs() {
|
|
13054
13429
|
this._catBar.querySelectorAll(".an-icon-cat").forEach((tab) => {
|
|
13055
|
-
tab.classList.toggle(
|
|
13430
|
+
tab.classList.toggle(
|
|
13431
|
+
"active",
|
|
13432
|
+
/** @type {HTMLElement} */
|
|
13433
|
+
tab.dataset.cat === this._activeCat
|
|
13434
|
+
);
|
|
13056
13435
|
});
|
|
13057
13436
|
}
|
|
13058
13437
|
_filterIcons(query, cat) {
|
|
13059
13438
|
const q = (query || "").trim().toLowerCase();
|
|
13060
13439
|
let visibleCount = 0;
|
|
13061
13440
|
this._grid.querySelectorAll(".an-icon-cell").forEach((cell) => {
|
|
13062
|
-
const
|
|
13063
|
-
const
|
|
13441
|
+
const hCell = cell;
|
|
13442
|
+
const name = hCell.dataset.name;
|
|
13443
|
+
const cellCat = hCell.dataset.cat;
|
|
13064
13444
|
const matchesCat = !cat || cat === "all" || cellCat === cat;
|
|
13065
13445
|
const matchesQuery = !q || name.includes(q);
|
|
13066
13446
|
const visible = matchesCat && matchesQuery;
|
|
13067
|
-
|
|
13447
|
+
hCell.style.display = visible ? "" : "none";
|
|
13068
13448
|
if (visible) visibleCount++;
|
|
13069
13449
|
});
|
|
13070
13450
|
let empty = this._grid.querySelector(".an-icon-empty");
|
|
@@ -13073,12 +13453,16 @@ var IconDialog = class {
|
|
|
13073
13453
|
empty.textContent = "No icons found";
|
|
13074
13454
|
this._grid.appendChild(empty);
|
|
13075
13455
|
}
|
|
13076
|
-
empty.style.display = visibleCount > 0 ? "none" : "";
|
|
13456
|
+
/** @type {HTMLElement} */ empty.style.display = visibleCount > 0 ? "none" : "";
|
|
13077
13457
|
}
|
|
13078
13458
|
_selectIcon(name) {
|
|
13079
13459
|
this._selectedIcon = name;
|
|
13080
13460
|
this._grid.querySelectorAll(".an-icon-cell").forEach((cell) => {
|
|
13081
|
-
cell.classList.toggle(
|
|
13461
|
+
cell.classList.toggle(
|
|
13462
|
+
"active",
|
|
13463
|
+
/** @type {HTMLElement} */
|
|
13464
|
+
cell.dataset.name === name
|
|
13465
|
+
);
|
|
13082
13466
|
});
|
|
13083
13467
|
this._insertBtn.removeAttribute("disabled");
|
|
13084
13468
|
this._updatePreview(name);
|
|
@@ -13117,7 +13501,7 @@ var IconDialog = class {
|
|
|
13117
13501
|
range.collapse(false);
|
|
13118
13502
|
}
|
|
13119
13503
|
const _sc = range.startContainer;
|
|
13120
|
-
const _tdAnchor = (_sc.nodeType === 1 ? _sc : _sc.parentElement)?.closest
|
|
13504
|
+
const _tdAnchor = (_sc.nodeType === 1 ? _sc : _sc.parentElement)?.closest("td, th");
|
|
13121
13505
|
range.deleteContents();
|
|
13122
13506
|
if (_tdAnchor && _tdAnchor.isConnected && !_tdAnchor.contains(range.startContainer)) {
|
|
13123
13507
|
range.setStart(_tdAnchor, 0);
|
|
@@ -13388,13 +13772,13 @@ var ContextMenu = class {
|
|
|
13388
13772
|
this._menuDisposers.forEach((d) => {
|
|
13389
13773
|
try {
|
|
13390
13774
|
d();
|
|
13391
|
-
} catch (
|
|
13775
|
+
} catch (_e) {}
|
|
13392
13776
|
});
|
|
13393
13777
|
this._menuDisposers = [];
|
|
13394
13778
|
this._disposers.forEach((d) => {
|
|
13395
13779
|
try {
|
|
13396
13780
|
d();
|
|
13397
|
-
} catch (
|
|
13781
|
+
} catch (_e) {}
|
|
13398
13782
|
});
|
|
13399
13783
|
this._disposers = [];
|
|
13400
13784
|
if (this.el && this.el.parentNode) this.el.parentNode.removeChild(this.el);
|
|
@@ -13585,13 +13969,13 @@ var ContextMenu = class {
|
|
|
13585
13969
|
});
|
|
13586
13970
|
this._menuDisposers.push(offHeader);
|
|
13587
13971
|
const offMove = on(gridEl, "mousemove", (e) => {
|
|
13588
|
-
const cell = e.target
|
|
13972
|
+
const cell = e.target?.closest("[data-row]");
|
|
13589
13973
|
if (!cell) return;
|
|
13590
13974
|
setHighlight(+cell.dataset.row, +cell.dataset.col);
|
|
13591
13975
|
});
|
|
13592
13976
|
const offLeave = on(gridEl, "mouseleave", () => setHighlight(0, 0));
|
|
13593
13977
|
const offClick = on(gridEl, "click", (e) => {
|
|
13594
|
-
const cell = e.target
|
|
13978
|
+
const cell = e.target?.closest("[data-row]");
|
|
13595
13979
|
if (!cell) return;
|
|
13596
13980
|
const rows = +cell.dataset.row;
|
|
13597
13981
|
const cols = +cell.dataset.col;
|
|
@@ -13616,7 +14000,7 @@ var ContextMenu = class {
|
|
|
13616
14000
|
class: "an-context-item",
|
|
13617
14001
|
"data-name": it.name || ""
|
|
13618
14002
|
});
|
|
13619
|
-
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;
|
|
13620
14004
|
if (it.icon) {
|
|
13621
14005
|
const iconSpan = createElement("span", {
|
|
13622
14006
|
class: "an-context-icon",
|
|
@@ -13648,7 +14032,7 @@ var ContextMenu = class {
|
|
|
13648
14032
|
const winSel = window.getSelection();
|
|
13649
14033
|
this._savedRange = winSel && winSel.rangeCount > 0 ? winSel.getRangeAt(0).cloneRange() : null;
|
|
13650
14034
|
this._renderItems(this._items);
|
|
13651
|
-
|
|
14035
|
+
const openX = event.clientX;
|
|
13652
14036
|
let openY = event.clientY;
|
|
13653
14037
|
if (this._savedRange && !this._savedRange.collapsed) try {
|
|
13654
14038
|
const selRect = this._savedRange.getBoundingClientRect();
|
|
@@ -13814,7 +14198,7 @@ var ContextMenu = class {
|
|
|
13814
14198
|
while (el = iter.nextNode()) {
|
|
13815
14199
|
if (!editable.contains(el) || el === editable) continue;
|
|
13816
14200
|
try {
|
|
13817
|
-
if (range.intersectsNode(el)) el.removeAttribute("style");
|
|
14201
|
+
if (range.intersectsNode(el)) /** @type {Element} */ el.removeAttribute("style");
|
|
13818
14202
|
} catch {}
|
|
13819
14203
|
}
|
|
13820
14204
|
this.context.invoke("editor.afterCommand");
|
|
@@ -14076,8 +14460,8 @@ var FindReplace = class {
|
|
|
14076
14460
|
const replaceActions = this._dialog.querySelector(".an-fr-replace-actions");
|
|
14077
14461
|
const title = this._dialog.querySelector(".an-dialog-title");
|
|
14078
14462
|
const isReplace = this._mode === "replace";
|
|
14079
|
-
if (replaceRow) replaceRow.style.display = isReplace ? "" : "none";
|
|
14080
|
-
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";
|
|
14081
14465
|
if (title) title.textContent = isReplace ? this.context.locale.findReplace.findReplaceTitle : this.context.locale.findReplace.findTitle;
|
|
14082
14466
|
}
|
|
14083
14467
|
_buildDialog() {
|
|
@@ -14088,106 +14472,123 @@ var FindReplace = class {
|
|
|
14088
14472
|
"aria-modal": "true",
|
|
14089
14473
|
"aria-label": L.findReplaceTitle
|
|
14090
14474
|
});
|
|
14091
|
-
const box = createElement("div", { class: "an-dialog-box" });
|
|
14092
|
-
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>`;
|
|
14093
14480
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
14094
14481
|
title.textContent = L.findTitle;
|
|
14482
|
+
titleGroup.append(iconEl, title);
|
|
14095
14483
|
const closeBtn = createElement("button", {
|
|
14096
14484
|
type: "button",
|
|
14097
14485
|
class: "an-icon-close",
|
|
14098
|
-
|
|
14486
|
+
title: L.close,
|
|
14487
|
+
"aria-label": L.close
|
|
14099
14488
|
});
|
|
14100
|
-
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>`;
|
|
14101
14490
|
this._closeBtn = closeBtn;
|
|
14102
|
-
|
|
14103
|
-
box.appendChild(
|
|
14104
|
-
const
|
|
14491
|
+
header.append(titleGroup, closeBtn);
|
|
14492
|
+
box.appendChild(header);
|
|
14493
|
+
const searchBar = createElement("div", { class: "an-fr-search-bar" });
|
|
14105
14494
|
const findInput = createElement("input", {
|
|
14106
14495
|
type: "text",
|
|
14107
|
-
class: "an-input",
|
|
14496
|
+
class: "an-input an-fr-input",
|
|
14108
14497
|
placeholder: L.findPlaceholder,
|
|
14109
14498
|
"aria-label": L.searchAriaLabel
|
|
14110
14499
|
});
|
|
14111
14500
|
this._findInput = findInput;
|
|
14112
|
-
findRow.appendChild(findInput);
|
|
14113
|
-
box.appendChild(findRow);
|
|
14114
|
-
const optRow = createElement("div", { class: "an-fr-options-row" });
|
|
14115
|
-
const caseLabel = createElement("label", { class: "an-label an-label-inline" });
|
|
14116
14501
|
const caseCheckbox = createElement("input", {
|
|
14117
14502
|
type: "checkbox",
|
|
14118
|
-
|
|
14503
|
+
style: "display:none",
|
|
14504
|
+
"aria-hidden": "true"
|
|
14119
14505
|
});
|
|
14120
14506
|
this._caseCheckbox = caseCheckbox;
|
|
14121
|
-
|
|
14122
|
-
|
|
14123
|
-
|
|
14124
|
-
|
|
14125
|
-
|
|
14126
|
-
|
|
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";
|
|
14127
14514
|
const prevBtn = createElement("button", {
|
|
14128
14515
|
type: "button",
|
|
14129
|
-
class: "an-btn"
|
|
14516
|
+
class: "an-fr-icon-btn",
|
|
14517
|
+
title: "Previous (Shift+Enter)",
|
|
14518
|
+
"aria-label": "Previous"
|
|
14130
14519
|
});
|
|
14131
|
-
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>`;
|
|
14132
14521
|
const nextBtn = createElement("button", {
|
|
14133
14522
|
type: "button",
|
|
14134
|
-
class: "an-
|
|
14523
|
+
class: "an-fr-icon-btn",
|
|
14524
|
+
title: "Next (Enter)",
|
|
14525
|
+
"aria-label": "Next"
|
|
14135
14526
|
});
|
|
14136
|
-
nextBtn.
|
|
14137
|
-
|
|
14138
|
-
|
|
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);
|
|
14139
14532
|
const replaceRow = createElement("div", { class: "an-fr-replace-row" });
|
|
14140
14533
|
replaceRow.style.display = "none";
|
|
14141
14534
|
const replaceInput = createElement("input", {
|
|
14142
14535
|
type: "text",
|
|
14143
|
-
class: "an-input",
|
|
14536
|
+
class: "an-input an-fr-input",
|
|
14144
14537
|
placeholder: L.replacePlaceholder,
|
|
14145
14538
|
"aria-label": L.replaceAriaLabel
|
|
14146
14539
|
});
|
|
14147
14540
|
this._replaceInput = replaceInput;
|
|
14148
|
-
replaceRow.appendChild(replaceInput);
|
|
14149
|
-
box.appendChild(replaceRow);
|
|
14150
|
-
const replaceActions = createElement("div", { class: "an-dialog-actions an-fr-replace-actions" });
|
|
14151
|
-
replaceActions.style.display = "none";
|
|
14152
14541
|
const replaceBtn = createElement("button", {
|
|
14153
14542
|
type: "button",
|
|
14154
|
-
class: "an-btn"
|
|
14543
|
+
class: "an-btn an-fr-replace-btn"
|
|
14155
14544
|
});
|
|
14156
14545
|
replaceBtn.textContent = L.replaceBtn;
|
|
14157
14546
|
const replaceAllBtn = createElement("button", {
|
|
14158
14547
|
type: "button",
|
|
14159
|
-
class: "an-btn an-btn-primary"
|
|
14548
|
+
class: "an-btn an-btn-primary an-fr-replace-btn"
|
|
14160
14549
|
});
|
|
14161
14550
|
replaceAllBtn.textContent = L.replaceAllBtn;
|
|
14162
|
-
|
|
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";
|
|
14163
14555
|
box.appendChild(replaceActions);
|
|
14164
14556
|
overlay.appendChild(box);
|
|
14557
|
+
makeDraggable(header, box);
|
|
14165
14558
|
const d1 = on(closeBtn, "click", () => this._close());
|
|
14166
14559
|
const d2 = on(overlay, "click", (e) => {
|
|
14167
14560
|
if (e.target === overlay) this._close();
|
|
14168
14561
|
});
|
|
14169
14562
|
const d3 = on(findInput, "input", () => this._onSearch());
|
|
14170
|
-
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", () => {
|
|
14171
14570
|
this._caseSensitive = caseCheckbox.checked;
|
|
14571
|
+
caseBtn.classList.toggle("an-fr-icon-btn--active", this._caseSensitive);
|
|
14172
14572
|
this._onSearch();
|
|
14173
14573
|
});
|
|
14174
|
-
const
|
|
14175
|
-
const
|
|
14176
|
-
const
|
|
14177
|
-
const
|
|
14178
|
-
const
|
|
14179
|
-
|
|
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") {
|
|
14180
14581
|
e.preventDefault();
|
|
14181
|
-
|
|
14582
|
+
ke.shiftKey ? this._prev() : this._next();
|
|
14182
14583
|
}
|
|
14183
14584
|
});
|
|
14184
|
-
const
|
|
14585
|
+
const d11 = on(replaceInput, "keydown", (e) => {
|
|
14185
14586
|
if (e.key === "Enter") {
|
|
14186
14587
|
e.preventDefault();
|
|
14187
14588
|
this._replace();
|
|
14188
14589
|
}
|
|
14189
14590
|
});
|
|
14190
|
-
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);
|
|
14191
14592
|
return overlay;
|
|
14192
14593
|
}
|
|
14193
14594
|
_onSearch() {
|
|
@@ -14548,9 +14949,10 @@ var ImageCropOverlay = class {
|
|
|
14548
14949
|
}), on(h, "touchstart", (e) => {
|
|
14549
14950
|
e.preventDefault();
|
|
14550
14951
|
e.stopPropagation();
|
|
14952
|
+
const te = e;
|
|
14551
14953
|
this._startHandleDrag({
|
|
14552
|
-
clientX:
|
|
14553
|
-
clientY:
|
|
14954
|
+
clientX: te.touches[0].clientX,
|
|
14955
|
+
clientY: te.touches[0].clientY
|
|
14554
14956
|
}, id);
|
|
14555
14957
|
}, { passive: false }));
|
|
14556
14958
|
this._handles[id] = h;
|
|
@@ -14567,9 +14969,10 @@ var ImageCropOverlay = class {
|
|
|
14567
14969
|
if (e.target !== cropBox && e.target !== grid) return;
|
|
14568
14970
|
e.preventDefault();
|
|
14569
14971
|
e.stopPropagation();
|
|
14972
|
+
const te2 = e;
|
|
14570
14973
|
this._startBoxMove({
|
|
14571
|
-
clientX:
|
|
14572
|
-
clientY:
|
|
14974
|
+
clientX: te2.touches[0].clientX,
|
|
14975
|
+
clientY: te2.touches[0].clientY
|
|
14573
14976
|
});
|
|
14574
14977
|
}, { passive: false }));
|
|
14575
14978
|
const infoEl = document.createElement("div");
|
|
@@ -14731,9 +15134,10 @@ var ImageCropOverlay = class {
|
|
|
14731
15134
|
_attachDocDrag(onMove) {
|
|
14732
15135
|
const onTouchMove = (e) => {
|
|
14733
15136
|
e.preventDefault();
|
|
15137
|
+
const te3 = e;
|
|
14734
15138
|
onMove({
|
|
14735
|
-
clientX:
|
|
14736
|
-
clientY:
|
|
15139
|
+
clientX: te3.touches[0].clientX,
|
|
15140
|
+
clientY: te3.touches[0].clientY
|
|
14737
15141
|
});
|
|
14738
15142
|
};
|
|
14739
15143
|
const cleanup = () => {
|
|
@@ -15310,7 +15714,9 @@ var BubbleToolbar = class {
|
|
|
15310
15714
|
const d6 = this.context.on("contextMenu:hide", () => {
|
|
15311
15715
|
this._contextMenuOpen = false;
|
|
15312
15716
|
});
|
|
15313
|
-
|
|
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);
|
|
15314
15720
|
return this;
|
|
15315
15721
|
}
|
|
15316
15722
|
destroy() {
|
|
@@ -15424,20 +15830,22 @@ var BubbleToolbar = class {
|
|
|
15424
15830
|
picker.appendChild(customRow);
|
|
15425
15831
|
document.body.appendChild(picker);
|
|
15426
15832
|
this._picker = picker;
|
|
15427
|
-
|
|
15428
|
-
|
|
15429
|
-
|
|
15833
|
+
const pickerAny = picker;
|
|
15834
|
+
pickerAny._paletteEl = palette;
|
|
15835
|
+
pickerAny._noColorBtn = noColorBtn;
|
|
15836
|
+
pickerAny._colorInput = colorInput;
|
|
15430
15837
|
}
|
|
15431
15838
|
_openColorPicker(type, anchorBtn) {
|
|
15432
15839
|
const sel = window.getSelection();
|
|
15433
15840
|
if (sel && sel.rangeCount > 0) this._savedRange = sel.getRangeAt(0).cloneRange();
|
|
15434
15841
|
this._pickerType = type;
|
|
15435
|
-
const
|
|
15436
|
-
const
|
|
15842
|
+
const pickerAny = this._picker;
|
|
15843
|
+
const palette = pickerAny._paletteEl;
|
|
15844
|
+
const noColorBtn = pickerAny._noColorBtn;
|
|
15437
15845
|
if (type === "hiliteColor") {
|
|
15438
15846
|
if (!palette.contains(noColorBtn)) palette.appendChild(noColorBtn);
|
|
15439
15847
|
} else if (palette.contains(noColorBtn)) palette.removeChild(noColorBtn);
|
|
15440
|
-
this._picker._colorInput.value = type === "foreColor" ? "#000000" : "#ffff00";
|
|
15848
|
+
/** @type {any} */ this._picker._colorInput.value = type === "foreColor" ? "#000000" : "#ffff00";
|
|
15441
15849
|
this._picker.style.display = "block";
|
|
15442
15850
|
const pw = this._picker.offsetWidth;
|
|
15443
15851
|
const ph = this._picker.offsetHeight;
|
|
@@ -15471,7 +15879,7 @@ var BubbleToolbar = class {
|
|
|
15471
15879
|
const name = type === "hiliteColor" ? "hiliteColor" : "foreColor";
|
|
15472
15880
|
const btn = this._el && this._el.querySelector(`[data-name="${name}"]`);
|
|
15473
15881
|
const strip = btn && btn.querySelector(".an-bubble-color-strip");
|
|
15474
|
-
if (strip) strip.style.background = color === "transparent" ? "transparent" : color;
|
|
15882
|
+
if (strip) /** @type {HTMLElement} */ strip.style.background = color === "transparent" ? "transparent" : color;
|
|
15475
15883
|
this._closeColorPicker();
|
|
15476
15884
|
this._syncActive();
|
|
15477
15885
|
}
|
|
@@ -15487,6 +15895,14 @@ var BubbleToolbar = class {
|
|
|
15487
15895
|
let top = rect.top - bh - gap;
|
|
15488
15896
|
left = Math.max(8, Math.min(left, window.innerWidth - bw - 8));
|
|
15489
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
|
+
}
|
|
15490
15906
|
el.style.top = `${top}px`;
|
|
15491
15907
|
el.style.left = `${left}px`;
|
|
15492
15908
|
el.style.visibility = "";
|
|
@@ -15518,12 +15934,12 @@ var BubbleToolbar = class {
|
|
|
15518
15934
|
const cs = window.getComputedStyle(node);
|
|
15519
15935
|
const foreBtn = this._el.querySelector("[data-name=\"foreColor\"]");
|
|
15520
15936
|
const foreStrip = foreBtn && foreBtn.querySelector(".an-bubble-color-strip");
|
|
15521
|
-
if (foreStrip) foreStrip.style.background = cs.color || "#000000";
|
|
15937
|
+
if (foreStrip) /** @type {HTMLElement} */ foreStrip.style.background = cs.color || "#000000";
|
|
15522
15938
|
const hiliteBtn = this._el.querySelector("[data-name=\"hiliteColor\"]");
|
|
15523
15939
|
const hiliteStrip = hiliteBtn && hiliteBtn.querySelector(".an-bubble-color-strip");
|
|
15524
15940
|
if (hiliteStrip) {
|
|
15525
15941
|
const bg = cs.backgroundColor;
|
|
15526
|
-
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;
|
|
15527
15943
|
}
|
|
15528
15944
|
}
|
|
15529
15945
|
_onSelectionChange() {
|
|
@@ -15651,11 +16067,11 @@ var Mention = class {
|
|
|
15651
16067
|
el.setAttribute("role", "listbox");
|
|
15652
16068
|
el.addEventListener("mousedown", (e) => e.preventDefault());
|
|
15653
16069
|
el.addEventListener("click", (e) => {
|
|
15654
|
-
const item = e.target
|
|
16070
|
+
const item = e.target?.closest(".an-mention-item");
|
|
15655
16071
|
if (item) this._select(+item.dataset.index);
|
|
15656
16072
|
});
|
|
15657
16073
|
el.addEventListener("mousemove", (e) => {
|
|
15658
|
-
const item = e.target
|
|
16074
|
+
const item = e.target?.closest(".an-mention-item");
|
|
15659
16075
|
if (item) this._highlightItem(+item.dataset.index);
|
|
15660
16076
|
});
|
|
15661
16077
|
document.body.appendChild(el);
|
|
@@ -15670,7 +16086,7 @@ var Mention = class {
|
|
|
15670
16086
|
const li = document.createElement("div");
|
|
15671
16087
|
li.className = "an-mention-item";
|
|
15672
16088
|
li.setAttribute("role", "option");
|
|
15673
|
-
li.dataset.index = i;
|
|
16089
|
+
li.dataset.index = String(i);
|
|
15674
16090
|
if (item.avatar) {
|
|
15675
16091
|
const img = document.createElement("img");
|
|
15676
16092
|
img.src = item.avatar;
|
|
@@ -15920,7 +16336,7 @@ var Context = class {
|
|
|
15920
16336
|
/**
|
|
15921
16337
|
* Registers and initialises a custom module on this instance.
|
|
15922
16338
|
* @param {string} name
|
|
15923
|
-
* @param {
|
|
16339
|
+
* @param {new (ctx: this) => any} ModuleClass
|
|
15924
16340
|
* @returns {this}
|
|
15925
16341
|
*/
|
|
15926
16342
|
registerModule(name, ModuleClass) {
|
|
@@ -16227,10 +16643,12 @@ var Context = class {
|
|
|
16227
16643
|
this._disposers.forEach((d) => d());
|
|
16228
16644
|
this._disposers = [];
|
|
16229
16645
|
const container = this.layoutInfo.container;
|
|
16646
|
+
const wasDark = container && container.classList.contains("an-theme-dark");
|
|
16230
16647
|
if (container && container.parentNode) {
|
|
16231
16648
|
this.targetEl.style.display = "";
|
|
16232
16649
|
container.parentNode.removeChild(container);
|
|
16233
16650
|
}
|
|
16651
|
+
if (wasDark && !document.querySelector(".an-container.an-theme-dark")) document.body.classList.remove("an-theme-dark");
|
|
16234
16652
|
if (typeof this.options.onDestroy === "function") this.options.onDestroy(this);
|
|
16235
16653
|
this._alive = false;
|
|
16236
16654
|
this._listeners.clear();
|
|
@@ -16239,7 +16657,8 @@ var Context = class {
|
|
|
16239
16657
|
* Syncs editor HTML back into the original textarea/input for form submission.
|
|
16240
16658
|
*/
|
|
16241
16659
|
_syncToTarget() {
|
|
16242
|
-
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();
|
|
16243
16662
|
}
|
|
16244
16663
|
};
|
|
16245
16664
|
//#endregion
|
|
@@ -16359,13 +16778,21 @@ function any(arr, predicate) {
|
|
|
16359
16778
|
*/
|
|
16360
16779
|
var userAgent = navigator.userAgent;
|
|
16361
16780
|
var env = {
|
|
16781
|
+
/** True if browser is Chrome */
|
|
16362
16782
|
isChrome: /Chrome\//.test(userAgent),
|
|
16783
|
+
/** True if browser is Firefox */
|
|
16363
16784
|
isFF: /Firefox\//.test(userAgent),
|
|
16785
|
+
/** True if browser is Safari (not Chrome) */
|
|
16364
16786
|
isSafari: /^((?!chrome|android).)*safari/i.test(userAgent),
|
|
16787
|
+
/** True if browser is Edge (Chromium) */
|
|
16365
16788
|
isEdge: /Edg\//.test(userAgent),
|
|
16789
|
+
/** True if running on macOS */
|
|
16366
16790
|
isMac: /Macintosh/.test(userAgent),
|
|
16791
|
+
/** True if running on mobile */
|
|
16367
16792
|
isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent),
|
|
16793
|
+
/** True if touch is supported */
|
|
16368
16794
|
isTouch: "ontouchstart" in window || navigator.maxTouchPoints > 0,
|
|
16795
|
+
/** Modifier key name depending on platform */
|
|
16369
16796
|
modifierKey: /Macintosh/.test(userAgent) ? "metaKey" : "ctrlKey"
|
|
16370
16797
|
};
|
|
16371
16798
|
//#endregion
|
|
@@ -16374,6 +16801,13 @@ var _originalDefaults = { ...defaultOptions };
|
|
|
16374
16801
|
/** @type {WeakMap<Element, Context>} */
|
|
16375
16802
|
var instances = /* @__PURE__ */ new WeakMap();
|
|
16376
16803
|
var AutumnNote = {
|
|
16804
|
+
/**
|
|
16805
|
+
* Creates (or returns existing) editor instance on one or more elements.
|
|
16806
|
+
*
|
|
16807
|
+
* @param {string|Element|NodeList|Element[]} selector
|
|
16808
|
+
* @param {import('./settings.js').AsnOptions} [options]
|
|
16809
|
+
* @returns {Context|Context[]} single Context or array of Contexts
|
|
16810
|
+
*/
|
|
16377
16811
|
create(selector, options = {}) {
|
|
16378
16812
|
const ctxs = resolveElements(selector).map((el) => {
|
|
16379
16813
|
if (instances.has(el)) return instances.get(el);
|
|
@@ -16384,6 +16818,10 @@ var AutumnNote = {
|
|
|
16384
16818
|
});
|
|
16385
16819
|
return ctxs.length === 1 ? ctxs[0] : ctxs;
|
|
16386
16820
|
},
|
|
16821
|
+
/**
|
|
16822
|
+
* Destroys the editor(s) on the given selector.
|
|
16823
|
+
* @param {string|Element|NodeList|Element[]} selector
|
|
16824
|
+
*/
|
|
16387
16825
|
destroy(selector) {
|
|
16388
16826
|
resolveElements(selector).forEach((el) => {
|
|
16389
16827
|
const ctx = instances.get(el);
|
|
@@ -16393,23 +16831,45 @@ var AutumnNote = {
|
|
|
16393
16831
|
}
|
|
16394
16832
|
});
|
|
16395
16833
|
},
|
|
16834
|
+
/**
|
|
16835
|
+
* Returns the Context instance for a given element (or null).
|
|
16836
|
+
* @param {string|Element} selector
|
|
16837
|
+
* @returns {Context|null}
|
|
16838
|
+
*/
|
|
16396
16839
|
getInstance(selector) {
|
|
16397
16840
|
const el = typeof selector === "string" ? document.querySelector(selector) : selector;
|
|
16398
16841
|
return el ? instances.get(el) || null : null;
|
|
16399
16842
|
},
|
|
16843
|
+
/** Returns a shallow copy of the default options (read-only snapshot). */
|
|
16400
16844
|
get defaults() {
|
|
16401
16845
|
return { ...defaultOptions };
|
|
16402
16846
|
},
|
|
16847
|
+
/** Merges properties into the global defaults, applied to all future instances. */
|
|
16403
16848
|
setDefaults(overrides) {
|
|
16404
16849
|
Object.assign(defaultOptions, overrides);
|
|
16405
16850
|
},
|
|
16851
|
+
/** Restores global defaults to their original factory values. */
|
|
16406
16852
|
resetDefaults() {
|
|
16407
16853
|
Object.keys(defaultOptions).forEach((k) => delete defaultOptions[k]);
|
|
16408
16854
|
Object.assign(defaultOptions, _originalDefaults);
|
|
16409
16855
|
},
|
|
16856
|
+
/**
|
|
16857
|
+
* Registers a custom module to be included in every new editor instance.
|
|
16858
|
+
* @param {string} name - unique module key used for ctx.invoke() calls
|
|
16859
|
+
* @param {Function} ModuleClass - class with initialize() and optional destroy()
|
|
16860
|
+
*/
|
|
16410
16861
|
registerModule(name, ModuleClass) {
|
|
16411
16862
|
_customModules.set(name, ModuleClass);
|
|
16412
16863
|
},
|
|
16864
|
+
/**
|
|
16865
|
+
* Installs a plugin globally — applied to every future editor instance.
|
|
16866
|
+
* Plugin `buttons` are registered to the global button registry immediately
|
|
16867
|
+
* so they are available when Toolbar initialises inside create().
|
|
16868
|
+
* Plugin `install()` is called after all built-in modules have initialised.
|
|
16869
|
+
* @param {object} plugin - { name, version?, buttons?, install?, uninstall? }
|
|
16870
|
+
* @param {object} [options] - Forwarded to plugin.install(context, options)
|
|
16871
|
+
* @returns {typeof AutumnNote}
|
|
16872
|
+
*/
|
|
16413
16873
|
use(plugin, options = {}) {
|
|
16414
16874
|
if (!plugin || typeof plugin.name !== "string") throw new TypeError("[AutumnNote] AutumnNote.use: plugin must have a string `name` property.");
|
|
16415
16875
|
if (_globalPlugins.has(plugin.name)) {
|
|
@@ -16423,14 +16883,26 @@ var AutumnNote = {
|
|
|
16423
16883
|
});
|
|
16424
16884
|
return this;
|
|
16425
16885
|
},
|
|
16886
|
+
/**
|
|
16887
|
+
* Returns true if a plugin with the given name has been registered globally.
|
|
16888
|
+
* @param {string} name
|
|
16889
|
+
* @returns {boolean}
|
|
16890
|
+
*/
|
|
16426
16891
|
hasPlugin(name) {
|
|
16427
16892
|
return _globalPlugins.has(name);
|
|
16428
16893
|
},
|
|
16894
|
+
/**
|
|
16895
|
+
* Registers a single button definition in the global button registry.
|
|
16896
|
+
* After create(), call ctx.invoke('toolbar.rebuild') to render new buttons.
|
|
16897
|
+
* @param {object} btnDef - ButtonDef-compatible object with a `name` string
|
|
16898
|
+
* @returns {typeof AutumnNote}
|
|
16899
|
+
*/
|
|
16429
16900
|
registerButton(btnDef) {
|
|
16430
16901
|
registerButton(btnDef);
|
|
16431
16902
|
return this;
|
|
16432
16903
|
},
|
|
16433
|
-
version
|
|
16904
|
+
/** Library version */
|
|
16905
|
+
version: "1.5.0"
|
|
16434
16906
|
};
|
|
16435
16907
|
/**
|
|
16436
16908
|
* @param {string|Element|NodeList|Element[]} selector
|
|
@@ -16443,6 +16915,6 @@ function resolveElements(selector) {
|
|
|
16443
16915
|
return [];
|
|
16444
16916
|
}
|
|
16445
16917
|
//#endregion
|
|
16446
|
-
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 };
|
|
16447
16919
|
|
|
16448
16920
|
//# sourceMappingURL=autumnnote.es.js.map
|