autumnnote 1.6.7 → 1.8.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.
@@ -968,6 +968,13 @@
968
968
  }
969
969
  };
970
970
  var removeFormatBtn = btn("removeFormat", "remove-format", "Remove Format", () => execCommand("removeFormat"));
971
+ var directionBtn = btn("direction", "direction", "Toggle Text Direction (LTR / RTL)", (ctx) => {
972
+ const editable = ctx.layoutInfo.editable;
973
+ const next = (editable.getAttribute("dir") || "ltr") === "ltr" ? "rtl" : "ltr";
974
+ editable.setAttribute("dir", next);
975
+ editable.style.textAlign = next === "rtl" ? "right" : "left";
976
+ ctx.invoke("editor.afterCommand");
977
+ });
971
978
  /** @type {DropdownDef} */
972
979
  var fontFamilyBtn = {
973
980
  name: "fontFamily",
@@ -1090,9 +1097,122 @@
1090
1097
  var fullscreenBtn = btn("fullscreen", "expand", "Fullscreen", (ctx) => ctx.invoke("fullscreen.toggle"), (ctx) => ctx.invoke("fullscreen.isActive"));
1091
1098
  var shortcutsBtn = btn("shortcuts", "keyboard", "Keyboard Shortcuts (Ctrl+Shift+/)", (ctx) => ctx.invoke("shortcutsDialog.show"));
1092
1099
  var findBtn = btn("find", "search", "Find (Ctrl+F)", (ctx) => ctx.invoke("findReplace.show", "find"));
1100
+ var findReplaceBtn = btn("findReplace", "find-replace", "Find & Replace (Ctrl+H)", (ctx) => ctx.invoke("findReplace.show", "replace"));
1093
1101
  var inlineCodeBtn = btn("inlineCode", "inline-code", "Inline Code (Ctrl+`)", (ctx) => ctx.invoke("editor.inlineCode"), () => isInlineCode());
1094
1102
  var checklistBtn = btn("checklist", "checklist", "Checklist", (ctx) => ctx.invoke("editor.toggleChecklist"), () => isInChecklist());
1095
1103
  var printBtn = btn("print", "print", "Print", (ctx) => ctx.invoke("editor.print"));
1104
+ /** @type {{ name: string, type: 'colorpicker', icon: string, tooltip: string, defaultColor: string, action: Function }} */
1105
+ var foreColorBtn = {
1106
+ name: "foreColor",
1107
+ type: "colorpicker",
1108
+ icon: "foreColor",
1109
+ tooltip: "Text Color",
1110
+ defaultColor: "#e11d48",
1111
+ action: (ctx, color) => foreColor(color)
1112
+ };
1113
+ /** @type {{ name: string, type: 'colorpicker', icon: string, tooltip: string, defaultColor: string, action: Function }} */
1114
+ var backColorBtn = {
1115
+ name: "backColor",
1116
+ type: "colorpicker",
1117
+ icon: "backColor",
1118
+ tooltip: "Highlight Color",
1119
+ defaultColor: "#fbbf24",
1120
+ action: (ctx, color) => backColor(color)
1121
+ };
1122
+ /**
1123
+ * The default toolbar button groups.
1124
+ * Each sub-array is a button group (separated by a divider).
1125
+ */
1126
+ var defaultToolbar = [
1127
+ [
1128
+ paragraphStyleBtn,
1129
+ fontFamilyBtn,
1130
+ fontSizeBtn,
1131
+ lineHeightBtn
1132
+ ],
1133
+ [undoBtn, redoBtn],
1134
+ [
1135
+ boldBtn,
1136
+ italicBtn,
1137
+ underlineBtn,
1138
+ strikeBtn,
1139
+ inlineCodeBtn
1140
+ ],
1141
+ [superscriptBtn, subscriptBtn],
1142
+ [foreColorBtn, backColorBtn],
1143
+ [
1144
+ alignLeftBtn,
1145
+ alignCenterBtn,
1146
+ alignRightBtn,
1147
+ alignJustifyBtn
1148
+ ],
1149
+ [
1150
+ ulBtn,
1151
+ olBtn,
1152
+ checklistBtn,
1153
+ indentBtn,
1154
+ outdentBtn
1155
+ ],
1156
+ [
1157
+ hrBtn,
1158
+ linkBtn,
1159
+ imageBtn,
1160
+ videoBtn,
1161
+ tableBtn,
1162
+ emojiBtn,
1163
+ iconBtn
1164
+ ],
1165
+ [
1166
+ removeFormatBtn,
1167
+ codeviewBtn,
1168
+ fullscreenBtn,
1169
+ findBtn,
1170
+ printBtn,
1171
+ shortcutsBtn
1172
+ ]
1173
+ ];
1174
+ var buttons = {
1175
+ boldBtn,
1176
+ italicBtn,
1177
+ underlineBtn,
1178
+ strikeBtn,
1179
+ superscriptBtn,
1180
+ subscriptBtn,
1181
+ alignLeftBtn,
1182
+ alignCenterBtn,
1183
+ alignRightBtn,
1184
+ alignJustifyBtn,
1185
+ ulBtn,
1186
+ olBtn,
1187
+ indentBtn,
1188
+ outdentBtn,
1189
+ undoBtn,
1190
+ redoBtn,
1191
+ hrBtn,
1192
+ linkBtn,
1193
+ imageBtn,
1194
+ videoBtn,
1195
+ emojiBtn,
1196
+ iconBtn,
1197
+ tableBtn,
1198
+ fontSizeBtn,
1199
+ removeFormatBtn,
1200
+ directionBtn,
1201
+ fontFamilyBtn,
1202
+ paragraphStyleBtn,
1203
+ lineHeightBtn,
1204
+ codeviewBtn,
1205
+ fullscreenBtn,
1206
+ shortcutsBtn,
1207
+ findBtn,
1208
+ findReplaceBtn,
1209
+ inlineCodeBtn,
1210
+ checklistBtn,
1211
+ printBtn,
1212
+ foreColorBtn,
1213
+ backColorBtn,
1214
+ defaultToolbar
1215
+ };
1096
1216
  //#endregion
1097
1217
  //#region src/js/settings.js
1098
1218
  /**
@@ -1166,68 +1286,7 @@
1166
1286
  maxHeight: 0,
1167
1287
  focus: false,
1168
1288
  resizable: true,
1169
- toolbar: [
1170
- [
1171
- paragraphStyleBtn,
1172
- fontFamilyBtn,
1173
- fontSizeBtn,
1174
- lineHeightBtn
1175
- ],
1176
- [undoBtn, redoBtn],
1177
- [
1178
- boldBtn,
1179
- italicBtn,
1180
- underlineBtn,
1181
- strikeBtn,
1182
- inlineCodeBtn
1183
- ],
1184
- [superscriptBtn, subscriptBtn],
1185
- [{
1186
- name: "foreColor",
1187
- type: "colorpicker",
1188
- icon: "foreColor",
1189
- tooltip: "Text Color",
1190
- defaultColor: "#e11d48",
1191
- action: (ctx, color) => foreColor(color)
1192
- }, {
1193
- name: "backColor",
1194
- type: "colorpicker",
1195
- icon: "backColor",
1196
- tooltip: "Highlight Color",
1197
- defaultColor: "#fbbf24",
1198
- action: (ctx, color) => backColor(color)
1199
- }],
1200
- [
1201
- alignLeftBtn,
1202
- alignCenterBtn,
1203
- alignRightBtn,
1204
- alignJustifyBtn
1205
- ],
1206
- [
1207
- ulBtn,
1208
- olBtn,
1209
- checklistBtn,
1210
- indentBtn,
1211
- outdentBtn
1212
- ],
1213
- [
1214
- hrBtn,
1215
- linkBtn,
1216
- imageBtn,
1217
- videoBtn,
1218
- tableBtn,
1219
- emojiBtn,
1220
- iconBtn
1221
- ],
1222
- [
1223
- removeFormatBtn,
1224
- codeviewBtn,
1225
- fullscreenBtn,
1226
- findBtn,
1227
- printBtn,
1228
- shortcutsBtn
1229
- ]
1230
- ],
1289
+ toolbar: defaultToolbar,
1231
1290
  useBootstrap: false,
1232
1291
  toolbarButtonClass: "btn btn-sm btn-light",
1233
1292
  useFontAwesome: true,
@@ -1448,6 +1507,7 @@
1448
1507
  findPlaceholder: "Find…",
1449
1508
  searchAriaLabel: "Search text",
1450
1509
  caseSensitive: "\xA0Case sensitive",
1510
+ wholeWord: "Whole Word",
1451
1511
  prevBtn: "← Prev",
1452
1512
  nextBtn: "Next →",
1453
1513
  replacePlaceholder: "Replace with…",
@@ -1455,8 +1515,15 @@
1455
1515
  replaceBtn: "Replace",
1456
1516
  replaceAllBtn: "Replace All",
1457
1517
  noResults: "No results",
1518
+ useRegex: "Use Regular Expression",
1458
1519
  close: "×"
1459
1520
  },
1521
+ autoSaveRestore: {
1522
+ found: "Draft found. Restore?",
1523
+ foundAt: "Draft from {date}. Restore?",
1524
+ restore: "Restore",
1525
+ discard: "Discard"
1526
+ },
1460
1527
  shortcutsDialog: {
1461
1528
  title: "Keyboard Shortcuts",
1462
1529
  ariaLabel: "Keyboard Shortcuts",
@@ -1600,7 +1667,8 @@
1600
1667
  enableWordWrap: "Enable Word Wrap",
1601
1668
  disableWordWrap: "Disable Word Wrap",
1602
1669
  convertToParagraph: "Convert to Paragraph",
1603
- deleteCodeBlock: "Delete Code Block"
1670
+ deleteCodeBlock: "Delete Code Block",
1671
+ lineNumbers: "Toggle Line Numbers"
1604
1672
  },
1605
1673
  table: {
1606
1674
  ariaLabel: "Table actions",
@@ -1617,14 +1685,26 @@
1617
1685
  columnWidth: "Column Width",
1618
1686
  rowHeight: "Row Height",
1619
1687
  tableBorderWidth: "Table Border Width",
1688
+ tableBorderColor: "Table Border Color",
1620
1689
  deleteTable: "Delete Table",
1690
+ cellAlignLeft: "Align Left",
1691
+ cellAlignCenter: "Align Center",
1692
+ cellAlignRight: "Align Right",
1693
+ cellAlignJustify: "Align Justify",
1694
+ toggleHeaderRow: "Toggle Header Row",
1621
1695
  cellBackground: "Cell Background",
1622
1696
  noShading: "No Shading",
1697
+ noBorderColor: "No Border Color",
1623
1698
  columnWidthPx: "Column Width (px)",
1624
1699
  rowHeightPx: "Row Height (px)",
1625
1700
  tableBorderWidthPx: "Table Border Width (px)",
1626
1701
  cancelBtn: "Cancel",
1627
- applyBtn: "Apply"
1702
+ applyBtn: "Apply",
1703
+ sortAsc: "Sort Ascending",
1704
+ sortDesc: "Sort Descending",
1705
+ exportCSV: "Export as CSV",
1706
+ cellPadding: "Cell Padding",
1707
+ cellPaddingPx: "Cell Padding (px)"
1628
1708
  },
1629
1709
  video: {
1630
1710
  ariaLabel: "Video actions",
@@ -1816,6 +1896,7 @@
1816
1896
  replaceBtn: "Thay thế",
1817
1897
  replaceAllBtn: "Thay thế tất cả",
1818
1898
  noResults: "Không có kết quả",
1899
+ useRegex: "Dùng biểu thức chính quy",
1819
1900
  close: "×"
1820
1901
  },
1821
1902
  shortcutsDialog: {
@@ -1957,7 +2038,8 @@
1957
2038
  enableWordWrap: "Bật xuống dòng",
1958
2039
  disableWordWrap: "Tắt xuống dòng",
1959
2040
  convertToParagraph: "Chuyển thành đoạn văn",
1960
- deleteCodeBlock: "Xóa khối mã"
2041
+ deleteCodeBlock: "Xóa khối mã",
2042
+ lineNumbers: "Bật/Tắt số dòng"
1961
2043
  },
1962
2044
  table: {
1963
2045
  ariaLabel: "Hành động bảng",
@@ -1981,7 +2063,12 @@
1981
2063
  rowHeightPx: "Chiều cao hàng (px)",
1982
2064
  tableBorderWidthPx: "Độ rộng viền bảng (px)",
1983
2065
  cancelBtn: "Hủy",
1984
- applyBtn: "Áp dụng"
2066
+ applyBtn: "Áp dụng",
2067
+ sortAsc: "Sắp xếp tăng dần",
2068
+ sortDesc: "Sắp xếp giảm dần",
2069
+ exportCSV: "Xuất CSV",
2070
+ cellPadding: "Khoảng đệm ô",
2071
+ cellPaddingPx: "Khoảng đệm ô (px)"
1985
2072
  },
1986
2073
  video: {
1987
2074
  ariaLabel: "Hành động video",
@@ -1999,6 +2086,12 @@
1999
2086
  errors: {
2000
2087
  imageFormat: (type) => `Định dạng "${type}" không được hỗ trợ hiển thị trên trình duyệt. Vui lòng chuyển đổi sang JPEG, PNG hoặc WebP.`,
2001
2088
  imageSize: (maxSize) => `Tệp hình ảnh quá lớn. Kích thước tối đa cho phép là ${maxSize} MB.`
2089
+ },
2090
+ autoSaveRestore: {
2091
+ found: "Tìm thấy bản nháp. Khôi phục?",
2092
+ foundAt: "Bản nháp từ {date}. Khôi phục?",
2093
+ restore: "Khôi phục",
2094
+ discard: "Bỏ qua"
2002
2095
  }
2003
2096
  },
2004
2097
  ja: {
@@ -2148,6 +2241,7 @@
2148
2241
  replaceAriaLabel: "置換後のテキスト",
2149
2242
  replaceBtn: "置換",
2150
2243
  noResults: "結果なし",
2244
+ useRegex: "正規表現を使用",
2151
2245
  replaceAllBtn: "すべて置換",
2152
2246
  close: "×"
2153
2247
  },
@@ -2290,7 +2384,8 @@
2290
2384
  enableWordWrap: "折り返しを有効にする",
2291
2385
  disableWordWrap: "折り返しを無効にする",
2292
2386
  convertToParagraph: "段落に変換",
2293
- deleteCodeBlock: "コードブロックを削除"
2387
+ deleteCodeBlock: "コードブロックを削除",
2388
+ lineNumbers: "行番号を切り替え"
2294
2389
  },
2295
2390
  table: {
2296
2391
  ariaLabel: "テーブル操作",
@@ -2312,7 +2407,12 @@
2312
2407
  rowHeightPx: "行の高さ (px)",
2313
2408
  tableBorderWidthPx: "テーブルの枠幅 (px)",
2314
2409
  cancelBtn: "キャンセル",
2315
- applyBtn: "適用"
2410
+ applyBtn: "適用",
2411
+ sortAsc: "昇順で並べ替え",
2412
+ sortDesc: "降順で並べ替え",
2413
+ exportCSV: "CSVとしてエクスポート",
2414
+ cellPadding: "セルの余白",
2415
+ cellPaddingPx: "セルの余白 (px)"
2316
2416
  },
2317
2417
  video: {
2318
2418
  ariaLabel: "動画操作",
@@ -2330,6 +2430,12 @@
2330
2430
  errors: {
2331
2431
  imageFormat: (type) => `形式 "${type}" はブラウザでの表示をサポートしていません。JPEG、PNG、または WebP に変換してください。`,
2332
2432
  imageSize: (maxSize) => `画像ファイルが大きすぎます。最大許容サイズは ${maxSize} MB です。`
2433
+ },
2434
+ autoSaveRestore: {
2435
+ found: "下書きが見つかりました。復元しますか?",
2436
+ foundAt: "{date} の下書きが見つかりました。復元しますか?",
2437
+ restore: "復元",
2438
+ discard: "破棄"
2333
2439
  }
2334
2440
  },
2335
2441
  zh: {
@@ -2479,6 +2585,7 @@
2479
2585
  replaceAriaLabel: "替换为",
2480
2586
  replaceBtn: "替换",
2481
2587
  noResults: "没有结果",
2588
+ useRegex: "使用正则表达式",
2482
2589
  replaceAllBtn: "全部替换",
2483
2590
  close: "×"
2484
2591
  },
@@ -2621,7 +2728,8 @@
2621
2728
  enableWordWrap: "启用自动换行",
2622
2729
  disableWordWrap: "禁用自动换行",
2623
2730
  convertToParagraph: "转换为段落",
2624
- deleteCodeBlock: "删除代码块"
2731
+ deleteCodeBlock: "删除代码块",
2732
+ lineNumbers: "切换行号"
2625
2733
  },
2626
2734
  table: {
2627
2735
  ariaLabel: "表格操作",
@@ -2643,7 +2751,12 @@
2643
2751
  rowHeightPx: "行高 (px)",
2644
2752
  tableBorderWidthPx: "表格边框宽度 (px)",
2645
2753
  cancelBtn: "取消",
2646
- applyBtn: "应用"
2754
+ applyBtn: "应用",
2755
+ sortAsc: "升序排列",
2756
+ sortDesc: "降序排列",
2757
+ exportCSV: "导出为 CSV",
2758
+ cellPadding: "单元格内边距",
2759
+ cellPaddingPx: "单元格内边距 (px)"
2647
2760
  },
2648
2761
  video: {
2649
2762
  ariaLabel: "视频操作",
@@ -2661,6 +2774,12 @@
2661
2774
  errors: {
2662
2775
  imageFormat: (type) => `格式 "${type}" 不支持在浏览器中显示。请转换为 JPEG、PNG 或 WebP。`,
2663
2776
  imageSize: (maxSize) => `图片文件过大。最大允许大小为 ${maxSize} MB。`
2777
+ },
2778
+ autoSaveRestore: {
2779
+ found: "找到草稿。是否恢复?",
2780
+ foundAt: "发现 {date} 的草稿。是否恢复?",
2781
+ restore: "恢复",
2782
+ discard: "放弃"
2664
2783
  }
2665
2784
  },
2666
2785
  fr: {
@@ -2810,6 +2929,7 @@
2810
2929
  replaceAriaLabel: "Remplacer par",
2811
2930
  replaceBtn: "Remplacer",
2812
2931
  noResults: "Aucun résultat",
2932
+ useRegex: "Utiliser une expression régulière",
2813
2933
  replaceAllBtn: "Tout remplacer",
2814
2934
  close: "×"
2815
2935
  },
@@ -2952,7 +3072,8 @@
2952
3072
  enableWordWrap: "Activer le retour à la ligne",
2953
3073
  disableWordWrap: "Désactiver le retour à la ligne",
2954
3074
  convertToParagraph: "Convertir en paragraphe",
2955
- deleteCodeBlock: "Supprimer le bloc de code"
3075
+ deleteCodeBlock: "Supprimer le bloc de code",
3076
+ lineNumbers: "Activer/désactiver les numéros de ligne"
2956
3077
  },
2957
3078
  table: {
2958
3079
  ariaLabel: "Actions du tableau",
@@ -2974,7 +3095,12 @@
2974
3095
  rowHeightPx: "Hauteur de ligne (px)",
2975
3096
  tableBorderWidthPx: "Épaisseur des bordures (px)",
2976
3097
  cancelBtn: "Annuler",
2977
- applyBtn: "Appliquer"
3098
+ applyBtn: "Appliquer",
3099
+ sortAsc: "Trier par ordre croissant",
3100
+ sortDesc: "Trier par ordre décroissant",
3101
+ exportCSV: "Exporter en CSV",
3102
+ cellPadding: "Rembourrage des cellules",
3103
+ cellPaddingPx: "Rembourrage des cellules (px)"
2978
3104
  },
2979
3105
  video: {
2980
3106
  ariaLabel: "Actions de la vidéo",
@@ -2992,6 +3118,12 @@
2992
3118
  errors: {
2993
3119
  imageFormat: (type) => `Le format "${type}" n'est pas pris en charge par le navigateur. Veuillez le convertir en JPEG, PNG ou WebP.`,
2994
3120
  imageSize: (maxSize) => `Le fichier image est trop volumineux. La taille maximale autorisée est de ${maxSize}\u00a0Mo.`
3121
+ },
3122
+ autoSaveRestore: {
3123
+ found: "Brouillon trouvé. Restaurer ?",
3124
+ foundAt: "Brouillon du {date}. Restaurer ?",
3125
+ restore: "Restaurer",
3126
+ discard: "Ignorer"
2995
3127
  }
2996
3128
  },
2997
3129
  de: {
@@ -3141,6 +3273,7 @@
3141
3273
  replaceAriaLabel: "Ersetzen durch",
3142
3274
  replaceBtn: "Ersetzen",
3143
3275
  noResults: "Keine Ergebnisse",
3276
+ useRegex: "Regulären Ausdruck verwenden",
3144
3277
  replaceAllBtn: "Alle ersetzen",
3145
3278
  close: "×"
3146
3279
  },
@@ -3283,7 +3416,8 @@
3283
3416
  enableWordWrap: "Zeilenumbruch aktivieren",
3284
3417
  disableWordWrap: "Zeilenumbruch deaktivieren",
3285
3418
  convertToParagraph: "In Absatz umwandeln",
3286
- deleteCodeBlock: "Codeblock löschen"
3419
+ deleteCodeBlock: "Codeblock löschen",
3420
+ lineNumbers: "Zeilennummern umschalten"
3287
3421
  },
3288
3422
  table: {
3289
3423
  ariaLabel: "Tabellen-Aktionen",
@@ -3305,7 +3439,12 @@
3305
3439
  rowHeightPx: "Zeilenhöhe (px)",
3306
3440
  tableBorderWidthPx: "Tabellenrahmenbreite (px)",
3307
3441
  cancelBtn: "Abbrechen",
3308
- applyBtn: "Anwenden"
3442
+ applyBtn: "Anwenden",
3443
+ sortAsc: "Aufsteigend sortieren",
3444
+ sortDesc: "Absteigend sortieren",
3445
+ exportCSV: "Als CSV exportieren",
3446
+ cellPadding: "Zellauffüllung",
3447
+ cellPaddingPx: "Zellauffüllung (px)"
3309
3448
  },
3310
3449
  video: {
3311
3450
  ariaLabel: "Video-Aktionen",
@@ -3323,6 +3462,12 @@
3323
3462
  errors: {
3324
3463
  imageFormat: (type) => `Das Format „${type}" wird in Webbrowsern nicht unterstützt. Bitte konvertieren Sie es zuerst in JPEG, PNG oder WebP.`,
3325
3464
  imageSize: (maxSize) => `Die Bilddatei ist zu groß. Die maximal zulässige Größe beträgt ${maxSize} MB.`
3465
+ },
3466
+ autoSaveRestore: {
3467
+ found: "Entwurf gefunden. Wiederherstellen?",
3468
+ foundAt: "Entwurf vom {date}. Wiederherstellen?",
3469
+ restore: "Wiederherstellen",
3470
+ discard: "Verwerfen"
3326
3471
  }
3327
3472
  },
3328
3473
  es: {
@@ -3472,6 +3617,7 @@
3472
3617
  replaceAriaLabel: "Reemplazar con",
3473
3618
  replaceBtn: "Reemplazar",
3474
3619
  noResults: "Sin resultados",
3620
+ useRegex: "Usar expresión regular",
3475
3621
  replaceAllBtn: "Reemplazar todo",
3476
3622
  close: "×"
3477
3623
  },
@@ -3614,7 +3760,8 @@
3614
3760
  enableWordWrap: "Activar ajuste de línea",
3615
3761
  disableWordWrap: "Desactivar ajuste de línea",
3616
3762
  convertToParagraph: "Convertir en párrafo",
3617
- deleteCodeBlock: "Eliminar bloque de código"
3763
+ deleteCodeBlock: "Eliminar bloque de código",
3764
+ lineNumbers: "Alternar números de línea"
3618
3765
  },
3619
3766
  table: {
3620
3767
  ariaLabel: "Acciones de tabla",
@@ -3636,7 +3783,12 @@
3636
3783
  rowHeightPx: "Alto de fila (px)",
3637
3784
  tableBorderWidthPx: "Grosor del borde (px)",
3638
3785
  cancelBtn: "Cancelar",
3639
- applyBtn: "Aplicar"
3786
+ applyBtn: "Aplicar",
3787
+ sortAsc: "Ordenar ascendente",
3788
+ sortDesc: "Ordenar descendente",
3789
+ exportCSV: "Exportar como CSV",
3790
+ cellPadding: "Relleno de celda",
3791
+ cellPaddingPx: "Relleno de celda (px)"
3640
3792
  },
3641
3793
  video: {
3642
3794
  ariaLabel: "Acciones de vídeo",
@@ -3654,6 +3806,12 @@
3654
3806
  errors: {
3655
3807
  imageFormat: (type) => `El formato "${type}" no es compatible con los navegadores web. Por favor, conviértalo primero a JPEG, PNG o WebP.`,
3656
3808
  imageSize: (maxSize) => `El archivo de imagen es demasiado grande. El tamaño máximo permitido es ${maxSize} MB.`
3809
+ },
3810
+ autoSaveRestore: {
3811
+ found: "Borrador encontrado. ¿Restaurar?",
3812
+ foundAt: "Borrador del {date}. ¿Restaurar?",
3813
+ restore: "Restaurar",
3814
+ discard: "Descartar"
3657
3815
  }
3658
3816
  },
3659
3817
  ko: {
@@ -3803,6 +3961,7 @@
3803
3961
  replaceAriaLabel: "바꿀 내용",
3804
3962
  replaceBtn: "바꾸기",
3805
3963
  noResults: "결과 없음",
3964
+ useRegex: "정규식 사용",
3806
3965
  replaceAllBtn: "모두 바꾸기",
3807
3966
  close: "×"
3808
3967
  },
@@ -3945,7 +4104,8 @@
3945
4104
  enableWordWrap: "줄 바꿈 사용",
3946
4105
  disableWordWrap: "줄 바꿈 해제",
3947
4106
  convertToParagraph: "단락으로 변환",
3948
- deleteCodeBlock: "코드 블록 삭제"
4107
+ deleteCodeBlock: "코드 블록 삭제",
4108
+ lineNumbers: "줄 번호 전환"
3949
4109
  },
3950
4110
  table: {
3951
4111
  ariaLabel: "표 작업",
@@ -3967,7 +4127,12 @@
3967
4127
  rowHeightPx: "행 높이 (px)",
3968
4128
  tableBorderWidthPx: "표 테두리 너비 (px)",
3969
4129
  cancelBtn: "취소",
3970
- applyBtn: "적용"
4130
+ applyBtn: "적용",
4131
+ sortAsc: "오름차순 정렬",
4132
+ sortDesc: "내림차순 정렬",
4133
+ exportCSV: "CSV로 내보내기",
4134
+ cellPadding: "셀 패딩",
4135
+ cellPaddingPx: "셀 패딩 (px)"
3971
4136
  },
3972
4137
  video: {
3973
4138
  ariaLabel: "동영상 작업",
@@ -3985,6 +4150,12 @@
3985
4150
  errors: {
3986
4151
  imageFormat: (type) => `"${type}" 형식은 웹 브라우저에서 지원되지 않습니다. JPEG, PNG 또는 WebP로 변환해 주세요.`,
3987
4152
  imageSize: (maxSize) => `이미지 파일이 너무 큽니다. 최대 허용 크기는 ${maxSize} MB입니다.`
4153
+ },
4154
+ autoSaveRestore: {
4155
+ found: "초안을 찾았습니다. 복원하시겠습니까?",
4156
+ foundAt: "{date}의 초안을 찾았습니다. 복원하시겠습니까?",
4157
+ restore: "복원",
4158
+ discard: "삭제"
3988
4159
  }
3989
4160
  }
3990
4161
  };
@@ -4181,6 +4352,9 @@
4181
4352
  if (options.theme === "dark") {
4182
4353
  container.classList.add("an-theme-dark");
4183
4354
  document.body.classList.add("an-theme-dark");
4355
+ } else if (options.theme === "auto") {
4356
+ container.classList.add("an-theme-auto");
4357
+ document.body.classList.add("an-theme-auto");
4184
4358
  }
4185
4359
  if (options.readOnly) {
4186
4360
  container.classList.add("an-disabled");
@@ -4406,6 +4580,14 @@
4406
4580
  canRedo() {
4407
4581
  return this.stackOffset < this.stack.length - 1;
4408
4582
  }
4583
+ /** @returns {number} */
4584
+ getUndoCount() {
4585
+ return Math.max(0, this.stackOffset);
4586
+ }
4587
+ /** @returns {number} */
4588
+ getRedoCount() {
4589
+ return Math.max(0, this.stack.length - 1 - this.stackOffset);
4590
+ }
4409
4591
  };
