autumnnote 1.6.7 → 1.7.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.
@@ -1455,6 +1455,7 @@
1455
1455
  replaceBtn: "Replace",
1456
1456
  replaceAllBtn: "Replace All",
1457
1457
  noResults: "No results",
1458
+ useRegex: "Use Regular Expression",
1458
1459
  close: "×"
1459
1460
  },
1460
1461
  shortcutsDialog: {
@@ -1600,7 +1601,8 @@
1600
1601
  enableWordWrap: "Enable Word Wrap",
1601
1602
  disableWordWrap: "Disable Word Wrap",
1602
1603
  convertToParagraph: "Convert to Paragraph",
1603
- deleteCodeBlock: "Delete Code Block"
1604
+ deleteCodeBlock: "Delete Code Block",
1605
+ lineNumbers: "Toggle Line Numbers"
1604
1606
  },
1605
1607
  table: {
1606
1608
  ariaLabel: "Table actions",
@@ -1617,14 +1619,26 @@
1617
1619
  columnWidth: "Column Width",
1618
1620
  rowHeight: "Row Height",
1619
1621
  tableBorderWidth: "Table Border Width",
1622
+ tableBorderColor: "Table Border Color",
1620
1623
  deleteTable: "Delete Table",
1624
+ cellAlignLeft: "Align Left",
1625
+ cellAlignCenter: "Align Center",
1626
+ cellAlignRight: "Align Right",
1627
+ cellAlignJustify: "Align Justify",
1628
+ toggleHeaderRow: "Toggle Header Row",
1621
1629
  cellBackground: "Cell Background",
1622
1630
  noShading: "No Shading",
1631
+ noBorderColor: "No Border Color",
1623
1632
  columnWidthPx: "Column Width (px)",
1624
1633
  rowHeightPx: "Row Height (px)",
1625
1634
  tableBorderWidthPx: "Table Border Width (px)",
1626
1635
  cancelBtn: "Cancel",
1627
- applyBtn: "Apply"
1636
+ applyBtn: "Apply",
1637
+ sortAsc: "Sort Ascending",
1638
+ sortDesc: "Sort Descending",
1639
+ exportCSV: "Export as CSV",
1640
+ cellPadding: "Cell Padding",
1641
+ cellPaddingPx: "Cell Padding (px)"
1628
1642
  },
1629
1643
  video: {
1630
1644
  ariaLabel: "Video actions",
@@ -1816,6 +1830,7 @@
1816
1830
  replaceBtn: "Thay thế",
1817
1831
  replaceAllBtn: "Thay thế tất cả",
1818
1832
  noResults: "Không có kết quả",
1833
+ useRegex: "Dùng biểu thức chính quy",
1819
1834
  close: "×"
1820
1835
  },
1821
1836
  shortcutsDialog: {
@@ -1957,7 +1972,8 @@
1957
1972
  enableWordWrap: "Bật xuống dòng",
1958
1973
  disableWordWrap: "Tắt xuống dòng",
1959
1974
  convertToParagraph: "Chuyển thành đoạn văn",
1960
- deleteCodeBlock: "Xóa khối mã"
1975
+ deleteCodeBlock: "Xóa khối mã",
1976
+ lineNumbers: "Bật/Tắt số dòng"
1961
1977
  },
1962
1978
  table: {
1963
1979
  ariaLabel: "Hành động bảng",
@@ -1981,7 +1997,12 @@
1981
1997
  rowHeightPx: "Chiều cao hàng (px)",
1982
1998
  tableBorderWidthPx: "Độ rộng viền bảng (px)",
1983
1999
  cancelBtn: "Hủy",
1984
- applyBtn: "Áp dụng"
2000
+ applyBtn: "Áp dụng",
2001
+ sortAsc: "Sắp xếp tăng dần",
2002
+ sortDesc: "Sắp xếp giảm dần",
2003
+ exportCSV: "Xuất CSV",
2004
+ cellPadding: "Khoảng đệm ô",
2005
+ cellPaddingPx: "Khoảng đệm ô (px)"
1985
2006
  },
1986
2007
  video: {
1987
2008
  ariaLabel: "Hành động video",
@@ -2148,6 +2169,7 @@
2148
2169
  replaceAriaLabel: "置換後のテキスト",
2149
2170
  replaceBtn: "置換",
2150
2171
  noResults: "結果なし",
2172
+ useRegex: "正規表現を使用",
2151
2173
  replaceAllBtn: "すべて置換",
2152
2174
  close: "×"
2153
2175
  },
@@ -2290,7 +2312,8 @@
2290
2312
  enableWordWrap: "折り返しを有効にする",
2291
2313
  disableWordWrap: "折り返しを無効にする",
2292
2314
  convertToParagraph: "段落に変換",
2293
- deleteCodeBlock: "コードブロックを削除"
2315
+ deleteCodeBlock: "コードブロックを削除",
2316
+ lineNumbers: "行番号を切り替え"
2294
2317
  },
2295
2318
  table: {
2296
2319
  ariaLabel: "テーブル操作",
@@ -2312,7 +2335,12 @@
2312
2335
  rowHeightPx: "行の高さ (px)",
2313
2336
  tableBorderWidthPx: "テーブルの枠幅 (px)",
2314
2337
  cancelBtn: "キャンセル",
2315
- applyBtn: "適用"
2338
+ applyBtn: "適用",
2339
+ sortAsc: "昇順で並べ替え",
2340
+ sortDesc: "降順で並べ替え",
2341
+ exportCSV: "CSVとしてエクスポート",
2342
+ cellPadding: "セルの余白",
2343
+ cellPaddingPx: "セルの余白 (px)"
2316
2344
  },
