autumnnote 1.8.0 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/js/i18n/de.js CHANGED
@@ -151,6 +151,7 @@ export const de = {
151
151
  findPlaceholder: 'Suchen…',
152
152
  searchAriaLabel: 'Suchtext',
153
153
  caseSensitive: '\u00a0Groß-/Kleinschreibung',
154
+ wholeWord: 'Ganzes Wort',
154
155
  prevBtn: '← Zurück',
155
156
  nextBtn: 'Weiter →',
156
157
  replacePlaceholder: 'Ersetzen durch…',
@@ -293,7 +294,16 @@ export const de = {
293
294
  columnWidth: 'Spaltenbreite',
294
295
  rowHeight: 'Zeilenhöhe',
295
296
  tableBorderWidth: 'Tabellenrahmenbreite',
297
+ tableBorderColor: 'Tabellenrahmenfarbe',
296
298
  deleteTable: 'Tabelle löschen',
299
+ cellAlignLeft: 'Linksbündig',
300
+ cellAlignCenter: 'Zentrieren',
301
+ cellAlignRight: 'Rechtsbündig',
302
+ cellAlignJustify: 'Blocksatz',
303
+ toggleHeaderRow: 'Kopfzeile umschalten',
304
+ cellBackground: 'Zellhintergrund',
305
+ noShading: 'Kein Hintergrund',
306
+ noBorderColor: 'Keine Rahmenfarbe',
297
307
  columnWidthPx: 'Spaltenbreite (px)',
298
308
  rowHeightPx: 'Zeilenhöhe (px)',
299
309
  tableBorderWidthPx: 'Tabellenrahmenbreite (px)',
package/src/js/i18n/es.js CHANGED
@@ -151,6 +151,7 @@ export const es = {
151
151
  findPlaceholder: 'Buscar…',
152
152
  searchAriaLabel: 'Texto de búsqueda',
153
153
  caseSensitive: '\u00a0Distinguir mayúsculas',
154
+ wholeWord: 'Palabra completa',
154
155
  prevBtn: '← Anterior',
155
156
  nextBtn: 'Siguiente →',
156
157
  replacePlaceholder: 'Reemplazar con…',
@@ -293,7 +294,16 @@ export const es = {
293
294
  columnWidth: 'Ancho de columna',
294
295
  rowHeight: 'Alto de fila',
295
296
  tableBorderWidth: 'Grosor del borde de la tabla',
297
+ tableBorderColor: 'Color del borde de la tabla',
296
298
  deleteTable: 'Eliminar tabla',
299
+ cellAlignLeft: 'Alinear a la izquierda',
300
+ cellAlignCenter: 'Centrar',
301
+ cellAlignRight: 'Alinear a la derecha',
302
+ cellAlignJustify: 'Justificar',
303
+ toggleHeaderRow: 'Activar fila de encabezado',
304
+ cellBackground: 'Fondo de celda',
305
+ noShading: 'Sin fondo',
306
+ noBorderColor: 'Sin color de borde',
297
307
  columnWidthPx: 'Ancho de columna (px)',
298
308
  rowHeightPx: 'Alto de fila (px)',
299
309
  tableBorderWidthPx: 'Grosor del borde (px)',
package/src/js/i18n/fr.js CHANGED
@@ -152,6 +152,7 @@ export const fr = {
152
152
  findPlaceholder: 'Rechercher\u2026',
153
153
  searchAriaLabel: 'Texte à rechercher',
154
154
  caseSensitive: '\u00a0Respecter la casse',
155
+ wholeWord: 'Mot entier',
155
156
  prevBtn: '\u2190 Préc.',
156
157
  nextBtn: 'Suiv. \u2192',
157
158
  replacePlaceholder: 'Remplacer par\u2026',
@@ -294,7 +295,16 @@ export const fr = {
294
295
  columnWidth: 'Largeur de colonne',
295
296
  rowHeight: 'Hauteur de ligne',
296
297
  tableBorderWidth: 'Épaisseur des bordures',
298
+ tableBorderColor: 'Couleur de bordure',
297
299
  deleteTable: 'Supprimer le tableau',
300
+ cellAlignLeft: 'Aligner \u00e0 gauche',
301
+ cellAlignCenter: 'Centrer',
302
+ cellAlignRight: 'Aligner \u00e0 droite',
303
+ cellAlignJustify: 'Justifier',
304
+ toggleHeaderRow: 'Ligne d\'en-t\u00eate',
305
+ cellBackground: 'Couleur de fond',
306
+ noShading: 'Aucun fond',
307
+ noBorderColor: 'Aucune bordure',
298
308
  columnWidthPx: 'Largeur de colonne (px)',
299
309
  rowHeightPx: 'Hauteur de ligne (px)',
300
310
  tableBorderWidthPx: 'Épaisseur des bordures (px)',
package/src/js/i18n/ja.js CHANGED
@@ -152,6 +152,7 @@ export const ja = {
152
152
  findPlaceholder: '検索\u2026',
153
153
  searchAriaLabel: '検索テキスト',
154
154
  caseSensitive: '\u00a0大文字/小文字を区別',
155
+ wholeWord: '単語単位',
155
156
  prevBtn: '\u2190 前へ',
156
157
  nextBtn: '次へ \u2192',
157
158
  replacePlaceholder: '置換後\u2026',
@@ -294,7 +295,16 @@ export const ja = {
294
295
  columnWidth: '列幅',
295
296
  rowHeight: '行の高さ',
296
297
  tableBorderWidth: 'テーブルの枠幅',
298
+ tableBorderColor: 'テーブルの枠線色',
297
299
  deleteTable: 'テーブルを削除',
300
+ cellAlignLeft: '左揃え',
301
+ cellAlignCenter: '中央揃え',
302
+ cellAlignRight: '右揃え',
303
+ cellAlignJustify: '両端揃え',
304
+ toggleHeaderRow: 'ヘッダー行の切り替え',
305
+ cellBackground: 'セル背景色',
306
+ noShading: '背景色なし',
307
+ noBorderColor: '枠線色なし',
298
308
  columnWidthPx: '列幅 (px)',
299
309
  rowHeightPx: '行の高さ (px)',
300
310
  tableBorderWidthPx: 'テーブルの枠幅 (px)',
package/src/js/i18n/ko.js CHANGED
@@ -151,6 +151,7 @@ export const ko = {
151
151
  findPlaceholder: '찾기…',
152
152
  searchAriaLabel: '검색 텍스트',
153
153
  caseSensitive: '\u00a0대소문자 구분',
154
+ wholeWord: '전체 단어',
154
155
  prevBtn: '← 이전',
155
156
  nextBtn: '다음 →',
156
157
  replacePlaceholder: '바꿀 내용…',
@@ -293,7 +294,16 @@ export const ko = {
293
294
  columnWidth: '열 너비',
294
295
  rowHeight: '행 높이',
295
296
  tableBorderWidth: '표 테두리 너비',
297
+ tableBorderColor: '표 테두리 색상',
296
298
  deleteTable: '표 삭제',
299
+ cellAlignLeft: '왼쪽 정렬',
300
+ cellAlignCenter: '가운데 정렬',
301
+ cellAlignRight: '오른쪽 정렬',
302
+ cellAlignJustify: '양쪽 정렬',
303
+ toggleHeaderRow: '머리글 행 전환',
304
+ cellBackground: '셀 배경색',
305
+ noShading: '배경 없음',
306
+ noBorderColor: '테두리 색 없음',
297
307
  columnWidthPx: '열 너비 (px)',
298
308
  rowHeightPx: '행 높이 (px)',
299
309
  tableBorderWidthPx: '표 테두리 너비 (px)',
package/src/js/i18n/vi.js CHANGED
@@ -152,6 +152,7 @@ export const vi = {
152
152
  findPlaceholder: 'Tìm\u2026',
153
153
  searchAriaLabel: 'Văn bản tìm kiếm',
154
154
  caseSensitive: '\u00a0Phân biệt hoa thường',
155
+ wholeWord: 'Toàn bộ từ',
155
156
  prevBtn: '\u2190 Trước',
156
157
  nextBtn: 'Tiếp \u2192',
157
158
  replacePlaceholder: 'Thay thế bằng\u2026',
@@ -294,9 +295,16 @@ export const vi = {
294
295
  columnWidth: 'Chiều rộng cột',
295
296
  rowHeight: 'Chiều cao hàng',
296
297
  tableBorderWidth: 'Độ rộng viền bảng',
298
+ tableBorderColor: 'Màu viền bảng',
297
299
  deleteTable: 'Xóa bảng',
300
+ cellAlignLeft: 'Căn trái',
301
+ cellAlignCenter: 'Căn giữa',
302
+ cellAlignRight: 'Căn phải',
303
+ cellAlignJustify: 'Căn đều',
304
+ toggleHeaderRow: 'Bật/tắt hàng tiêu đề',
298
305
  cellBackground: 'Màu Nền Ô',
299
306
  noShading: 'Xóa Màu Nền',
307
+ noBorderColor: 'Xóa màu viền',
300
308
  columnWidthPx: 'Chiều rộng cột (px)',
301
309
  rowHeightPx: 'Chiều cao hàng (px)',
302
310
  tableBorderWidthPx: 'Độ rộng viền bảng (px)',
package/src/js/i18n/zh.js CHANGED
@@ -152,6 +152,7 @@ export const zh = {
152
152
  findPlaceholder: '查找\u2026',
153
153
  searchAriaLabel: '搜索文字',
154
154
  caseSensitive: '\u00a0区分大小写',
155
+ wholeWord: '全字匹配',
155
156
  prevBtn: '\u2190 上一个',
156
157
  nextBtn: '下一个 \u2192',
157
158
  replacePlaceholder: '替换为\u2026',
@@ -294,7 +295,16 @@ export const zh = {
294
295
  columnWidth: '列宽',
295
296
  rowHeight: '行高',
296
297
  tableBorderWidth: '表格边框宽度',
298
+ tableBorderColor: '表格边框颜色',
297
299
  deleteTable: '删除表格',
300
+ cellAlignLeft: '左对齐',
301
+ cellAlignCenter: '居中对齐',
302
+ cellAlignRight: '右对齐',
303
+ cellAlignJustify: '两端对齐',
304
+ toggleHeaderRow: '切换标题行',
305
+ cellBackground: '单元格背景',
306
+ noShading: '无底纹',
307
+ noBorderColor: '无边框颜色',
298
308
  columnWidthPx: '列宽 (px)',
299
309
  rowHeightPx: '行高 (px)',
300
310
  tableBorderWidthPx: '表格边框宽度 (px)',
package/src/js/index.js CHANGED
@@ -144,7 +144,7 @@ const AutumnNote = {
144
144
  buttons,
145
145
 
146
146
  /** Library version */
147
- version: '1.8.0',
147
+ version: '1.8.2',
148
148
  };
149
149
 
150
150
  // ---------------------------------------------------------------------------
@@ -365,7 +365,7 @@ export class Clipboard {
365
365
  const mime = /:(.*?);/.exec(header)?.[1] ?? 'image/png';
366
366
  const binary = atob(b64);
367
367
  const arr = new Uint8Array(binary.length);
368
- for (let i = 0; i < binary.length; i++) arr[i] = binary.codePointAt(i);
368
+ for (let i = 0; i < binary.length; i++) arr[i] = binary.charCodeAt(i);
369
369
  return new Blob([arr], { type: mime });
370
370
  }
371
371
 
@@ -107,6 +107,7 @@ export class ImageDialog extends BaseDialog {
107
107
  // ---------------------------------------------------------------------------
108
108
 
109
109
  _onFileChange() {
110
+ if (this.context._alive === false) return;
110
111
  const file = this._fileInput?.files?.[0];
111
112
  if (!file?.type?.startsWith('image/')) return;
112
113
 
@@ -17,6 +17,7 @@
17
17
  * debounce: 200,
18
18
  * onSearch: (query, callback) => void,
19
19
  * onInsert: (item) => string | null,
20
+ * onError: (err: Error) => void,
20
21
  * mentionClass: 'an-mention',
21
22
  * allowSpaces: false,
22
23
  * }
@@ -60,6 +61,7 @@ export class Mention {
60
61
  debounce: cfg.debounce ?? 200,
61
62
  onSearch: cfg.onSearch,
62
63
  onInsert: cfg.onInsert || null,
64
+ onError: cfg.onError || null,
63
65
  mentionClass: cfg.mentionClass || 'an-mention',
64
66
  allowSpaces: cfg.allowSpaces || false,
65
67
  };
@@ -277,7 +279,14 @@ export class Mention {
277
279
  this._renderItems(items);
278
280
  this._showDropdown();
279
281
  };
280
- const result = this._cfg.onSearch(this._query, cb);
282
+ let result;
283
+ try {
284
+ result = this._cfg.onSearch(this._query, cb);
285
+ } catch (err) {
286
+ this._hideDropdown();
287
+ if (typeof this._cfg.onError === 'function') this._cfg.onError(err);
288
+ return;
289
+ }
281
290
  if (result && typeof result.then === 'function') {
282
291
  result.then(cb).catch((err) => {
283
292
  this._hideDropdown();
@@ -1470,9 +1470,30 @@ export class TableTooltip {
1470
1470
  : bText.localeCompare(aText);
1471
1471
  });
1472
1472
  rows.forEach((row) => tbody.appendChild(row));
1473
+ this._markSortIndicator(table, colIdx, direction);
1473
1474
  this.context.invoke('editor.afterCommand');
1474
1475
  }
1475
1476
 
1477
+ /**
1478
+ * Marks the header cell of the sorted column with `an-sort-asc`/`an-sort-desc`
1479
+ * so the active sort column and direction are visible, and clears any previous
1480
+ * indicator. No-op for tables without a `<thead>` (no header row to mark).
1481
+ * @param {HTMLTableElement} table
1482
+ * @param {number} colIdx
1483
+ * @param {'asc'|'desc'} direction
1484
+ */
1485
+ _markSortIndicator(table, colIdx, direction) {
1486
+ const thead = table.querySelector('thead');
1487
+ if (!thead) return;
1488
+ thead.querySelectorAll('.an-sort-asc, .an-sort-desc').forEach((el) => {
1489
+ el.classList.remove('an-sort-asc', 'an-sort-desc');
1490
+ });
1491
+ const headerRow = thead.querySelector('tr');
1492
+ if (!headerRow) return;
1493
+ const headerCell = getCellAtVisualCol(headerRow, colIdx);
1494
+ if (headerCell) headerCell.classList.add(direction === 'asc' ? 'an-sort-asc' : 'an-sort-desc');
1495
+ }
1496
+
1476
1497
  _exportTableCSV() {
1477
1498
  const table = this._activeTable;
1478
1499
  if (!table) return;
@@ -31,9 +31,13 @@
31
31
 
32
32
  &.an-focused {
33
33
  border-color: var(--an-focus-color, #{$an-primary});
34
- // color-mix() blends the focus colour with transparent for the glow ring.
35
- // Falls back gracefully to the default blue glow in older browsers.
36
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--an-focus-color, #{$an-primary}) 18%, transparent);
34
+ // Fallback glow for browsers without color-mix() (pre-Chrome 111, Safari 15.3, Firefox 112).
35
+ // Uses the static $an-primary value so --an-focus-color overrides are ignored in those browsers.
36
+ box-shadow: 0 0 0 3px rgba($an-primary, 0.18);
37
+ // Modern browsers get a fully themeable glow that respects --an-focus-color.
38
+ @supports (color: color-mix(in srgb, red, blue)) {
39
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--an-focus-color, #{$an-primary}) 18%, transparent);
40
+ }
37
41
  }
38
42
 
39
43
  &.an-disabled {
@@ -431,6 +435,8 @@
431
435
  padding: $an-editable-pad;
432
436
  min-height: 0;
433
437
  outline: none;
438
+
439
+
434
440
  line-height: $an-line-height;
435
441
  color: $an-text;
436
442
  overflow-y: auto;
@@ -565,6 +571,17 @@
565
571
  th {
566
572
  background: $an-bg-toolbar;
567
573
  font-weight: 600;
574
+
575
+ // Sort indicator — shows the active sorted column and direction
576
+ &.an-sort-asc::after,
577
+ &.an-sort-desc::after {
578
+ display: inline-block;
579
+ margin-left: 6px;
580
+ font-size: 0.7em;
581
+ opacity: 0.6;
582
+ }
583
+ &.an-sort-asc::after { content: '\25B2'; }
584
+ &.an-sort-desc::after { content: '\25BC'; }
568
585
  }
569
586
  }
570
587
  }
package/types/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * AutumnNote – TypeScript declarations
3
- * @version 1.8.0
3
+ * @version 1.8.2
4
4
  */
5
5
 
6
6
  // ---------------------------------------------------------------------------
@@ -106,7 +106,7 @@ export interface AsnOptions {
106
106
  colorSwatches?: string[];
107
107
  /**
108
108
  * Display language for the editor UI.
109
- * Built-in: 'en' (default) | 'vi' | 'ja' | 'zh' | 'fr'.
109
+ * Built-in: 'en' (default) | 'vi' | 'ja' | 'zh' | 'fr' | 'de' | 'es' | 'ko'.
110
110
  * Pass a partial locale object to override individual strings.
111
111
  */
112
112
  lang?: string | Partial<AsnLocale>;
@@ -323,7 +323,7 @@ export interface AsnLocale {
323
323
  };
324
324
  }
325
325
 
326
- /** Registry of all built-in locales (keys: 'en', 'vi', 'ja', 'zh', 'fr'). */
326
+ /** Registry of all built-in locales (keys: 'en', 'vi', 'ja', 'zh', 'fr', 'de', 'es', 'ko'). */
327
327
  export declare const locales: Record<string, AsnLocale>;
328
328
 
329
329
  /**