4410
4592
  //#endregion
4411
4593
  //#region src/js/editing/Table.js
@@ -5478,6 +5660,12 @@
5478
5660
  canRedo() {
5479
5661
  return this._history ? this._history.canRedo() : false;
5480
5662
  }
5663
+ getUndoCount() {
5664
+ return this._history ? this._history.getUndoCount() : 0;
5665
+ }
5666
+ getRedoCount() {
5667
+ return this._history ? this._history.getRedoCount() : 0;
5668
+ }
5481
5669
  bold() {
5482
5670
  bold();
5483
5671
  this.afterCommand();
@@ -6339,9 +6527,21 @@
6339
6527
  this._bindResize(handle);
6340
6528
  this.el.appendChild(handle);
6341
6529
  }
6342
- this._wordCountEl = createElement("span", { class: "an-word-count" });
6343
- this._charCountEl = createElement("span", { class: "an-char-count" });
6344
- const info = createElement("div", { class: "an-status-info" });
6530
+ this._wordCountEl = createElement("span", {
6531
+ class: "an-word-count",
6532
+ role: "status",
6533
+ "aria-live": "polite",
6534
+ "aria-atomic": "true"
6535
+ });
6536
+ this._charCountEl = createElement("span", {
6537
+ class: "an-char-count",
6538
+ "aria-live": "polite",
6539
+ "aria-atomic": "true"
6540
+ });
6541
+ const info = createElement("div", {
6542
+ class: "an-status-info",
6543
+ "aria-label": "Editor statistics"
6544
+ });
6345
6545
  info.appendChild(this._wordCountEl);