2317
2345
  video: {
2318
2346
  ariaLabel: "動画操作",
@@ -2479,6 +2507,7 @@
2479
2507
  replaceAriaLabel: "替换为",
2480
2508
  replaceBtn: "替换",
2481
2509
  noResults: "没有结果",
2510
+ useRegex: "使用正则表达式",
2482
2511
  replaceAllBtn: "全部替换",
2483
2512
  close: "×"
2484
2513
  },
@@ -2621,7 +2650,8 @@
2621
2650
  enableWordWrap: "启用自动换行",
2622
2651
  disableWordWrap: "禁用自动换行",
2623
2652
  convertToParagraph: "转换为段落",
2624
- deleteCodeBlock: "删除代码块"
2653
+ deleteCodeBlock: "删除代码块",
2654
+ lineNumbers: "切换行号"
2625
2655
  },
2626
2656
  table: {
2627
2657
  ariaLabel: "表格操作",
@@ -2643,7 +2673,12 @@
2643
2673
  rowHeightPx: "行高 (px)",
2644
2674
  tableBorderWidthPx: "表格边框宽度 (px)",
2645
2675
  cancelBtn: "取消",
2646
- applyBtn: "应用"
2676
+ applyBtn: "应用",
2677
+ sortAsc: "升序排列",
2678
+ sortDesc: "降序排列",
2679
+ exportCSV: "导出为 CSV",
2680
+ cellPadding: "单元格内边距",
2681
+ cellPaddingPx: "单元格内边距 (px)"
2647
2682
  },
2648
2683
  video: {
2649
2684
  ariaLabel: "视频操作",
@@ -2810,6 +2845,7 @@
2810
2845
  replaceAriaLabel: "Remplacer par",
2811
2846
  replaceBtn: "Remplacer",
2812
2847
  noResults: "Aucun résultat",
2848
+ useRegex: "Utiliser une expression régulière",
2813
2849
  replaceAllBtn: "Tout remplacer",
2814
2850
  close: "×"
2815
2851
  },
@@ -2952,7 +2988,8 @@
2952
2988
  enableWordWrap: "Activer le retour à la ligne",
2953
2989
  disableWordWrap: "Désactiver le retour à la ligne",
2954
2990
  convertToParagraph: "Convertir en paragraphe",
2955
- deleteCodeBlock: "Supprimer le bloc de code"
2991
+ deleteCodeBlock: "Supprimer le bloc de code",
2992
+ lineNumbers: "Activer/désactiver les numéros de ligne"
2956
2993
  },
2957
2994
  table: {
2958
2995
  ariaLabel: "Actions du tableau",
@@ -2974,7 +3011,12 @@
2974
3011
  rowHeightPx: "Hauteur de ligne (px)",
2975
3012
  tableBorderWidthPx: "Épaisseur des bordures (px)",
2976
3013
  cancelBtn: "Annuler",
2977
- applyBtn: "Appliquer"
3014
+ applyBtn: "Appliquer",
3015
+ sortAsc: "Trier par ordre croissant",
3016
+ sortDesc: "Trier par ordre décroissant",
3017
+ exportCSV: "Exporter en CSV",
3018
+ cellPadding: "Rembourrage des cellules",
3019
+ cellPaddingPx: "Rembourrage des cellules (px)"
2978
3020
  },
2979
3021
  video: {
2980
3022
  ariaLabel: "Actions de la vidéo",
@@ -3141,6 +3183,7 @@
3141
3183
  replaceAriaLabel: "Ersetzen durch",
3142
3184
  replaceBtn: "Ersetzen",
3143
3185
  noResults: "Keine Ergebnisse",
3186
+ useRegex: "Regulären Ausdruck verwenden",
3144
3187
  replaceAllBtn: "Alle ersetzen",
3145
3188
  close: "×"
3146
3189
  },
@@ -3283,7 +3326,8 @@
3283
3326
  enableWordWrap: "Zeilenumbruch aktivieren",
3284
3327
  disableWordWrap: "Zeilenumbruch deaktivieren",
3285
3328
  convertToParagraph: "In Absatz umwandeln",
3286
- deleteCodeBlock: "Codeblock löschen"
3329
+ deleteCodeBlock: "Codeblock löschen",
3330
+ lineNumbers: "Zeilennummern umschalten"
3287
3331
  },
3288
3332
  table: {
3289
3333
  ariaLabel: "Tabellen-Aktionen",
@@ -3305,7 +3349,12 @@
3305
3349
  rowHeightPx: "Zeilenhöhe (px)",
3306
3350
  tableBorderWidthPx: "Tabellenrahmenbreite (px)",
3307
3351
  cancelBtn: "Abbrechen",
3308
- applyBtn: "Anwenden"
3352
+ applyBtn: "Anwenden",
3353
+ sortAsc: "Aufsteigend sortieren",
3354
+ sortDesc: "Absteigend sortieren",
3355
+ exportCSV: "Als CSV exportieren",
3356
+ cellPadding: "Zellauffüllung",
3357
+ cellPaddingPx: "Zellauffüllung (px)"
3309
3358
  },
3310
3359
  video: {
3311
3360
  ariaLabel: "Video-Aktionen",
@@ -3472,6 +3521,7 @@
3472
3521
  replaceAriaLabel: "Reemplazar con",
3473
3522
  replaceBtn: "Reemplazar",
3474
3523
  noResults: "Sin resultados",
3524
+ useRegex: "Usar expresión regular",
3475
3525
  replaceAllBtn: "Reemplazar todo",
3476
3526
  close: "×"
3477
3527
  },
@@ -3614,7 +3664,8 @@
3614
3664
  enableWordWrap: "Activar ajuste de línea",
3615
3665
  disableWordWrap: "Desactivar ajuste de línea",
3616
3666
  convertToParagraph: "Convertir en párrafo",
3617
- deleteCodeBlock: "Eliminar bloque de código"
3667
+ deleteCodeBlock: "Eliminar bloque de código",
3668
+ lineNumbers: "Alternar números de línea"
3618
3669
  },
