autumnnote 2.0.0 → 2.2.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 (64) hide show
  1. package/README.md +72 -5
  2. package/dist/autumnnote.cjs +20 -20
  3. package/dist/autumnnote.css +1 -1
  4. package/dist/autumnnote.es.js +661 -798
  5. package/dist/autumnnote.es.js.map +1 -1
  6. package/dist/autumnnote.min.js +20 -20
  7. package/dist/autumnnote.umd.js +20 -20
  8. package/dist/autumnnote.umd.js.map +1 -1
  9. package/dist/icon-data-V0Xqv-wX.js +255 -0
  10. package/dist/icon-data-V0Xqv-wX.js.map +1 -0
  11. package/package.json +13 -4
  12. package/types/index.d.ts +8 -0
  13. package/src/js/Context.js +0 -854
  14. package/src/js/core/detectLang.js +0 -98
  15. package/src/js/core/dom.js +0 -372
  16. package/src/js/core/env.js +0 -25
  17. package/src/js/core/key.js +0 -66
  18. package/src/js/core/lists.js +0 -121
  19. package/src/js/core/markdown.js +0 -695
  20. package/src/js/core/range.js +0 -194
  21. package/src/js/core/sanitise.js +0 -231
  22. package/src/js/editing/History.js +0 -266
  23. package/src/js/editing/Style.js +0 -812
  24. package/src/js/editing/Table.js +0 -105
  25. package/src/js/editing/Typing.js +0 -397
  26. package/src/js/index.js +0 -193
  27. package/src/js/index.umd.js +0 -17
  28. package/src/js/module/AutoSaveRestore.js +0 -125
  29. package/src/js/module/BaseDialog.js +0 -133
  30. package/src/js/module/BaseMediaTooltip.js +0 -142
  31. package/src/js/module/BaseResizer.js +0 -312
  32. package/src/js/module/BubbleToolbar.js +0 -483
  33. package/src/js/module/Buttons.js +0 -399
  34. package/src/js/module/Clipboard.js +0 -579
  35. package/src/js/module/CodeTooltip.js +0 -493
  36. package/src/js/module/Codeview.js +0 -125
  37. package/src/js/module/ContextMenu.js +0 -621
  38. package/src/js/module/Editor.js +0 -747
  39. package/src/js/module/EmojiDialog.js +0 -254
  40. package/src/js/module/FindReplace.js +0 -512
  41. package/src/js/module/Fullscreen.js +0 -80
  42. package/src/js/module/IconDialog.js +0 -618
  43. package/src/js/module/ImageCropOverlay.js +0 -586
  44. package/src/js/module/ImageDialog.js +0 -193
  45. package/src/js/module/ImageResizer.js +0 -42
  46. package/src/js/module/ImageTooltip.js +0 -285
  47. package/src/js/module/LinkDialog.js +0 -145
  48. package/src/js/module/LinkTooltip.js +0 -250
  49. package/src/js/module/MarkdownShortcuts.js +0 -250
  50. package/src/js/module/Mention.js +0 -365
  51. package/src/js/module/Placeholder.js +0 -51
  52. package/src/js/module/ShortcutsDialog.js +0 -111
  53. package/src/js/module/SlashMenu.js +0 -376
  54. package/src/js/module/Statusbar.js +0 -246
  55. package/src/js/module/TableTooltip.js +0 -1521
  56. package/src/js/module/Toolbar.js +0 -750
  57. package/src/js/module/VideoDialog.js +0 -193
  58. package/src/js/module/VideoResizer.js +0 -66
  59. package/src/js/module/VideoTooltip.js +0 -248
  60. package/src/js/module/emoji-data.js +0 -496
  61. package/src/js/renderer.js +0 -120
  62. package/src/js/settings.js +0 -214
  63. package/src/styles/_variables.scss +0 -48
  64. package/src/styles/autumnnote.scss +0 -2866