6346
6546
  info.appendChild(this._charCountEl);
6347
6547
  this.el.appendChild(info);
@@ -6581,6 +6781,15 @@
6581
6781
  if (!clipboardData) return;
6582
6782
  const forcePlain = this._forcePlain;
6583
6783
  this._forcePlain = false;
6784
+ const maxBytes = (this.options.maxPasteSize ?? 5) * 1024 * 1024;
6785
+ if (maxBytes > 0) {
6786
+ const text = clipboardData.getData("text/plain") || "";
6787
+ const html = clipboardData.getData("text/html") || "";
6788
+ if (Math.max(text.length, html.length) > maxBytes) {
6789
+ event.preventDefault();
6790
+ return;
6791
+ }
6792
+ }
6584
6793
  if (clipboardData.items) {
6585
6794
  const imageItems = Array.from(clipboardData.items).filter((item) => item.kind === "file" && item.type.startsWith("image/"));
6586
6795
  if (imageItems.length > 0) {
@@ -6999,6 +7208,10 @@
6999
7208
  this._firstInput = null;
7000
7209
  this._removeTrap = null;
7001
7210
  }
7211
+ /** @returns {HTMLElement} */
7212
+ _buildDialog() {
7213
+ throw new Error("_buildDialog() must be implemented by subclass");
7214
+ }
7002
7215
  initialize() {
7003
7216
  this._dialog = this._buildDialog();
7004
7217
  document.body.appendChild(this._dialog);
@@ -7699,6 +7912,7 @@
7699
7912
  const aspectRatio = startW / (startH || 1);
7700
7913
  const isCorner = pos.length === 2;
7701
7914
  const editable = this.context.layoutInfo.editable;
7915
+ const minSz = this.context.options?.minImageSize ?? 20;
7702
7916
  let _raf = null;
7703
7917
  const onMove = (me) => {
7704
7918
  if (_raf !== null) return;
@@ -7711,15 +7925,15 @@
7711
7925
  const maxW = editable.clientWidth || Infinity;
7712
7926
  let newW = startW;
7713
7927
  let newH = startH;
7714
- if (pos.includes("e")) newW = Math.max(20, startW + dx);
7715
- if (pos.includes("w")) newW = Math.max(20, startW - dx);
7716
- if (pos.includes("s")) newH = Math.max(20, startH + dy);
7717
- if (pos.includes("n")) newH = Math.max(20, startH - dy);
7928
+ if (pos.includes("e")) newW = Math.max(minSz, startW + dx);
7929
+ if (pos.includes("w")) newW = Math.max(minSz, startW - dx);
7930
+ if (pos.includes("s")) newH = Math.max(minSz, startH + dy);
7931
+ if (pos.includes("n")) newH = Math.max(minSz, startH - dy);
7718
7932
  newW = Math.min(newW, maxW);
7719
- if (isCorner) if (Math.abs(dx) >= Math.abs(dy)) newH = Math.max(20, Math.round(newW / aspectRatio));
7933
+ if (isCorner) if (Math.abs(dx) >= Math.abs(dy)) newH = Math.max(minSz, Math.round(newW / aspectRatio));
7720
7934
  else {
7721
- newW = Math.min(Math.max(20, Math.round(newH * aspectRatio)), maxW);
7722
- newH = Math.max(20, Math.round(newW / aspectRatio));
7935
+ newW = Math.min(Math.max(minSz, Math.round(newH * aspectRatio)), maxW);
7936
+ newH = Math.max(minSz, Math.round(newW / aspectRatio));
7723
7937
  }
7724
7938
  img.style.width = `${newW}px`;
7725
7939
  img.style.height = `${newH}px`;
@@ -8781,7 +8995,17 @@
8781
8995
  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>`,
8782
8996
  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>`,
8783
8997
  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>`,
8784
- 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>`
8998
+ 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>`,
8999
+ borderColor: `<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="14" rx="1"/><line x1="3" y1="10" x2="21" y2="10" stroke-width="1.5"/><line x1="12" y1="3" x2="12" y2="17" stroke-width="1.5"/><path d="M3 21h18" stroke-width="3"/></svg>`,
9000
+ alignLeft: `<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="21" y1="6" x2="3" y2="6"/><line x1="15" y1="12" x2="3" y2="12"/><line x1="17" y1="18" x2="3" y2="18"/></svg>`,
9001
+ alignCenter: `<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="21" y1="6" x2="3" y2="6"/><line x1="17" y1="12" x2="7" y2="12"/><line x1="19" y1="18" x2="5" y2="18"/></svg>`,
9002
+ alignRight: `<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="21" y1="6" x2="3" y2="6"/><line x1="21" y1="12" x2="9" y2="12"/><line x1="21" y1="18" x2="7" y2="18"/></svg>`,
9003
+ alignJustify: `<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="21" y1="6" x2="3" y2="6"/><line x1="21" y1="12" x2="3" y2="12"/><line x1="21" y1="18" x2="3" y2="18"/></svg>`,
9004
+ headerRow: `<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"/><rect x="3" y="3" width="18" height="8" rx="1" fill="currentColor" opacity="0.2"/><line x1="3" y1="11" x2="21" y2="11"/><line x1="3" y1="16" x2="21" y2="16"/><line x1="9" y1="11" x2="9" y2="21"/><line x1="15" y1="11" x2="15" y2="21"/></svg>`,
9005
+ sortAsc: `<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="6" x2="11" y2="6"/><line x1="4" y1="12" x2="11" y2="12"/><line x1="4" y1="18" x2="13" y2="18"/><path d="M15 9l3-3 3 3"/><line x1="18" y1="6" x2="18" y2="18"/></svg>`,
9006
+ sortDesc: `<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="6" x2="13" y2="6"/><line x1="4" y1="12" x2="11" y2="12"/><line x1="4" y1="18" x2="11" y2="18"/><path d="M15 15l3 3 3-3"/><line x1="18" y1="6" x2="18" y2="18"/></svg>`,
9007
+ exportCSV: `<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="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>`,
9008
+ cellPadding: `<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"/><rect x="7" y="7" width="10" height="10" rx="0.5" stroke-dasharray="2 1.5"/></svg>`
8785
9009
  };
8786
9010
  var SHADE_PRESETS = [
8787
9011
  "#000000",
@@ -8826,6 +9050,10 @@
8826
9050
  this._shadePopover = null;
8827
9051
  this._shadeTitleEl = null;
8828
9052
  this._shadeColorStrip = null;
9053
+ this._borderColorPopover = null;
9054
+ this._borderColorTitleEl = null;
9055
+ this._borderColorStrip = null;
9056
+ this._borderColorNoBtn = null;
8829
9057
  this._selectMode = false;
8830
9058
  this._selectedCells = [];
8831
9059
  this._selectStart = null;
@@ -8840,6 +9068,8 @@
8840
9068
  document.body.appendChild(this._sizePopover);
8841
9069
  this._shadePopover = this._buildCellShadePopover();
8842
9070
  document.body.appendChild(this._shadePopover);
9071
+ this._borderColorPopover = this._buildBorderColorPopover();
9072
+ document.body.appendChild(this._borderColorPopover);
8843
9073
  const editable = this.context.layoutInfo.editable;
8844
9074
  this._editable = editable;
8845
9075
  const onSelMousedown = (e) => {
@@ -8881,7 +9111,7 @@
8881
9111
  }, { passive: true }), on(document, "click", (e) => {
8882
9112
  const et = e.target;
8883
9113
  if (this._selectMode && this._activeTable?.contains(et)) return;
8884
- if (this._activeTable && !this._activeTable.contains(et) && !this._el.contains(et) && !this._sizePopover?.contains(et)) this._hide();
9114
+ if (this._activeTable && !this._activeTable.contains(et) && !this._el.contains(et) && !this._sizePopover?.contains(et) && !this._borderColorPopover?.contains(et)) this._hide();
8885
9115
  }), on(document, "selectionchange", () => this._syncShadeStrip()), on(globalThis, "scroll", () => this._hide(), { passive: true }), on(globalThis, "resize", () => this._hide(), { passive: true }));
8886
9116
  this._initResize();
8887
9117
  return this;
@@ -9016,6 +9246,8 @@
9016
9246
  this._sizePopover = null;
9017
9247
  if (this._shadePopover?.parentNode) this._shadePopover.remove();
9018
9248
  this._shadePopover = null;
9249
+ if (this._borderColorPopover?.parentNode) this._borderColorPopover.remove();
9250
+ this._borderColorPopover = null;
9019
9251
  }