3619
3670
  table: {
3620
3671
  ariaLabel: "Acciones de tabla",
@@ -3636,7 +3687,12 @@
3636
3687
  rowHeightPx: "Alto de fila (px)",
3637
3688
  tableBorderWidthPx: "Grosor del borde (px)",
3638
3689
  cancelBtn: "Cancelar",
3639
- applyBtn: "Aplicar"
3690
+ applyBtn: "Aplicar",
3691
+ sortAsc: "Ordenar ascendente",
3692
+ sortDesc: "Ordenar descendente",
3693
+ exportCSV: "Exportar como CSV",
3694
+ cellPadding: "Relleno de celda",
3695
+ cellPaddingPx: "Relleno de celda (px)"
3640
3696
  },
3641
3697
  video: {
3642
3698
  ariaLabel: "Acciones de vídeo",
@@ -3803,6 +3859,7 @@
3803
3859
  replaceAriaLabel: "바꿀 내용",
3804
3860
  replaceBtn: "바꾸기",
3805
3861
  noResults: "결과 없음",
3862
+ useRegex: "정규식 사용",
3806
3863
  replaceAllBtn: "모두 바꾸기",
3807
3864
  close: "×"
3808
3865
  },
@@ -3945,7 +4002,8 @@
3945
4002
  enableWordWrap: "줄 바꿈 사용",
3946
4003
  disableWordWrap: "줄 바꿈 해제",
3947
4004
  convertToParagraph: "단락으로 변환",
3948
- deleteCodeBlock: "코드 블록 삭제"
4005
+ deleteCodeBlock: "코드 블록 삭제",
4006
+ lineNumbers: "줄 번호 전환"
3949
4007
  },
3950
4008
  table: {
3951
4009
  ariaLabel: "표 작업",
@@ -3967,7 +4025,12 @@
3967
4025
  rowHeightPx: "행 높이 (px)",
3968
4026
  tableBorderWidthPx: "표 테두리 너비 (px)",
3969
4027
  cancelBtn: "취소",
3970
- applyBtn: "적용"
4028
+ applyBtn: "적용",
4029
+ sortAsc: "오름차순 정렬",
4030
+ sortDesc: "내림차순 정렬",
4031
+ exportCSV: "CSV로 내보내기",
4032
+ cellPadding: "셀 패딩",
4033
+ cellPaddingPx: "셀 패딩 (px)"
3971
4034
  },
3972
4035
  video: {
3973
4036
  ariaLabel: "동영상 작업",
@@ -4181,6 +4244,9 @@
4181
4244
  if (options.theme === "dark") {
4182
4245
  container.classList.add("an-theme-dark");
4183
4246
  document.body.classList.add("an-theme-dark");
4247
+ } else if (options.theme === "auto") {
4248
+ container.classList.add("an-theme-auto");
4249
+ document.body.classList.add("an-theme-auto");
4184
4250
  }
4185
4251
  if (options.readOnly) {
4186
4252
  container.classList.add("an-disabled");
@@ -4406,6 +4472,14 @@
4406
4472
  canRedo() {
4407
4473
  return this.stackOffset < this.stack.length - 1;
4408
4474
  }
4475
+ /** @returns {number} */
4476
+ getUndoCount() {
4477
+ return Math.max(0, this.stackOffset);
4478
+ }
4479
+ /** @returns {number} */
4480
+ getRedoCount() {
4481
+ return Math.max(0, this.stack.length - 1 - this.stackOffset);
4482
+ }
4409
4483
  };
4410
4484
  //#endregion
4411
4485
  //#region src/js/editing/Table.js
@@ -5478,6 +5552,12 @@
5478
5552
  canRedo() {
5479
5553
  return this._history ? this._history.canRedo() : false;
5480
5554
  }
5555
+ getUndoCount() {
5556
+ return this._history ? this._history.getUndoCount() : 0;
5557
+ }
5558
+ getRedoCount() {
5559
+ return this._history ? this._history.getRedoCount() : 0;
5560
+ }
5481
5561
  bold() {
5482
5562
  bold();
5483
5563
  this.afterCommand();
@@ -6339,9 +6419,21 @@
6339
6419
  this._bindResize(handle);
6340
6420
  this.el.appendChild(handle);
6341
6421
  }
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" });
6422
+ this._wordCountEl = createElement("span", {
6423
+ class: "an-word-count",
6424
+ role: "status",
6425
+ "aria-live": "polite",
6426
+ "aria-atomic": "true"
6427
+ });
6428
+ this._charCountEl = createElement("span", {
6429
+ class: "an-char-count",
6430
+ "aria-live": "polite",
6431
+ "aria-atomic": "true"
6432
+ });
6433
+ const info = createElement("div", {
6434
+ class: "an-status-info",
6435
+ "aria-label": "Editor statistics"
6436
+ });
6345
6437
  info.appendChild(this._wordCountEl);
6346
6438
  info.appendChild(this._charCountEl);
6347
6439
  this.el.appendChild(info);
@@ -6999,6 +7091,10 @@
6999
7091
  this._firstInput = null;
7000
7092
  this._removeTrap = null;
7001
7093
  }
