@malva-ui/editor 0.1.13 → 0.1.14
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 +5 -5
- package/fesm2022/malva-ui-editor-ai.mjs +17 -0
- package/fesm2022/malva-ui-editor-ai.mjs.map +1 -0
- package/fesm2022/malva-ui-editor.mjs +10227 -0
- package/fesm2022/malva-ui-editor.mjs.map +1 -0
- package/package.json +35 -26
- package/types/malva-ui-editor-ai.d.ts +1 -0
- package/types/malva-ui-editor.d.ts +2995 -0
- package/ai/index.d.ts +0 -12
- package/ai/malva-ui-editor-ai.d.ts +0 -5
- package/esm2022/ai/index.js +0 -12
- package/esm2022/ai/index.js.map +0 -1
- package/esm2022/ai/malva-ui-editor-ai.js +0 -5
- package/esm2022/ai/malva-ui-editor-ai.js.map +0 -1
- package/esm2022/index.js +0 -37
- package/esm2022/index.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-actions.js +0 -69
- package/esm2022/lib/ai/editor-ai-actions.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-context.js +0 -612
- package/esm2022/lib/ai/editor-ai-context.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-menu.js +0 -288
- package/esm2022/lib/ai/editor-ai-menu.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-review-bar.js +0 -223
- package/esm2022/lib/ai/editor-ai-review-bar.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-stream.js +0 -677
- package/esm2022/lib/ai/editor-ai-stream.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-suggestions.js +0 -751
- package/esm2022/lib/ai/editor-ai-suggestions.js.map +0 -1
- package/esm2022/lib/ai/editor-ai.tokens.js +0 -10
- package/esm2022/lib/ai/editor-ai.tokens.js.map +0 -1
- package/esm2022/lib/ai/editor-ai.types.js +0 -1
- package/esm2022/lib/ai/editor-ai.types.js.map +0 -1
- package/esm2022/lib/editor/editor.js +0 -985
- package/esm2022/lib/editor/editor.js.map +0 -1
- package/esm2022/lib/editor-extension-preflight.js +0 -83
- package/esm2022/lib/editor-extension-preflight.js.map +0 -1
- package/esm2022/lib/editor-serialization.js +0 -152
- package/esm2022/lib/editor-serialization.js.map +0 -1
- package/esm2022/lib/editor-toolbar-context.js +0 -259
- package/esm2022/lib/editor-toolbar-context.js.map +0 -1
- package/esm2022/lib/editor.tokens.js +0 -10
- package/esm2022/lib/editor.tokens.js.map +0 -1
- package/esm2022/lib/editor.types.js +0 -48
- package/esm2022/lib/editor.types.js.map +0 -1
- package/esm2022/lib/extensions/editor-block-handle.js +0 -760
- package/esm2022/lib/extensions/editor-block-handle.js.map +0 -1
- package/esm2022/lib/extensions/editor-extensions.js +0 -321
- package/esm2022/lib/extensions/editor-extensions.js.map +0 -1
- package/esm2022/lib/extensions/editor-markdown-compatibility.js +0 -162
- package/esm2022/lib/extensions/editor-markdown-compatibility.js.map +0 -1
- package/esm2022/lib/extensions/editor-upload-placeholder.js +0 -156
- package/esm2022/lib/extensions/editor-upload-placeholder.js.map +0 -1
- package/esm2022/lib/status/editor-status.js +0 -64
- package/esm2022/lib/status/editor-status.js.map +0 -1
- package/esm2022/lib/toolbar/editor-alignment.js +0 -203
- package/esm2022/lib/toolbar/editor-alignment.js.map +0 -1
- package/esm2022/lib/toolbar/editor-block-insert.js +0 -101
- package/esm2022/lib/toolbar/editor-block-insert.js.map +0 -1
- package/esm2022/lib/toolbar/editor-color-control.js +0 -71
- package/esm2022/lib/toolbar/editor-color-control.js.map +0 -1
- package/esm2022/lib/toolbar/editor-command-button.js +0 -115
- package/esm2022/lib/toolbar/editor-command-button.js.map +0 -1
- package/esm2022/lib/toolbar/editor-heading.js +0 -266
- package/esm2022/lib/toolbar/editor-heading.js.map +0 -1
- package/esm2022/lib/toolbar/editor-highlight.js +0 -84
- package/esm2022/lib/toolbar/editor-highlight.js.map +0 -1
- package/esm2022/lib/toolbar/editor-image-upload-dialog.js +0 -289
- package/esm2022/lib/toolbar/editor-image-upload-dialog.js.map +0 -1
- package/esm2022/lib/toolbar/editor-image-upload.js +0 -315
- package/esm2022/lib/toolbar/editor-image-upload.js.map +0 -1
- package/esm2022/lib/toolbar/editor-inline-marks.js +0 -124
- package/esm2022/lib/toolbar/editor-inline-marks.js.map +0 -1
- package/esm2022/lib/toolbar/editor-link.js +0 -265
- package/esm2022/lib/toolbar/editor-link.js.map +0 -1
- package/esm2022/lib/toolbar/editor-list.js +0 -249
- package/esm2022/lib/toolbar/editor-list.js.map +0 -1
- package/esm2022/lib/toolbar/editor-table.js +0 -292
- package/esm2022/lib/toolbar/editor-table.js.map +0 -1
- package/esm2022/lib/toolbar/editor-text-color.js +0 -82
- package/esm2022/lib/toolbar/editor-text-color.js.map +0 -1
- package/esm2022/lib/toolbar/editor-toolbar-widget.js +0 -41
- package/esm2022/lib/toolbar/editor-toolbar-widget.js.map +0 -1
- package/esm2022/lib/toolbar/editor-toolbar.defs.js +0 -60
- package/esm2022/lib/toolbar/editor-toolbar.defs.js.map +0 -1
- package/esm2022/lib/toolbar/editor-toolbar.js +0 -826
- package/esm2022/lib/toolbar/editor-toolbar.js.map +0 -1
- package/esm2022/lib/toolbar/editor-undo-redo.js +0 -72
- package/esm2022/lib/toolbar/editor-undo-redo.js.map +0 -1
- package/esm2022/lib/toolbar/editor-zoom.js +0 -330
- package/esm2022/lib/toolbar/editor-zoom.js.map +0 -1
- package/esm2022/lib/upload/editor-image-upload-coordinator.js +0 -480
- package/esm2022/lib/upload/editor-image-upload-coordinator.js.map +0 -1
- package/esm2022/malva-ui-editor.js +0 -5
- package/esm2022/malva-ui-editor.js.map +0 -1
- package/index.d.ts +0 -35
- package/lib/ai/editor-ai-actions.d.ts +0 -27
- package/lib/ai/editor-ai-context.d.ts +0 -307
- package/lib/ai/editor-ai-menu.d.ts +0 -142
- package/lib/ai/editor-ai-review-bar.d.ts +0 -116
- package/lib/ai/editor-ai-stream.d.ts +0 -207
- package/lib/ai/editor-ai-suggestions.d.ts +0 -219
- package/lib/ai/editor-ai.tokens.d.ts +0 -10
- package/lib/ai/editor-ai.types.d.ts +0 -176
- package/lib/editor/editor.d.ts +0 -243
- package/lib/editor-extension-preflight.d.ts +0 -23
- package/lib/editor-serialization.d.ts +0 -74
- package/lib/editor-toolbar-context.d.ts +0 -116
- package/lib/editor.tokens.d.ts +0 -6
- package/lib/editor.types.d.ts +0 -194
- package/lib/extensions/editor-block-handle.d.ts +0 -59
- package/lib/extensions/editor-extensions.d.ts +0 -165
- package/lib/extensions/editor-markdown-compatibility.d.ts +0 -11
- package/lib/extensions/editor-upload-placeholder.d.ts +0 -75
- package/lib/status/editor-status.d.ts +0 -24
- package/lib/toolbar/editor-alignment.d.ts +0 -61
- package/lib/toolbar/editor-block-insert.d.ts +0 -26
- package/lib/toolbar/editor-color-control.d.ts +0 -32
- package/lib/toolbar/editor-command-button.d.ts +0 -29
- package/lib/toolbar/editor-heading.d.ts +0 -68
- package/lib/toolbar/editor-highlight.d.ts +0 -21
- package/lib/toolbar/editor-image-upload-dialog.d.ts +0 -96
- package/lib/toolbar/editor-image-upload.d.ts +0 -71
- package/lib/toolbar/editor-inline-marks.d.ts +0 -30
- package/lib/toolbar/editor-link.d.ts +0 -78
- package/lib/toolbar/editor-list.d.ts +0 -67
- package/lib/toolbar/editor-table.d.ts +0 -133
- package/lib/toolbar/editor-text-color.d.ts +0 -21
- package/lib/toolbar/editor-toolbar-widget.d.ts +0 -19
- package/lib/toolbar/editor-toolbar.d.ts +0 -157
- package/lib/toolbar/editor-toolbar.defs.d.ts +0 -35
- package/lib/toolbar/editor-undo-redo.d.ts +0 -26
- package/lib/toolbar/editor-zoom.d.ts +0 -108
- package/lib/upload/editor-image-upload-coordinator.d.ts +0 -55
- package/malva-ui-editor.d.ts +0 -5
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import { Injectable, InjectionToken, signal } from '@angular/core';
|
|
2
|
-
import * as i0 from "@angular/core";
|
|
3
|
-
/** Injects the command state belonging to the nearest `mlv-editor`. */
|
|
4
|
-
export const MLV_EDITOR_TOOLBAR_CONTEXT = new InjectionToken('MLV_EDITOR_TOOLBAR_CONTEXT');
|
|
5
|
-
/** @internal Per-editor invalidation state for built-in toolbar rendering. */
|
|
6
|
-
export class MlvEditorToolbarRevision {
|
|
7
|
-
/** @internal Increments after every Tiptap transaction or selection update. */
|
|
8
|
-
revision = signal(0, /* @ts-ignore */
|
|
9
|
-
...(ngDevMode ? [{ debugName: "revision" }] : /* istanbul ignore next */ []));
|
|
10
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorToolbarRevision, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
11
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorToolbarRevision });
|
|
12
|
-
}
|
|
13
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorToolbarRevision, decorators: [{
|
|
14
|
-
type: Injectable
|
|
15
|
-
}] });
|
|
16
|
-
/** @internal Supplies the built-in toolbar's per-editor invalidation signal. */
|
|
17
|
-
export const MLV_EDITOR_TOOLBAR_REVISION = new InjectionToken('MLV_EDITOR_TOOLBAR_REVISION');
|
|
18
|
-
/** @internal Projected editor-toolbar widgets share this editor-scoped roving registry. */
|
|
19
|
-
export class MlvEditorToolbarRovingRegistry {
|
|
20
|
-
_widgets = signal([], /* @ts-ignore */
|
|
21
|
-
...(ngDevMode ? [{ debugName: "_widgets" }] : /* istanbul ignore next */ []));
|
|
22
|
-
_active = signal(null, /* @ts-ignore */
|
|
23
|
-
...(ngDevMode ? [{ debugName: "_active" }] : /* istanbul ignore next */ []));
|
|
24
|
-
_disabled = signal(false, /* @ts-ignore */
|
|
25
|
-
...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
|
|
26
|
-
_domStateRevision = signal(0, /* @ts-ignore */
|
|
27
|
-
...(ngDevMode ? [{ debugName: "_domStateRevision" }] : /* istanbul ignore next */ []));
|
|
28
|
-
_observer;
|
|
29
|
-
_root;
|
|
30
|
-
_hasInteracted = false;
|
|
31
|
-
register(widget) {
|
|
32
|
-
this._widgets.update((widgets) => [...widgets, widget]);
|
|
33
|
-
this._observeStateChanges();
|
|
34
|
-
if (!this._active())
|
|
35
|
-
this._active.set(widget);
|
|
36
|
-
queueMicrotask(() => {
|
|
37
|
-
if (!this._hasInteracted)
|
|
38
|
-
this._focusFirstWidget();
|
|
39
|
-
});
|
|
40
|
-
return () => {
|
|
41
|
-
this._widgets.update((widgets) => widgets.filter((item) => item !== widget));
|
|
42
|
-
if (this._active() === widget) {
|
|
43
|
-
this._focusFirstWidget();
|
|
44
|
-
}
|
|
45
|
-
if (!this._widgets().length)
|
|
46
|
-
this._disconnectObserver();
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
/** @internal Resolves the single effective tab stop, even during DOM mutations. */
|
|
50
|
-
isActive(widget) {
|
|
51
|
-
this._domStateRevision();
|
|
52
|
-
const active = this._active();
|
|
53
|
-
const effectiveActive = active && this._enabled(active)
|
|
54
|
-
? active
|
|
55
|
-
: (this._enabledWidgets()[0] ?? null);
|
|
56
|
-
return (!this._disabled() && effectiveActive === widget && this._enabled(widget));
|
|
57
|
-
}
|
|
58
|
-
activate(widget) {
|
|
59
|
-
if (this._widgets().includes(widget) && this._enabled(widget)) {
|
|
60
|
-
this._hasInteracted = true;
|
|
61
|
-
this._active.set(widget);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
connect(root) {
|
|
65
|
-
this._root = root;
|
|
66
|
-
this._observeStateChanges();
|
|
67
|
-
return () => {
|
|
68
|
-
if (this._root === root) {
|
|
69
|
-
this._root = undefined;
|
|
70
|
-
this._disconnectObserver();
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
setDisabled(disabled) {
|
|
75
|
-
this._disabled.set(disabled);
|
|
76
|
-
if (!disabled)
|
|
77
|
-
this._synchronizeActiveWidget();
|
|
78
|
-
}
|
|
79
|
-
focusBoundary(boundary) {
|
|
80
|
-
if (this._disabled())
|
|
81
|
-
return;
|
|
82
|
-
const widgets = this._enabledWidgets();
|
|
83
|
-
const target = boundary === 'start' ? widgets[0] : widgets[widgets.length - 1];
|
|
84
|
-
if (!target)
|
|
85
|
-
return;
|
|
86
|
-
this.activate(target);
|
|
87
|
-
target.focus();
|
|
88
|
-
}
|
|
89
|
-
move(current, direction, wrap) {
|
|
90
|
-
if (this._disabled())
|
|
91
|
-
return;
|
|
92
|
-
const widgets = this._enabledWidgets();
|
|
93
|
-
if (!widgets.length)
|
|
94
|
-
return;
|
|
95
|
-
const index = Math.max(0, widgets.indexOf(current));
|
|
96
|
-
const nextIndex = index + direction;
|
|
97
|
-
const target = wrap
|
|
98
|
-
? widgets[(nextIndex + widgets.length) % widgets.length]
|
|
99
|
-
: widgets[Math.min(Math.max(nextIndex, 0), widgets.length - 1)];
|
|
100
|
-
if (!target)
|
|
101
|
-
return;
|
|
102
|
-
this.activate(target);
|
|
103
|
-
target.focus();
|
|
104
|
-
}
|
|
105
|
-
_enabled(widget) {
|
|
106
|
-
return (!widget.closest('[hidden]') &&
|
|
107
|
-
!widget.hasAttribute('disabled') &&
|
|
108
|
-
widget.getAttribute('aria-disabled') !== 'true');
|
|
109
|
-
}
|
|
110
|
-
_enabledWidgets() {
|
|
111
|
-
return this._widgets()
|
|
112
|
-
.filter((widget) => this._enabled(widget))
|
|
113
|
-
.sort((left, right) => {
|
|
114
|
-
const position = left.compareDocumentPosition(right);
|
|
115
|
-
return position & 4 ? -1 : position & 2 ? 1 : 0;
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
_observeStateChanges() {
|
|
119
|
-
if (this._observer ||
|
|
120
|
-
typeof MutationObserver === 'undefined' ||
|
|
121
|
-
!this._root ||
|
|
122
|
-
typeof Node === 'undefined' ||
|
|
123
|
-
!(this._root instanceof Node)) {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
this._observer = new MutationObserver(() => {
|
|
127
|
-
this._domStateRevision.update((revision) => revision + 1);
|
|
128
|
-
this._synchronizeActiveWidget();
|
|
129
|
-
});
|
|
130
|
-
this._observer.observe(this._root, {
|
|
131
|
-
attributes: true,
|
|
132
|
-
attributeFilter: ['aria-disabled', 'disabled', 'hidden'],
|
|
133
|
-
childList: true,
|
|
134
|
-
subtree: true,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
_synchronizeActiveWidget() {
|
|
138
|
-
const active = this._active();
|
|
139
|
-
if (active && this._enabled(active))
|
|
140
|
-
return;
|
|
141
|
-
this._focusFirstWidget();
|
|
142
|
-
}
|
|
143
|
-
_focusFirstWidget() {
|
|
144
|
-
this._active.set(this._enabledWidgets()[0] ?? null);
|
|
145
|
-
}
|
|
146
|
-
_disconnectObserver() {
|
|
147
|
-
this._observer?.disconnect();
|
|
148
|
-
this._observer = undefined;
|
|
149
|
-
}
|
|
150
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorToolbarRovingRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
151
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorToolbarRovingRegistry });
|
|
152
|
-
}
|
|
153
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorToolbarRovingRegistry, decorators: [{
|
|
154
|
-
type: Injectable
|
|
155
|
-
}] });
|
|
156
|
-
/** @internal Resolves the nearest editor's projected-toolbar roving registry. */
|
|
157
|
-
export const MLV_EDITOR_TOOLBAR_ROVING = new InjectionToken('MLV_EDITOR_TOOLBAR_ROVING');
|
|
158
|
-
/**
|
|
159
|
-
* Internal per-editor registry for CDK overlay roots owned by toolbar controls.
|
|
160
|
-
* It is intentionally excluded from the public barrel: public controls use it
|
|
161
|
-
* only to preserve the editor's composite focus boundary.
|
|
162
|
-
*/
|
|
163
|
-
export class MlvEditorOverlayRegistry {
|
|
164
|
-
_entries = new Map();
|
|
165
|
-
_onFocusIn;
|
|
166
|
-
_onFocusOut;
|
|
167
|
-
/** @internal Wires the nearest editor's composite focus handlers. */
|
|
168
|
-
setFocusHandlers(onFocusIn, onFocusOut) {
|
|
169
|
-
this._onFocusIn = onFocusIn;
|
|
170
|
-
this._onFocusOut = onFocusOut;
|
|
171
|
-
}
|
|
172
|
-
/** @internal Registers a rendered overlay root and returns its teardown. */
|
|
173
|
-
register(root, close) {
|
|
174
|
-
const existing = this._entries.get(root);
|
|
175
|
-
if (existing) {
|
|
176
|
-
existing.close = close;
|
|
177
|
-
return () => this._remove(root);
|
|
178
|
-
}
|
|
179
|
-
const onFocusIn = (event) => this._onFocusIn?.(event);
|
|
180
|
-
const onFocusOut = (event) => this._onFocusOut?.(event);
|
|
181
|
-
const entry = { root, close, onFocusIn, onFocusOut };
|
|
182
|
-
this._entries.set(root, entry);
|
|
183
|
-
root.addEventListener('focusin', onFocusIn, true);
|
|
184
|
-
root.addEventListener('focusout', onFocusOut, true);
|
|
185
|
-
return () => this._remove(root);
|
|
186
|
-
}
|
|
187
|
-
/** @internal Whether a node is rendered in an editor-owned overlay. */
|
|
188
|
-
contains(node) {
|
|
189
|
-
if (!node)
|
|
190
|
-
return false;
|
|
191
|
-
return [...this._entries.values()].some((entry) => entry.root.contains(node));
|
|
192
|
-
}
|
|
193
|
-
/** @internal Closes all owned overlays and removes their listeners. */
|
|
194
|
-
closeAll() {
|
|
195
|
-
for (const entry of [...this._entries.values()]) {
|
|
196
|
-
try {
|
|
197
|
-
entry.close();
|
|
198
|
-
}
|
|
199
|
-
catch {
|
|
200
|
-
// A third-party overlay must not prevent remaining editor cleanup.
|
|
201
|
-
}
|
|
202
|
-
finally {
|
|
203
|
-
this._remove(entry.root);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
/** @internal Removes listener resources without invoking overlay close callbacks. */
|
|
208
|
-
destroy() {
|
|
209
|
-
for (const entry of [...this._entries.values()])
|
|
210
|
-
this._remove(entry.root);
|
|
211
|
-
}
|
|
212
|
-
_remove(root) {
|
|
213
|
-
const entry = this._entries.get(root);
|
|
214
|
-
if (!entry)
|
|
215
|
-
return;
|
|
216
|
-
this._entries.delete(root);
|
|
217
|
-
entry.root.removeEventListener('focusin', entry.onFocusIn, true);
|
|
218
|
-
entry.root.removeEventListener('focusout', entry.onFocusOut, true);
|
|
219
|
-
}
|
|
220
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorOverlayRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
221
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorOverlayRegistry });
|
|
222
|
-
}
|
|
223
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorOverlayRegistry, decorators: [{
|
|
224
|
-
type: Injectable
|
|
225
|
-
}] });
|
|
226
|
-
/** @internal Injection token for editor-owned overlay registration. */
|
|
227
|
-
export const MLV_EDITOR_OVERLAY_REGISTRY = new InjectionToken('MLV_EDITOR_OVERLAY_REGISTRY');
|
|
228
|
-
/**
|
|
229
|
-
* Internal per-editor abort registry for uploads that outlive an interaction.
|
|
230
|
-
* It remains non-public until the upload coordinator consumes it in Task 11.
|
|
231
|
-
*/
|
|
232
|
-
export class MlvEditorUploadAbortRegistry {
|
|
233
|
-
_aborters = new Set();
|
|
234
|
-
/** @internal Registers one in-flight upload abort callback. */
|
|
235
|
-
register(abort) {
|
|
236
|
-
this._aborters.add(abort);
|
|
237
|
-
return () => this._aborters.delete(abort);
|
|
238
|
-
}
|
|
239
|
-
/** @internal Aborts every registered upload without allowing one failure to stop cleanup. */
|
|
240
|
-
abortAll() {
|
|
241
|
-
for (const abort of [...this._aborters]) {
|
|
242
|
-
this._aborters.delete(abort);
|
|
243
|
-
try {
|
|
244
|
-
abort();
|
|
245
|
-
}
|
|
246
|
-
catch {
|
|
247
|
-
// A transport abort is best effort; all remaining uploads still stop.
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorUploadAbortRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
252
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorUploadAbortRegistry });
|
|
253
|
-
}
|
|
254
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorUploadAbortRegistry, decorators: [{
|
|
255
|
-
type: Injectable
|
|
256
|
-
}] });
|
|
257
|
-
/** @internal Injection token for the editor-owned upload abort registry. */
|
|
258
|
-
export const MLV_EDITOR_UPLOAD_ABORT_REGISTRY = new InjectionToken('MLV_EDITOR_UPLOAD_ABORT_REGISTRY');
|
|
259
|
-
//# sourceMappingURL=editor-toolbar-context.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor-toolbar-context.js","sourceRoot":"","sources":["../../../../../libs/editor/src/lib/editor-toolbar-context.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, InjectionToken, signal } from '@angular/core';\nimport type { Signal, WritableSignal } from '@angular/core';\nimport type { Editor } from '@tiptap/core';\nimport type {\n MlvEditorError,\n MlvEditorFormat,\n MlvEditorImageUploadControl,\n} from './editor.types';\n\n/**\n * Editor-scoped command state made available to toolbar and projected controls.\n *\n * Commands are deliberately supplied as callbacks so Malva does not conceal\n * Tiptap's API or constrain third-party extensions.\n */\nexport interface MlvEditorToolbarContext {\n /** The editor instance owned by the nearest editor shell. */\n readonly editor: Signal<Editor | null>;\n /** Whether every interactive command surface is disabled. */\n readonly disabled: Signal<boolean>;\n /** Whether document mutation commands are unavailable. */\n readonly readonly: Signal<boolean>;\n /** Whether focus is currently inside the editor composite. */\n readonly focused: Signal<boolean>;\n /** Whether the owner has an editor and permits document mutation. */\n readonly editable: Signal<boolean>;\n /** The current serialization format. */\n readonly format: Signal<MlvEditorFormat>;\n /** View-only editor zoom percentage. */\n readonly zoom: WritableSignal<number>;\n /** Optional editor-owned image upload capability for standalone toolbars. */\n readonly imageUpload?: MlvEditorImageUploadControl;\n /** Runs a mutation command without allowing unavailable commands to throw. */\n run(command: (editor: Editor) => boolean): boolean;\n /** Checks a command without allowing unavailable commands to throw. */\n can(command: (editor: Editor) => boolean): boolean;\n /** Safely reads a Tiptap active state. */\n isActive(name: string, attributes?: Record<string, unknown>): boolean;\n /** Reports a typed recoverable error through the owning editor. */\n reportError(error: MlvEditorError): void;\n}\n\n/** Injects the command state belonging to the nearest `mlv-editor`. */\nexport const MLV_EDITOR_TOOLBAR_CONTEXT =\n new InjectionToken<MlvEditorToolbarContext>('MLV_EDITOR_TOOLBAR_CONTEXT');\n\n/** @internal Per-editor invalidation state for built-in toolbar rendering. */\n@Injectable()\nexport class MlvEditorToolbarRevision {\n /** @internal Increments after every Tiptap transaction or selection update. */\n readonly revision = signal(0);\n}\n\n/** @internal Supplies the built-in toolbar's per-editor invalidation signal. */\nexport const MLV_EDITOR_TOOLBAR_REVISION = new InjectionToken<Signal<number>>(\n 'MLV_EDITOR_TOOLBAR_REVISION',\n);\n\n/** @internal Projected editor-toolbar widgets share this editor-scoped roving registry. */\n@Injectable()\nexport class MlvEditorToolbarRovingRegistry {\n private readonly _widgets = signal<readonly HTMLElement[]>([]);\n private readonly _active = signal<HTMLElement | null>(null);\n private readonly _disabled = signal(false);\n private readonly _domStateRevision = signal(0);\n private _observer: MutationObserver | undefined;\n private _root: HTMLElement | undefined;\n private _hasInteracted = false;\n\n register(widget: HTMLElement): () => void {\n this._widgets.update((widgets) => [...widgets, widget]);\n this._observeStateChanges();\n if (!this._active()) this._active.set(widget);\n queueMicrotask(() => {\n if (!this._hasInteracted) this._focusFirstWidget();\n });\n return () => {\n this._widgets.update((widgets) =>\n widgets.filter((item) => item !== widget),\n );\n if (this._active() === widget) {\n this._focusFirstWidget();\n }\n if (!this._widgets().length) this._disconnectObserver();\n };\n }\n\n /** @internal Resolves the single effective tab stop, even during DOM mutations. */\n isActive(widget: HTMLElement): boolean {\n this._domStateRevision();\n const active = this._active();\n const effectiveActive =\n active && this._enabled(active)\n ? active\n : (this._enabledWidgets()[0] ?? null);\n return (\n !this._disabled() && effectiveActive === widget && this._enabled(widget)\n );\n }\n\n activate(widget: HTMLElement): void {\n if (this._widgets().includes(widget) && this._enabled(widget)) {\n this._hasInteracted = true;\n this._active.set(widget);\n }\n }\n\n connect(root: HTMLElement): () => void {\n this._root = root;\n this._observeStateChanges();\n return () => {\n if (this._root === root) {\n this._root = undefined;\n this._disconnectObserver();\n }\n };\n }\n\n setDisabled(disabled: boolean): void {\n this._disabled.set(disabled);\n if (!disabled) this._synchronizeActiveWidget();\n }\n\n focusBoundary(boundary: 'start' | 'end'): void {\n if (this._disabled()) return;\n const widgets = this._enabledWidgets();\n const target =\n boundary === 'start' ? widgets[0] : widgets[widgets.length - 1];\n if (!target) return;\n this.activate(target);\n target.focus();\n }\n\n move(current: HTMLElement, direction: -1 | 1, wrap: boolean): void {\n if (this._disabled()) return;\n const widgets = this._enabledWidgets();\n if (!widgets.length) return;\n const index = Math.max(0, widgets.indexOf(current));\n const nextIndex = index + direction;\n const target = wrap\n ? widgets[(nextIndex + widgets.length) % widgets.length]\n : widgets[Math.min(Math.max(nextIndex, 0), widgets.length - 1)];\n if (!target) return;\n this.activate(target);\n target.focus();\n }\n\n private _enabled(widget: HTMLElement): boolean {\n return (\n !widget.closest('[hidden]') &&\n !widget.hasAttribute('disabled') &&\n widget.getAttribute('aria-disabled') !== 'true'\n );\n }\n\n private _enabledWidgets(): readonly HTMLElement[] {\n return this._widgets()\n .filter((widget) => this._enabled(widget))\n .sort((left, right) => {\n const position = left.compareDocumentPosition(right);\n return position & 4 ? -1 : position & 2 ? 1 : 0;\n });\n }\n\n private _observeStateChanges(): void {\n if (\n this._observer ||\n typeof MutationObserver === 'undefined' ||\n !this._root ||\n typeof Node === 'undefined' ||\n !(this._root instanceof Node)\n ) {\n return;\n }\n this._observer = new MutationObserver(() => {\n this._domStateRevision.update((revision) => revision + 1);\n this._synchronizeActiveWidget();\n });\n this._observer.observe(this._root, {\n attributes: true,\n attributeFilter: ['aria-disabled', 'disabled', 'hidden'],\n childList: true,\n subtree: true,\n });\n }\n\n private _synchronizeActiveWidget(): void {\n const active = this._active();\n if (active && this._enabled(active)) return;\n this._focusFirstWidget();\n }\n\n private _focusFirstWidget(): void {\n this._active.set(this._enabledWidgets()[0] ?? null);\n }\n\n private _disconnectObserver(): void {\n this._observer?.disconnect();\n this._observer = undefined;\n }\n}\n\n/** @internal Resolves the nearest editor's projected-toolbar roving registry. */\nexport const MLV_EDITOR_TOOLBAR_ROVING =\n new InjectionToken<MlvEditorToolbarRovingRegistry>(\n 'MLV_EDITOR_TOOLBAR_ROVING',\n );\n\ninterface MlvEditorOverlayEntry {\n readonly root: HTMLElement;\n close: () => void;\n readonly onFocusIn: (event: FocusEvent) => void;\n readonly onFocusOut: (event: FocusEvent) => void;\n}\n\n/**\n * Internal per-editor registry for CDK overlay roots owned by toolbar controls.\n * It is intentionally excluded from the public barrel: public controls use it\n * only to preserve the editor's composite focus boundary.\n */\n@Injectable()\nexport class MlvEditorOverlayRegistry {\n private readonly _entries = new Map<HTMLElement, MlvEditorOverlayEntry>();\n private _onFocusIn: ((event: FocusEvent) => void) | undefined;\n private _onFocusOut: ((event: FocusEvent) => void) | undefined;\n\n /** @internal Wires the nearest editor's composite focus handlers. */\n setFocusHandlers(\n onFocusIn: (event: FocusEvent) => void,\n onFocusOut: (event: FocusEvent) => void,\n ): void {\n this._onFocusIn = onFocusIn;\n this._onFocusOut = onFocusOut;\n }\n\n /** @internal Registers a rendered overlay root and returns its teardown. */\n register(root: HTMLElement, close: () => void): () => void {\n const existing = this._entries.get(root);\n if (existing) {\n existing.close = close;\n return () => this._remove(root);\n }\n const onFocusIn = (event: FocusEvent) => this._onFocusIn?.(event);\n const onFocusOut = (event: FocusEvent) => this._onFocusOut?.(event);\n const entry: MlvEditorOverlayEntry = { root, close, onFocusIn, onFocusOut };\n this._entries.set(root, entry);\n root.addEventListener('focusin', onFocusIn, true);\n root.addEventListener('focusout', onFocusOut, true);\n return () => this._remove(root);\n }\n\n /** @internal Whether a node is rendered in an editor-owned overlay. */\n contains(node: Node | null): boolean {\n if (!node) return false;\n return [...this._entries.values()].some((entry) =>\n entry.root.contains(node),\n );\n }\n\n /** @internal Closes all owned overlays and removes their listeners. */\n closeAll(): void {\n for (const entry of [...this._entries.values()]) {\n try {\n entry.close();\n } catch {\n // A third-party overlay must not prevent remaining editor cleanup.\n } finally {\n this._remove(entry.root);\n }\n }\n }\n\n /** @internal Removes listener resources without invoking overlay close callbacks. */\n destroy(): void {\n for (const entry of [...this._entries.values()]) this._remove(entry.root);\n }\n\n private _remove(root: HTMLElement): void {\n const entry = this._entries.get(root);\n if (!entry) return;\n this._entries.delete(root);\n entry.root.removeEventListener('focusin', entry.onFocusIn, true);\n entry.root.removeEventListener('focusout', entry.onFocusOut, true);\n }\n}\n\n/** @internal Injection token for editor-owned overlay registration. */\nexport const MLV_EDITOR_OVERLAY_REGISTRY =\n new InjectionToken<MlvEditorOverlayRegistry>('MLV_EDITOR_OVERLAY_REGISTRY');\n\n/**\n * Internal per-editor abort registry for uploads that outlive an interaction.\n * It remains non-public until the upload coordinator consumes it in Task 11.\n */\n@Injectable()\nexport class MlvEditorUploadAbortRegistry {\n private readonly _aborters = new Set<() => void>();\n\n /** @internal Registers one in-flight upload abort callback. */\n register(abort: () => void): () => void {\n this._aborters.add(abort);\n return () => this._aborters.delete(abort);\n }\n\n /** @internal Aborts every registered upload without allowing one failure to stop cleanup. */\n abortAll(): void {\n for (const abort of [...this._aborters]) {\n this._aborters.delete(abort);\n try {\n abort();\n } catch {\n // A transport abort is best effort; all remaining uploads still stop.\n }\n }\n }\n}\n\n/** @internal Injection token for the editor-owned upload abort registry. */\nexport const MLV_EDITOR_UPLOAD_ABORT_REGISTRY =\n new InjectionToken<MlvEditorUploadAbortRegistry>(\n 'MLV_EDITOR_UPLOAD_ABORT_REGISTRY',\n );\n"]}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { InjectionToken } from '@angular/core';
|
|
2
|
-
/** Optional dependency-injection token for a host-provided image uploader. */
|
|
3
|
-
export const MLV_EDITOR_IMAGE_UPLOADER = new InjectionToken('MLV_EDITOR_IMAGE_UPLOADER');
|
|
4
|
-
/** Default restrictions for image files inserted through the editor. */
|
|
5
|
-
export const MLV_EDITOR_DEFAULT_IMAGE_UPLOAD_OPTIONS = {
|
|
6
|
-
accept: ['image/*'],
|
|
7
|
-
maxSize: 10 * 1024 * 1024,
|
|
8
|
-
maxFiles: 1,
|
|
9
|
-
};
|
|
10
|
-
//# sourceMappingURL=editor.tokens.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor.tokens.js","sourceRoot":"","sources":["../../../../../libs/editor/src/lib/editor.tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAM/C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,yBAAyB,GACpC,IAAI,cAAc,CAAyB,2BAA2B,CAAC,CAAC;AAE1E,wEAAwE;AACxE,MAAM,CAAC,MAAM,uCAAuC,GAClD;IACE,MAAM,EAAE,CAAC,SAAS,CAAC;IACnB,OAAO,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;IACzB,QAAQ,EAAE,CAAC;CACZ,CAAC","sourcesContent":["import { InjectionToken } from '@angular/core';\nimport {\n type MlvEditorImageUploader,\n type MlvEditorImageUploadOptions,\n} from './editor.types';\n\n/** Optional dependency-injection token for a host-provided image uploader. */\nexport const MLV_EDITOR_IMAGE_UPLOADER =\n new InjectionToken<MlvEditorImageUploader>('MLV_EDITOR_IMAGE_UPLOADER');\n\n/** Default restrictions for image files inserted through the editor. */\nexport const MLV_EDITOR_DEFAULT_IMAGE_UPLOAD_OPTIONS: MlvEditorImageUploadOptions =\n {\n accept: ['image/*'],\n maxSize: 10 * 1024 * 1024,\n maxFiles: 1,\n };\n"]}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default image URL policy used by the editor upload coordinator.
|
|
3
|
-
*
|
|
4
|
-
* Only absolute HTTP(S) URLs with a hostname and without credentials are
|
|
5
|
-
* accepted. Leading and trailing whitespace is ignored, while whitespace or
|
|
6
|
-
* control characters inside the URL are rejected.
|
|
7
|
-
*
|
|
8
|
-
* @param url Candidate image URL returned by an uploader.
|
|
9
|
-
* @returns Whether the URL is safe to insert.
|
|
10
|
-
*/
|
|
11
|
-
export function mlvEditorDefaultImageUrlPolicy(url) {
|
|
12
|
-
if (typeof url !== 'string')
|
|
13
|
-
return false;
|
|
14
|
-
const trimmedUrl = url.trim();
|
|
15
|
-
const hasControlCharacter = [...trimmedUrl].some((character) => {
|
|
16
|
-
const codePoint = character.codePointAt(0) ?? 0;
|
|
17
|
-
return codePoint < 0x20 || codePoint === 0x7f;
|
|
18
|
-
});
|
|
19
|
-
if (!trimmedUrl || /\s/u.test(trimmedUrl) || hasControlCharacter) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
try {
|
|
23
|
-
const parsedUrl = new URL(trimmedUrl);
|
|
24
|
-
return ((parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:') &&
|
|
25
|
-
parsedUrl.hostname.length > 0 &&
|
|
26
|
-
parsedUrl.username.length === 0 &&
|
|
27
|
-
parsedUrl.password.length === 0);
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Editor-owned image-upload capability forwarded to standalone toolbars.
|
|
35
|
-
*
|
|
36
|
-
* The capability is intentionally one shared reference so toolbar controls
|
|
37
|
-
* never create a second uploader, request registry, or placeholder owner. Its
|
|
38
|
-
* private brand makes this a library-owned capability rather than a structural
|
|
39
|
-
* protocol for consumers to implement.
|
|
40
|
-
*/
|
|
41
|
-
export class MlvEditorImageUploadControl {
|
|
42
|
-
/** @private Nominal brand preventing structural implementations. */
|
|
43
|
-
_mlvEditorImageUploadControlBrand = true;
|
|
44
|
-
constructor() {
|
|
45
|
-
void this._mlvEditorImageUploadControlBrand;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
//# sourceMappingURL=editor.types.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor.types.js","sourceRoot":"","sources":["../../../../../libs/editor/src/lib/editor.types.ts"],"names":[],"mappings":"AA+BA;;;;;;;;;GASG;AACH,MAAM,UAAU,8BAA8B,CAAC,GAAW;IACxD,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,MAAM,mBAAmB,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;QAC7D,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChD,OAAO,SAAS,GAAG,IAAI,IAAI,SAAS,KAAK,IAAI,CAAC;IAChD,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,mBAAmB,EAAE,CAAC;QACjE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;QACtC,OAAO,CACL,CAAC,SAAS,CAAC,QAAQ,KAAK,OAAO,IAAI,SAAS,CAAC,QAAQ,KAAK,QAAQ,CAAC;YACnE,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;YAC7B,SAAS,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAC/B,SAAS,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAChC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AA8GD;;;;;;;GAOG;AACH,MAAM,OAAgB,2BAA2B;IAC/C,oEAAoE;IACnD,iCAAiC,GAAG,IAAI,CAAC;IAE1D;QACE,KAAK,IAAI,CAAC,iCAAiC,CAAC;IAC9C,CAAC;CAiCF","sourcesContent":["import type { Signal } from '@angular/core';\nimport type { Editor } from '@tiptap/core';\nimport type {} from '@tiptap/markdown';\nimport type { Transaction } from '@tiptap/pm/state';\n\n/**\n * Supported external serialization formats for editor content.\n *\n * `'html'` and `'markdown'` carry text markup. `'json'` carries the Tiptap\n * document itself as `JSON.stringify(editor.getJSON())`, so custom block nodes\n * round-trip their typed attributes instead of being flattened into HTML\n * attributes. The model type stays `string | null` in every format; a JSON\n * host parses that string at its own boundary.\n */\nexport type MlvEditorFormat = 'html' | 'markdown' | 'json';\n\n/**\n * Width of the centred editor content column.\n *\n * `'default'` is a comfortable reading measure, `'wide'` suits dense or tabular\n * documents, and `'full'` lets the column fill its host. A horizontal gutter is\n * reserved at every value, so block affordances never overlap text.\n */\nexport type MlvEditorContentWidth = 'default' | 'wide' | 'full';\n\n/** Origin of an image file supplied to the editor. */\nexport type MlvEditorImageUploadSource = 'button' | 'paste' | 'drop';\n\n/** Decides whether an uploaded image URL is safe to insert into the editor. */\nexport type MlvEditorImageUrlPolicy = (url: string) => boolean;\n\n/**\n * Default image URL policy used by the editor upload coordinator.\n *\n * Only absolute HTTP(S) URLs with a hostname and without credentials are\n * accepted. Leading and trailing whitespace is ignored, while whitespace or\n * control characters inside the URL are rejected.\n *\n * @param url Candidate image URL returned by an uploader.\n * @returns Whether the URL is safe to insert.\n */\nexport function mlvEditorDefaultImageUrlPolicy(url: string): boolean {\n if (typeof url !== 'string') return false;\n const trimmedUrl = url.trim();\n const hasControlCharacter = [...trimmedUrl].some((character) => {\n const codePoint = character.codePointAt(0) ?? 0;\n return codePoint < 0x20 || codePoint === 0x7f;\n });\n if (!trimmedUrl || /\\s/u.test(trimmedUrl) || hasControlCharacter) {\n return false;\n }\n\n try {\n const parsedUrl = new URL(trimmedUrl);\n return (\n (parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:') &&\n parsedUrl.hostname.length > 0 &&\n parsedUrl.username.length === 0 &&\n parsedUrl.password.length === 0\n );\n } catch {\n return false;\n }\n}\n\n/** Details emitted when the Tiptap selection changes. */\nexport interface MlvEditorSelectionChange {\n /** Editor that produced the selection transaction. */\n readonly editor: Editor;\n\n /** Tiptap transaction containing the updated selection. */\n readonly transaction: Transaction;\n}\n\n/** Details emitted for every Tiptap transaction. */\nexport interface MlvEditorTransactionEvent {\n /** Editor that produced the transaction. */\n readonly editor: Editor;\n\n /** Tiptap transaction emitted by the editor. */\n readonly transaction: Transaction;\n}\n\n/** Details emitted when the editor receives or loses focus. */\nexport interface MlvEditorFocusEvent {\n /** Editor associated with the native focus event. */\n readonly editor: Editor;\n\n /** Native browser focus event. */\n readonly event: FocusEvent;\n}\n\n/** Context supplied to an image uploader for one upload operation. */\nexport interface MlvEditorImageUploadContext {\n /** Origin of the image file. */\n readonly source: MlvEditorImageUploadSource;\n\n /** Signal that is aborted when the upload should stop. */\n readonly signal: AbortSignal;\n\n /** Reports upload progress as a percentage from 0 through 100. */\n readonly reportProgress: (percentage: number) => void;\n}\n\n/** Image metadata returned by an image uploader after a successful upload. */\nexport interface MlvEditorImageUploadResult {\n /** URL used in the inserted image node. */\n readonly src: string;\n\n /** Optional alternative text for the image. */\n readonly alt?: string;\n\n /** Optional image title. */\n readonly title?: string;\n\n /** Optional rendered image width. */\n readonly width?: number;\n\n /** Optional rendered image height. */\n readonly height?: number;\n}\n\n/** Adapter used to transfer image files selected, pasted, or dropped in the editor. */\nexport interface MlvEditorImageUploader {\n /**\n * Uploads an image file and returns the metadata used to insert it.\n *\n * @param file Image file to upload.\n * @param context Source, cancellation, and progress facilities for this upload.\n * @returns Metadata for the successfully uploaded image.\n */\n upload(\n file: File,\n context: MlvEditorImageUploadContext,\n ): Promise<MlvEditorImageUploadResult>;\n}\n\n/** Constraints applied before images are sent to an uploader. */\nexport interface MlvEditorImageUploadOptions {\n /** MIME types or patterns accepted by the editor. */\n readonly accept: readonly string[];\n\n /** Largest allowed file size in bytes. */\n readonly maxSize: number;\n\n /** Maximum number of files accepted in one upload action. */\n readonly maxFiles: number;\n\n /** Optional host policy replacing the default uploaded-image URL decision. */\n readonly urlPolicy?: MlvEditorImageUrlPolicy;\n}\n\n/** One upload retained by the editor while it is active or retryable. */\nexport interface MlvEditorPendingUpload {\n /** Stable identifier shared with the non-serializable placeholder. */\n readonly id: string;\n\n /** Image file supplied by the host interaction. */\n readonly file: File;\n\n /** Interaction that supplied the file. */\n readonly source: MlvEditorImageUploadSource;\n\n /** Current finite upload progress from zero through one hundred. */\n readonly progress: number;\n\n /** Whether the upload is active or retained after a recoverable failure. */\n readonly status: 'uploading' | 'failed';\n\n /** Recoverable failure retained while the upload can be retried or removed. */\n readonly error?: MlvEditorError;\n}\n\n/**\n * Editor-owned image-upload capability forwarded to standalone toolbars.\n *\n * The capability is intentionally one shared reference so toolbar controls\n * never create a second uploader, request registry, or placeholder owner. Its\n * private brand makes this a library-owned capability rather than a structural\n * protocol for consumers to implement.\n */\nexport abstract class MlvEditorImageUploadControl {\n /** @private Nominal brand preventing structural implementations. */\n private readonly _mlvEditorImageUploadControlBrand = true;\n\n protected constructor() {\n void this._mlvEditorImageUploadControlBrand;\n }\n\n /** Whether this editor can currently begin image uploads. */\n abstract readonly available: Signal<boolean>;\n\n /** Whether either the input or injected adapter resolves for this editor. */\n abstract readonly adapterAvailable: Signal<boolean>;\n\n /** Current editor-scoped validation options. */\n abstract readonly options: Signal<MlvEditorImageUploadOptions>;\n\n /** Active and retryable uploads owned by this editor. */\n abstract readonly pending: Signal<readonly MlvEditorPendingUpload[]>;\n\n /** Starts validated uploads in the owning editor. */\n abstract start(\n files: readonly File[],\n source: MlvEditorImageUploadSource,\n metadata?: {\n readonly position?: number;\n readonly alt?: string;\n readonly title?: string;\n },\n ): readonly string[];\n\n /** Cancels one active request. */\n abstract cancel(id: string): void;\n\n /** Retries one recoverable request. */\n abstract retry(id: string): void;\n\n /** Removes one recoverable failure. */\n abstract remove(id: string): void;\n}\n\n/** Details emitted after a successful image upload. */\nexport interface MlvEditorImageUploadSuccess {\n /** Image file that was uploaded. */\n readonly file: File;\n\n /** Origin of the image file. */\n readonly source: MlvEditorImageUploadSource;\n\n /** Metadata returned by the image uploader. */\n readonly result: MlvEditorImageUploadResult;\n}\n\n/** Details emitted when an image upload fails. */\nexport interface MlvEditorImageUploadFailure {\n /** Image file whose upload failed. */\n readonly file: File;\n\n /** Origin of the image file. */\n readonly source: MlvEditorImageUploadSource;\n\n /** Recoverable error describing the failed upload. */\n readonly error: MlvEditorError;\n}\n\n/** Details emitted when an image upload is cancelled. */\nexport interface MlvEditorImageUploadCancelled {\n /** Image file whose upload was cancelled. */\n readonly file: File;\n\n /** Origin of the image file. */\n readonly source: MlvEditorImageUploadSource;\n}\n\n/**\n * Categories of recoverable errors emitted by the editor.\n *\n * `'ai-transport'` reports an AI provider that threw or whose stream failed;\n * `'ai-result'` reports AI output that could not be used. Both restore the\n * document to its pre-request checkpoint; cancellation is silent and never\n * emits an error.\n */\nexport type MlvEditorErrorCode =\n | 'configuration'\n | 'parse'\n | 'serialize'\n | 'unsupported-command'\n | 'upload-validation'\n | 'upload-transport'\n | 'upload-result'\n | 'ai-transport'\n | 'ai-result';\n\n/** Structured error emitted instead of throwing through Angular change detection. */\nexport interface MlvEditorError {\n /** Stable category that callers can use for error handling. */\n readonly code: MlvEditorErrorCode;\n\n /** Human-readable description of the failure. */\n readonly message: string;\n\n /** Whether the editor can continue operating after the failure. */\n readonly recoverable: boolean;\n\n /** Original failure when one is available. */\n readonly cause?: unknown;\n}\n"]}
|