9020
9252
  _buildTooltip() {
9021
9253
  const L = this.context.locale.tooltips.table;
@@ -9039,10 +9271,18 @@
9039
9271
  el.appendChild(this._makeBtn(ICONS$2.colLeft, L.addColumnLeft, () => this._addColumn("left")));
9040
9272
  el.appendChild(this._makeBtn(ICONS$2.colRight, L.addColumnRight, () => this._addColumn("right")));
9041
9273
  el.appendChild(this._makeBtn(ICONS$2.deleteCol, L.deleteColumn, () => this._deleteColumn()));
9274
+ el.appendChild(this._makeBtn(ICONS$2.sortAsc, L.sortAsc, () => this._sortColumn("asc")));
9275
+ el.appendChild(this._makeBtn(ICONS$2.sortDesc, L.sortDesc, () => this._sortColumn("desc")));
9042
9276
  el.appendChild(this._sep());
9043
9277
  el.appendChild(this._makeBtn(ICONS$2.mergeCells, L.mergeCells, () => this._mergeCells()));
9044
9278
  el.appendChild(this._makeBtn(ICONS$2.unmergeCells, L.unmergeCells, () => this._unmergeCells()));
9045
9279
  el.appendChild(this._sep());
9280
+ el.appendChild(this._makeBtn(ICONS$2.alignLeft, L.cellAlignLeft, () => this._applyCellAlign("left")));
9281
+ el.appendChild(this._makeBtn(ICONS$2.alignCenter, L.cellAlignCenter, () => this._applyCellAlign("center")));
9282
+ el.appendChild(this._makeBtn(ICONS$2.alignRight, L.cellAlignRight, () => this._applyCellAlign("right")));
9283
+ el.appendChild(this._makeBtn(ICONS$2.alignJustify, L.cellAlignJustify, () => this._applyCellAlign("justify")));
9284
+ el.appendChild(this._makeBtn(ICONS$2.headerRow, L.toggleHeaderRow, () => this._toggleHeaderRow()));
9285
+ el.appendChild(this._sep());
9046
9286
  const shadeBtn = createElement("button", {
9047
9287
  type: "button",
9048
9288
  class: "an-link-tooltip-btn an-link-tooltip-btn--shade",
@@ -9064,12 +9304,33 @@
9064
9304
  el.appendChild(this._makeBtn(ICONS$2.colWidth, L.columnWidth, () => this._openSizePopover("col")));
9065
9305
  el.appendChild(this._makeBtn(ICONS$2.rowHeight, L.rowHeight, () => this._openSizePopover("row")));
9066
9306
  el.appendChild(this._makeBtn(ICONS$2.tableBorder, L.tableBorderWidth, () => this._openSizePopover("border")));
9307
+ el.appendChild(this._makeBtn(ICONS$2.cellPadding, L.cellPadding, () => this._openSizePopover("cellPadding")));
9308
+ const borderColorBtn = createElement("button", {
9309
+ type: "button",
9310
+ class: "an-link-tooltip-btn an-link-tooltip-btn--shade",
9311
+ title: L.tableBorderColor
9312
+ });
9313
+ const borderColorSvgWrap = createElement("span", { class: "an-bubble-btn-svg" });
9314
+ borderColorSvgWrap.innerHTML = ICONS$2.borderColor;
9315
+ const borderColorStrip = createElement("span", { class: "an-link-tooltip-color-strip" });
9316
+ borderColorBtn.appendChild(borderColorSvgWrap);
9317
+ borderColorBtn.appendChild(borderColorStrip);
9318
+ this._borderColorStrip = borderColorStrip;
9319
+ this._disposers.push(on(borderColorBtn, "click", (e) => {
9320
+ e.preventDefault();
9321
+ e.stopPropagation();
9322
+ this._openBorderColorPopover();
9323
+ }));
9324
+ el.appendChild(borderColorBtn);
9067
9325
  el.appendChild(this._sep());
9068
9326
  el.appendChild(this._makeBtn(ICONS$2.deleteTable, L.deleteTable, () => this._deleteTable(), true));
9327
+ el.appendChild(this._sep());
9328
+ el.appendChild(this._makeBtn(ICONS$2.exportCSV, L.exportCSV, () => this._exportTableCSV()));
9069
9329
  this._disposers.push(on(el, "mouseenter", () => this._clearTimers()), on(el, "mouseleave", () => {
9070
9330
  if (this._selectMode) return;
9071
9331
  if (this._sizePopover && this._sizePopover.style.display !== "none") return;
9072
9332
  if (this._shadePopover && this._shadePopover.style.display !== "none") return;
9333
+ if (this._borderColorPopover && this._borderColorPopover.style.display !== "none") return;
9073
9334
  this._scheduleHide();
9074
9335
  }));
9075
9336
  return el;
@@ -9117,6 +9378,7 @@
9117
9378
  if (!this._activeTable) return;
9118
9379
  this._el.style.display = "flex";
9119
9380
  this._syncShadeStrip();
9381
+ this._syncBorderColorStrip();
9120
9382
  requestAnimationFrame(() => {
9121
9383
  if (this._activeTable) this._positionNear(this._activeTable);
9122
9384
  });
@@ -9138,6 +9400,7 @@
9138
9400
  this._clearSelection();
9139
9401
  this._clearTimers();
9140
9402
  this._hideSizePopover();
9403
+ this._hideBorderColorPopover();
9141
9404
  }
9142
9405
  _clearTimers() {
9143
9406
  clearTimeout(this._showTimer);
@@ -9537,6 +9800,19 @@
9537
9800
  });
9538
9801
  this.context.invoke("editor.afterCommand");
9539
9802
  };
