autumnnote 1.0.8 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +331 -637
- package/dist/autumnnote.es.js +2865 -158
- package/dist/autumnnote.es.js.map +1 -1
- package/dist/autumnnote.umd.js +2864 -157
- package/dist/autumnnote.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/js/Context.js +4 -0
- package/src/js/i18n/de.js +320 -0
- package/src/js/i18n/en.js +328 -0
- package/src/js/i18n/es.js +320 -0
- package/src/js/i18n/fr.js +321 -0
- package/src/js/i18n/index.js +59 -0
- package/src/js/i18n/ja.js +321 -0
- package/src/js/i18n/ko.js +320 -0
- package/src/js/i18n/vi.js +321 -0
- package/src/js/i18n/zh.js +321 -0
- package/src/js/index.js +2 -1
- package/src/js/module/CodeTooltip.js +12 -9
- package/src/js/module/ContextMenu.js +13 -11
- package/src/js/module/EmojiDialog.js +8 -7
- package/src/js/module/FindReplace.js +14 -13
- package/src/js/module/IconDialog.js +14 -13
- package/src/js/module/ImageDialog.js +17 -16
- package/src/js/module/ImageTooltip.js +13 -12
- package/src/js/module/LinkDialog.js +10 -9
- package/src/js/module/LinkTooltip.js +6 -5
- package/src/js/module/ShortcutsDialog.js +5 -4
- package/src/js/module/Statusbar.js +6 -5
- package/src/js/module/TableTooltip.js +22 -19
- package/src/js/module/Toolbar.js +21 -15
- package/src/js/module/VideoDialog.js +10 -9
- package/src/js/module/VideoTooltip.js +12 -11
- package/src/js/settings.js +4 -0
- package/types/index.d.ts +58 -1
|
@@ -76,16 +76,17 @@ export class CodeTooltip {
|
|
|
76
76
|
// ---------------------------------------------------------------------------
|
|
77
77
|
|
|
78
78
|
_buildTooltip() {
|
|
79
|
+
const L = this.context.locale.tooltips.code;
|
|
79
80
|
const el = createElement('div', {
|
|
80
81
|
class: 'an-link-tooltip an-code-tooltip',
|
|
81
82
|
role: 'toolbar',
|
|
82
|
-
'aria-label':
|
|
83
|
+
'aria-label': L.ariaLabel,
|
|
83
84
|
});
|
|
84
85
|
el.style.display = 'none';
|
|
85
86
|
|
|
86
87
|
// Label
|
|
87
88
|
this._label = createElement('span', { class: 'an-link-tooltip-url' });
|
|
88
|
-
this._label.textContent =
|
|
89
|
+
this._label.textContent = L.label;
|
|
89
90
|
el.appendChild(this._label);
|
|
90
91
|
|
|
91
92
|
el.appendChild(this._sep());
|
|
@@ -93,8 +94,8 @@ export class CodeTooltip {
|
|
|
93
94
|
// Language selector
|
|
94
95
|
this._langSelect = createElement('select', {
|
|
95
96
|
class: 'an-code-lang-select',
|
|
96
|
-
title:
|
|
97
|
-
'aria-label':
|
|
97
|
+
title: L.syntaxLanguage,
|
|
98
|
+
'aria-label': L.syntaxAriaLabel,
|
|
98
99
|
});
|
|
99
100
|
const LANGUAGES = [
|
|
100
101
|
['', 'Plain text'], ['javascript', 'JavaScript'], ['typescript', 'TypeScript'],
|
|
@@ -115,25 +116,25 @@ export class CodeTooltip {
|
|
|
115
116
|
el.appendChild(this._sep());
|
|
116
117
|
|
|
117
118
|
// Copy code
|
|
118
|
-
this._copyBtn = this._makeBtn(ICONS.copy,
|
|
119
|
+
this._copyBtn = this._makeBtn(ICONS.copy, L.copyCode, () => this._copyCode());
|
|
119
120
|
|
|
120
121
|
el.appendChild(this._copyBtn);
|
|
121
122
|
|
|
122
123
|
el.appendChild(this._sep());
|
|
123
124
|
|
|
124
125
|
// Toggle word-wrap
|
|
125
|
-
this._wrapBtn = this._makeBtn(ICONS.wrapOn,
|
|
126
|
+
this._wrapBtn = this._makeBtn(ICONS.wrapOn, L.toggleWordWrap, () => this._toggleWrap());
|
|
126
127
|
el.appendChild(this._wrapBtn);
|
|
127
128
|
|
|
128
129
|
el.appendChild(this._sep());
|
|
129
130
|
|
|
130
131
|
// Convert to normal paragraph
|
|
131
|
-
el.appendChild(this._makeBtn(ICONS.toParagraph,
|
|
132
|
+
el.appendChild(this._makeBtn(ICONS.toParagraph, L.convertToParagraph, () => this._toParagraph()));
|
|
132
133
|
|
|
133
134
|
el.appendChild(this._sep());
|
|
134
135
|
|
|
135
136
|
// Delete block
|
|
136
|
-
el.appendChild(this._makeBtn(ICONS.deleteCode,
|
|
137
|
+
el.appendChild(this._makeBtn(ICONS.deleteCode, L.deleteCodeBlock, () => this._delete(), true));
|
|
137
138
|
|
|
138
139
|
// Keep tooltip alive while hovering it
|
|
139
140
|
this._disposers.push(
|
|
@@ -241,7 +242,9 @@ export class CodeTooltip {
|
|
|
241
242
|
const wrapped = (this._activePre.style.whiteSpace || '').includes('pre-wrap')
|
|
242
243
|
|| window.getComputedStyle(this._activePre).whiteSpace === 'pre-wrap';
|
|
243
244
|
this._wrapBtn.classList.toggle('active', wrapped);
|
|
244
|
-
this._wrapBtn.title = wrapped
|
|
245
|
+
this._wrapBtn.title = wrapped
|
|
246
|
+
? this.context.locale.tooltips.code.disableWordWrap
|
|
247
|
+
: this.context.locale.tooltips.code.enableWordWrap;
|
|
245
248
|
}
|
|
246
249
|
|
|
247
250
|
_syncLangSelect() {
|
|
@@ -48,8 +48,9 @@ const COLOR_PRESETS = [
|
|
|
48
48
|
|
|
49
49
|
function makeColorSubItems(colorType) {
|
|
50
50
|
const label = colorType === 'foreColor' ? 'Text Color' : 'Highlight Color';
|
|
51
|
+
const localeKey = colorType === 'foreColor' ? 'textColor' : 'highlightColor';
|
|
51
52
|
return () => [
|
|
52
|
-
{ back: true, label, navigate: () => defaultItems },
|
|
53
|
+
{ back: true, label, localeKey, navigate: () => defaultItems },
|
|
53
54
|
{ colorPalette: true, colorType },
|
|
54
55
|
];
|
|
55
56
|
}
|
|
@@ -171,7 +172,8 @@ export class ContextMenu {
|
|
|
171
172
|
const iconSpan = createElement('span', { class: 'an-context-icon', 'aria-hidden': 'true' });
|
|
172
173
|
iconSpan.innerHTML = ICONS.back;
|
|
173
174
|
backBtn.appendChild(iconSpan);
|
|
174
|
-
|
|
175
|
+
const backLabel = (it.localeKey && this.context.locale.contextMenu[it.localeKey]) || it.label || this.context.locale.contextMenu.back || 'Back';
|
|
176
|
+
backBtn.appendChild(createElement('span', { class: 'an-context-label' }, [backLabel]));
|
|
175
177
|
const off = on(backBtn, 'click', (e) => {
|
|
176
178
|
e.stopPropagation();
|
|
177
179
|
const curLeft = parseFloat(this.el.style.left);
|
|
@@ -204,7 +206,7 @@ export class ContextMenu {
|
|
|
204
206
|
btn.appendChild(iconSpan);
|
|
205
207
|
}
|
|
206
208
|
}
|
|
207
|
-
btn.appendChild(createElement('span', { class: 'an-context-label' }, [it.label || it.name]));
|
|
209
|
+
btn.appendChild(createElement('span', { class: 'an-context-label' }, [(this.context.locale.contextMenu[it.name] || it.label || it.name)]));
|
|
208
210
|
const chevron = createElement('span', { class: 'an-context-chevron', 'aria-hidden': 'true' });
|
|
209
211
|
chevron.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>`;
|
|
210
212
|
btn.appendChild(chevron);
|
|
@@ -238,9 +240,9 @@ export class ContextMenu {
|
|
|
238
240
|
if (it.colorType === 'hiliteColor') {
|
|
239
241
|
const noColor = createElement('div', {
|
|
240
242
|
class: 'an-context-color-swatch an-context-color-none',
|
|
241
|
-
title: 'No highlight',
|
|
243
|
+
title: this.context.locale.contextMenu.noHighlight || 'No highlight',
|
|
242
244
|
role: 'button',
|
|
243
|
-
'aria-label': 'No highlight',
|
|
245
|
+
'aria-label': this.context.locale.contextMenu.noHighlight || 'No highlight',
|
|
244
246
|
});
|
|
245
247
|
noColor.innerHTML = ICONS.noColor;
|
|
246
248
|
const offNo = on(noColor, 'click', (e) => { e.stopPropagation(); this._applyColor('hiliteColor', 'transparent'); });
|
|
@@ -254,10 +256,10 @@ export class ContextMenu {
|
|
|
254
256
|
const colorInput = createElement('input', {
|
|
255
257
|
type: 'color',
|
|
256
258
|
value: it.colorType === 'foreColor' ? '#000000' : '#ffff00',
|
|
257
|
-
title: 'Custom color',
|
|
258
|
-
'aria-label': 'Custom color',
|
|
259
|
+
title: this.context.locale.contextMenu.customColor || 'Custom color',
|
|
260
|
+
'aria-label': this.context.locale.contextMenu.customColor || 'Custom color',
|
|
259
261
|
});
|
|
260
|
-
const customLabel = createElement('span', {}, ['Custom…']);
|
|
262
|
+
const customLabel = createElement('span', {}, [this.context.locale.contextMenu.customColorLabel || 'Custom…']);
|
|
261
263
|
const offCustom = on(colorInput, 'change', () => this._applyColor(it.colorType, colorInput.value));
|
|
262
264
|
this._menuDisposers.push(offCustom);
|
|
263
265
|
customRow.appendChild(colorInput);
|
|
@@ -277,7 +279,7 @@ export class ContextMenu {
|
|
|
277
279
|
iconSpan.innerHTML = it.icon;
|
|
278
280
|
headerBtn.appendChild(iconSpan);
|
|
279
281
|
}
|
|
280
|
-
headerBtn.appendChild(createElement('span', { class: 'an-context-label' }, [it.label || 'Insert Table']));
|
|
282
|
+
headerBtn.appendChild(createElement('span', { class: 'an-context-label' }, [this.context.locale.contextMenu.table || it.label || 'Insert Table']));
|
|
281
283
|
const chevron = createElement('span', { class: 'an-context-chevron', 'aria-hidden': 'true' });
|
|
282
284
|
chevron.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>`;
|
|
283
285
|
headerBtn.appendChild(chevron);
|
|
@@ -305,7 +307,7 @@ export class ContextMenu {
|
|
|
305
307
|
cells.forEach((cell) => {
|
|
306
308
|
cell.classList.toggle('active', +cell.dataset.row <= rows && +cell.dataset.col <= cols);
|
|
307
309
|
});
|
|
308
|
-
labelEl.textContent = (rows && cols) ? `${cols} × ${rows}` : 'Insert Table';
|
|
310
|
+
labelEl.textContent = (rows && cols) ? `${cols} × ${rows}` : (this.context.locale.contextMenu.table || 'Insert Table');
|
|
309
311
|
};
|
|
310
312
|
|
|
311
313
|
panel.appendChild(gridEl);
|
|
@@ -358,7 +360,7 @@ export class ContextMenu {
|
|
|
358
360
|
iconSpan.innerHTML = it.icon;
|
|
359
361
|
btn.appendChild(iconSpan);
|
|
360
362
|
}
|
|
361
|
-
btn.appendChild(createElement('span', { class: 'an-context-label' }, [it.label || it.name]));
|
|
363
|
+
btn.appendChild(createElement('span', { class: 'an-context-label' }, [(this.context.locale.contextMenu[it.name] || it.label || it.name)]));
|
|
362
364
|
const off = on(btn, 'click', (e) => {
|
|
363
365
|
e.stopPropagation();
|
|
364
366
|
this.hide();
|
|
@@ -555,19 +555,20 @@ export class EmojiDialog {
|
|
|
555
555
|
// ---------------------------------------------------------------------------
|
|
556
556
|
|
|
557
557
|
_buildDialog() {
|
|
558
|
+
const L = this.context.locale.emojiDialog;
|
|
558
559
|
const overlay = createElement('div', {
|
|
559
560
|
class: 'an-dialog-overlay',
|
|
560
561
|
role: 'dialog',
|
|
561
562
|
'aria-modal': 'true',
|
|
562
|
-
'aria-label':
|
|
563
|
+
'aria-label': L.ariaLabel,
|
|
563
564
|
});
|
|
564
565
|
const box = createElement('div', { class: 'an-dialog-box an-emoji-box' });
|
|
565
566
|
|
|
566
567
|
// Title row
|
|
567
568
|
const titleRow = createElement('div', { class: 'an-icon-title-row' });
|
|
568
569
|
const title = createElement('h3', { class: 'an-dialog-title' });
|
|
569
|
-
title.textContent =
|
|
570
|
-
const closeBtn = createElement('button', { type: 'button', class: 'an-icon-close', 'aria-label':
|
|
570
|
+
title.textContent = L.title;
|
|
571
|
+
const closeBtn = createElement('button', { type: 'button', class: 'an-icon-close', 'aria-label': L.close });
|
|
571
572
|
closeBtn.innerHTML = '×';
|
|
572
573
|
titleRow.append(title, closeBtn);
|
|
573
574
|
|
|
@@ -575,7 +576,7 @@ export class EmojiDialog {
|
|
|
575
576
|
const searchInput = createElement('input', {
|
|
576
577
|
type: 'search',
|
|
577
578
|
class: 'an-input an-icon-search',
|
|
578
|
-
placeholder:
|
|
579
|
+
placeholder: L.searchPlaceholder,
|
|
579
580
|
autocomplete: 'off',
|
|
580
581
|
});
|
|
581
582
|
this._searchInput = searchInput;
|
|
@@ -583,11 +584,11 @@ export class EmojiDialog {
|
|
|
583
584
|
// Category tabs
|
|
584
585
|
const catBar = createElement('div', { class: 'an-icon-cats' });
|
|
585
586
|
const allTab = createElement('button', { type: 'button', class: 'an-icon-cat active', 'data-cat': 'all' });
|
|
586
|
-
allTab.textContent =
|
|
587
|
+
allTab.textContent = L.all;
|
|
587
588
|
catBar.appendChild(allTab);
|
|
588
589
|
EMOJI_CATS.forEach(({ id, label }) => {
|
|
589
590
|
const tab = createElement('button', { type: 'button', class: 'an-icon-cat', 'data-cat': id });
|
|
590
|
-
tab.textContent = label;
|
|
591
|
+
tab.textContent = (L.categories && L.categories[id]) || label;
|
|
591
592
|
catBar.appendChild(tab);
|
|
592
593
|
});
|
|
593
594
|
this._catBar = catBar;
|
|
@@ -611,7 +612,7 @@ export class EmojiDialog {
|
|
|
611
612
|
// Cancel only — clicking an emoji inserts immediately
|
|
612
613
|
const btnRow = createElement('div', { class: 'an-dialog-actions' });
|
|
613
614
|
const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });
|
|
614
|
-
cancelBtn.textContent =
|
|
615
|
+
cancelBtn.textContent = L.cancelBtn;
|
|
615
616
|
btnRow.appendChild(cancelBtn);
|
|
616
617
|
|
|
617
618
|
box.append(titleRow, searchInput, catBar, grid, btnRow);
|
|
@@ -122,7 +122,7 @@ export class FindReplace {
|
|
|
122
122
|
const isReplace = this._mode === 'replace';
|
|
123
123
|
if (replaceRow) replaceRow.style.display = isReplace ? '' : 'none';
|
|
124
124
|
if (replaceActions) replaceActions.style.display = isReplace ? '' : 'none';
|
|
125
|
-
if (title) title.textContent = isReplace ?
|
|
125
|
+
if (title) title.textContent = isReplace ? this.context.locale.findReplace.findReplaceTitle : this.context.locale.findReplace.findTitle;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
// ---------------------------------------------------------------------------
|
|
@@ -130,24 +130,25 @@ export class FindReplace {
|
|
|
130
130
|
// ---------------------------------------------------------------------------
|
|
131
131
|
|
|
132
132
|
_buildDialog() {
|
|
133
|
+
const L = this.context.locale.findReplace;
|
|
133
134
|
const overlay = createElement('div', {
|
|
134
135
|
class: 'an-dialog-overlay an-fr-dialog',
|
|
135
136
|
role: 'dialog',
|
|
136
137
|
'aria-modal': 'true',
|
|
137
|
-
'aria-label':
|
|
138
|
+
'aria-label': L.findReplaceTitle,
|
|
138
139
|
});
|
|
139
140
|
const box = createElement('div', { class: 'an-dialog-box' });
|
|
140
141
|
|
|
141
142
|
// ---- Title row ----
|
|
142
143
|
const titleRow = createElement('div', { class: 'an-icon-title-row' });
|
|
143
144
|
const title = createElement('h3', { class: 'an-dialog-title' });
|
|
144
|
-
title.textContent =
|
|
145
|
+
title.textContent = L.findTitle;
|
|
145
146
|
const closeBtn = createElement('button', {
|
|
146
147
|
type: 'button',
|
|
147
148
|
class: 'an-icon-close',
|
|
148
149
|
'aria-label': 'Close',
|
|
149
150
|
});
|
|
150
|
-
closeBtn.textContent =
|
|
151
|
+
closeBtn.textContent = L.close;
|
|
151
152
|
this._closeBtn = closeBtn;
|
|
152
153
|
titleRow.append(title, closeBtn);
|
|
153
154
|
box.appendChild(titleRow);
|
|
@@ -157,8 +158,8 @@ export class FindReplace {
|
|
|
157
158
|
const findInput = createElement('input', {
|
|
158
159
|
type: 'text',
|
|
159
160
|
class: 'an-input',
|
|
160
|
-
placeholder:
|
|
161
|
-
'aria-label':
|
|
161
|
+
placeholder: L.findPlaceholder,
|
|
162
|
+
'aria-label': L.searchAriaLabel,
|
|
162
163
|
});
|
|
163
164
|
this._findInput = findInput;
|
|
164
165
|
findRow.appendChild(findInput);
|
|
@@ -172,7 +173,7 @@ export class FindReplace {
|
|
|
172
173
|
'aria-label': 'Case sensitive',
|
|
173
174
|
});
|
|
174
175
|
this._caseCheckbox = caseCheckbox;
|
|
175
|
-
caseLabel.append(caseCheckbox, document.createTextNode(
|
|
176
|
+
caseLabel.append(caseCheckbox, document.createTextNode(L.caseSensitive));
|
|
176
177
|
const counter = createElement('span', { class: 'an-fr-counter' });
|
|
177
178
|
this._counterEl = counter;
|
|
178
179
|
optRow.append(caseLabel, counter);
|
|
@@ -181,9 +182,9 @@ export class FindReplace {
|
|
|
181
182
|
// ---- Find actions ----
|
|
182
183
|
const findActions = createElement('div', { class: 'an-dialog-actions an-fr-find-actions' });
|
|
183
184
|
const prevBtn = createElement('button', { type: 'button', class: 'an-btn' });
|
|
184
|
-
prevBtn.textContent =
|
|
185
|
+
prevBtn.textContent = L.prevBtn;
|
|
185
186
|
const nextBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });
|
|
186
|
-
nextBtn.textContent =
|
|
187
|
+
nextBtn.textContent = L.nextBtn;
|
|
187
188
|
findActions.append(prevBtn, nextBtn);
|
|
188
189
|
box.appendChild(findActions);
|
|
189
190
|
|
|
@@ -193,8 +194,8 @@ export class FindReplace {
|
|
|
193
194
|
const replaceInput = createElement('input', {
|
|
194
195
|
type: 'text',
|
|
195
196
|
class: 'an-input',
|
|
196
|
-
placeholder:
|
|
197
|
-
'aria-label':
|
|
197
|
+
placeholder: L.replacePlaceholder,
|
|
198
|
+
'aria-label': L.replaceAriaLabel,
|
|
198
199
|
});
|
|
199
200
|
this._replaceInput = replaceInput;
|
|
200
201
|
replaceRow.appendChild(replaceInput);
|
|
@@ -204,9 +205,9 @@ export class FindReplace {
|
|
|
204
205
|
const replaceActions = createElement('div', { class: 'an-dialog-actions an-fr-replace-actions' });
|
|
205
206
|
replaceActions.style.display = 'none';
|
|
206
207
|
const replaceBtn = createElement('button', { type: 'button', class: 'an-btn' });
|
|
207
|
-
replaceBtn.textContent =
|
|
208
|
+
replaceBtn.textContent = L.replaceBtn;
|
|
208
209
|
const replaceAllBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });
|
|
209
|
-
replaceAllBtn.textContent =
|
|
210
|
+
replaceAllBtn.textContent = L.replaceAllBtn;
|
|
210
211
|
replaceActions.append(replaceBtn, replaceAllBtn);
|
|
211
212
|
box.appendChild(replaceActions);
|
|
212
213
|
|
|
@@ -332,11 +332,12 @@ export class IconDialog {
|
|
|
332
332
|
// ---------------------------------------------------------------------------
|
|
333
333
|
|
|
334
334
|
_buildDialog() {
|
|
335
|
+
const L = this.context.locale.iconDialog;
|
|
335
336
|
const overlay = createElement('div', {
|
|
336
337
|
class: 'an-dialog-overlay',
|
|
337
338
|
role: 'dialog',
|
|
338
339
|
'aria-modal': 'true',
|
|
339
|
-
'aria-label':
|
|
340
|
+
'aria-label': L.ariaLabel,
|
|
340
341
|
});
|
|
341
342
|
|
|
342
343
|
const box = createElement('div', { class: 'an-dialog-box an-icon-box' });
|
|
@@ -344,8 +345,8 @@ export class IconDialog {
|
|
|
344
345
|
// Title row
|
|
345
346
|
const titleRow = createElement('div', { class: 'an-icon-title-row' });
|
|
346
347
|
const title = createElement('h3', { class: 'an-dialog-title' });
|
|
347
|
-
title.textContent =
|
|
348
|
-
const closeBtn = createElement('button', { type: 'button', class: 'an-icon-close', 'aria-label':
|
|
348
|
+
title.textContent = L.title;
|
|
349
|
+
const closeBtn = createElement('button', { type: 'button', class: 'an-icon-close', 'aria-label': L.close });
|
|
349
350
|
closeBtn.innerHTML = '×';
|
|
350
351
|
titleRow.append(title, closeBtn);
|
|
351
352
|
|
|
@@ -353,7 +354,7 @@ export class IconDialog {
|
|
|
353
354
|
const searchInput = createElement('input', {
|
|
354
355
|
type: 'search',
|
|
355
356
|
class: 'an-input an-icon-search',
|
|
356
|
-
placeholder:
|
|
357
|
+
placeholder: L.searchPlaceholder,
|
|
357
358
|
autocomplete: 'off',
|
|
358
359
|
});
|
|
359
360
|
this._searchInput = searchInput;
|
|
@@ -361,11 +362,11 @@ export class IconDialog {
|
|
|
361
362
|
// Category tabs
|
|
362
363
|
const catBar = createElement('div', { class: 'an-icon-cats' });
|
|
363
364
|
const allTab = createElement('button', { type: 'button', class: 'an-icon-cat active', 'data-cat': 'all' });
|
|
364
|
-
allTab.textContent =
|
|
365
|
+
allTab.textContent = L.all;
|
|
365
366
|
catBar.appendChild(allTab);
|
|
366
367
|
ICON_CATEGORIES.forEach(({ id, label }) => {
|
|
367
368
|
const tab = createElement('button', { type: 'button', class: 'an-icon-cat', 'data-cat': id });
|
|
368
|
-
tab.textContent = label;
|
|
369
|
+
tab.textContent = (L.categories && L.categories[id]) || label;
|
|
369
370
|
catBar.appendChild(tab);
|
|
370
371
|
});
|
|
371
372
|
this._catBar = catBar;
|
|
@@ -386,7 +387,7 @@ export class IconDialog {
|
|
|
386
387
|
const optRow = createElement('div', { class: 'an-icon-options' });
|
|
387
388
|
|
|
388
389
|
const styleLabel = createElement('label', { class: 'an-label' });
|
|
389
|
-
styleLabel.textContent =
|
|
390
|
+
styleLabel.textContent = L.style;
|
|
390
391
|
const styleSelect = createElement('select', { class: 'an-input an-icon-option-select' });
|
|
391
392
|
[['fa-solid', 'Solid'], ['fa-regular', 'Regular'], ['fa-light', 'Light (Pro)']].forEach(([v, t]) => {
|
|
392
393
|
const opt = createElement('option', { value: v });
|
|
@@ -397,7 +398,7 @@ export class IconDialog {
|
|
|
397
398
|
this._styleSelect = styleSelect;
|
|
398
399
|
|
|
399
400
|
const sizeLabel = createElement('label', { class: 'an-label' });
|
|
400
|
-
sizeLabel.textContent =
|
|
401
|
+
sizeLabel.textContent = L.size;
|
|
401
402
|
const sizeSelect = createElement('select', { class: 'an-input an-icon-option-select' });
|
|
402
403
|
[['', 'Inherit'], ['0.75em', '0.75em'], ['1em', '1em'], ['1.25em', '1.25em'], ['1.5em', '1.5em'], ['2em', '2em'], ['3em', '3em']].forEach(([v, t]) => {
|
|
403
404
|
const opt = createElement('option', { value: v });
|
|
@@ -408,30 +409,30 @@ export class IconDialog {
|
|
|
408
409
|
this._sizeSelect = sizeSelect;
|
|
409
410
|
|
|
410
411
|
const colorLabel = createElement('label', { class: 'an-label' });
|
|
411
|
-
colorLabel.textContent =
|
|
412
|
+
colorLabel.textContent = L.color;
|
|
412
413
|
const colorInput = createElement('input', { type: 'color', class: 'an-icon-color', value: '#000000' });
|
|
413
414
|
this._colorInput = colorInput;
|
|
414
415
|
|
|
415
416
|
const useColorLabel = createElement('label', { class: 'an-label an-label-inline an-icon-use-color' });
|
|
416
417
|
const useColorCb = createElement('input', { type: 'checkbox', checked: '' });
|
|
417
418
|
this._useColorCb = useColorCb;
|
|
418
|
-
useColorLabel.append(useColorCb, document.createTextNode(
|
|
419
|
+
useColorLabel.append(useColorCb, document.createTextNode(L.useColor));
|
|
419
420
|
|
|
420
421
|
optRow.append(styleLabel, styleSelect, sizeLabel, sizeSelect, colorLabel, colorInput, useColorLabel);
|
|
421
422
|
|
|
422
423
|
// Preview
|
|
423
424
|
const preview = createElement('div', { class: 'an-icon-preview' });
|
|
424
425
|
const previewHint = createElement('span', { class: 'an-icon-preview-hint' });
|
|
425
|
-
previewHint.textContent =
|
|
426
|
+
previewHint.textContent = L.selectHint;
|
|
426
427
|
preview.appendChild(previewHint);
|
|
427
428
|
this._preview = preview;
|
|
428
429
|
|
|
429
430
|
// Actions
|
|
430
431
|
const btnRow = createElement('div', { class: 'an-dialog-actions' });
|
|
431
432
|
const insertBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary', disabled: '' });
|
|
432
|
-
insertBtn.textContent =
|
|
433
|
+
insertBtn.textContent = L.insertBtn;
|
|
433
434
|
const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });
|
|
434
|
-
cancelBtn.textContent =
|
|
435
|
+
cancelBtn.textContent = L.cancelBtn;
|
|
435
436
|
btnRow.append(insertBtn, cancelBtn);
|
|
436
437
|
this._insertBtn = insertBtn;
|
|
437
438
|
|
|
@@ -57,35 +57,36 @@ export class ImageDialog {
|
|
|
57
57
|
// ---------------------------------------------------------------------------
|
|
58
58
|
|
|
59
59
|
_buildDialog() {
|
|
60
|
+
const L = this.context.locale.imageDialog;
|
|
60
61
|
const overlay = createElement('div', {
|
|
61
62
|
class: 'an-dialog-overlay',
|
|
62
63
|
role: 'dialog',
|
|
63
64
|
'aria-modal': 'true',
|
|
64
|
-
'aria-label':
|
|
65
|
+
'aria-label': L.ariaLabel,
|
|
65
66
|
});
|
|
66
67
|
const box = createElement('div', { class: 'an-dialog-box' });
|
|
67
68
|
|
|
68
69
|
const title = createElement('h3', { class: 'an-dialog-title' });
|
|
69
|
-
title.textContent =
|
|
70
|
+
title.textContent = L.title;
|
|
70
71
|
|
|
71
72
|
// URL tab
|
|
72
73
|
const urlLabel = createElement('label', { class: 'an-label' });
|
|
73
|
-
urlLabel.textContent =
|
|
74
|
+
urlLabel.textContent = L.imageUrl;
|
|
74
75
|
const urlInput = createElement('input', {
|
|
75
76
|
type: 'url',
|
|
76
77
|
class: 'an-input',
|
|
77
|
-
placeholder:
|
|
78
|
+
placeholder: L.urlPlaceholder,
|
|
78
79
|
autocomplete: 'off',
|
|
79
80
|
});
|
|
80
81
|
this._urlInput = urlInput;
|
|
81
82
|
|
|
82
83
|
// Alt text
|
|
83
84
|
const altLabel = createElement('label', { class: 'an-label' });
|
|
84
|
-
altLabel.textContent =
|
|
85
|
+
altLabel.textContent = L.altText;
|
|
85
86
|
const altInput = createElement('input', {
|
|
86
87
|
type: 'text',
|
|
87
88
|
class: 'an-input',
|
|
88
|
-
placeholder:
|
|
89
|
+
placeholder: L.altPlaceholder,
|
|
89
90
|
autocomplete: 'off',
|
|
90
91
|
});
|
|
91
92
|
this._altInput = altInput;
|
|
@@ -94,13 +95,13 @@ export class ImageDialog {
|
|
|
94
95
|
|
|
95
96
|
// Alignment
|
|
96
97
|
const alignLabel = createElement('label', { class: 'an-label' });
|
|
97
|
-
alignLabel.textContent =
|
|
98
|
+
alignLabel.textContent = L.alignment;
|
|
98
99
|
const alignRow = createElement('div', { class: 'an-align-row' });
|
|
99
100
|
const alignOptions = [
|
|
100
|
-
{ value: '', label:
|
|
101
|
-
{ value: 'left', label:
|
|
102
|
-
{ value: 'center', label:
|
|
103
|
-
{ value: 'right', label:
|
|
101
|
+
{ value: '', label: L.alignNone },
|
|
102
|
+
{ value: 'left', label: L.alignLeft },
|
|
103
|
+
{ value: 'center', label: L.alignCenter },
|
|
104
|
+
{ value: 'right', label: L.alignRight },
|
|
104
105
|
];
|
|
105
106
|
alignOptions.forEach(({ value, label }) => {
|
|
106
107
|
const radioId = `an-align-${value || 'none'}`;
|
|
@@ -114,7 +115,7 @@ export class ImageDialog {
|
|
|
114
115
|
box.append(alignLabel, alignRow);
|
|
115
116
|
if (this.options.allowImageUpload !== false) {
|
|
116
117
|
const fileLabel = createElement('label', { class: 'an-label' });
|
|
117
|
-
fileLabel.textContent =
|
|
118
|
+
fileLabel.textContent = L.uploadLabel;
|
|
118
119
|
const fileInput = createElement('input', {
|
|
119
120
|
type: 'file',
|
|
120
121
|
class: 'an-input',
|
|
@@ -132,9 +133,9 @@ export class ImageDialog {
|
|
|
132
133
|
// Buttons
|
|
133
134
|
const btnRow = createElement('div', { class: 'an-dialog-actions' });
|
|
134
135
|
const insertBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });
|
|
135
|
-
insertBtn.textContent =
|
|
136
|
+
insertBtn.textContent = L.insertBtn;
|
|
136
137
|
const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });
|
|
137
|
-
cancelBtn.textContent =
|
|
138
|
+
cancelBtn.textContent = L.cancelBtn;
|
|
138
139
|
btnRow.appendChild(insertBtn);
|
|
139
140
|
btnRow.appendChild(cancelBtn);
|
|
140
141
|
|
|
@@ -166,7 +167,7 @@ export class ImageDialog {
|
|
|
166
167
|
'image/webp', 'image/svg+xml', 'image/avif',
|
|
167
168
|
]);
|
|
168
169
|
if (!SUPPORTED.has(file.type)) {
|
|
169
|
-
const message =
|
|
170
|
+
const message = this.context.locale.errors.imageFormat(file.type);
|
|
170
171
|
if (this._fileHint) this._fileHint.textContent = message;
|
|
171
172
|
this.context.triggerEvent('imageError', { file, message });
|
|
172
173
|
this._fileInput.value = '';
|
|
@@ -177,7 +178,7 @@ export class ImageDialog {
|
|
|
177
178
|
// Validate file size (max 5 MB by default)
|
|
178
179
|
const maxSize = (this.options.maxImageSize || 5) * 1024 * 1024;
|
|
179
180
|
if (file.size > maxSize) {
|
|
180
|
-
const message =
|
|
181
|
+
const message = this.context.locale.errors.imageSize(this.options.maxImageSize || 5);
|
|
181
182
|
if (this._fileHint) this._fileHint.textContent = message;
|
|
182
183
|
console.warn('[AutumnNote] ImageDialog:', message);
|
|
183
184
|
this.context.triggerEvent('imageError', { file, message });
|
|
@@ -75,24 +75,25 @@ export class ImageTooltip {
|
|
|
75
75
|
// ---------------------------------------------------------------------------
|
|
76
76
|
|
|
77
77
|
_buildTooltip() {
|
|
78
|
+
const L = this.context.locale.tooltips.image;
|
|
78
79
|
const el = createElement('div', {
|
|
79
80
|
class: 'an-link-tooltip an-image-tooltip',
|
|
80
81
|
role: 'toolbar',
|
|
81
|
-
'aria-label':
|
|
82
|
+
'aria-label': L.ariaLabel,
|
|
82
83
|
});
|
|
83
84
|
el.style.display = 'none';
|
|
84
85
|
|
|
85
86
|
// Label showing "Image"
|
|
86
87
|
this._label = createElement('span', { class: 'an-link-tooltip-url' });
|
|
87
|
-
this._label.textContent =
|
|
88
|
+
this._label.textContent = L.label;
|
|
88
89
|
el.appendChild(this._label);
|
|
89
90
|
|
|
90
91
|
el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));
|
|
91
92
|
|
|
92
|
-
this._floatLeftBtn = this._makeBtn(ICONS.floatLeft,
|
|
93
|
-
this._floatNoneBtn = this._makeBtn(ICONS.floatNone,
|
|
94
|
-
this._alignCenterBtn = this._makeBtn(ICONS.alignCenter,
|
|
95
|
-
this._floatRightBtn = this._makeBtn(ICONS.floatRight,
|
|
93
|
+
this._floatLeftBtn = this._makeBtn(ICONS.floatLeft, L.floatLeft, () => this._setFloat('left'));
|
|
94
|
+
this._floatNoneBtn = this._makeBtn(ICONS.floatNone, L.noFloat, () => this._setFloat(''));
|
|
95
|
+
this._alignCenterBtn = this._makeBtn(ICONS.alignCenter, L.alignCenter, () => this._setCenter());
|
|
96
|
+
this._floatRightBtn = this._makeBtn(ICONS.floatRight, L.floatRight, () => this._setFloat('right'));
|
|
96
97
|
|
|
97
98
|
el.appendChild(this._floatLeftBtn);
|
|
98
99
|
el.appendChild(this._floatNoneBtn);
|
|
@@ -101,28 +102,28 @@ export class ImageTooltip {
|
|
|
101
102
|
|
|
102
103
|
el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));
|
|
103
104
|
|
|
104
|
-
this._originalBtn = this._makeBtn(ICONS.originalSize,
|
|
105
|
+
this._originalBtn = this._makeBtn(ICONS.originalSize, L.originalSize, () => this._resetSize());
|
|
105
106
|
|
|
106
107
|
el.appendChild(this._originalBtn);
|
|
107
108
|
|
|
108
109
|
el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));
|
|
109
110
|
|
|
110
|
-
el.appendChild(this._makeBtn(ICONS.rotateLeft,
|
|
111
|
-
el.appendChild(this._makeBtn(ICONS.rotateRight,
|
|
111
|
+
el.appendChild(this._makeBtn(ICONS.rotateLeft, L.rotateLeft, () => this._rotate(-90)));
|
|
112
|
+
el.appendChild(this._makeBtn(ICONS.rotateRight, L.rotateRight, () => this._rotate(90)));
|
|
112
113
|
|
|
113
114
|
el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));
|
|
114
115
|
|
|
115
|
-
this._cropBtn = this._makeBtn(ICONS.crop,
|
|
116
|
+
this._cropBtn = this._makeBtn(ICONS.crop, L.cropImage, () => this._crop());
|
|
116
117
|
el.appendChild(this._cropBtn);
|
|
117
118
|
|
|
118
119
|
el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));
|
|
119
120
|
|
|
120
|
-
this._captionBtn = this._makeBtn(ICONS.caption,
|
|
121
|
+
this._captionBtn = this._makeBtn(ICONS.caption, L.addCaption, () => this._toggleCaption());
|
|
121
122
|
el.appendChild(this._captionBtn);
|
|
122
123
|
|
|
123
124
|
el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));
|
|
124
125
|
|
|
125
|
-
this._deleteBtn = this._makeBtn(ICONS.deleteImg,
|
|
126
|
+
this._deleteBtn = this._makeBtn(ICONS.deleteImg, L.deleteImage, () => this._delete(), true);
|
|
126
127
|
|
|
127
128
|
el.appendChild(this._deleteBtn);
|
|
128
129
|
|
|
@@ -59,19 +59,20 @@ export class LinkDialog {
|
|
|
59
59
|
// ---------------------------------------------------------------------------
|
|
60
60
|
|
|
61
61
|
_buildDialog() {
|
|
62
|
-
const
|
|
62
|
+
const L = this.context.locale.linkDialog;
|
|
63
|
+
const overlay = createElement('div', { class: 'an-dialog-overlay', role: 'dialog', 'aria-modal': 'true', 'aria-label': L.ariaLabel });
|
|
63
64
|
const box = createElement('div', { class: 'an-dialog-box' });
|
|
64
65
|
|
|
65
66
|
const title = createElement('h3', { class: 'an-dialog-title' });
|
|
66
|
-
title.textContent =
|
|
67
|
+
title.textContent = L.title;
|
|
67
68
|
|
|
68
69
|
// URL field
|
|
69
70
|
const urlLabel = createElement('label', { class: 'an-label' });
|
|
70
|
-
urlLabel.textContent =
|
|
71
|
+
urlLabel.textContent = L.url;
|
|
71
72
|
const urlInput = createElement('input', {
|
|
72
73
|
type: 'url',
|
|
73
74
|
class: 'an-input',
|
|
74
|
-
placeholder:
|
|
75
|
+
placeholder: L.urlPlaceholder,
|
|
75
76
|
id: 'an-link-url',
|
|
76
77
|
name: 'url',
|
|
77
78
|
autocomplete: 'off',
|
|
@@ -80,11 +81,11 @@ export class LinkDialog {
|
|
|
80
81
|
|
|
81
82
|
// Text field
|
|
82
83
|
const textLabel = createElement('label', { class: 'an-label' });
|
|
83
|
-
textLabel.textContent =
|
|
84
|
+
textLabel.textContent = L.displayText;
|
|
84
85
|
const textInput = createElement('input', {
|
|
85
86
|
type: 'text',
|
|
86
87
|
class: 'an-input',
|
|
87
|
-
placeholder:
|
|
88
|
+
placeholder: L.textPlaceholder,
|
|
88
89
|
id: 'an-link-text',
|
|
89
90
|
name: 'linkText',
|
|
90
91
|
autocomplete: 'off',
|
|
@@ -100,14 +101,14 @@ export class LinkDialog {
|
|
|
100
101
|
});
|
|
101
102
|
this._tabCheckbox = tabCheckbox;
|
|
102
103
|
tabLabel.appendChild(tabCheckbox);
|
|
103
|
-
tabLabel.appendChild(document.createTextNode('
|
|
104
|
+
tabLabel.appendChild(document.createTextNode(' ' + L.openInNewTab));
|
|
104
105
|
|
|
105
106
|
// Buttons
|
|
106
107
|
const btnRow = createElement('div', { class: 'an-dialog-actions' });
|
|
107
108
|
const insertBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });
|
|
108
|
-
insertBtn.textContent =
|
|
109
|
+
insertBtn.textContent = L.insertBtn;
|
|
109
110
|
const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });
|
|
110
|
-
cancelBtn.textContent =
|
|
111
|
+
cancelBtn.textContent = L.cancelBtn;
|
|
111
112
|
btnRow.appendChild(insertBtn);
|
|
112
113
|
btnRow.appendChild(cancelBtn);
|
|
113
114
|
|