7094
+ /** @returns {HTMLElement} */
7095
+ _buildDialog() {
7096
+ throw new Error("_buildDialog() must be implemented by subclass");
7097
+ }
7002
7098
  initialize() {
7003
7099
  this._dialog = this._buildDialog();
7004
7100
  document.body.appendChild(this._dialog);
@@ -8781,7 +8877,17 @@
8781
8877
  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
8878
  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
8879
  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>`
8880
+ 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>`,
8881
+ 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>`,
8882
+ 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>`,
8883
+ 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>`,
8884
+ 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>`,
8885
+ 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>`,
8886
+ 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>`,
8887
+ 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>`,
8888
+ 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>`,
8889
+ 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>`,
8890
+ 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
8891
  };
8786
8892
  var SHADE_PRESETS = [
8787
8893
  "#000000",
@@ -8826,6 +8932,10 @@
8826
8932
  this._shadePopover = null;
8827
8933
  this._shadeTitleEl = null;
8828
8934
  this._shadeColorStrip = null;
8935
+ this._borderColorPopover = null;
8936
+ this._borderColorTitleEl = null;
8937
+ this._borderColorStrip = null;
8938
+ this._borderColorNoBtn = null;
8829
8939
  this._selectMode = false;
8830
8940
  this._selectedCells = [];
8831
8941
  this._selectStart = null;
@@ -8840,6 +8950,8 @@
8840
8950
  document.body.appendChild(this._sizePopover);
8841
8951
  this._shadePopover = this._buildCellShadePopover();
8842
8952
  document.body.appendChild(this._shadePopover);
8953
+ this._borderColorPopover = this._buildBorderColorPopover();
8954
+ document.body.appendChild(this._borderColorPopover);
8843
8955
  const editable = this.context.layoutInfo.editable;
8844
8956
  this._editable = editable;
8845
8957
  const onSelMousedown = (e) => {
@@ -8881,7 +8993,7 @@
8881
8993
  }, { passive: true }), on(document, "click", (e) => {
8882
8994
  const et = e.target;
8883
8995
  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();
8996
+ if (this._activeTable && !this._activeTable.contains(et) && !this._el.contains(et) && !this._sizePopover?.contains(et) && !this._borderColorPopover?.contains(et)) this._hide();
8885
8997
  }), on(document, "selectionchange", () => this._syncShadeStrip()), on(globalThis, "scroll", () => this._hide(), { passive: true }), on(globalThis, "resize", () => this._hide(), { passive: true }));
8886
8998
  this._initResize();
8887
8999
  return this;
@@ -9016,6 +9128,8 @@
9016
9128
  this._sizePopover = null;
9017
9129
  if (this._shadePopover?.parentNode) this._shadePopover.remove();
9018
9130
  this._shadePopover = null;
9131
+ if (this._borderColorPopover?.parentNode) this._borderColorPopover.remove();
9132
+ this._borderColorPopover = null;
9019
9133
  }
9020
9134
  _buildTooltip() {
9021
9135
  const L = this.context.locale.tooltips.table;
@@ -9039,10 +9153,18 @@
9039
9153
  el.appendChild(this._makeBtn(ICONS$2.colLeft, L.addColumnLeft, () => this._addColumn("left")));
9040
9154
  el.appendChild(this._makeBtn(ICONS$2.colRight, L.addColumnRight, () => this._addColumn("right")));
9041
9155
  el.appendChild(this._makeBtn(ICONS$2.deleteCol, L.deleteColumn, () => this._deleteColumn()));
9156
+ el.appendChild(this._makeBtn(ICONS$2.sortAsc, L.sortAsc, () => this._sortColumn("asc")));
9157
+ el.appendChild(this._makeBtn(ICONS$2.sortDesc, L.sortDesc, () => this._sortColumn("desc")));
9042
9158
  el.appendChild(this._sep());
9043
9159
  el.appendChild(this._makeBtn(ICONS$2.mergeCells, L.mergeCells, () => this._mergeCells()));
9044
9160
  el.appendChild(this._makeBtn(ICONS$2.unmergeCells, L.unmergeCells, () => this._unmergeCells()));
9045
9161
  el.appendChild(this._sep());
9162
+ el.appendChild(this._makeBtn(ICONS$2.alignLeft, L.cellAlignLeft, () => this._applyCellAlign("left")));
9163
+ el.appendChild(this._makeBtn(ICONS$2.alignCenter, L.cellAlignCenter, () => this._applyCellAlign("center")));
9164
+ el.appendChild(this._makeBtn(ICONS$2.alignRight, L.cellAlignRight, () => this._applyCellAlign("right")));
9165
+ el.appendChild(this._makeBtn(ICONS$2.alignJustify, L.cellAlignJustify, () => this._applyCellAlign("justify")));
9166
+ el.appendChild(this._makeBtn(ICONS$2.headerRow, L.toggleHeaderRow, () => this._toggleHeaderRow()));
9167
+ el.appendChild(this._sep());
9046
9168
  const shadeBtn = createElement("button", {
9047
9169
  type: "button",
9048
9170
  class: "an-link-tooltip-btn an-link-tooltip-btn--shade",
@@ -9064,12 +9186,33 @@
9064
9186
  el.appendChild(this._makeBtn(ICONS$2.colWidth, L.columnWidth, () => this._openSizePopover("col")));
9065
9187
  el.appendChild(this._makeBtn(ICONS$2.rowHeight, L.rowHeight, () => this._openSizePopover("row")));
9066
9188
  el.appendChild(this._makeBtn(ICONS$2.tableBorder, L.tableBorderWidth, () => this._openSizePopover("border")));
9189
+ el.appendChild(this._makeBtn(ICONS$2.cellPadding, L.cellPadding, () => this._openSizePopover("cellPadding")));
9190
+ const borderColorBtn = createElement("button", {
9191
+ type: "button",
9192
+ class: "an-link-tooltip-btn an-link-tooltip-btn--shade",
9193
+ title: L.tableBorderColor
9194
+ });
9195
+ const borderColorSvgWrap = createElement("span", { class: "an-bubble-btn-svg" });
9196
+ borderColorSvgWrap.innerHTML = ICONS$2.borderColor;
9197
+ const borderColorStrip = createElement("span", { class: "an-link-tooltip-color-strip" });
9198
+ borderColorBtn.appendChild(borderColorSvgWrap);
9199
+ borderColorBtn.appendChild(borderColorStrip);
9200
+ this._borderColorStrip = borderColorStrip;
9201
+ this._disposers.push(on(borderColorBtn, "click", (e) => {
9202
+ e.preventDefault();
9203
+ e.stopPropagation();
9204
+ this._openBorderColorPopover();
9205
+ }));
9206
+ el.appendChild(borderColorBtn);
9067
9207
  el.appendChild(this._sep());
9068
9208
  el.appendChild(this._makeBtn(ICONS$2.deleteTable, L.deleteTable, () => this._deleteTable(), true));
9209
+ el.appendChild(this._sep());
9210
+ el.appendChild(this._makeBtn(ICONS$2.exportCSV, L.exportCSV, () => this._exportTableCSV()));
9069
9211
  this._disposers.push(on(el, "mouseenter", () => this._clearTimers()), on(el, "mouseleave", () => {
9070
9212
  if (this._selectMode) return;
9071
9213
  if (this._sizePopover && this._sizePopover.style.display !== "none") return;
9072
9214
  if (this._shadePopover && this._shadePopover.style.display !== "none") return;
9215
+ if (this._borderColorPopover && this._borderColorPopover.style.display !== "none") return;
9073
9216
  this._scheduleHide();
9074
9217
  }));
9075
9218
  return el;
@@ -9117,6 +9260,7 @@
9117
9260
  if (!this._activeTable) return;
9118
9261
  this._el.style.display = "flex";
9119
9262
  this._syncShadeStrip();
9263
+ this._syncBorderColorStrip();
9120
9264
  requestAnimationFrame(() => {
9121
9265
  if (this._activeTable) this._positionNear(this._activeTable);
9122
9266
  });
@@ -9138,6 +9282,7 @@
9138
9282
  this._clearSelection();
9139
9283
  this._clearTimers();
9140
9284
  this._hideSizePopover();
9285
+ this._hideBorderColorPopover();
9141
9286
  }
9142
9287
  _clearTimers() {
9143
9288
  clearTimeout(this._showTimer);
@@ -9537,6 +9682,19 @@
9537
9682
  });
9538
9683
  this.context.invoke("editor.afterCommand");
9539
9684
  };
9685
+ } else if (type === "cellPadding") {
9686
+ const firstCell = this._getSelectedCells()[0] || this._getCell();
9687
+ const currentPad = firstCell ? Number.parseInt(firstCell.style.padding, 10) || Number.parseInt(firstCell.style.paddingTop, 10) || 4 : 4;
9688
+ this._sizeTitleEl.textContent = this.context.locale.tooltips.table.cellPaddingPx;
9689
+ this._sizeInputEl.min = "0";
9690
+ this._sizeInputEl.max = "40";
9691
+ this._sizeInputEl.value = String(currentPad);
9692
+ this._sizeApply = (val) => {
9693
+ this._getSelectedCells().forEach((c) => {
9694
+ if (c) c.style.padding = `${val}px`;
9695
+ });
9696
+ this.context.invoke("editor.afterCommand");
9697
+ };
9540
9698
  } else {
9541
9699
  const isCol = type === "col";
9542
9700
  const activeCells = this._getSelectedCells().filter((c) => {
@@ -9633,7 +9791,7 @@
9633
9791
  value: "#ffffff"
9634
9792
  });
9635
9793
  const customLabel = createElement("span");
9636
- customLabel.textContent = "Custom…";
9794
+ customLabel.textContent = this.context.locale.contextMenu.customColorLabel;
9637
9795
  this._disposers.push(on(colorInput, "change", () => this._applyCellShade(colorInput.value)));
9638
9796
  customRow.appendChild(colorInput);
9639
9797
  customRow.appendChild(customLabel);
@@ -9674,6 +9832,172 @@
9674
9832
  this._hideCellShadePopover();
9675
9833
  this.context.invoke("editor.afterCommand");
9676
9834
  }
9835
+ _buildBorderColorPopover() {
9836
+ const pop = createElement("div", { class: "an-cell-shade-popover" });
9837
+ pop.style.display = "none";
9838
+ const title = createElement("div", { class: "an-size-popover-title" });
9839
+ pop.appendChild(title);
9840
+ this._borderColorTitleEl = title;
9841
+ const palette = createElement("div", { class: "an-context-color-palette" });
9842
+ SHADE_PRESETS.forEach((color) => {
9843
+ const sw = createElement("div", {
9844
+ class: "an-context-color-swatch",
9845
+ title: color
9846
+ });
9847
+ sw.style.background = color;
9848
+ this._disposers.push(on(sw, "click", (e) => {
9849
+ e.stopPropagation();
9850
+ this._applyBorderColor(color);
9851
+ }));
9852
+ palette.appendChild(sw);
9853
+ });
9854
+ pop.appendChild(palette);
9855
+ const noColorRow = createElement("div", { class: "an-context-color-custom" });
9856
+ const noColorBtn = createElement("button", {
9857
+ type: "button",
9858
+ class: "an-shade-no-color"
9859
+ });
9860
+ this._disposers.push(on(noColorBtn, "click", () => this._applyBorderColor("")));
9861
+ noColorRow.appendChild(noColorBtn);
9862
+ pop.appendChild(noColorRow);
9863
+ this._borderColorNoBtn = noColorBtn;
9864
+ const customRow = createElement("div", { class: "an-context-color-custom" });
9865
+ const colorInput = createElement("input", {
9866
+ type: "color",
9867
+ class: "an-shade-color-input",
9868
+ value: "#000000"
9869
+ });
9870
+ const customLabel = createElement("span");
9871
+ customLabel.textContent = this.context.locale.contextMenu.customColorLabel;
9872
+ this._disposers.push(on(colorInput, "change", () => this._applyBorderColor(colorInput.value)));
9873
+ customRow.appendChild(colorInput);
9874
+ customRow.appendChild(customLabel);
9875
+ pop.appendChild(customRow);
9876
+ this._disposers.push(on(pop, "mousedown", (e) => e.preventDefault()), on(pop, "mouseenter", () => this._clearTimers()), on(pop, "mouseleave", () => this._scheduleHide()), on(document, "click", (e) => {
9877
+ const et = e.target;
9878
+ if (this._borderColorPopover && this._borderColorPopover.style.display !== "none" && !this._borderColorPopover.contains(et) && !this._el?.contains(et)) this._hideBorderColorPopover();
9879
+ }));
9880
+ return pop;
9881
+ }
9882
+ _openBorderColorPopover() {
9883
+ if (!this._borderColorPopover) return;
9884
+ const L = this.context.locale.tooltips.table;
9885
+ if (this._borderColorTitleEl) this._borderColorTitleEl.textContent = L.tableBorderColor;
9886
+ if (this._borderColorNoBtn) this._borderColorNoBtn.textContent = L.noBorderColor;
9887
+ this._borderColorPopover.style.display = "block";
9888
+ requestAnimationFrame(() => {
9889
+ if (!this._borderColorPopover || !this._el) return;
9890
+ const pw = this._borderColorPopover.offsetWidth || 170;
9891
+ const ph = this._borderColorPopover.offsetHeight || 120;
9892
+ const tipRect = this._el.getBoundingClientRect();
9893
+ let left = tipRect.left;
9894
+ let top = tipRect.bottom + 6;
9895
+ if (left + pw > globalThis.innerWidth - 8) left = globalThis.innerWidth - pw - 8;
9896
+ if (top + ph > globalThis.innerHeight - 8) top = tipRect.top - ph - 6;
9897
+ this._borderColorPopover.style.left = `${Math.max(8, left)}px`;
9898
+ this._borderColorPopover.style.top = `${Math.max(8, top)}px`;
9899
+ });
9900
+ }
9901
+ _hideBorderColorPopover() {
9902
+ if (this._borderColorPopover) this._borderColorPopover.style.display = "none";
9903
+ }
9904
+ _applyBorderColor(color) {
9905
+ const table = this._activeTable;
9906
+ if (!table) return;
9907
+ Array.from(table.querySelectorAll("td, th")).forEach((c) => {
9908
+ c.style.borderColor = color;
9909
+ });
9910
+ if (this._borderColorStrip) this._borderColorStrip.style.background = color || "transparent";
9911
+ this._hideBorderColorPopover();
9912
+ this.context.invoke("editor.afterCommand");
9913
+ }
9914
+ _syncBorderColorStrip() {
9915
+ if (!this._borderColorStrip || !this._el || this._el.style.display === "none") return;
9916
+ const firstCell = this._activeTable?.querySelector("td, th");
9917
+ this._borderColorStrip.style.background = firstCell?.style.borderColor || "transparent";
9918
+ }
9919
+ _applyCellAlign(align) {
9920
+ this._getSelectedCells().forEach((c) => {
9921
+ if (c) c.style.textAlign = align;
9922
+ });
9923
+ this.context.invoke("editor.afterCommand");
9924
+ }
9925
+ _toggleHeaderRow() {
9926
+ const table = this._activeTable;
9927
+ if (!table) return;
9928
+ const firstRow = table.querySelector("tr");
9929
+ if (!firstRow) return;
9930
+ if (firstRow.closest("thead") !== null) {
9931
+ let tbody = table.querySelector("tbody");
9932
+ if (!tbody) {
9933
+ tbody = document.createElement("tbody");
9934
+ table.appendChild(tbody);
9935
+ }
9936
+ Array.from(firstRow.cells).forEach((cell) => {
9937
+ const td = document.createElement("td");
9938
+ td.innerHTML = cell.innerHTML;
9939
+ td.style.cssText = cell.style.cssText;
9940
+ firstRow.replaceChild(td, cell);
9941
+ });
9942
+ tbody.insertBefore(firstRow, tbody.firstChild);
9943
+ const thead = table.querySelector("thead");
9944
+ if (thead && thead.rows.length === 0) thead.remove();
9945
+ } else {
9946
+ let thead = table.querySelector("thead");
9947
+ if (!thead) {
9948
+ thead = document.createElement("thead");
9949
+ table.insertBefore(thead, table.firstChild);
9950
+ }
9951
+ Array.from(firstRow.cells).forEach((cell) => {
9952
+ const th = document.createElement("th");
9953
+ th.innerHTML = cell.innerHTML;
9954
+ th.style.cssText = cell.style.cssText;
9955
+ firstRow.replaceChild(th, cell);
9956
+ });
9957
+ thead.appendChild(firstRow);
9958
+ }
9959
+ this.context.invoke("editor.afterCommand");
9960
+ }
9961
+ _sortColumn(direction) {
9962
+ const table = this._activeTable;
9963
+ if (!table) return;
9964
+ const cell = this._getCell();
9965
+ if (!cell) return;
9966
+ const colIdx = getVisualColIndex(cell);
9967
+ if (colIdx === -1) return;
9968
+ const tbody = table.querySelector("tbody") || table;
9969
+ const rows = Array.from(tbody.querySelectorAll(":scope > tr"));
9970
+ if (rows.length < 2) return;
9971
+ rows.sort((a, b) => {
9972
+ const aCell = getCellAtVisualCol(a, colIdx);
9973
+ const bCell = getCellAtVisualCol(b, colIdx);
9974
+ const aText = (aCell?.textContent || "").trim();
9975
+ const bText = (bCell?.textContent || "").trim();
9976
+ const aNum = parseFloat(aText);
9977
+ const bNum = parseFloat(bText);
9978
+ if (!isNaN(aNum) && !isNaN(bNum)) return direction === "asc" ? aNum - bNum : bNum - aNum;
9979
+ return direction === "asc" ? aText.localeCompare(bText) : bText.localeCompare(aText);
9980
+ });
9981
+ rows.forEach((row) => tbody.appendChild(row));
9982
+ this.context.invoke("editor.afterCommand");
9983
+ }
9984
+ _exportTableCSV() {
9985
+ const table = this._activeTable;
9986
+ if (!table) return;
9987
+ const csv = Array.from(table.querySelectorAll("tr")).map((row) => Array.from(row.querySelectorAll("td, th")).map((cell) => {
9988
+ return `"${(cell.textContent || "").trim().replace(/"/g, "\"\"")}"`;
9989
+ }).join(",")).join("\n");
9990
+ const blob = new Blob(["" + csv], { type: "text/csv;charset=utf-8;" });
9991
+ const url = URL.createObjectURL(blob);
9992
+ const a = document.createElement("a");
9993
+ a.href = url;
9994
+ a.download = "table.csv";
9995
+ a.style.display = "none";
9996
+ document.body.appendChild(a);
9997
+ a.click();
9998
+ a.remove();
9999
+ URL.revokeObjectURL(url);
10000
+ }
9677
10001
  };
