autumnnote 2.1.0 → 2.3.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.
Files changed (65) hide show
  1. package/README.md +74 -6
  2. package/dist/autumnnote.cjs +27 -22
  3. package/dist/autumnnote.es.js +474 -591
  4. package/dist/autumnnote.es.js.map +1 -1
  5. package/dist/autumnnote.min.js +27 -22
  6. package/dist/autumnnote.umd.js +27 -22
  7. package/dist/autumnnote.umd.js.map +1 -1
  8. package/dist/icon-data-V0Xqv-wX.js +255 -0
  9. package/dist/icon-data-V0Xqv-wX.js.map +1 -0
  10. package/package.json +12 -3
  11. package/types/index.d.ts +8 -0
  12. package/src/js/Context.js +0 -854
  13. package/src/js/core/detectLang.js +0 -98
  14. package/src/js/core/dom.js +0 -372
  15. package/src/js/core/env.js +0 -38
  16. package/src/js/core/key.js +0 -66
  17. package/src/js/core/lists.js +0 -121
  18. package/src/js/core/markdown.js +0 -695
  19. package/src/js/core/range.js +0 -194
  20. package/src/js/core/sanitise.js +0 -304
  21. package/src/js/editing/History.js +0 -266
  22. package/src/js/editing/Style.js +0 -812
  23. package/src/js/editing/Table.js +0 -105
  24. package/src/js/editing/Typing.js +0 -397
  25. package/src/js/index.js +0 -193
  26. package/src/js/index.umd.js +0 -17
  27. package/src/js/module/AutoSaveRestore.js +0 -125
  28. package/src/js/module/BaseDialog.js +0 -133
  29. package/src/js/module/BaseMediaTooltip.js +0 -142
  30. package/src/js/module/BaseResizer.js +0 -322
  31. package/src/js/module/BubbleToolbar.js +0 -483
  32. package/src/js/module/Buttons.js +0 -399
  33. package/src/js/module/Clipboard.js +0 -579
  34. package/src/js/module/CodeTooltip.js +0 -493
  35. package/src/js/module/Codeview.js +0 -125
  36. package/src/js/module/ContextMenu.js +0 -621
  37. package/src/js/module/Editor.js +0 -747
  38. package/src/js/module/EmojiDialog.js +0 -254
  39. package/src/js/module/FindReplace.js +0 -512
  40. package/src/js/module/Fullscreen.js +0 -80
  41. package/src/js/module/IconDialog.js +0 -618
  42. package/src/js/module/ImageCropOverlay.js +0 -586
  43. package/src/js/module/ImageDialog.js +0 -193
  44. package/src/js/module/ImageResizer.js +0 -42
  45. package/src/js/module/ImageTooltip.js +0 -285
  46. package/src/js/module/LinkDialog.js +0 -145
  47. package/src/js/module/LinkTooltip.js +0 -250
  48. package/src/js/module/MarkdownShortcuts.js +0 -250
  49. package/src/js/module/Mention.js +0 -365
  50. package/src/js/module/Placeholder.js +0 -51
  51. package/src/js/module/ShortcutsDialog.js +0 -111
  52. package/src/js/module/SlashMenu.js +0 -376
  53. package/src/js/module/Statusbar.js +0 -246
  54. package/src/js/module/TableTooltip.js +0 -1392
  55. package/src/js/module/Toolbar.js +0 -855
  56. package/src/js/module/VideoDialog.js +0 -193
  57. package/src/js/module/VideoResizer.js +0 -66
  58. package/src/js/module/VideoTooltip.js +0 -248
  59. package/src/js/module/emoji-data.js +0 -496
  60. package/src/js/module/table-grid.js +0 -102
  61. package/src/js/module/table-icons.js +0 -33
  62. package/src/js/renderer.js +0 -120
  63. package/src/js/settings.js +0 -214
  64. package/src/styles/_variables.scss +0 -48
  65. package/src/styles/autumnnote.scss +0 -2877
