autumnnote 1.14.0 → 1.16.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 (46) hide show
  1. package/README.md +37 -10
  2. package/dist/autumnnote.cjs +61 -0
  3. package/dist/autumnnote.css +2 -2579
  4. package/dist/autumnnote.es.js +4934 -9981
  5. package/dist/autumnnote.es.js.map +1 -1
  6. package/dist/autumnnote.min.js +61 -0
  7. package/dist/autumnnote.umd.js +39 -17545
  8. package/dist/autumnnote.umd.js.map +1 -1
  9. package/package.json +24 -15
  10. package/src/js/Context.js +154 -15
  11. package/src/js/core/sanitise.js +47 -11
  12. package/src/js/editing/History.js +38 -6
  13. package/src/js/i18n/de.js +15 -0
  14. package/src/js/i18n/en.js +15 -0
  15. package/src/js/i18n/es.js +15 -0
  16. package/src/js/i18n/fr.js +15 -0
  17. package/src/js/i18n/ja.js +15 -0
  18. package/src/js/i18n/ko.js +15 -0
  19. package/src/js/i18n/vi.js +15 -0
  20. package/src/js/i18n/zh.js +15 -0
  21. package/src/js/index.js +13 -1
  22. package/src/js/module/Clipboard.js +25 -7
  23. package/src/js/module/Editor.js +25 -5
  24. package/src/js/module/ImageCropOverlay.js +5 -0
  25. package/src/js/module/ImageDialog.js +34 -6
  26. package/src/js/module/MarkdownShortcuts.js +2 -2
  27. package/src/js/module/SlashMenu.js +376 -0
  28. package/src/js/module/Statusbar.js +3 -9
  29. package/src/js/module/TableTooltip.js +2 -1
  30. package/src/js/module/VideoDialog.js +3 -13
  31. package/src/js/settings.js +30 -0
  32. package/src/styles/autumnnote.scss +49 -0
  33. package/types/core/dom.d.ts +32 -0
  34. package/types/core/env.d.ts +10 -0
  35. package/types/core/func.d.ts +11 -0
  36. package/types/core/key.d.ts +3 -0
  37. package/types/core/lists.d.ts +10 -0
  38. package/types/core/range.d.ts +22 -0
  39. package/types/core/sanitise.d.ts +9 -0
  40. package/types/index.d.ts +102 -8
  41. package/dist/_headers +0 -5
  42. package/dist/image/banner.png +0 -0
  43. package/dist/image/favicon.ico +0 -0
  44. package/dist/image/og-banner.png +0 -0
  45. package/dist/robots.txt +0 -4
  46. package/dist/sitemap.xml +0 -58
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  import { createElement, on } from '../core/dom.js';
11
+ import { sanitiseUrl } from '../core/sanitise.js';
11
12
  import { BaseDialog } from './BaseDialog.js';
12
13
 
13
14
  const ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2"/></svg>`;