9678
10002
  //#endregion
9679
10003
  //#region src/js/module/CodeTooltip.js
@@ -9684,7 +10008,8 @@
9684
10008
  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
10009
  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
10010
  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>`
10011
+ 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>`,
10012
+ 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
10013
  };
9689
10014
  var CodeTooltip = class {
9690
10015
  /** @param {import('../Context.js').Context} context */
@@ -9696,6 +10021,8 @@
9696
10021
  this._hideTimer = null;
9697
10022
  this._disposers = [];
9698
10023
  this._copyBtn = null;
10024
+ this._wrapBtn = null;
10025
+ this._lineNumbersBtn = null;
9699
10026
  this._langSelect = null;
9700
10027
  this._prismScript = null;
9701
10028
  }
@@ -9776,6 +10103,8 @@
9776
10103
  el.appendChild(this._sep());
9777
10104
  this._wrapBtn = this._makeBtn(ICONS$1.wrapOn, L.toggleWordWrap, () => this._toggleWrap());
9778
10105
  el.appendChild(this._wrapBtn);
10106
+ this._lineNumbersBtn = this._makeBtn(ICONS$1.lineNumbers, L.lineNumbers, () => this._toggleLineNumbers());
10107
+ el.appendChild(this._lineNumbersBtn);
9779
10108
  el.appendChild(this._sep());