@@ -1,399 +0,0 @@
1
- /**
2
- * Buttons.js - Toolbar button definitions and factories
3
- * All buttons are plain objects describing their appearance and action.
4
- * They are rendered by the Toolbar module.
5
- */
6
-
7
- import * as Style from '../editing/Style.js';
8
-
9
- // ---------------------------------------------------------------------------
10
- // Dropdown definition helper
11
- // ---------------------------------------------------------------------------
12
-
13
- /**
14
- * @typedef {object} DropdownDef
15
- * @property {string} name - unique identifier
16
- * @property {'select'} type - discriminator for Toolbar renderer
17
- * @property {string} tooltip
18
- * @property {Array<string|{value:string,label:string,disabled?:boolean}>} [items] - overridden at render time from options
19
- * @property {Function} action - called with (context, value)
20
- * @property {Function} [getValue] - called with (context) to get current value
21
- * @property {string} [selectClass] - extra CSS class(es) for the <select>
22
- * @property {string} [placeholder] - placeholder text for the empty option
23
- */
24
-
25
- // ---------------------------------------------------------------------------
26
- // Button factory helpers
27
- // ---------------------------------------------------------------------------
28
-
29
- /**
30
- * @typedef {object} ButtonDef
31
- * @property {string} name - unique identifier
32
- * @property {string} icon - SVG or HTML icon markup / text
33
- * @property {string} tooltip - tooltip string
34
- * @property {Function} action - called with (context) when clicked
35
- * @property {Function} [isActive] - called with (context) to determine active state
36
- * @property {Function} [isDisabled] - called with (context) to determine disabled state
37
- * @property {string} [className] - extra CSS class(es)
38
- */
39
-
40
- /**
41
- * Creates a simple button definition.
42
- * @param {string} name
43
- * @param {string} icon
44
- * @param {string} tooltip
45
- * @param {Function} action
46
- * @param {Function} [isActive]
47
- * @param {Function} [isDisabled]
48
- * @returns {ButtonDef}
49
- */
50
- function btn(name, icon, tooltip, action, isActive, isDisabled) {
51
- // `icon` is an identifier (e.g. 'bold', 'italic'). Rendering to
52
- // visual markup (FontAwesome or fallback) is done in Toolbar._createButton
53
- return { name, icon, tooltip, action, isActive, isDisabled };
54
- }
55
-
56
- // ---------------------------------------------------------------------------
57
- // Global button registry
58
- // ---------------------------------------------------------------------------
59
-
60
- /**
61
- * Global registry for custom buttons registered via AutumnNote.registerButton()
62
- * or via a plugin's `buttons` array. Toolbar resolves string names from here.
63
- * @type {Map<string, object>}
64
- */
65
- export const _buttonRegistry = new Map();
66
-
67
- /**
68
- * Registers a button definition in the global registry so it can be referenced
69
- * by string name in toolbar configuration: `toolbar: [['myBtn', boldBtn]]`.
70
- * @param {object} btnDef - Any ToolbarItemDef-compatible object with a `name` string.
71
- */
72
- export function registerButton(btnDef) {
73
- if (!btnDef || typeof btnDef.name !== 'string') {
74
- console.warn('[AutumnNote] registerButton: btnDef must have a string `name` property.');
75
- return;
76
- }
77
- if (_buttonRegistry.has(btnDef.name)) {
78
- console.warn(`[AutumnNote] registerButton: overwriting existing button "${btnDef.name}".`);
79
- }
80
- _buttonRegistry.set(btnDef.name, btnDef);
81
- }
82
-
83
- /**
84
- * Looks up a button definition by name from the global registry.
85
- * Returns undefined when not found.
86
- * @param {string} name
87
- * @returns {object|undefined}
88
- */
89
- export function getButton(name) {
90
- return _buttonRegistry.get(name);
91
- }
92
-
93
- // ---------------------------------------------------------------------------
94
- // Style buttons
95
- // ---------------------------------------------------------------------------
96
-
97
- export const boldBtn = btn('bold', 'bold', 'Bold (Ctrl+B)', () => Style.bold(), () => document.queryCommandState('bold'));
98
- export const italicBtn = btn('italic', 'italic', 'Italic (Ctrl+I)', () => Style.italic(), () => document.queryCommandState('italic'));
99
- export const underlineBtn = btn('underline', 'underline', 'Underline (Ctrl+U)', () => Style.underline(), () => {
100
- // queryCommandState('underline') is unreliable inside <code> elements;
101
- // also check for a <u> ancestor in the DOM using startContainer for
102
- // consistent behaviour across both collapsed and range selections.
103
- if (document.queryCommandState('underline')) return true;
104
- const sel = globalThis.getSelection();
105
- if (!sel?.rangeCount) return false;
106
- let sc = sel.getRangeAt(0).startContainer;
107
- if (sc.nodeType === 3) sc = sc.parentElement;
108
- return !!(/** @type {Element} */ (sc)?.closest('u'));
109
- });
110
- export const strikeBtn = btn('strikethrough', 'strikethrough', 'Strikethrough', () => Style.strikethrough(), () => document.queryCommandState('strikeThrough'));
111
- export const superscriptBtn = btn('superscript', 'superscript', 'Superscript', () => Style.superscript(), () => document.queryCommandState('superscript'));
112
- export const subscriptBtn = btn('subscript', 'subscript', 'Subscript', () => Style.subscript(), () => document.queryCommandState('subscript'));
113
-
114
- // ---------------------------------------------------------------------------
115
- // Alignment buttons
116
- // ---------------------------------------------------------------------------
117
-
118
- export const alignLeftBtn = btn('alignLeft', 'align-left', 'Align Left', () => Style.justifyLeft());
119
- export const alignCenterBtn = btn('alignCenter', 'align-center', 'Align Center', () => Style.justifyCenter());
120
- export const alignRightBtn = btn('alignRight', 'align-right', 'Align Right', () => Style.justifyRight());
121
- export const alignJustifyBtn = btn('alignJustify', 'align-justify', 'Justify', () => Style.justifyFull());
122
-
123
- // ---------------------------------------------------------------------------
124
- // List buttons
125
- // ---------------------------------------------------------------------------
126
-
127
- export const ulBtn = btn('ul', 'list-ul', 'Unordered List', () => Style.insertUnorderedList());
128
- export const olBtn = btn('ol', 'list-ol', 'Ordered List', () => Style.insertOrderedList());
129
-
130
- // ---------------------------------------------------------------------------
131
- // Indent buttons
132
- // ---------------------------------------------------------------------------
133
-
134
- export const indentBtn = btn('indent', 'indent', 'Indent', () => Style.indent());
135
- export const outdentBtn = btn('outdent', 'outdent', 'Outdent', () => Style.outdent());
136
-
137
- // ---------------------------------------------------------------------------
138
- // Undo / redo buttons
139
- // ---------------------------------------------------------------------------
140
-
141
- export const undoBtn = btn('undo', 'undo', 'Undo (Ctrl+Z)', (_ctx) => _ctx.invoke('editor.undo'), undefined, (ctx) => !ctx.invoke('editor.canUndo'));
142
- export const redoBtn = btn('redo', 'redo', 'Redo (Ctrl+Y)', (_ctx) => _ctx.invoke('editor.redo'), undefined, (ctx) => !ctx.invoke('editor.canRedo'));
143
-
144
- // ---------------------------------------------------------------------------
145
- // Insert media — HR, Link, Image
146
- // ---------------------------------------------------------------------------
147
-
148
- export const hrBtn = btn('hr', 'minus', 'Horizontal Rule', () => Style.execCommand('insertHorizontalRule'));
149
- export const linkBtn = btn('link', 'link', 'Insert Link', (ctx) => ctx.invoke('linkDialog.show'));
150
- export const imageBtn = btn('image', 'image', 'Insert Image', (ctx) => ctx.invoke('imageDialog.show'));
151
- export const videoBtn = btn('video', 'video', 'Insert Video', (ctx) => ctx.invoke('videoDialog.show'));
152
- export const emojiBtn = btn('emoji', 'emoji', 'Insert Emoji', (ctx) => ctx.invoke('emojiDialog.show'));
153
- export const iconBtn = btn('icon', 'icon', 'Insert FA Icon', (ctx) => ctx.invoke('iconDialog.show'));
154
-
155
- /** @type {ButtonDef & { type: 'grid' }} */
156
- export const tableBtn = {
157
- name: 'table',
158
- type: 'grid',
159
- icon: 'table',
160
- tooltip: 'Insert Table',
161
- action: (ctx, rows, cols) => {
162
- ctx.invoke('editor.insertTable', cols, rows);
163
- ctx.invoke('editor.afterCommand');
164
- },
165
- };
166
-
167
- // ---------------------------------------------------------------------------
168
- // Font size dropdown
169
- // ---------------------------------------------------------------------------
170
-
171
- /** @type {DropdownDef} */
172
- export const fontSizeBtn = {
173
- name: 'fontSize',
174
- type: 'select',
175
- tooltip: 'Font Size',
176
- placeholder: 'Size',
177
- selectClass: 'an-select-narrow',
178
- items: ['8px', '10px', '11px', '12px', '13px', '14px', '16px', '18px', '20px', '24px', '28px', '32px', '36px', '48px', '72px'],
179
- action: (ctx, value) => Style.fontSize(value, ctx.layoutInfo.editable),
180
- getValue: (ctx) => {
181
- try {
182
- const sel = globalThis.getSelection();
183
- if (sel?.rangeCount) {
184
- let el = /** @type {Element|null} */ (sel.getRangeAt(0).startContainer);
185
- if (el?.nodeType === 3) el = el.parentElement;
186
- while (el?.nodeType === 1 && !/** @type {HTMLElement} */ (el).style.fontSize) el = el.parentElement;
187
- const size = /** @type {HTMLElement} */ (el)?.style.fontSize || '';
188
- if (size) return size;
189
- }
190
- // Fallback: read the base font size from the editable element itself
191
- const editable = ctx?.layoutInfo?.editable;
192
- if (editable) return editable.style.fontSize || '';
193
- return '';
194
- } catch { return ''; }
195
- },
196
- };
197
-
198
- // ---------------------------------------------------------------------------
199
- // Remove format button
200
- // ---------------------------------------------------------------------------
201
-
202
- export const removeFormatBtn = btn('removeFormat', 'remove-format', 'Remove Format', () => Style.execCommand('removeFormat'));
203
-
204
- // ---------------------------------------------------------------------------
205
- // Direction (LTR / RTL) toggle button
206
- // ---------------------------------------------------------------------------
207
-
208
- export const directionBtn = btn(
209
- 'direction',
210
- 'direction',
211
- 'Toggle Text Direction (LTR / RTL)',
212
- (ctx) => {
213
- const editable = ctx.layoutInfo.editable;
214
- const current = editable.getAttribute('dir') || 'ltr';
215
- const next = current === 'ltr' ? 'rtl' : 'ltr';
216
- editable.setAttribute('dir', next);
217
- editable.style.textAlign = next === 'rtl' ? 'right' : 'left';
218
- ctx.invoke('editor.afterCommand');
219
- },
220
- );
221
-
222
- // ---------------------------------------------------------------------------
223
- // Font family dropdown
224
- // ---------------------------------------------------------------------------
225
-
226
- /** @type {DropdownDef} */
227
- export const fontFamilyBtn = {
228
- name: 'fontFamily',
229
- type: 'select',
230
- tooltip: 'Font Family',
231
- action: (ctx, value) => Style.fontName(value),
232
- getValue: () => {
233
- try { return document.queryCommandValue('fontName') || ''; } catch { return ''; }
234
- },
235
- };
236
-
237
- // ---------------------------------------------------------------------------
238
- // Paragraph style dropdown (Normal / H1-H6 / Quote / Code)
239
- // ---------------------------------------------------------------------------
240
-
241
- /** @type {DropdownDef} */
242
- export const paragraphStyleBtn = {
243
- name: 'paragraphStyle',
244
- type: 'select',
245
- tooltip: 'Paragraph Style',
246
- placeholder: 'Style',
247
- selectClass: 'an-select-style',
248
- items: [
249
- { value: 'p', label: 'Normal' },
250
- { value: 'h1', label: 'H1' },
251
- { value: 'h2', label: 'H2' },
252
- { value: 'h3', label: 'H3' },
253
- { value: 'h4', label: 'H4' },
254
- { value: 'h5', label: 'H5' },
255
- { value: 'h6', label: 'H6' },
256
- { value: 'blockquote', label: 'Quote' },
257
- { value: 'pre', label: 'Code' },
258
- ],
259
- action: (_ctx, value) => Style.formatBlock(value),
260
- getValue: () => {
261
- try {
262
- const raw = document.queryCommandValue('formatBlock').toLowerCase().replace(/[<>]/g, '');
263
- return raw === 'div' ? 'p' : (raw || 'p');
264
- } catch { return ''; }
265
- },
266
- };
267
-
268
- // ---------------------------------------------------------------------------
269
- // Line-height dropdown
270
- // ---------------------------------------------------------------------------
271
-
272
- /** @type {DropdownDef} */
273
- export const lineHeightBtn = {
274
- name: 'lineHeight',
275
- type: 'select',
276
- tooltip: 'Line Height',
277
- placeholder: '\u2195 Line',
278
- selectClass: 'an-select-narrow',
279
- items: ['1.0', '1.15', '1.5', '1.75', '2.0', '2.5', '3.0'],
280
- action: (_ctx, value) => Style.lineHeight(value),
281
- getValue: () => {
282
- try {
283
- const sel = globalThis.getSelection();
284
- if (!sel?.rangeCount) return '';
285
- const BLOCKS = new Set(['P','DIV','H1','H2','H3','H4','H5','H6','LI','BLOCKQUOTE','PRE','TD','TH']);
286
- let el = /** @type {Element|null} */ (sel.getRangeAt(0).startContainer);
287
- if (el?.nodeType === 3) el = el.parentElement;
288
- while (el && !BLOCKS.has(/** @type {Element} */ (el).tagName)) el = el.parentElement;
289
- if (!el) return '';
290
- return /** @type {HTMLElement} */ (el).style.lineHeight || getComputedStyle(/** @type {Element} */ (el)).lineHeight || '';
291
- } catch { return ''; }
292
- },
293
- };
294
-
295
- // ---------------------------------------------------------------------------
296
- // Code view / fullscreen
297
- // ---------------------------------------------------------------------------
298
-
299
- export const codeviewBtn = btn('codeview', 'code', 'HTML Code View', (ctx) => ctx.invoke('codeview.toggle'), (ctx) => ctx.invoke('codeview.isActive'));
300
- export const fullscreenBtn = btn('fullscreen', 'expand', 'Fullscreen', (ctx) => ctx.invoke('fullscreen.toggle'), (ctx) => ctx.invoke('fullscreen.isActive'));
301
- export const shortcutsBtn = btn('shortcuts', 'keyboard', 'Keyboard Shortcuts (Ctrl+Shift+/)', (ctx) => ctx.invoke('shortcutsDialog.show'));
302
- export const findBtn = btn('find', 'search', 'Find (Ctrl+F)', (ctx) => ctx.invoke('findReplace.show', 'find'));
303
- export const findReplaceBtn = btn('findReplace', 'find-replace', 'Find & Replace (Ctrl+H)', (ctx) => ctx.invoke('findReplace.show', 'replace'));
304
- export const inlineCodeBtn = btn('inlineCode', 'inline-code', 'Inline Code (Ctrl+`)', (ctx) => ctx.invoke('editor.inlineCode'), () => Style.isInlineCode());
305
- export const checklistBtn = btn('checklist', 'checklist', 'Checklist', (ctx) => ctx.invoke('editor.toggleChecklist'), () => Style.isInChecklist());
306
- export const printBtn = btn('print', 'print', 'Print', (ctx) => ctx.invoke('editor.print'));
307
-
308
- // ---------------------------------------------------------------------------
309
- // Text / background colour pickers
310
- // ---------------------------------------------------------------------------
311
-
312
- /** @type {{ name: string, type: 'colorpicker', icon: string, tooltip: string, defaultColor: string, action: Function }} */
313
- export const foreColorBtn = {
314
- name: 'foreColor',
315
- type: 'colorpicker',
316
- icon: 'foreColor',
317
- tooltip: 'Text Color',
318
- defaultColor: '#e11d48',
319
- action: (ctx, color) => Style.foreColor(color),
320
- };
321
-
322
- /** @type {{ name: string, type: 'colorpicker', icon: string, tooltip: string, defaultColor: string, action: Function }} */
323
- export const backColorBtn = {
324
- name: 'backColor',
325
- type: 'colorpicker',
326
- icon: 'backColor',
327
- tooltip: 'Highlight Color',
328
- defaultColor: '#fbbf24',
329
- action: (ctx, color) => Style.backColor(color),
330
- };
331
-
332
- // ---------------------------------------------------------------------------
333
- // Default toolbar layout
334
- // ---------------------------------------------------------------------------
335
-
336
- /**
337
- * The default toolbar button groups.
338
- * Each sub-array is a button group (separated by a divider).
339
- */
340
- export const defaultToolbar = [
341
- [paragraphStyleBtn, fontFamilyBtn, fontSizeBtn, lineHeightBtn],
342
- [undoBtn, redoBtn],
343
- [boldBtn, italicBtn, underlineBtn, strikeBtn, inlineCodeBtn],
344
- [superscriptBtn, subscriptBtn],
345
- [foreColorBtn, backColorBtn],
346
- [alignLeftBtn, alignCenterBtn, alignRightBtn, alignJustifyBtn],
347
- [ulBtn, olBtn, checklistBtn, indentBtn, outdentBtn],
348
- [hrBtn, linkBtn, imageBtn, videoBtn, tableBtn, emojiBtn, iconBtn],
349
- [removeFormatBtn, codeviewBtn, fullscreenBtn, findBtn, printBtn, shortcutsBtn],
350
- ];
351
-
352
- // ---------------------------------------------------------------------------
353
- // Buttons namespace — all pre-built button definitions in a single object.
354
- // Exposed as AutumnNote.buttons so UMD / CJS consumers can access them
355
- // without named imports: AutumnNote.buttons.boldBtn, etc.
356
- // ---------------------------------------------------------------------------
357
-
358
- export const buttons = {
359
- boldBtn,
360
- italicBtn,
361
- underlineBtn,
362
- strikeBtn,
363
- superscriptBtn,
364
- subscriptBtn,
365
- alignLeftBtn,
366
- alignCenterBtn,
367
- alignRightBtn,
368
- alignJustifyBtn,
369
- ulBtn,
370
- olBtn,
371
- indentBtn,
372
- outdentBtn,
373
- undoBtn,
374
- redoBtn,
375
- hrBtn,
376
- linkBtn,
377
- imageBtn,
378
- videoBtn,
379
- emojiBtn,
380
- iconBtn,
381
- tableBtn,
382
- fontSizeBtn,
383
- removeFormatBtn,
384
- directionBtn,
385
- fontFamilyBtn,
386
- paragraphStyleBtn,
387
- lineHeightBtn,
388
- codeviewBtn,
389
- fullscreenBtn,
390
- shortcutsBtn,
391
- findBtn,
392
- findReplaceBtn,
393
- inlineCodeBtn,
394
- checklistBtn,
395
- printBtn,
396
- foreColorBtn,
397
- backColorBtn,
398
- defaultToolbar,
399
- };