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,322 +0,0 @@
1
- /**
2
- * BaseResizer.js — Shared drag-to-resize overlay for selectable embeds.
3
- *
4
- * ImageResizer and VideoResizer were ~28% duplicate: identical overlay
5
- * construction, selection tracking, scroll/resize repositioning and drag maths,
6
- * differing only in what counts as a target and how the new size is applied.
7
- * Subclasses now supply just those differences via the hooks below.
8
- *
9
- * Mirrors the existing BaseDialog pattern used by the dialog modules.
10
- */
11
-
12
- import { on } from '../core/dom.js';
13
-
14
- /**
15
- * Eight handle positions. 'pos' is used as CSS class suffix and to determine
16
- * which axis/direction is being dragged.
17
- *
18
- * Pos length 2 → corner handle → maintain aspect ratio.
19
- * Pos length 1 → edge handle → single-axis resize.
20
- */
21
- const HANDLE_DEFS = [
22
- { pos: 'nw', cursor: 'nw-resize' },
23
- { pos: 'n', cursor: 'n-resize' },
24
- { pos: 'ne', cursor: 'ne-resize' },
25
- { pos: 'e', cursor: 'e-resize' },
26
- { pos: 'se', cursor: 'se-resize' },
27
- { pos: 's', cursor: 's-resize' },
28
- { pos: 'sw', cursor: 'sw-resize' },
29
- { pos: 'w', cursor: 'w-resize' },
30
- ];
31
-
32
- export class BaseResizer {
33
- /** @param {import('../Context.js').Context} context */
34
- constructor(context) {
35
- this.context = context;
36
- /** @type {HTMLElement|null} Currently selected element */
37
- this._active = null;
38
- /** @type {HTMLElement|null} */
39
- this._overlay = null;
40
- this._disposers = [];
41
- this._positionRaf = null;
42
- /** @type {{l:number,t:number,w:number,h:number}|null} Last written overlay box */
43
- this._lastOverlayPos = null;
44
- }
45
-
46
- // ---------------------------------------------------------------------------
47
- // Subclass hooks
48
- // ---------------------------------------------------------------------------
49
-
50
- /** CSS class for the overlay element. @returns {string} */
51
- get _overlayClass() { return 'an-resizer'; }
52
-
53
- /** CSS class applied to the selected element. @returns {string} */
54
- get _selectedClass() { return 'an-selected'; }
55
-
56
- /**
57
- * Resolves an event target to a resizable element.
58
- * @param {EventTarget|null} _el
59
- * @returns {HTMLElement|null}
60
- */
61
- _findTarget(_el) { return null; }
62
-
63
- /**
64
- * Natural starting dimensions of the target, used as the drag baseline.
65
- * @param {HTMLElement} _target
66
- * @returns {{ w: number, h: number }}
67
- */
68
- _getStartSize(_target) { return { w: 0, h: 0 }; }
69
-
70
- /** Smallest allowed dimensions. @returns {{ minW: number, minH: number }} */
71
- _getMinSize() { return { minW: 20, minH: 20 }; }
72
-
73
- /**
74
- * Writes the new size to the target (and any inner embed).
75
- * @param {HTMLElement} _target
76
- * @param {number} _w
77
- * @param {number} _h
78
- */
79
- _applySize(_target, _w, _h) {}
80
-
81
- /**
82
- * Additional listeners a subclass needs; the returned disposers are torn down
83
- * with the rest in destroy().
84
- * @returns {Array<() => void>}
85
- */
86
- _extraListeners() { return []; }
87
-
88
- // ---------------------------------------------------------------------------
89
- // Lifecycle
90
- // ---------------------------------------------------------------------------
91
-
92
- initialize() {
93
- this._overlay = this._buildOverlay();
94
- const container = this.context.layoutInfo.editable.closest('.an-container') || document.body;
95
- container.appendChild(this._overlay);
96
- this._container = container;
97
-
98
- const editable = this.context.layoutInfo.editable;
99
-
100
- // Debounce window resize — _updateOverlayPosition already has rAF gating but
101
- // every call cancels + re-schedules it; a debounce reduces that churn.
102
- let resizeDebounce = null;
103
- const onWindowResize = () => {
104
- clearTimeout(resizeDebounce);
105
- resizeDebounce = setTimeout(() => this._updateOverlayPosition(), 100);
106
- };
107
-
108
- this._disposers.push(
109
- on(editable, 'click', (e) => this._onEditorClick(e)),
110
- // Also select on right-click so the highlight shows before the context menu
111
- on(editable, 'contextmenu', (e) => {
112
- if (this.context.layoutInfo.container.classList.contains('an-disabled')) return;
113
- const target = this._findTarget(e.target);
114
- if (target) this._select(target);
115
- }),
116
- on(document, 'click', (e) => this._onDocClick(e)),
117
- on(globalThis, 'scroll', () => this._updateOverlayPosition(), { passive: true }),
118
- on(globalThis, 'resize', onWindowResize, { passive: true }),
119
- on(editable, 'scroll', () => this._updateOverlayPosition(), { passive: true }),
120
- ...this._extraListeners(),
121
- );
122
-
123
- return this;
124
- }
125
-
126
- destroy() {
127
- this._disposers.forEach((d) => d());
128
- this._disposers = [];
129
- if (this._dragDisposers) {
130
- this._dragDisposers.forEach((d) => d());
131
- this._dragDisposers = null;
132
- }
133
- if (this._positionRaf) {
134
- cancelAnimationFrame(this._positionRaf);
135
- this._positionRaf = null;
136
- }
137
- this._deselect();
138
- this._overlay?.remove();
139
- this._overlay = null;
140
- }
141
-
142
- // ---------------------------------------------------------------------------
143
- // Public API used by other modules
144
- // ---------------------------------------------------------------------------
145
-
146
- /** Re-sync overlay position (call after external size changes). */
147
- updateOverlay() {
148
- this._updateOverlayPosition();
149
- }
150
-
151
- /** Programmatically clear the current selection. */
152
- deselect() {
153
- this._deselect();
154
- }
155
-
156
- // ---------------------------------------------------------------------------
157
- // Internal
158
- // ---------------------------------------------------------------------------
159
-
160
- _buildOverlay() {
161
- const overlay = document.createElement('div');
162
- overlay.className = this._overlayClass;
163
- overlay.style.display = 'none';
164
-
165
- HANDLE_DEFS.forEach(({ pos }) => {
166
- const h = document.createElement('div');
167
- h.className = `an-resize-handle an-resize-${pos}`;
168
- h.dataset.handle = pos;
169
- // Attach handle listeners here so they're torn down in destroy() via _disposers
170
- this._disposers.push(
171
- // Pointer events rather than mouse events, so the same code path serves
172
- // mouse, touch and pen. The handles also set `touch-action: none` in
173
- // CSS — without it a touch drag is claimed by the browser as a scroll
174
- // gesture and the pointer stream is cancelled before it starts.
175
- on(h, 'pointerdown', (e) => {
176
- e.preventDefault();
177
- e.stopPropagation();
178
- this._startResize(e, pos);
179
- }),
180
- );
181
- overlay.appendChild(h);
182
- });
183
-
184
- return overlay;
185
- }
186
-
187
- _onEditorClick(e) {
188
- if (this.context.layoutInfo.container.classList.contains('an-disabled')) return;
189
- const target = this._findTarget(e.target);
190
- if (target) {
191
- // Prevent the browser from dropping the text selection / showing its own
192
- // native resize affordance.
193
- e.preventDefault();
194
- this._select(target);
195
- }
196
- }
197
-
198
- _onDocClick(e) {
199
- if (!this._active) return;
200
- if (this._active.contains(e.target)) return;
201
- if (this._overlay?.contains(e.target)) return;
202
- // Don't deselect while interacting with the context menu
203
- if (e.target.closest?.('.an-contextmenu')) return;
204
- this._deselect();
205
- }
206
-
207
- _select(target) {
208
- if (this._active && this._active !== target) {
209
- this._active.classList.remove(this._selectedClass);
210
- }
211
- this._active = target;
212
- this._lastOverlayPos = null; // invalidate position cache on new selection
213
- target.classList.add(this._selectedClass);
214
- this._updateOverlayPosition();
215
- this._overlay.style.display = 'block';
216
- }
217
-
218
- _deselect() {
219
- if (this._active) {
220
- this._active.classList.remove(this._selectedClass);
221
- this._active = null;
222
- }
223
- if (this._overlay) this._overlay.style.display = 'none';
224
- }
225
-
226
- _updateOverlayPosition() {
227
- if (this._positionRaf) cancelAnimationFrame(this._positionRaf);
228
- this._positionRaf = requestAnimationFrame(() => {
229
- this._positionRaf = null;
230
- this._updateOverlayPositionNow();
231
- });
232
- }
233
-
234
- _updateOverlayPositionNow() {
235
- if (!this._active || !this._overlay) return;
236
- const offsetParent = this._overlay.offsetParent || this._container;
237
- const containerRect = offsetParent.getBoundingClientRect();
238
- const rect = this._active.getBoundingClientRect();
239
-
240
- // Skip DOM writes when position hasn't changed (common during non-scroll rAF ticks)
241
- const p = this._lastOverlayPos;
242
- if (p?.l === rect.left && p.t === rect.top && p.w === rect.width && p.h === rect.height) return;
243
- this._lastOverlayPos = { l: rect.left, t: rect.top, w: rect.width, h: rect.height };
244
-
245
- const left = rect.left - containerRect.left + offsetParent.scrollLeft;
246
- const top = rect.top - containerRect.top + offsetParent.scrollTop;
247
- this._overlay.style.left = `${left}px`;
248
- this._overlay.style.top = `${top}px`;
249
- this._overlay.style.width = `${rect.width}px`;
250
- this._overlay.style.height = `${rect.height}px`;
251
- }
252
-
253
- _startResize(e, pos) {
254
- const target = this._active;
255
- if (!target) return;
256
-
257
- const startX = e.clientX;
258
- const startY = e.clientY;
259
- const { w: startW, h: startH } = this._getStartSize(target);
260
- const { minW, minH } = this._getMinSize();
261
- const aspectRatio = startW / (startH || 1);
262
- const isCorner = pos.length === 2; // 'nw','ne','se','sw'
263
-
264
- const editable = this.context.layoutInfo.editable;
265
- let raf = null; // rAF handle — ensures at most one write per paint frame
266
-
267
- const onMove = (me) => {
268
- if (raf !== null) return; // frame already pending, discard this event
269
- const clientX = me.clientX;
270
- const clientY = me.clientY;
271
- raf = requestAnimationFrame(() => {
272
- raf = null;
273
- const dx = clientX - startX;
274
- const dy = clientY - startY;
275
- const maxW = editable.clientWidth || Infinity;
276
- let newW = startW;
277
- let newH = startH;
278
-
279
- if (pos.includes('e')) newW = Math.max(minW, startW + dx);
280
- if (pos.includes('w')) newW = Math.max(minW, startW - dx);
281
- if (pos.includes('s')) newH = Math.max(minH, startH + dy);
282
- if (pos.includes('n')) newH = Math.max(minH, startH - dy);
283
-
284
- newW = Math.min(newW, maxW);
285
-
286
- if (isCorner) {
287
- if (Math.abs(dx) >= Math.abs(dy)) {
288
- newH = Math.max(minH, Math.round(newW / aspectRatio));
289
- } else {
290
- newW = Math.min(Math.max(minW, Math.round(newH * aspectRatio)), maxW);
291
- newH = Math.max(minH, Math.round(newW / aspectRatio));
292
- }
293
- }
294
-
295
- this._applySize(target, newW, newH);
296
- this._updateOverlayPosition();
297
- });
298
- };
299
-
300
- const stop = () => {
301
- document.removeEventListener('pointermove', onMove);
302
- document.removeEventListener('pointerup', onUp);
303
- document.removeEventListener('pointercancel', onUp);
304
- };
305
-
306
- const onUp = () => {
307
- if (raf !== null) { cancelAnimationFrame(raf); raf = null; }
308
- stop();
309
- this._dragDisposers = null;
310
- this.context.invoke('editor.afterCommand');
311
- };
312
-
313
- document.addEventListener('pointermove', onMove);
314
- document.addEventListener('pointerup', onUp);
315
- // A touch drag interrupted by the system (incoming call, gesture takeover)
316
- // ends with pointercancel and no pointerup, which would otherwise leave the
317
- // move listener attached for the rest of the session.
318
- document.addEventListener('pointercancel', onUp);
319
- // Track these so destroy() can clean them up if called during an active drag
320
- this._dragDisposers = [stop];
321
- }
322
- }