9803
+ } else if (type === "cellPadding") {
9804
+ const firstCell = this._getSelectedCells()[0] || this._getCell();
9805
+ const currentPad = firstCell ? Number.parseInt(firstCell.style.padding, 10) || Number.parseInt(firstCell.style.paddingTop, 10) || 4 : 4;
9806
+ this._sizeTitleEl.textContent = this.context.locale.tooltips.table.cellPaddingPx;
9807
+ this._sizeInputEl.min = "0";
9808
+ this._sizeInputEl.max = "40";
9809
+ this._sizeInputEl.value = String(currentPad);
9810
+ this._sizeApply = (val) => {
9811
+ this._getSelectedCells().forEach((c) => {
9812
+ if (c) c.style.padding = `${val}px`;
9813
+ });
9814
+ this.context.invoke("editor.afterCommand");
9815
+ };
9540
9816
  } else {
9541
9817
  const isCol = type === "col";
9542
9818
  const activeCells = this._getSelectedCells().filter((c) => {
@@ -9633,7 +9909,7 @@
9633
9909
  value: "#ffffff"
9634
9910
  });
9635
9911
  const customLabel = createElement("span");
9636
- customLabel.textContent = "Custom…";
9912
+ customLabel.textContent = this.context.locale.contextMenu.customColorLabel;
9637
9913
  this._disposers.push(on(colorInput, "change", () => this._applyCellShade(colorInput.value)));
9638
9914
  customRow.appendChild(colorInput);
9639
9915
  customRow.appendChild(customLabel);
@@ -9674,6 +9950,172 @@
9674
9950
  this._hideCellShadePopover();
9675
9951
  this.context.invoke("editor.afterCommand");
9676
9952
  }