9780
10109
  el.appendChild(this._makeBtn(ICONS$1.toParagraph, L.convertToParagraph, () => this._toParagraph()));
9781
10110
  el.appendChild(this._sep());
@@ -9814,6 +10143,7 @@
9814
10143
  this._showTimer = setTimeout(() => {
9815
10144
  this._activePre = pre;
9816
10145
  this._syncWrapBtn();
10146
+ this._syncLineNumbersBtn();
9817
10147
  this._syncLangSelect();
9818
10148
  this._show(pre);
9819
10149
  }, SHOW_DELAY);
@@ -9858,6 +10188,12 @@
9858
10188
  this._wrapBtn.classList.toggle("active", wrapped);
9859
10189
  this._wrapBtn.title = wrapped ? this.context.locale.tooltips.code.disableWordWrap : this.context.locale.tooltips.code.enableWordWrap;
9860
10190
  }
10191
+ _syncLineNumbersBtn() {
10192
+ if (!this._activePre || !this._lineNumbersBtn) return;
10193
+ const on = this._activePre.classList.contains("an-code-line-numbers");
10194
+ this._lineNumbersBtn.classList.toggle("active", on);
10195
+ this._lineNumbersBtn.title = this.context.locale.tooltips.code.lineNumbers;
10196
+ }
9861
10197
  _syncLangSelect() {
9862
10198
  if (!this._activePre || !this._langSelect) return;
9863
10199
  const codeEl = this._activePre.querySelector("code");
@@ -9904,6 +10240,13 @@
9904
10240
  this.context.invoke("editor.afterCommand");
9905
10241
  this._positionNear(pre);
9906
10242
  }