@@ -115,12 +116,7 @@ export class VideoDialog extends BaseDialog {
115
116
  */
116
117
  _parseVideoUrl(url) {
117
118
  if (!url) return null;
118
-
119
- // Validate — block javascript: and other dangerous protocols
120
- try {
121
- const parsed = new URL(url);
122
- if (/^javascript:/i.test(parsed.protocol) || /^vbscript:/i.test(parsed.protocol)) return null;
123
- } catch { return null; }
119
+ if (!sanitiseUrl(url, { media: true })) return null;
124
120
 
125
121
  // YouTube watch: https://www.youtube.com/watch?v=ID
126
122
  const ytWatch = /(?:youtube\.com\/watch\?(?:.*&)?v=|youtube\.com\/embed\/)([a-zA-Z0-9_-]{11})/.exec(url);
@@ -182,13 +178,7 @@ export class VideoDialog extends BaseDialog {
182
178
  }
183
179
 
184
180
  // Unknown URL — let the user try as a direct video
185
- const safeSrc = (() => {
186
- try {
187
- const p = new URL(url);
188
- if (/^javascript:/i.test(p.protocol) || /^vbscript:/i.test(p.protocol)) return null;
189
- return url;
190
- } catch { return null; }
191
- })();
181
+ const safeSrc = sanitiseUrl(url, { media: true });
192
182
  if (!safeSrc) return null;
193
183
 
194
184
  const escapedSrc = safeSrc.replaceAll('"', '%22');
@@ -25,6 +25,7 @@ import { defaultToolbar } from './module/Buttons.js';
25
25
  * @property {number} [maxImageSize] - Max upload size in MB
26
26
  * @property {number} [tabSize] - Spaces per tab in non-list context
27
27
  * @property {number} [historyLimit] - Maximum undo/redo history steps
28
+ * @property {number} [historyMaxBytes] - Maximum combined size (chars) of all stacked undo/redo snapshots
28
29
  * @property {string} [defaultFontFamily] - Default font family applied to the editable area on init
29
30
  * @property {string} [defaultFontSize] - Default font size applied to the editable area on init (e.g. '14px')
30
31
  * @property {string[]} [fontFamilies] - Font families shown in the font-family toolbar dropdown
@@ -46,10 +47,13 @@ import { defaultToolbar } from './module/Buttons.js';
46
47
  * @property {string} [toolbarOverflow] - Toolbar overflow strategy: 'wrap' (default) | 'scroll'
47
48
  * @property {boolean} [autoSave] - Auto-save content to localStorage on change
48
49
  * @property {string} [autoSaveKey] - localStorage key used for auto-save (default: 'autumnnote-autosave')
50
+ * @property {number} [autoSaveDelay] - Debounce delay for auto-save writes in milliseconds
51
+ * @property {object|null} [autoSaveAdapter] - Optional async persistence adapter with save/load/remove methods
49
52
  * @property {number} [maxChars] - Maximum character count (0 = unlimited). Shows warning in statusbar.
50
53
  * @property {number} [maxWords] - Maximum word count (0 = unlimited). Shows warning in statusbar.
51
54
  * @property {boolean} [tableHeaderRow] - Insert a header row (<thead><th>) when creating tables
52
55
  * @property {Function} [onPaste] - Callback fired on every paste: ({ text, html }) => void
56
+ * @property {Function} [onPasteError] - Callback fired when pasted or dropped content cannot be processed
53
57
  * @property {Function} [onSelectionChange] - Callback fired on cursor/selection change: (context) => void
54
58
  * @property {string[]} [colorSwatches] - Custom brand colour swatches prepended to the colour-picker palette
55
59
  * @property {Function} [onDestroy] - Callback fired when the editor is destroyed: (context) => void
@@ -63,6 +67,7 @@ import { defaultToolbar } from './module/Buttons.js';
63
67
  * @property {boolean} [bubbleToolbar] - Show a mini floating toolbar above text selections
64
68
  * @property {string[]} [bubbleToolbarItems] - Button names for the bubble toolbar
65
69
  * @property {object|null} [mention] - @mention configuration (onSearch, minChars, ...)
70
+ * @property {boolean} [slashMenu] - Show a "/" command palette for quick block insertion (default true)
66
71
  * @property {string} [lang] - Display language or partial locale object override
67
72
  */
68
73
 
@@ -102,6 +107,10 @@ export const defaultOptions = {
102
107
  codeHighlightCDN: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0',
103
108
  markdownPaste: true,
104
109
  historyLimit: 100,
110
+ // Max combined size (chars) of all stacked undo/redo snapshots. Guards
111
+ // against documents with many large embedded images holding dozens of
112
+ // full-size copies in memory despite historyLimit.
113
+ historyMaxBytes: 10 * 1024 * 1024,
105
114
  // Default font family applied to the editor and shown in the dropdown when no explicit font is set
106
115
  defaultFontFamily: 'Arial',
107
116
  // Default font size applied to the editor and shown in the size dropdown when no explicit size is set
@@ -131,6 +140,8 @@ export const defaultOptions = {
131
140
  autoSave: false,
132
141
  // localStorage key used when autoSave is enabled
133
142
  autoSaveKey: 'autumnnote-autosave',
143
+ autoSaveDelay: 400,
144
+ autoSaveAdapter: null,
134
145
  // Maximum character count (0 = unlimited)
135
146
  maxChars: 0,
136
147
  // Maximum word count (0 = unlimited)
@@ -143,6 +154,8 @@ export const defaultOptions = {
143
154
  colorSwatches: [],
144
155
  // Callback fired after a paste event: function({ text, html })
145
156
  onPaste: null,
157
+ // Callback fired for rejected/failed paste and drop payloads: function({ message, size?, maxBytes? })
158
+ onPasteError: null,
146
159
  // Callback fired just before the editor instance is destroyed
147
160
  onDestroy: null,
148
161
  // Callback fired when the character limit is reached: function(context)
@@ -168,6 +181,23 @@ export const defaultOptions = {
168
181
  // e.g. "## " at line start → <h2>, "**bold**" → <strong>
169
182
  markdownShortcuts: true,
170
183
 
184
+ // "/" command palette for quick block insertion (headings, lists, table, image, ...).
185
+ // Triggers only when "/" is the first character typed on an otherwise-empty line.
186
+ slashMenu: true,
187
+ // Additional slash-menu commands supplied by applications/plugins.
188
+ slashCommands: [],
189
+
190
+ // Optional import/export adapters keyed by format name.
191
+ documentAdapters: {},
192
+ // Optional collaboration bridge notified with local HTML changes.
193
+ collaborationAdapter: null,
194
+
195
+ // Optional image processor (for example a Web Worker bridge). Receives a
196
+ // File and returns a data URL; Clipboard's canvas pipeline remains fallback.
197
+ imageProcessor: null,
198
+ // Add stable data-an-block-id attributes to top-level document blocks.
199
+ blockIds: false,
200
+
171
201
  // Maximum paste size in bytes (default 5 MB). Pastes larger than this are silently dropped.
172
202
  maxPasteSize: 5 * 1024 * 1024,
173
203
  // Minimum image dimension in px during resize (width and height). Prevents images from being
@@ -97,6 +97,17 @@
97
97
  }
98
98
  }
99
99
 
100
+ @media (prefers-reduced-motion: reduce) {
101
+ .an-container *,
102
+ .an-dialog-overlay *,
103
+ .an-slash-menu * {
104
+ scroll-behavior: auto !important;
105
+ animation-duration: 0.01ms !important;
106
+ animation-iteration-count: 1 !important;
107
+ transition-duration: 0.01ms !important;
108
+ }
109
+ }
110
+
100
111
  // =============================================================================
101
112
  // Toolbar
102
113
  // =============================================================================
@@ -2815,3 +2826,41 @@ $an-video-accent: #8b5cf6; // violet-500
2815
2826
  color: #93c5fd;
2816
2827
  }
2817
2828
  }
2829
+
2830
+ // =============================================================================
2831
+ // "/" command palette
2832
+ // =============================================================================
2833
+
2834
+ .an-slash-menu {
2835
+ display: none;
2836
+ position: fixed;
2837
+ z-index: 9998;
2838
+ background: $an-bg;
2839
+ border: 1px solid $an-border;
2840
+ border-radius: $an-radius;
2841
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
2842
+ min-width: 180px;
2843
+ max-width: 260px;
2844
+ max-height: 260px;
2845
+ overflow-y: auto;
2846
+ padding: 4px 0;
2847
+ }
2848
+
2849
+ .an-slash-menu-item {
2850
+ padding: 6px 12px;
2851
+ cursor: pointer;
2852
+ font-size: 13px;
2853
+ color: $an-text;
2854
+ transition: background $an-transition;
2855
+
2856
+ &:hover,
2857
+ &.an-slash-menu-active {
2858
+ background: $an-bg-btn-hover;
2859
+ }
2860
+ }
2861
+
2862
+ .an-slash-menu-empty {
2863
+ padding: 6px 12px;
2864
+ font-size: 13px;
2865
+ color: $an-muted;
2866
+ }
@@ -0,0 +1,32 @@
1
+ export const ELEMENT_NODE: 1;
2
+ export const TEXT_NODE: 3;
3
+ export function isElement(node: Node): boolean;
4
+ export function isText(node: Node): boolean;
5
+ export function isVoid(node: Node): boolean;
6
+ export function isPara(node: Node): boolean;
7
+ export function isLi(node: Node): boolean;
8
+ export function isList(node: Node): boolean;
9
+ export function isTable(node: Node): boolean;
10
+ export function isInline(node: Node): boolean;
11
+ export function isEditable(node: Node): boolean;
12
+ export function isAnchor(node: Node): boolean;
13
+ export function isImage(node: Node): boolean;
14
+ export function closest(node: Node, predicate: (node: Node) => boolean, stopAt?: Node): Node | null;
15
+ export function closestPara(node: Node, editable?: Node): Node | null;
16
+ export function ancestors(node: Node, stopAt?: Node): Node[];
17
+ export function children(node: Node): Node[];
18
+ export function prevElement(node: Node): Element | null;
19
+ export function nextElement(node: Node): Element | null;
20
+ export function createElement(tag: string, attrs?: Record<string, string>, childNodes?: Array<Node | string>): HTMLElement;
21
+ export function remove(node: Node): void;
22
+ export function unwrap(node: Node): void;
23
+ export function wrap(node: Node, wrapper: HTMLElement): HTMLElement;
24
+ export function insertAfter(newNode: Node, refNode: Node): void;
25
+ export function nodeValue(node: Node): string;
26
+ export function isEmpty(node: Node): boolean;
27
+ export function outerHtml(el: Element): string;
28
+ export function placeCaret(el: HTMLElement): void;
29
+ export function isInsideEditable(node: Node): boolean;
30
+ export function on(target: EventTarget, type: string, handler: EventListener, options?: AddEventListenerOptions): () => void;
31
+ export function trapFocus(container: HTMLElement, onEscape: () => void): () => void;
32
+ export function makeDraggable(handle: HTMLElement, box: HTMLElement): () => void;
@@ -0,0 +1,10 @@
1
+ export const env: {
2
+ isChrome: boolean;
3
+ isFF: boolean;
4
+ isSafari: boolean;
5
+ isEdge: boolean;
6
+ isMac: boolean;
7
+ isMobile: boolean;
8
+ isTouch: boolean;
9
+ modifierKey: string;
10
+ };
@@ -0,0 +1,11 @@
1
+ export function clamp(val: number, min: number, max: number): number;
2
+ export function debounce<T extends (...args: any[]) => any>(fn: T, delay: number): (...args: Parameters<T>) => void;
3
+ export function throttle<T extends (...args: any[]) => any>(fn: T, limit: number): (...args: Parameters<T>) => void;
4
+ export function compose(...fns: Function[]): Function;
5
+ export function identity<T>(x: T): T;
6
+ export function isNil(val: unknown): val is null | undefined;
7
+ export function isString(val: unknown): val is string;
8
+ export function isFunction(val: unknown): val is Function;
9
+ export function mergeDeep<T extends object, U extends object>(target: T, source: U): T & U;
10
+ export function isPlainObject(val: unknown): val is Record<string, unknown>;
11
+ export function rect2bnd(rect: DOMRect | null | undefined): Pick<DOMRect, 'top' | 'left' | 'width' | 'height' | 'bottom' | 'right'> | null;
@@ -0,0 +1,3 @@
1
+ export const key: Readonly<Record<'BACKSPACE' | 'TAB' | 'ENTER' | 'ESCAPE' | 'SPACE' | 'PAGE_UP' | 'PAGE_DOWN' | 'END' | 'HOME' | 'LEFT' | 'UP' | 'RIGHT' | 'DOWN' | 'DELETE' | 'NUM0' | 'NUM1' | 'NUM2' | 'NUM3' | 'NUM4' | 'NUM5' | 'NUM6' | 'NUM7' | 'NUM8' | 'B' | 'E' | 'I' | 'J' | 'K' | 'L' | 'R' | 'S' | 'U' | 'V' | 'Y' | 'Z' | 'SLASH' | 'PERIOD', string>>;
2
+ export function isKey(event: KeyboardEvent, keyName: string): boolean;
3
+ export function isModifier(event: KeyboardEvent, keyName: string): boolean;
@@ -0,0 +1,10 @@
1
+ export function last<T>(arr: T[]): T | undefined;
2
+ export function first<T>(arr: T[]): T | undefined;
3
+ export function initial<T>(arr: T[], n?: number): T[];
4
+ export function tail<T>(arr: T[], n?: number): T[];
5
+ export function flatten<T>(arr: T[][]): T[];
6
+ export function unique<T>(arr: T[]): T[];
7
+ export function chunk<T>(arr: T[], n: number): T[][];
8
+ export function groupBy<T>(arr: T[], keyFn: (item: T) => string): Record<string, T[]>;
9
+ export function all<T>(arr: T[], predicate: (item: T) => boolean): boolean;
10
+ export function any<T>(arr: T[], predicate: (item: T) => boolean): boolean;
@@ -0,0 +1,22 @@
1
+ export class WrappedRange {
2
+ constructor(sc: Node, so: number, ec: Node, eo: number);
3
+ sc: Node;
4
+ so: number;
5
+ ec: Node;
6
+ eo: number;
7
+ isCollapsed(): boolean;
8
+ toNativeRange(): Range;
9
+ select(): void;
10
+ commonAncestor(): Element | null;
11
+ blockNode(editable: HTMLElement): Element | null;
12
+ toString(): string;
13
+ getClientRects(): DOMRect | null;
14
+ insertNode(node: Node): void;
15
+ }
16
+ export function fromNativeRange(range: Range): WrappedRange;
17
+ export function currentRange(editable?: HTMLElement): WrappedRange | null;
18
+ export function rangeFromElement(el: HTMLElement): WrappedRange;
19
+ export function collapsedRange(node: Node, offset?: number): WrappedRange;
20
+ export function isSelectionInside(el: HTMLElement): boolean;
21
+ export function withSavedRange(fn: () => void): void;
22
+ export function splitText(textNode: Text, offset: number): [Text, Text];
@@ -0,0 +1,9 @@
1
+ export interface SanitiseHTMLOptions {
2
+ allowIframes?: boolean;
3
+ }
4
+ export interface SanitiseURLOptions {
5
+ allowData?: boolean;
6
+ media?: boolean;
7
+ }
8
+ export function sanitiseHTML(html: string, options?: SanitiseHTMLOptions): string;
9
+ export function sanitiseUrl(url: string | null | undefined, options?: SanitiseURLOptions): string | null;
package/types/index.d.ts CHANGED
@@ -1,12 +1,50 @@
1
1
  /**
2
2
  * AutumnNote – TypeScript declarations
3
- * @version 1.14.0
3
+ * @version 1.16.0
4
4
  */
5
5
 
6
6
  // ---------------------------------------------------------------------------
7
7
  // Options
8
8
  // ---------------------------------------------------------------------------
9
9
 
10
+ export interface PasteErrorData {
11
+ /** Human-readable description of the rejected paste or drop. */
12
+ message: string;
13
+ /** Payload size in bytes, when the failure is caused by a configured limit. */
14
+ size?: number;
15
+ /** Maximum permitted payload size in bytes, when applicable. */
16
+ maxBytes?: number;
17
+ }
18
+
19
+ export interface AutoSavePayload {
20
+ key: string;
21
+ html: string;
22
+ savedAt: number;
23
+ context: Context;
24
+ }
25
+
26
+ export interface AutoSaveAdapter {
27
+ save(payload: AutoSavePayload): void | Promise<void>;
28
+ load?(payload: { key: string; context: Context }): string | null | Promise<string | null>;
29
+ remove?(payload: { key: string; context: Context }): void | Promise<void>;
30
+ }
31
+
32
+ export interface SlashCommand {
33
+ id: string;
34
+ label?: string;
35
+ keywords?: string;
36
+ run(context: Context): void | Promise<void>;
37
+ }
38
+
39
+ export interface DocumentAdapter {
40
+ import?(data: unknown, context: Context): string | Promise<string>;
41
+ export?(context: Context, html: string): unknown | Promise<unknown>;
42
+ }
43
+
44
+ export interface CollaborationAdapter {
45
+ onLocalChange?(html: string, context: Context): void | Promise<void>;
46
+ }
47
+
10
48
  export interface AsnOptions {
11
49
  /** Placeholder text when the editor is empty. */
12
50
  placeholder?: string;
@@ -76,6 +114,8 @@ export interface AsnOptions {
76
114
  markdownPaste?: boolean;
77
115
  /** Maximum undo/redo history steps. */
78
116
  historyLimit?: number;
117
+ /** Maximum combined size (chars) of all stacked undo/redo snapshots. Default 10485760 (10 MB). */
118
+ historyMaxBytes?: number;
79
119
  /** Default font family applied to the editable area on init. */
80
120
  defaultFontFamily?: string;
81
121
  /** Default font size applied to the editable area on init (e.g. '14px'). */
@@ -94,6 +134,10 @@ export interface AsnOptions {
94
134
  autoSave?: boolean;
95
135
  /** localStorage key used for auto-save. */
96
136
  autoSaveKey?: string;
137
+ /** Debounce delay for auto-save writes. Default: 400ms. */
138
+ autoSaveDelay?: number;
139
+ /** Optional persistence adapter; localStorage remains the default. */
140
+ autoSaveAdapter?: AutoSaveAdapter | null;
97
141
  /** Maximum character count for the statusbar warning (0 = unlimited). */
98
142
  maxChars?: number;
99
143
  /** Maximum word count for the statusbar warning (0 = unlimited). */
@@ -102,6 +146,8 @@ export interface AsnOptions {
102
146
  tableHeaderRow?: boolean;
103
147
  /** Callback fired after every paste event. */
104
148
  onPaste?: (data: { text: string; html: string | null }) => void;
149
+ /** Callback fired when pasted or dropped content cannot be processed. */
150
+ onPasteError?: (error: PasteErrorData) => void;
105
151
  /** Additional color swatches shown at the top of the color picker. */
106
152
  colorSwatches?: string[];
107
153
  /** Custom focus ring colour — overrides the default blue. Accepts any valid CSS colour string, e.g. '#f97316'. */
@@ -142,6 +188,20 @@ export interface AsnOptions {
142
188
 
143
189
  /** @mention autocomplete configuration. Activated when mention.onSearch is provided. */
144
190
  mention?: MentionOptions | null;
191
+
192
+ // ---- Slash command menu ----------------------------------------------------
193
+
194
+ /** Show a "/" command palette for quick block insertion (headings, lists, table, image, ...). Default: true. */
195
+ slashMenu?: boolean;
196
+ /** Application/plugin-provided slash commands. */
197
+ slashCommands?: SlashCommand[];
198
+ /** Import/export adapters keyed by format. */
199
+ documentAdapters?: Record<string, DocumentAdapter>;
200
+ /** Optional external image processor, such as a Web Worker bridge. */
201
+ imageProcessor?: (file: File, helpers: { context: Context }) => string | Promise<string>;
202
+ collaborationAdapter?: CollaborationAdapter | null;
203
+ /** Adds stable IDs to top-level blocks for external collaboration adapters. */
204
+ blockIds?: boolean;
145
205
  }
146
206
 
147
207
  // ---------------------------------------------------------------------------
@@ -323,6 +383,20 @@ export interface AsnLocale {
323
383
  restore: string;
324
384
  discard: string;
325
385
  };
386
+ slashMenu: {
387
+ noResults: string;
388
+ heading1: string;
389
+ heading2: string;
390
+ heading3: string;
391
+ bulletList: string;
392
+ numberedList: string;
393
+ checklist: string;
394
+ blockquote: string;
395
+ codeBlock: string;
396
+ horizontalRule: string;
397
+ table: string;
398
+ image: string;
399
+ };
326
400
  }
327
401
 
328
402
  /** Registry of all built-in locales (keys: 'en', 'vi', 'ja', 'zh', 'fr', 'de', 'es', 'ko'). */
@@ -337,13 +411,13 @@ export declare const locales: Record<string, AsnLocale>;
337
411
  export declare function resolveLocale(lang: string | Partial<AsnLocale> | null | undefined): AsnLocale;
338
412
 
339
413
  // Re-export core utility modules exposed by the package entry-point.
340
- export * from '../src/js/core/dom.js';
341
- export * from '../src/js/core/range.js';
342
- export * from '../src/js/core/func.js';
343
- export * from '../src/js/core/key.js';
344
- export * from '../src/js/core/lists.js';
345
- export * from '../src/js/core/env.js';
346
- export * from '../src/js/core/sanitise.js';
414
+ export * from './core/dom.js';
415
+ export * from './core/range.js';
416
+ export * from './core/func.js';
417
+ export * from './core/key.js';
418
+ export * from './core/lists.js';
419
+ export * from './core/env.js';
420
+ export * from './core/sanitise.js';
347
421
 
348
422
  // ---------------------------------------------------------------------------
349
423
  // Context — per-instance editor hub
@@ -376,6 +450,15 @@ export declare class Context {
376
450
  /** Triggers an editor event. */
377
451
  triggerEvent(eventName: string, ...args: unknown[]): void;
378
452
 
453
+ /** Applies runtime-safe option changes without recreating the editor. */
454
+ updateOptions(overrides: Partial<AsnOptions>): this;
455
+
456
+ /** Flushes any pending auto-save write. */
457
+ flushAutoSave(): Promise<void>;
458
+
459
+ /** Loads a draft through the configured adapter or localStorage. */
460
+ loadAutoSave(): Promise<string | null>;
461
+
379
462
  /** Returns the current HTML content of the editor. */
380
463
  getHTML(): string;
381
464
 
@@ -419,6 +502,15 @@ export declare class Context {
419
502
  /** Returns the editor content as a Markdown string. */
420
503
  getMarkdown(): string;
421
504
 
505
+ getSelectionBookmark(): { start: number; end: number } | null;
506
+ restoreSelectionBookmark(bookmark: { start: number; end: number }): boolean;
507
+ importDocument(format: string, data: unknown): Promise<this>;
508
+ exportDocument(format: string): Promise<unknown>;
509
+ ensureBlockIds(): this;
510
+ getDocument(): { version: 1; html: string; markdown: string };
511
+ loadDocument(documentData: { html: string }): this;
512
+ applyRemoteHTML(html: string): this;
513
+
422
514
  /** Returns the current word count of the editor content. */
423
515
  getWordCount(): number;
424
516
 
@@ -458,6 +550,7 @@ export declare class Context {
458
550
  * @param ModuleClass - Class with `initialize()` and optional `destroy()`
459
551
  */
460
552
  registerModule(name: string, ModuleClass: new (ctx: Context) => object): this;
553
+ registerSlashCommand(command: SlashCommand): this;
461
554
 
462
555
  /**
463
556
  * Installs a plugin on this editor instance.
@@ -618,6 +711,7 @@ export interface AutumnNoteStatic {
618
711
  * referenced by string name in toolbar configuration.
619
712
  */
620
713
  registerButton(btnDef: ToolbarItemDef): this;
714
+ registerSlashCommand(command: SlashCommand): this;
621
715
 
622
716
  /**
623
717
  * All pre-built button definitions in a single namespace.
package/dist/_headers DELETED
@@ -1,5 +0,0 @@
1
- /*.html
2
- Cache-Control: public, max-age=0, must-revalidate
3
-
4
- /assets/*
5
- Cache-Control: public, max-age=31536000, immutable
Binary file
Binary file
Binary file
package/dist/robots.txt DELETED
@@ -1,4 +0,0 @@
1
- User-agent: *
2
- Allow: /
3
-
4
- Sitemap: https://autumn.konexforge.com/sitemap.xml
package/dist/sitemap.xml DELETED
@@ -1,58 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
3
- xmlns:xhtml="http://www.w3.org/1999/xhtml">
4
- <url>
5
- <loc>https://autumn.konexforge.com/</loc>
6
- <lastmod>2026-07-14</lastmod>
7
- <changefreq>monthly</changefreq>
8
- <priority>1.0</priority>
9
- <xhtml:link rel="alternate" hreflang="en" href="https://autumn.konexforge.com/" />
10
- <xhtml:link rel="alternate" hreflang="vi" href="https://autumn.konexforge.com/vi/" />
11
- <xhtml:link rel="alternate" hreflang="x-default" href="https://autumn.konexforge.com/" />
12
- </url>
13
- <url>
14
- <loc>https://autumn.konexforge.com/docs.html</loc>
15
- <lastmod>2026-07-14</lastmod>
16
- <changefreq>monthly</changefreq>
17
- <priority>0.9</priority>
18
- <xhtml:link rel="alternate" hreflang="en" href="https://autumn.konexforge.com/docs.html" />
19
- <xhtml:link rel="alternate" hreflang="vi" href="https://autumn.konexforge.com/vi/docs.html" />
20
- <xhtml:link rel="alternate" hreflang="x-default" href="https://autumn.konexforge.com/docs.html" />
21
- </url>
22
- <url>
23
- <loc>https://autumn.konexforge.com/playground.html</loc>
24
- <lastmod>2026-07-14</lastmod>
25
- <changefreq>monthly</changefreq>
26
- <priority>0.7</priority>
27
- <xhtml:link rel="alternate" hreflang="en" href="https://autumn.konexforge.com/playground.html" />
28
- <xhtml:link rel="alternate" hreflang="vi" href="https://autumn.konexforge.com/vi/playground.html" />
29
- <xhtml:link rel="alternate" hreflang="x-default" href="https://autumn.konexforge.com/playground.html" />
30
- </url>
31
- <url>
32
- <loc>https://autumn.konexforge.com/vi/</loc>
33
- <lastmod>2026-07-14</lastmod>
34
- <changefreq>monthly</changefreq>
35
- <priority>0.9</priority>
36
- <xhtml:link rel="alternate" hreflang="en" href="https://autumn.konexforge.com/" />
37
- <xhtml:link rel="alternate" hreflang="vi" href="https://autumn.konexforge.com/vi/" />
38
- <xhtml:link rel="alternate" hreflang="x-default" href="https://autumn.konexforge.com/" />
39
- </url>
40
- <url>
41
- <loc>https://autumn.konexforge.com/vi/docs.html</loc>
42
- <lastmod>2026-07-14</lastmod>
43
- <changefreq>monthly</changefreq>
44
- <priority>0.8</priority>
45
- <xhtml:link rel="alternate" hreflang="en" href="https://autumn.konexforge.com/docs.html" />
46
- <xhtml:link rel="alternate" hreflang="vi" href="https://autumn.konexforge.com/vi/docs.html" />
47
- <xhtml:link rel="alternate" hreflang="x-default" href="https://autumn.konexforge.com/docs.html" />
48
- </url>
49
- <url>
50
- <loc>https://autumn.konexforge.com/vi/playground.html</loc>
51
- <lastmod>2026-07-14</lastmod>
52
- <changefreq>monthly</changefreq>
53
- <priority>0.6</priority>
54
- <xhtml:link rel="alternate" hreflang="en" href="https://autumn.konexforge.com/playground.html" />
55
- <xhtml:link rel="alternate" hreflang="vi" href="https://autumn.konexforge.com/vi/playground.html" />
56
- <xhtml:link rel="alternate" hreflang="x-default" href="https://autumn.konexforge.com/playground.html" />
57
- </url>
58
- </urlset>