9953
+ _buildBorderColorPopover() {
9954
+ const pop = createElement("div", { class: "an-cell-shade-popover" });
9955
+ pop.style.display = "none";
9956
+ const title = createElement("div", { class: "an-size-popover-title" });
9957
+ pop.appendChild(title);
9958
+ this._borderColorTitleEl = title;
9959
+ const palette = createElement("div", { class: "an-context-color-palette" });
9960
+ SHADE_PRESETS.forEach((color) => {
9961
+ const sw = createElement("div", {
9962
+ class: "an-context-color-swatch",
9963
+ title: color
9964
+ });
9965
+ sw.style.background = color;
9966
+ this._disposers.push(on(sw, "click", (e) => {
9967
+ e.stopPropagation();
9968
+ this._applyBorderColor(color);
9969
+ }));
9970
+ palette.appendChild(sw);
9971
+ });
9972
+ pop.appendChild(palette);
9973
+ const noColorRow = createElement("div", { class: "an-context-color-custom" });
9974
+ const noColorBtn = createElement("button", {
9975
+ type: "button",
9976
+ class: "an-shade-no-color"
9977
+ });
9978
+ this._disposers.push(on(noColorBtn, "click", () => this._applyBorderColor("")));
9979
+ noColorRow.appendChild(noColorBtn);
9980
+ pop.appendChild(noColorRow);
9981
+ this._borderColorNoBtn = noColorBtn;
9982
+ const customRow = createElement("div", { class: "an-context-color-custom" });
9983
+ const colorInput = createElement("input", {
9984
+ type: "color",
9985
+ class: "an-shade-color-input",
9986
+ value: "#000000"
9987
+ });
9988
+ const customLabel = createElement("span");
9989
+ customLabel.textContent = this.context.locale.contextMenu.customColorLabel;
9990
+ this._disposers.push(on(colorInput, "change", () => this._applyBorderColor(colorInput.value)));
9991
+ customRow.appendChild(colorInput);
9992
+ customRow.appendChild(customLabel);
9993
+ pop.appendChild(customRow);
9994
+ this._disposers.push(on(pop, "mousedown", (e) => e.preventDefault()), on(pop, "mouseenter", () => this._clearTimers()), on(pop, "mouseleave", () => this._scheduleHide()), on(document, "click", (e) => {
9995
+ const et = e.target;
9996
+ if (this._borderColorPopover && this._borderColorPopover.style.display !== "none" && !this._borderColorPopover.contains(et) && !this._el?.contains(et)) this._hideBorderColorPopover();
9997
+ }));
9998
+ return pop;
9999
+ }
10000
+ _openBorderColorPopover() {
10001
+ if (!this._borderColorPopover) return;
10002
+ const L = this.context.locale.tooltips.table;
10003
+ if (this._borderColorTitleEl) this._borderColorTitleEl.textContent = L.tableBorderColor;
10004
+ if (this._borderColorNoBtn) this._borderColorNoBtn.textContent = L.noBorderColor;
10005
+ this._borderColorPopover.style.display = "block";
10006
+ requestAnimationFrame(() => {
10007
+ if (!this._borderColorPopover || !this._el) return;
10008
+ const pw = this._borderColorPopover.offsetWidth || 170;
10009
+ const ph = this._borderColorPopover.offsetHeight || 120;
10010
+ const tipRect = this._el.getBoundingClientRect();
10011
+ let left = tipRect.left;
10012
+ let top = tipRect.bottom + 6;
10013
+ if (left + pw > globalThis.innerWidth - 8) left = globalThis.innerWidth - pw - 8;
10014
+ if (top + ph > globalThis.innerHeight - 8) top = tipRect.top - ph - 6;
10015
+ this._borderColorPopover.style.left = `${Math.max(8, left)}px`;
10016
+ this._borderColorPopover.style.top = `${Math.max(8, top)}px`;
10017
+ });
10018
+ }
10019
+ _hideBorderColorPopover() {
10020
+ if (this._borderColorPopover) this._borderColorPopover.style.display = "none";
10021
+ }
10022
+ _applyBorderColor(color) {
10023
+ const table = this._activeTable;
10024
+ if (!table) return;
10025
+ Array.from(table.querySelectorAll("td, th")).forEach((c) => {
10026
+ c.style.borderColor = color;
10027
+ });
10028
+ if (this._borderColorStrip) this._borderColorStrip.style.background = color || "transparent";
10029
+ this._hideBorderColorPopover();
10030
+ this.context.invoke("editor.afterCommand");
10031
+ }
10032
+ _syncBorderColorStrip() {
10033
+ if (!this._borderColorStrip || !this._el || this._el.style.display === "none") return;
10034
+ const firstCell = this._activeTable?.querySelector("td, th");
10035
+ this._borderColorStrip.style.background = firstCell?.style.borderColor || "transparent";
10036
+ }
10037
+ _applyCellAlign(align) {
10038
+ this._getSelectedCells().forEach((c) => {
10039
+ if (c) c.style.textAlign = align;
10040
+ });
10041
+ this.context.invoke("editor.afterCommand");
10042
+ }
10043
+ _toggleHeaderRow() {
10044
+ const table = this._activeTable;
10045
+ if (!table) return;
10046
+ const firstRow = table.querySelector("tr");
10047
+ if (!firstRow) return;
10048
+ if (firstRow.closest("thead") !== null) {
10049
+ let tbody = table.querySelector("tbody");
10050
+ if (!tbody) {
10051
+ tbody = document.createElement("tbody");
10052
+ table.appendChild(tbody);
10053
+ }
10054
+ Array.from(firstRow.cells).forEach((cell) => {
10055
+ const td = document.createElement("td");
10056
+ td.innerHTML = cell.innerHTML;
10057
+ td.style.cssText = cell.style.cssText;
10058
+ firstRow.replaceChild(td, cell);
10059
+ });
10060
+ tbody.insertBefore(firstRow, tbody.firstChild);
10061
+ const thead = table.querySelector("thead");
10062
+ if (thead && thead.rows.length === 0) thead.remove();
10063
+ } else {
10064
+ let thead = table.querySelector("thead");
10065
+ if (!thead) {
10066
+ thead = document.createElement("thead");
10067
+ table.insertBefore(thead, table.firstChild);
10068
+ }
10069
+ Array.from(firstRow.cells).forEach((cell) => {
10070
+ const th = document.createElement("th");
10071
+ th.innerHTML = cell.innerHTML;
10072
+ th.style.cssText = cell.style.cssText;
10073
+ firstRow.replaceChild(th, cell);
10074
+ });
10075
+ thead.appendChild(firstRow);
10076
+ }
10077
+ this.context.invoke("editor.afterCommand");
10078
+ }
10079
+ _sortColumn(direction) {
10080
+ const table = this._activeTable;
10081
+ if (!table) return;
10082
+ const cell = this._getCell();
10083
+ if (!cell) return;
10084
+ const colIdx = getVisualColIndex(cell);
10085
+ if (colIdx === -1) return;
10086
+ const tbody = table.querySelector("tbody") || table;
10087
+ const rows = Array.from(tbody.querySelectorAll(":scope > tr"));
10088
+ if (rows.length < 2) return;
10089
+ rows.sort((a, b) => {
10090
+ const aCell = getCellAtVisualCol(a, colIdx);
10091
+ const bCell = getCellAtVisualCol(b, colIdx);
10092
+ const aText = (aCell?.textContent || "").trim();
10093
+ const bText = (bCell?.textContent || "").trim();
10094
+ const aNum = parseFloat(aText);
10095
+ const bNum = parseFloat(bText);
10096
+ if (!isNaN(aNum) && !isNaN(bNum)) return direction === "asc" ? aNum - bNum : bNum - aNum;
10097
+ return direction === "asc" ? aText.localeCompare(bText) : bText.localeCompare(aText);
10098
+ });
10099
+ rows.forEach((row) => tbody.appendChild(row));
10100
+ this.context.invoke("editor.afterCommand");
10101
+ }
10102
+ _exportTableCSV() {
10103
+ const table = this._activeTable;
10104
+ if (!table) return;
10105
+ const csv = Array.from(table.querySelectorAll("tr")).map((row) => Array.from(row.querySelectorAll("td, th")).map((cell) => {
10106
+ return `"${(cell.textContent || "").trim().replace(/"/g, "\"\"")}"`;
10107
+ }).join(",")).join("\n");
10108
+ const blob = new Blob(["" + csv], { type: "text/csv;charset=utf-8;" });
10109
+ const url = URL.createObjectURL(blob);
10110
+ const a = document.createElement("a");
10111
+ a.href = url;
10112
+ a.download = "table.csv";
10113
+ a.style.display = "none";
10114
+ document.body.appendChild(a);
10115
+ a.click();
10116
+ a.remove();
10117
+ URL.revokeObjectURL(url);
10118
+ }
9677
10119
  };