10243
+ _toggleLineNumbers() {
10244
+ const pre = this._activePre;
10245
+ if (!pre) return;
10246
+ pre.classList.toggle("an-code-line-numbers");
10247
+ this._syncLineNumbersBtn();
10248
+ this.context.invoke("editor.afterCommand");
10249
+ }
9907
10250
  /**
9908
10251
  * Applies a language to a given <pre> element: sets classes, data-language,
9909
10252
  * and triggers Prism highlighting. Called by the auto-detect flow.
@@ -13914,12 +14257,14 @@
13914
14257
  this._matches = [];
13915
14258
  this._currentIndex = -1;
13916
14259
  this._caseSensitive = false;
14260
+ this._useRegex = false;
13917
14261
  /** @type {'find'|'replace'} */
13918
14262
  this._mode = "find";
13919
14263
  /** Cached compiled regex — reused when query and case-sensitivity are unchanged */
13920
14264
  this._queryRegex = null;
13921
14265
  this._lastQuery = null;
13922
14266
  this._lastCaseSensitive = null;
14267
+ this._lastUseRegex = null;
13923
14268
  this._focusTimer = null;
13924
14269
  }
13925
14270
  destroy() {
@@ -14023,6 +14368,13 @@
14023
14368
  "aria-label": "Case sensitive"
14024
14369
  });
14025
14370
  caseBtn.textContent = "Aa";
14371
+ const regexBtn = createElement("button", {
14372
+ type: "button",
14373
+ class: "an-fr-icon-btn",
14374
+ title: L.useRegex,
14375
+ "aria-label": L.useRegex
14376
+ });
14377
+ regexBtn.textContent = ".*";
14026
14378
  const prevBtn = createElement("button", {
14027
14379
  type: "button",
14028
14380
  class: "an-fr-icon-btn",
@@ -14039,7 +14391,7 @@
14039
14391
  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
14392
  const counter = createElement("span", { class: "an-fr-counter" });
14041
14393
  this._counterEl = counter;
14042
- searchBar.append(findInput, caseCheckbox, caseBtn, prevBtn, nextBtn, counter);
14394
+ searchBar.append(findInput, caseCheckbox, caseBtn, regexBtn, prevBtn, nextBtn, counter);
14043
14395
  box.appendChild(searchBar);
14044
14396
  const replaceRow = createElement("div", { class: "an-fr-replace-row" });
14045
14397
  replaceRow.style.display = "none";
@@ -14100,7 +14452,14 @@
14100
14452
  this._replace();
14101
14453
  }
14102
14454
  });
