autumnnote 1.6.2 → 1.6.5

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.
@@ -3,7 +3,8 @@
3
3
  * Opened via the toolbar '?' button or Shift+? inside the editor.
4
4
  */
5
5
 
6
- import { createElement, on, trapFocus } from '../core/dom.js';
6
+ import { createElement, on } from '../core/dom.js';
7
+ import { BaseDialog } from './BaseDialog.js';
7
8
 
8
9
  const SHORTCUTS = [
9
10
  {
@@ -51,64 +52,37 @@ const SHORTCUTS = [
51
52
  },
52
53
  ];
53
54
 
54
- export class ShortcutsDialog {
55
- /** @param {import('../Context.js').Context} context */
56
- constructor(context) {
57
- this.context = context;
58
- this._dialog = null;
59
- this._closeBtn = null;
60
- this._disposers = [];
61
- }
62
-
63
- initialize() {
64
- this._dialog = this._buildDialog();
65
- document.body.appendChild(this._dialog);
66
- return this;
67
- }
55
+ const ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M6 11h.01M10 11h.01M14 11h.01M18 11h.01M6 15h.01M18 15h.01M10 15h4"/><path d="M7 3l5 4 5-4"/></svg>`;
68
56
 
69
- destroy() {
70
- this._disposers.forEach((d) => d());
71
- this._disposers = [];
72
- this._dialog?.remove();
73
- this._dialog = null;
74
- }
57
+ export class ShortcutsDialog extends BaseDialog {
58
+ // ---------------------------------------------------------------------------
59
+ // Public API
60
+ // ---------------------------------------------------------------------------
75
61
 
76
62
  show() {
77
- if (this._dialog) {
78
- this._dialog.style.display = 'flex';
79
- this._removeTrap = trapFocus(this._dialog, () => this._close());
80
- setTimeout(() => this._closeBtn?.focus(), 50);
81
- }
63
+ this._open();
82
64
  }
83
65
 
84
- _close() {
85
- if (this._dialog) this._dialog.style.display = 'none';
86
- if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }
87
- }
66
+ // ---------------------------------------------------------------------------
67
+ // Build dialog
68
+ // ---------------------------------------------------------------------------
88
69
 
89
70
  _buildDialog() {
90
- const overlay = createElement('div', {
91
- class: 'an-dialog-overlay',
92
- role: 'dialog',
93
- 'aria-modal': 'true',
94
- 'aria-label': this.context.locale.shortcutsDialog.ariaLabel,
95
- });
71
+ const L = this.context.locale.shortcutsDialog;
72
+ const { overlay, box } = this._buildDialogShell(L.ariaLabel, ICON_SVG, L.title);
73
+ box.classList.add('an-shortcuts-box');
96
74
 
97
- const box = createElement('div', { class: 'an-dialog-box an-shortcuts-box' });
98
-
99
- // Title row with close button
100
- const titleRow = createElement('div', { class: 'an-icon-title-row' });
101
- const title = createElement('h3', { class: 'an-dialog-title' });
102
- title.textContent = this.context.locale.shortcutsDialog.title;
75
+ // Close button pinned to the right of the header row
103
76
  const closeBtn = createElement('button', {
104
77
  type: 'button',
105
78
  class: 'an-icon-close',
106
- 'aria-label': this.context.locale.shortcutsDialog.close,
79
+ 'aria-label': L.close,
80
+ style: 'margin-left:auto',
107
81
  });
108
82
  closeBtn.textContent = '×';
109
83
  this._closeBtn = closeBtn;
110
- titleRow.append(title, closeBtn);
111
- box.appendChild(titleRow);
84
+ this._firstInput = closeBtn;
85
+ box.querySelector('.an-dialog-header').appendChild(closeBtn);
112
86
 
113
87
  const shortcuts = this.context.locale.shortcutsDialog.shortcuts || SHORTCUTS;
114
88
  shortcuts.forEach(({ category, items }) => {
@@ -129,11 +103,8 @@ export class ShortcutsDialog {
129
103
  box.appendChild(table);
130
104
  });
131
105
 
132
- overlay.appendChild(box);
133
-
134
106
  const d1 = on(closeBtn, 'click', () => this._close());
135
- const d2 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });
136
- this._disposers.push(d1, d2);
107
+ this._disposers.push(d1);
137
108
 
138
109
  return overlay;
139
110
  }
@@ -58,7 +58,7 @@ function getCellAfterVisualCol(row, visualIdx) {
58
58
  if (vIdx > visualIdx) {
59
59
  // next cell after the one that starts at / spans visualIdx
60
60
  const next = c.nextElementSibling;
61
- return (next && next.tagName === 'TD' || next && next.tagName === 'TH') ? /** @type {HTMLTableCellElement} */ (next) : null;
61
+ return (next?.tagName === 'TD' || next?.tagName === 'TH') ? /** @type {HTMLTableCellElement} */ (next) : null;
62
62
  }
63
63
  }
64
64
  return null;
@@ -388,11 +388,11 @@ export class TableTooltip {
388
388
  this._disposers = [];
389
389
  if (this._el && this._el.parentNode) this._el.remove();
390
390
  this._el = null;
391
- if (this._sizePopover && this._sizePopover.parentNode) {
391
+ if (this._sizePopover?.parentNode) {
392
392
  this._sizePopover.remove();
393
393
  }
394
394
  this._sizePopover = null;
395
- if (this._shadePopover && this._shadePopover.parentNode) {
395
+ if (this._shadePopover?.parentNode) {
396
396
  this._shadePopover.remove();
397
397
  }
398
398
  this._shadePopover = null;
@@ -604,7 +604,7 @@ export class TableTooltip {
604
604
  _getCell() {
605
605
  // Prefer the cell under the current text cursor (most intuitive for operations)
606
606
  const sel = globalThis.getSelection();
607
- if (sel && sel.rangeCount) {
607
+ if (sel?.rangeCount) {
608
608
  let container = sel.getRangeAt(0).commonAncestorContainer;
609
609
  if (container.nodeType === 3) container = container.parentElement;
610
610
  const cellFromSel = /** @type {Element} */ (container)?.closest('td, th');
@@ -659,7 +659,7 @@ export class TableTooltip {
659
659
  if (!startCell) return [];
660
660
  if (!endCell || startCell === endCell) return [startCell];
661
661
  const table = startCell.closest('table');
662
- if (!table || !table.contains(endCell)) return [startCell];
662
+ if (!table?.contains(endCell)) return [startCell];
663
663
 
664
664
  const { gridMap, cellPos } = buildGridMap(table);
665
665
  const sp = cellPos.get(startCell);
@@ -742,8 +742,8 @@ export class TableTooltip {
742
742
  for (let i = 0; i < colCount; i++) {
743
743
  const td = createElement('td', {}, ['\u00a0']);
744
744
  const ref = refCells[i];
745
- if (ref && ref.style.width) td.style.width = ref.style.width;
746
- if (ref && ref.style.minWidth) td.style.minWidth = ref.style.minWidth;
745
+ if (ref?.style.width) td.style.width = ref.style.width;
746
+ if (ref?.style.minWidth) td.style.minWidth = ref.style.minWidth;
747
747
  newRow.appendChild(td);
748
748
  }
749
749
  if (position === 'above') refRow.parentElement?.insertBefore(newRow, refRow);
@@ -399,7 +399,7 @@ export class Toolbar {
399
399
 
400
400
  const saveSelection = () => {
401
401
  const sel = globalThis.getSelection();
402
- savedRange = (sel && sel.rangeCount) ? sel.getRangeAt(0).cloneRange() : null;
402
+ savedRange = sel?.rangeCount ? sel.getRangeAt(0).cloneRange() : null;
403
403
  };
404
404
 
405
405
  const restoreSelection = () => {
@@ -543,7 +543,7 @@ export class Toolbar {
543
543
  const value = (typeof item === 'object') ? item.value : item;
544
544
  const label = (typeof item === 'object')
545
545
  ? (def.name === 'paragraphStyle'
546
- ? ((this.context.locale.toolbar.paragraphItems || {})[item.value] || item.label)
546
+ ? (this.context.locale.toolbar.paragraphItems?.[item.value] || item.label)
547
547
  : item.label)
548
548
  : item;
549
549
  const isHeader = (typeof item === 'object') && !!item.disabled;
@@ -563,7 +563,7 @@ export class Toolbar {
563
563
  let _savedRange = null;
564
564
  const dMousedown = on(select, 'mousedown', () => {
565
565
  const sel = globalThis.getSelection();
566
- _savedRange = (sel && sel.rangeCount) ? sel.getRangeAt(0).cloneRange() : null;
566
+ _savedRange = sel?.rangeCount ? sel.getRangeAt(0).cloneRange() : null;
567
567
  });
568
568
 
569
569
  const disposer = on(select, 'change', (e) => {
@@ -617,15 +617,13 @@ export class Toolbar {
617
617
  } else {
618
618
  btn.textContent = btnDef.icon || btnDef.name;
619
619
  }
620
- } else {
620
+ } else if (_SVG_MAP.has(btnDef.icon)) {
621
621
  // FontAwesome absent: use SVG fallback when available
622
- if (_SVG_MAP.has(btnDef.icon)) {
623
- btn.innerHTML = _SVG_MAP.get(btnDef.icon);
624
- } else if (_SVG_MAP.has(btnDef.name)) {
625
- btn.innerHTML = _SVG_MAP.get(btnDef.name);
626
- } else {
627
- btn.textContent = btnDef.icon || btnDef.name;
628
- }
622
+ btn.innerHTML = _SVG_MAP.get(btnDef.icon);
623
+ } else if (_SVG_MAP.has(btnDef.name)) {
624
+ btn.innerHTML = _SVG_MAP.get(btnDef.name);
625
+ } else {
626
+ btn.textContent = btnDef.icon || btnDef.name;
629
627
  }
630
628
 
631
629
  const disposer = on(btn, 'click', (event) => {