9678
10120
  //#endregion
9679
10121
  //#region src/js/module/CodeTooltip.js
@@ -9684,7 +10126,8 @@
9684
10126
  copy: `<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="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>`,
9685
10127
  wrapOn: `<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="3" y1="6" x2="21" y2="6"/><path d="M3 12h15a3 3 0 0 1 0 6H3"/><polyline points="6 15 3 18 6 21"/></svg>`,
9686
10128
  toParagraph: `<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="M13 4v16"/><path d="M17 4v16"/><path d="M9 4h8a4 4 0 0 1 0 8H9V4z"/></svg>`,
9687
- deleteCode: `<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"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/></svg>`
10129
+ deleteCode: `<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"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/></svg>`,
10130
+ lineNumbers: `<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="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-2-2-2"/></svg>`
9688
10131
  };
9689
10132
  var CodeTooltip = class {
9690
10133
  /** @param {import('../Context.js').Context} context */
@@ -9696,6 +10139,8 @@
9696
10139
  this._hideTimer = null;
9697
10140
  this._disposers = [];
9698
10141
  this._copyBtn = null;
10142
+ this._wrapBtn = null;
10143
+ this._lineNumbersBtn = null;
9699
10144
  this._langSelect = null;
9700
10145
  this._prismScript = null;
9701
10146
  }
@@ -9776,6 +10221,8 @@
9776
10221
  el.appendChild(this._sep());
9777
10222
  this._wrapBtn = this._makeBtn(ICONS$1.wrapOn, L.toggleWordWrap, () => this._toggleWrap());
9778
10223
  el.appendChild(this._wrapBtn);
10224
+ this._lineNumbersBtn = this._makeBtn(ICONS$1.lineNumbers, L.lineNumbers, () => this._toggleLineNumbers());
10225
+ el.appendChild(this._lineNumbersBtn);
9779
10226
  el.appendChild(this._sep());
9780
10227
  el.appendChild(this._makeBtn(ICONS$1.toParagraph, L.convertToParagraph, () => this._toParagraph()));
9781
10228
  el.appendChild(this._sep());
@@ -9814,6 +10261,7 @@
9814
10261
  this._showTimer = setTimeout(() => {
9815
10262
  this._activePre = pre;
9816
10263
  this._syncWrapBtn();
10264
+ this._syncLineNumbersBtn();
9817
10265
  this._syncLangSelect();
9818
10266
  this._show(pre);
9819
10267
  }, SHOW_DELAY);
@@ -9858,6 +10306,12 @@
9858
10306
  this._wrapBtn.classList.toggle("active", wrapped);
9859
10307
  this._wrapBtn.title = wrapped ? this.context.locale.tooltips.code.disableWordWrap : this.context.locale.tooltips.code.enableWordWrap;
9860
10308
  }
10309
+ _syncLineNumbersBtn() {
10310
+ if (!this._activePre || !this._lineNumbersBtn) return;
10311
+ const on = this._activePre.classList.contains("an-code-line-numbers");
10312
+ this._lineNumbersBtn.classList.toggle("active", on);
10313
+ this._lineNumbersBtn.title = this.context.locale.tooltips.code.lineNumbers;
10314
+ }
9861
10315
  _syncLangSelect() {
9862
10316
  if (!this._activePre || !this._langSelect) return;
9863
10317
  const codeEl = this._activePre.querySelector("code");
@@ -9904,6 +10358,13 @@
9904
10358
  this.context.invoke("editor.afterCommand");
9905
10359
  this._positionNear(pre);
9906
10360
  }
10361
+ _toggleLineNumbers() {
10362
+ const pre = this._activePre;
10363
+ if (!pre) return;
10364
+ pre.classList.toggle("an-code-line-numbers");
10365
+ this._syncLineNumbersBtn();
10366
+ this.context.invoke("editor.afterCommand");
10367
+ }
9907
10368
  /**
9908
10369
  * Applies a language to a given <pre> element: sets classes, data-language,
9909
10370
  * and triggers Prism highlighting. Called by the auto-detect flow.
@@ -13914,12 +14375,16 @@
13914
14375
  this._matches = [];
13915
14376
  this._currentIndex = -1;
13916
14377
  this._caseSensitive = false;
14378
+ this._useRegex = false;
14379
+ this._wholeWord = false;
13917
14380
  /** @type {'find'|'replace'} */
13918
14381
  this._mode = "find";
13919
14382
  /** Cached compiled regex — reused when query and case-sensitivity are unchanged */
13920
14383
  this._queryRegex = null;
13921
14384
  this._lastQuery = null;
13922
14385
  this._lastCaseSensitive = null;
14386
+ this._lastUseRegex = null;
14387
+ this._lastWholeWord = null;
13923
14388
  this._focusTimer = null;
13924
14389
  }
13925
14390
  destroy() {
@@ -14023,6 +14488,20 @@
14023
14488
  "aria-label": "Case sensitive"
14024
14489
  });
14025
14490
  caseBtn.textContent = "Aa";