14103
- this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
14455
+ const dRegex = on(regexBtn, "click", () => {
14456
+ this._useRegex = !this._useRegex;
14457
+ regexBtn.classList.toggle("an-fr-icon-btn--active", this._useRegex);
14458
+ this._queryRegex = null;
14459
+ this._lastQuery = null;
14460
+ this._onSearch();
14461
+ });
14462
+ this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, dRegex);
14104
14463
  return overlay;
14105
14464
  }
14106
14465
  _onSearch() {
@@ -14158,13 +14517,19 @@
14158
14517
  */
14159
14518
  _findRawMatches(query, root) {
14160
14519
  const results = [];
14161
- if (this._lastQuery !== query || this._lastCaseSensitive !== this._caseSensitive) {
14520
+ if (this._lastQuery !== query || this._lastCaseSensitive !== this._caseSensitive || this._lastUseRegex !== this._useRegex) {
14162
14521
  const flags = this._caseSensitive ? "g" : "gi";
14163
- const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
14164
- this._queryRegex = new RegExp(escaped, flags);
14522
+ try {
14523
+ const pattern = this._useRegex ? query : query.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
14524
+ this._queryRegex = new RegExp(pattern, flags);
14525
+ } catch (_) {
14526
+ this._queryRegex = null;
14527
+ }
14165
14528
  this._lastQuery = query;
14166
14529
  this._lastCaseSensitive = this._caseSensitive;
14530
+ this._lastUseRegex = this._useRegex;
14167
14531
  }
14532
+ if (!this._queryRegex) return results;
14168
14533
  const re = this._queryRegex;
14169
14534
  const MAX_RESULTS = 500;
14170
14535
  const walker = document.createTreeWalker(root, 4);
@@ -15700,14 +16065,16 @@
15700
16065
  this._query = query;
15701
16066
  clearTimeout(this._debounceTimer);
15702
16067
  this._debounceTimer = setTimeout(() => {
15703
- this._cfg.onSearch(this._query, (items) => {
16068
+ const cb = (items) => {
15704
16069
  if (!Array.isArray(items) || items.length === 0) {
15705
16070
  this._hideDropdown();
15706
16071
  return;
15707
16072
  }
15708
16073
  this._renderItems(items);
15709
16074
  this._showDropdown();
15710
- });
16075
+ };
16076
+ const result = this._cfg.onSearch(this._query, cb);
16077
+ if (result && typeof result.then === "function") result.then(cb).catch(() => this._hideDropdown());
15711
16078
  }, this._cfg.debounce);
15712
16079
  }
15713
16080
  _onKeydown(e) {
@@ -16016,6 +16383,20 @@
16016
16383
  this.invoke("editor.clearHistory");
16017
16384
  }
16018
16385
  /**
16386
+ * Returns the number of available undo steps.
16387
+ * @returns {number}
16388
+ */
16389
+ getUndoCount() {
16390
+ return this.invoke("editor.getUndoCount") ?? 0;
16391
+ }
16392
+ /**
16393
+ * Returns the number of available redo steps.
16394
+ * @returns {number}
16395
+ */
16396
+ getRedoCount() {
16397
+ return this.invoke("editor.getRedoCount") ?? 0;
16398
+ }
16399
+ /**
16019
16400
  * Returns true when the editor has no meaningful content.
16020
16401
  * @returns {boolean}
16021
16402
  */
@@ -16123,6 +16504,18 @@
16123
16504
  });
16124
16505
  }
16125
16506
  /**
16507
+ * Returns an array of heading objects representing the table of contents.
16508
+ * Each entry has: level (1-6), text (heading text), element (DOM element).
16509
+ * @returns {{ level: number, text: string, element: HTMLElement }[]}
16510
+ */
16511
+ getTableOfContents() {
16512
+ return Array.from(this.layoutInfo.editable.querySelectorAll("h1,h2,h3,h4,h5,h6")).map((el) => ({
16513
+ level: parseInt(el.tagName[1], 10),
16514
+ text: el.textContent?.trim() ?? "",
16515
+ element: el
16516
+ }));
16517
+ }
16518
+ /**
16126
16519
  * Sets whether the editor is disabled (readonly).
16127
16520
  * @param {boolean} disabled
16128
16521
  */
@@ -16159,11 +16552,13 @@
16159
16552
  this._disposers = [];
16160
16553
  const container = this.layoutInfo.container;
16161
16554
  const wasDark = container?.classList.contains("an-theme-dark");
16555
+ const wasAuto = container?.classList.contains("an-theme-auto");
16162
16556
  if (container?.parentNode) {
16163
16557
  this.targetEl.style.display = "";
16164
16558
  container.remove();
16165
16559
  }
16166
16560
  if (wasDark && !document.querySelector(".an-container.an-theme-dark")) document.body.classList.remove("an-theme-dark");
16561
+ if (wasAuto && !document.querySelector(".an-container.an-theme-auto")) document.body.classList.remove("an-theme-auto");
16167
16562
  if (typeof this.options.onDestroy === "function") this.options.onDestroy(this);
16168
16563
  this._alive = false;
16169
16564
  this._listeners.clear();
@@ -16291,7 +16686,7 @@
16291
16686
  return this;
16292
16687
  },
16293
16688
  /** Library version */
16294
- version: "1.6.7"
16689
+ version: "1.7.0"
16295
16690
  };
16296
16691
  /**
16297
16692
  * @param {string|Element|NodeList|Element[]} selector