@@ -1,312 +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
- on(h, 'mousedown', (e) => {
172
- e.preventDefault();
173
- e.stopPropagation();
174
- this._startResize(e, pos);
175
- }),
176
- );
177
- overlay.appendChild(h);
178
- });
179
-
180
- return overlay;
181
- }
182
-
183
- _onEditorClick(e) {
184
- if (this.context.layoutInfo.container.classList.contains('an-disabled')) return;
185
- const target = this._findTarget(e.target);
186
- if (target) {
187
- // Prevent the browser from dropping the text selection / showing its own
188
- // native resize affordance.
189
- e.preventDefault();
190
- this._select(target);
191
- }
192
- }
193
-
194
- _onDocClick(e) {
195
- if (!this._active) return;
196
- if (this._active.contains(e.target)) return;
197
- if (this._overlay?.contains(e.target)) return;
198
- // Don't deselect while interacting with the context menu
199
- if (e.target.closest?.('.an-contextmenu')) return;
200
- this._deselect();
201
- }
202
-
203
- _select(target) {
204
- if (this._active && this._active !== target) {
205
- this._active.classList.remove(this._selectedClass);
206
- }
207
- this._active = target;
208
- this._lastOverlayPos = null; // invalidate position cache on new selection
209
- target.classList.add(this._selectedClass);
210
- this._updateOverlayPosition();
211
- this._overlay.style.display = 'block';
212
- }
213
-
214
- _deselect() {
215
- if (this._active) {
216
- this._active.classList.remove(this._selectedClass);
217
- this._active = null;
218
- }
219
- if (this._overlay) this._overlay.style.display = 'none';
220
- }
221
-
222
- _updateOverlayPosition() {
223
- if (this._positionRaf) cancelAnimationFrame(this._positionRaf);
224
- this._positionRaf = requestAnimationFrame(() => {
225
- this._positionRaf = null;
226
- this._updateOverlayPositionNow();
227
- });
228
- }
229
-
230
- _updateOverlayPositionNow() {
231
- if (!this._active || !this._overlay) return;
232
- const offsetParent = this._overlay.offsetParent || this._container;
233
- const containerRect = offsetParent.getBoundingClientRect();
234
- const rect = this._active.getBoundingClientRect();
235
-
236
- // Skip DOM writes when position hasn't changed (common during non-scroll rAF ticks)
237
- const p = this._lastOverlayPos;
238
- if (p?.l === rect.left && p.t === rect.top && p.w === rect.width && p.h === rect.height) return;
239
- this._lastOverlayPos = { l: rect.left, t: rect.top, w: rect.width, h: rect.height };
240
-
241
- const left = rect.left - containerRect.left + offsetParent.scrollLeft;
242
- const top = rect.top - containerRect.top + offsetParent.scrollTop;
243
- this._overlay.style.left = `${left}px`;
244
- this._overlay.style.top = `${top}px`;
245
- this._overlay.style.width = `${rect.width}px`;
246
- this._overlay.style.height = `${rect.height}px`;
247
- }
248
-
249
- _startResize(e, pos) {
250
- const target = this._active;
251
- if (!target) return;
252
-
253
- const startX = e.clientX;
254
- const startY = e.clientY;
255
- const { w: startW, h: startH } = this._getStartSize(target);
256
- const { minW, minH } = this._getMinSize();
257
- const aspectRatio = startW / (startH || 1);
258
- const isCorner = pos.length === 2; // 'nw','ne','se','sw'
259
-
260
- const editable = this.context.layoutInfo.editable;
261
- let raf = null; // rAF handle — ensures at most one write per paint frame
262
-
263
- const onMove = (me) => {
264
- if (raf !== null) return; // frame already pending, discard this event
265
- const clientX = me.clientX;
266
- const clientY = me.clientY;
267
- raf = requestAnimationFrame(() => {
268
- raf = null;
269
- const dx = clientX - startX;
270
- const dy = clientY - startY;
271
- const maxW = editable.clientWidth || Infinity;
272
- let newW = startW;
273
- let newH = startH;
274
-
275
- if (pos.includes('e')) newW = Math.max(minW, startW + dx);
276
- if (pos.includes('w')) newW = Math.max(minW, startW - dx);
277
- if (pos.includes('s')) newH = Math.max(minH, startH + dy);
278
- if (pos.includes('n')) newH = Math.max(minH, startH - dy);
279
-
280
- newW = Math.min(newW, maxW);
281
-
282
- if (isCorner) {
283
- if (Math.abs(dx) >= Math.abs(dy)) {
284
- newH = Math.max(minH, Math.round(newW / aspectRatio));
285
- } else {
286
- newW = Math.min(Math.max(minW, Math.round(newH * aspectRatio)), maxW);
287
- newH = Math.max(minH, Math.round(newW / aspectRatio));
288
- }
289
- }
290
-
291
- this._applySize(target, newW, newH);
292
- this._updateOverlayPosition();
293
- });
294
- };
295
-
296
- const onUp = () => {
297
- if (raf !== null) { cancelAnimationFrame(raf); raf = null; }
298
- document.removeEventListener('mousemove', onMove);
299
- document.removeEventListener('mouseup', onUp);
300
- this._dragDisposers = null;
301
- this.context.invoke('editor.afterCommand');
302
- };
303
-
304
- document.addEventListener('mousemove', onMove);
305
- document.addEventListener('mouseup', onUp);
306
- // Track these so destroy() can clean them up if called during an active drag
307
- this._dragDisposers = [
308
- () => document.removeEventListener('mousemove', onMove),
309
- () => document.removeEventListener('mouseup', onUp),
310
- ];
311
- }
312
- }