14491
+ const regexBtn = createElement("button", {
14492
+ type: "button",
14493
+ class: "an-fr-icon-btn",
14494
+ title: L.useRegex,
14495
+ "aria-label": L.useRegex
14496
+ });
14497
+ regexBtn.textContent = ".*";
14498
+ const wholeWordBtn = createElement("button", {
14499
+ type: "button",
14500
+ class: "an-fr-icon-btn",
14501
+ title: L.wholeWord,
14502
+ "aria-label": L.wholeWord
14503
+ });
14504
+ wholeWordBtn.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" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="7" width="18" height="10" rx="2"/><line x1="7" y1="21" x2="7" y2="17"/><line x1="17" y1="21" x2="17" y2="17"/></svg>`;
14026
14505
  const prevBtn = createElement("button", {
14027
14506
  type: "button",
14028
14507
  class: "an-fr-icon-btn",
@@ -14039,7 +14518,7 @@
14039
14518
  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>`;
14040
14519
  const counter = createElement("span", { class: "an-fr-counter" });
14041
14520
  this._counterEl = counter;
14042
- searchBar.append(findInput, caseCheckbox, caseBtn, prevBtn, nextBtn, counter);
14521
+ searchBar.append(findInput, caseCheckbox, caseBtn, regexBtn, wholeWordBtn, prevBtn, nextBtn, counter);
14043
14522
  box.appendChild(searchBar);
14044
14523
  const replaceRow = createElement("div", { class: "an-fr-replace-row" });
14045
14524
  replaceRow.style.display = "none";
@@ -14100,7 +14579,21 @@
14100
14579
  this._replace();
14101
14580
  }
14102
14581
  });
14103
- this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
14582
+ const dRegex = on(regexBtn, "click", () => {
14583
+ this._useRegex = !this._useRegex;
14584
+ regexBtn.classList.toggle("an-fr-icon-btn--active", this._useRegex);
14585
+ this._queryRegex = null;
14586
+ this._lastQuery = null;
14587
+ this._onSearch();
14588
+ });
14589
+ const dWholeWord = on(wholeWordBtn, "click", () => {
14590
+ this._wholeWord = !this._wholeWord;
14591
+ wholeWordBtn.classList.toggle("an-fr-icon-btn--active", this._wholeWord);
14592
+ this._queryRegex = null;
14593
+ this._lastQuery = null;
14594
+ this._onSearch();
14595
+ });
14596
+ this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, dRegex, dWholeWord);
14104
14597
  return overlay;
14105
14598
  }
14106
14599
  _onSearch() {
@@ -14158,13 +14651,21 @@
14158
14651
  */
14159
14652
  _findRawMatches(query, root) {
14160
14653
  const results = [];
14161
- if (this._lastQuery !== query || this._lastCaseSensitive !== this._caseSensitive) {
14654
+ if (this._lastQuery !== query || this._lastCaseSensitive !== this._caseSensitive || this._lastUseRegex !== this._useRegex || this._lastWholeWord !== this._wholeWord) {
14162
14655
  const flags = this._caseSensitive ? "g" : "gi";
14163
- const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
14164
- this._queryRegex = new RegExp(escaped, flags);
14656
+ try {
14657
+ let pattern = this._useRegex ? query : query.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
14658
+ if (this._wholeWord) pattern = `\\b${pattern}\\b`;
14659
+ this._queryRegex = new RegExp(pattern, flags);
14660
+ } catch (_) {
14661
+ this._queryRegex = null;
14662
+ }
14165
14663
  this._lastQuery = query;
14166
14664
  this._lastCaseSensitive = this._caseSensitive;
14665
+ this._lastUseRegex = this._useRegex;
14666
+ this._lastWholeWord = this._wholeWord;
14167
14667
  }
14668
+ if (!this._queryRegex) return results;
14168
14669
  const re = this._queryRegex;
14169
14670
  const MAX_RESULTS = 500;
14170
14671
  const walker = document.createTreeWalker(root, 4);
@@ -15700,13 +16201,18 @@
15700
16201
  this._query = query;
15701
16202
  clearTimeout(this._debounceTimer);
15702
16203
  this._debounceTimer = setTimeout(() => {
15703
- this._cfg.onSearch(this._query, (items) => {
16204
+ const cb = (items) => {
15704
16205
  if (!Array.isArray(items) || items.length === 0) {
15705
16206
  this._hideDropdown();
15706
16207
  return;
15707
16208
  }
15708
16209
  this._renderItems(items);
15709
16210
  this._showDropdown();
16211
+ };
16212
+ const result = this._cfg.onSearch(this._query, cb);
16213
+ if (result && typeof result.then === "function") result.then(cb).catch((err) => {
16214
+ this._hideDropdown();
16215
+ if (typeof this._cfg.onError === "function") this._cfg.onError(err);
15710
16216
  });
15711
16217
  }, this._cfg.debounce);
15712
16218
  }
@@ -15975,10 +16481,13 @@
15975
16481
  }
15976
16482
  /**
15977
16483
  * Returns the current HTML content of the editor.
16484
+ * Zero-width spaces (U+200B) inserted by inline editing helpers are stripped
16485
+ * from the output so they don't leak into the consumer's HTML.
15978
16486
  * @returns {string}
15979
16487
  */
15980
16488
  getHTML() {
15981
- return this.invoke("editor.getHTML");
16489
+ const html = this.invoke("editor.getHTML");
16490
+ return typeof html === "string" ? html.replace(/​/g, "") : html;
15982
16491
  }
15983
16492
  /**
15984
16493
  * Sets the HTML content of the editor.
@@ -16016,6 +16525,20 @@
16016
16525
  this.invoke("editor.clearHistory");
16017
16526
  }
16018
16527
  /**
16528
+ * Returns the number of available undo steps.
16529
+ * @returns {number}
16530
+ */
16531
+ getUndoCount() {
16532
+ return this.invoke("editor.getUndoCount") ?? 0;
16533
+ }
16534
+ /**
16535
+ * Returns the number of available redo steps.
16536
+ * @returns {number}
16537
+ */
16538
+ getRedoCount() {
16539
+ return this.invoke("editor.getRedoCount") ?? 0;
16540
+ }
16541
+ /**
16019
16542
  * Returns true when the editor has no meaningful content.
16020
16543
  * @returns {boolean}
16021
16544
  */
@@ -16123,6 +16646,37 @@
16123
16646
  });
16124
16647
  }
16125
16648
  /**
16649
+ * Returns an array of heading objects representing the table of contents.
16650
+ * Each entry has: level (1-6), text (heading text), element (DOM element).
16651
+ * @returns {{ level: number, text: string, element: HTMLElement }[]}
16652
+ */
16653
+ getTableOfContents() {
16654
+ return Array.from(this.layoutInfo.editable.querySelectorAll("h1,h2,h3,h4,h5,h6")).map((el) => ({
16655
+ level: parseInt(el.tagName[1], 10),
16656
+ text: el.textContent?.trim() ?? "",
16657
+ element: el
16658
+ }));
16659
+ }
16660
+ /**
16661
+ * Moves focus into the editable area.
16662
+ */
16663
+ focus() {
16664
+ this.layoutInfo.editable.focus();
16665
+ }
16666
+ /**
16667
+ * Removes focus from the editable area.
16668
+ */
16669
+ blur() {
16670
+ this.layoutInfo.editable.blur();
16671
+ }
16672
+ /**
16673
+ * Returns true when the editor is currently in fullscreen mode.
16674
+ * @returns {boolean}
16675
+ */
16676
+ isFullscreen() {
16677
+ return this.invoke("fullscreen.isActive") === true;
16678
+ }
16679
+ /**
16126
16680
  * Sets whether the editor is disabled (readonly).
16127
16681
  * @param {boolean} disabled
16128
16682
  */
@@ -16159,11 +16713,13 @@
16159
16713
  this._disposers = [];
16160
16714
  const container = this.layoutInfo.container;
16161
16715
  const wasDark = container?.classList.contains("an-theme-dark");
16716
+ const wasAuto = container?.classList.contains("an-theme-auto");
16162
16717
  if (container?.parentNode) {
16163
16718
  this.targetEl.style.display = "";
16164
16719
  container.remove();
16165
16720
  }
16166
16721
  if (wasDark && !document.querySelector(".an-container.an-theme-dark")) document.body.classList.remove("an-theme-dark");
16722
+ if (wasAuto && !document.querySelector(".an-container.an-theme-auto")) document.body.classList.remove("an-theme-auto");
16167
16723
  if (typeof this.options.onDestroy === "function") this.options.onDestroy(this);
16168
16724
  this._alive = false;
16169
16725
  this._listeners.clear();
@@ -16290,8 +16846,10 @@
16290
16846
  registerButton(btnDef);
16291
16847
  return this;
16292
16848
  },
16849
+ /** All pre-built button definitions — accessible in every module format including UMD/CJS. */
16850
+ buttons,
16293
16851
  /** Library version */
16294
- version: "1.6.7"
16852
+ version: "1.8.0"
16295
16853
  };
16296
16854
  /**
16297
16855
  * @param {string|Element|NodeList|Element[]} selector