@sobree/core 0.1.0 → 0.1.2
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/dist/doc/types.d.ts +40 -30
- package/dist/docx/shared/units.d.ts +3 -2
- package/dist/docx/shared/xml.d.ts +12 -0
- package/dist/editor/commands.d.ts +14 -0
- package/dist/editor/context.d.ts +71 -0
- package/dist/editor/dom.d.ts +21 -0
- package/dist/editor/events.d.ts +29 -0
- package/dist/editor/index.d.ts +85 -663
- package/dist/editor/internal/mutations.d.ts +1 -1
- package/dist/editor/ops/blocks.d.ts +42 -0
- package/dist/editor/ops/comments.d.ts +12 -0
- package/dist/editor/ops/parts.d.ts +71 -0
- package/dist/editor/ops/review.d.ts +67 -0
- package/dist/editor/ops/runs.d.ts +83 -0
- package/dist/editor/ops/trackedInput.d.ts +44 -0
- package/dist/editor/query.d.ts +22 -0
- package/dist/editor/revisionRuns.d.ts +56 -0
- package/dist/editor/selection.d.ts +34 -0
- package/dist/editor/types.d.ts +292 -0
- package/dist/editor/view/docRenderer/anchorPosition.d.ts +18 -0
- package/dist/editor/view/docRenderer/sectionFlow.d.ts +23 -0
- package/dist/editor/view/docRenderer/table.d.ts +11 -2
- package/dist/index.css +1 -1
- package/dist/index.js +6099 -6020
- package/dist/index.js.map +1 -1
- package/dist/paperStack/paginationV2/apply.d.ts +18 -0
- package/dist/paperStack/paginationV2/engine.d.ts +7 -0
- package/dist/paperStack/paginationV2/measure.d.ts +9 -0
- package/dist/paperStack/paginationV2/types.d.ts +273 -0
- package/dist/paperStack/paper.d.ts +31 -9
- package/dist/paperStack/paperStack.d.ts +13 -1
- package/dist/paperStack/paperZone.d.ts +35 -0
- package/dist/plugins/marks.d.ts +4 -4
- package/dist/ydoc/schema.d.ts +5 -0
- package/package.json +1 -3
- package/dist/__vite-browser-external-DYxpcVy9.js +0 -5
- package/dist/__vite-browser-external-DYxpcVy9.js.map +0 -1
package/dist/editor/index.d.ts
CHANGED
|
@@ -1,266 +1,20 @@
|
|
|
1
1
|
import { BlobCache, BlobStore } from '../blob';
|
|
2
|
-
import { BlockRef, EditError, EditResult, InlinePosition,
|
|
3
|
-
import { EmbedFontFaces, EmbedFontOptions } from '../fonts';
|
|
2
|
+
import { Range as ApiRange, BlockRef, EditError, EditResult, InlinePosition, Selection } from '../doc/api';
|
|
4
3
|
import { RunPropertiesPatch } from '../doc/runs';
|
|
5
|
-
import { Block, InlineRun,
|
|
4
|
+
import { Block, InlineRun, SobreeDocument } from '../doc/types';
|
|
5
|
+
import { EmbedFontFaces, EmbedFontOptions } from '../fonts';
|
|
6
|
+
import { History } from '../history';
|
|
6
7
|
import { BlockRegistry } from './internal/blockRegistry';
|
|
7
8
|
import { countBlocks } from './internal/positionMap';
|
|
9
|
+
import { EditorSelection } from './selection';
|
|
8
10
|
import { EditorTable } from './table';
|
|
9
|
-
import {
|
|
11
|
+
import { ApiRangeType, BlockInfo, ChangePayload, CommandBus, CommandDefinition, CommandSnapshot, EditorEvent, EditorEventPayload, EditorOptions, KeyDownPayload, OutlineItem, ParagraphPropertiesPatch, RevisionSpan, SelectionPayload, TrackChangesState, Unsubscribe, WrapTag } from './types';
|
|
10
12
|
import * as Y from "yjs";
|
|
13
|
+
export { EditorCommands } from './commands';
|
|
14
|
+
export { EditorSelection } from './selection';
|
|
11
15
|
export type { BlockRef, EditError, EditResult, InlinePosition, Selection };
|
|
12
|
-
export type ApiRangeType
|
|
13
|
-
|
|
14
|
-
* One logical tracked change — a maximal run of consecutive inline
|
|
15
|
-
* runs that all carry a `revision` marker by the same author.
|
|
16
|
-
* `getRevisions()` returns these; pass `range` straight to
|
|
17
|
-
* `acceptRevision` / `rejectRevision`.
|
|
18
|
-
*
|
|
19
|
-
* `kinds` is the set of revision types in the span: `["ins"]` or
|
|
20
|
-
* `["del"]` for a plain change, both for a delete-then-insert
|
|
21
|
-
* replacement (which accepts/rejects as a single unit).
|
|
22
|
-
*/
|
|
23
|
-
export interface RevisionSpan {
|
|
24
|
-
range: ApiRange;
|
|
25
|
-
author?: string;
|
|
26
|
-
kinds: ("ins" | "del")[];
|
|
27
|
-
/** ISO date of the span's first revision run, if recorded. */
|
|
28
|
-
date?: string;
|
|
29
|
-
/**
|
|
30
|
-
* Discriminator between revision levels:
|
|
31
|
-
* `"inline"` (default for backwards compat) — the span covers
|
|
32
|
-
* `ins`/`del` text runs inside a block. Pass `range` to
|
|
33
|
-
* `acceptRevision` / `rejectRevision`.
|
|
34
|
-
* `"paragraph"` — the span flags the *paragraph mark* itself on
|
|
35
|
-
* `range.from.block`. The range covers offset `[0, length]` of
|
|
36
|
-
* the block so it still selects the right element for UIs, but
|
|
37
|
-
* accept/reject must go through `acceptParagraphRevision` /
|
|
38
|
-
* `rejectParagraphRevision`.
|
|
39
|
-
* `"format"` — the span flags a tracked format change
|
|
40
|
-
* (`<w:rPrChange>`) on contiguous runs by the same author.
|
|
41
|
-
* `kinds` always reports `["ins"]` (the marker is binary: a
|
|
42
|
-
* format change exists or not). Pass `range` to
|
|
43
|
-
* `acceptFormatRevision` / `rejectFormatRevision`.
|
|
44
|
-
*/
|
|
45
|
-
level?: "inline" | "paragraph" | "format";
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Track-changes mode. When `enabled` is true, the editor reinterprets
|
|
49
|
-
* authoring mutations as tracked revisions rather than direct edits:
|
|
50
|
-
*
|
|
51
|
-
* - `insertRun` stamps `revision: { type: "ins", author }` on the
|
|
52
|
-
* inserted run instead of merging it in plainly.
|
|
53
|
-
* - `deleteRange` stamps `revision: { type: "del", author }` on the
|
|
54
|
-
* plain text runs in range instead of dropping them. A run that's
|
|
55
|
-
* already an `ins` *by the same author* is dropped instead — the
|
|
56
|
-
* author cancelling their own pending insert — and runs already
|
|
57
|
-
* carrying a peer's revision are left untouched (the API user must
|
|
58
|
-
* resolve those via `acceptRevision` / `rejectRevision` first).
|
|
59
|
-
* - All other mutations (`applyRunProperties`, block-level ops, etc.)
|
|
60
|
-
* pass through unchanged in this first cut; format-change tracking
|
|
61
|
-
* (`<w:rPrChange>`) and paragraph-mark tracking will land later.
|
|
62
|
-
*
|
|
63
|
-
* `author` is the human-readable name written into the revision
|
|
64
|
-
* marker. Optional — falls back to no `author` field, mirroring the
|
|
65
|
-
* Word semantics for anonymous-author tracked changes.
|
|
66
|
-
*
|
|
67
|
-
* This is the *authoring* side of the review feature. `getRevisions`
|
|
68
|
-
* / `acceptRevision` / `rejectRevision` are the *consumption* side
|
|
69
|
-
* and work the same regardless of this flag.
|
|
70
|
-
*/
|
|
71
|
-
export interface TrackChangesState {
|
|
72
|
-
enabled: boolean;
|
|
73
|
-
author?: string;
|
|
74
|
-
}
|
|
75
|
-
export type { CellRef, InsertAt, InsertColumnOpts, InsertRowOpts, MergeCellsOpts, } from './table';
|
|
76
|
-
/**
|
|
77
|
-
* Payload delivered to `change` subscribers. Plain data — safe to
|
|
78
|
-
* JSON-stringify and ship over a wire. `rawParts` is stripped from
|
|
79
|
-
* `document` so the payload never carries binary Uint8Arrays.
|
|
80
|
-
*/
|
|
81
|
-
export interface ChangePayload {
|
|
82
|
-
doc: SobreeDocument;
|
|
83
|
-
/**
|
|
84
|
-
* @deprecated Use `doc` instead. This alias is kept for backwards
|
|
85
|
-
* compatibility within the pre-1.0 line and will be removed before
|
|
86
|
-
* v1. Same reference as `doc`.
|
|
87
|
-
*/
|
|
88
|
-
document: SobreeDocument;
|
|
89
|
-
revision: number;
|
|
90
|
-
documentVersion: number;
|
|
91
|
-
}
|
|
92
|
-
/** Summary of a top-level block, for `getBlocks()` and list-style UIs. */
|
|
93
|
-
export interface BlockInfo {
|
|
94
|
-
/** Current position in the body (unstable across edits). */
|
|
95
|
-
index: number;
|
|
96
|
-
/** Stable id — pair with `version` to form a `BlockRef`. */
|
|
97
|
-
id: string;
|
|
98
|
-
/** Bumps on every modification of this block. */
|
|
99
|
-
version: number;
|
|
100
|
-
kind: Block["kind"];
|
|
101
|
-
styleId?: string;
|
|
102
|
-
alignment?: ParagraphAlignment;
|
|
103
|
-
/** Plain-text preview. */
|
|
104
|
-
text: string;
|
|
105
|
-
/** Total character-length of the block's content (see `runsLength`). */
|
|
106
|
-
length: number;
|
|
107
|
-
}
|
|
108
|
-
/** Outline entry — one per heading in document order. */
|
|
109
|
-
export interface OutlineItem {
|
|
110
|
-
level: number;
|
|
111
|
-
text: string;
|
|
112
|
-
blockIndex: number;
|
|
113
|
-
block: BlockRef;
|
|
114
|
-
}
|
|
115
|
-
export type ParagraphPropertiesPatch = {
|
|
116
|
-
[K in keyof ParagraphProperties]?: ParagraphProperties[K] | undefined;
|
|
117
|
-
};
|
|
118
|
-
export type WrapTag = "sup" | "sub" | "strong" | "em" | "u" | "s" | "mark";
|
|
119
|
-
export type EditorEvent = "change" | "selection" | "keydown" | "track-changes-change";
|
|
120
|
-
export type EditorEventPayload = {
|
|
121
|
-
change: ChangePayload;
|
|
122
|
-
selection: SelectionPayload;
|
|
123
|
-
keydown: KeyDownPayload;
|
|
124
|
-
"track-changes-change": TrackChangesState;
|
|
125
|
-
};
|
|
126
|
-
export type Unsubscribe = () => void;
|
|
127
|
-
/**
|
|
128
|
-
* Payload delivered to `selection` subscribers. Fires whenever the live
|
|
129
|
-
* DOM selection changes — typing, clicking, arrow-key navigation, focus
|
|
130
|
-
* loss, programmatic restore. Subscribers should subscribe through the
|
|
131
|
-
* editor rather than `document.addEventListener("selectionchange")`
|
|
132
|
-
* directly so cleanup is centralised and the editor can later add
|
|
133
|
-
* dedup / throttling.
|
|
134
|
-
*
|
|
135
|
-
* `selection` is the model shape (`null` when focus is outside the
|
|
136
|
-
* editor). The convenience fields below mirror what `EditorSelection`
|
|
137
|
-
* exposes for ergonomics — read whichever one you need.
|
|
138
|
-
*/
|
|
139
|
-
export interface SelectionPayload {
|
|
140
|
-
selection: Selection;
|
|
141
|
-
range: ApiRange | null;
|
|
142
|
-
caret: InlinePosition | null;
|
|
143
|
-
block: BlockRef | null;
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Payload delivered to `keydown` subscribers. Fires for every key press
|
|
147
|
-
* inside the editor host. The editor binds NO shortcuts itself —
|
|
148
|
-
* plugins map keys to API calls via `preventDefault()` (stops the
|
|
149
|
-
* browser's default action) and `stopPropagation()` (stops the chain
|
|
150
|
-
* of remaining subscribers). Subscribers fire in registration order.
|
|
151
|
-
*/
|
|
152
|
-
export interface KeyDownPayload {
|
|
153
|
-
/** `KeyboardEvent.key` — `"b"`, `"Enter"`, `"ArrowLeft"`, … (lowercased for letters). */
|
|
154
|
-
key: string;
|
|
155
|
-
/** `KeyboardEvent.code` — `"KeyB"`, `"Enter"`, `"ArrowLeft"`, … (layout-independent). */
|
|
156
|
-
code: string;
|
|
157
|
-
ctrl: boolean;
|
|
158
|
-
shift: boolean;
|
|
159
|
-
alt: boolean;
|
|
160
|
-
meta: boolean;
|
|
161
|
-
/** Stop the browser's default for this key (insertion, navigation, …). */
|
|
162
|
-
preventDefault(): void;
|
|
163
|
-
/** Stop further subscribers from receiving this key. */
|
|
164
|
-
stopPropagation(): void;
|
|
165
|
-
/** Underlying DOM event — for advanced needs (`isComposing`, repeat, …). */
|
|
166
|
-
originalEvent: KeyboardEvent;
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* A registered command — a named, callable unit of editor work that
|
|
170
|
-
* plugins coordinate around. Same definition gets reached by a
|
|
171
|
-
* keyboard shortcut, a toolbar click, a programmatic call from an
|
|
172
|
-
* agent, or an MCP request.
|
|
173
|
-
*
|
|
174
|
-
* The `run` function is the one place the work happens. `isActive` and
|
|
175
|
-
* `isAvailable` let UI plugins paint toggle / disabled state without
|
|
176
|
-
* understanding what the command actually does.
|
|
177
|
-
*/
|
|
178
|
-
export interface CommandDefinition<Args = void> {
|
|
179
|
-
/** Dotted, namespaced — `"mark.toggle.bold"`, `"section.insertBreak"`, … */
|
|
180
|
-
name: string;
|
|
181
|
-
/** Short human label for tooltips / command palettes. */
|
|
182
|
-
title?: string;
|
|
183
|
-
/** Perform the work. Should be idempotent w.r.t. selection (a second
|
|
184
|
-
* invocation on an already-bold selection clears bold, etc.). */
|
|
185
|
-
run: (args: Args) => void;
|
|
186
|
-
/** True when the command represents an active state (mark already on,
|
|
187
|
-
* block is already a heading, …). Drives toolbar `is-active`. */
|
|
188
|
-
isActive?: () => boolean;
|
|
189
|
-
/** False when the command can't run (e.g. selection is wrong shape).
|
|
190
|
-
* Defaults to true. Drives toolbar `disabled`. */
|
|
191
|
-
isAvailable?: () => boolean;
|
|
192
|
-
}
|
|
193
|
-
/** Snapshot of one registered command — what `commands.list()` returns. */
|
|
194
|
-
export interface CommandSnapshot {
|
|
195
|
-
name: string;
|
|
196
|
-
title: string;
|
|
197
|
-
isActive: boolean;
|
|
198
|
-
isAvailable: boolean;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Registry every plugin uses to talk to every other plugin. The
|
|
202
|
-
* editor owns it; plugins register commands on attach and unregister
|
|
203
|
-
* on detach. Keyboard plugins, toolbar plugins, and a future MCP
|
|
204
|
-
* adapter all share the same dispatch path: `editor.commands.execute(name)`.
|
|
205
|
-
*/
|
|
206
|
-
export interface CommandBus {
|
|
207
|
-
/** Register a command. Returns an unsubscribe that removes it. */
|
|
208
|
-
register<Args = void>(def: CommandDefinition<Args>): () => void;
|
|
209
|
-
/** Run a registered command. No-op (with a warning) if unknown. */
|
|
210
|
-
execute<Args = void>(name: string, args?: Args): void;
|
|
211
|
-
/** Snapshot every registered command — for command palettes,
|
|
212
|
-
* toolbars rendering toggle states, accessibility audits. */
|
|
213
|
-
list(): CommandSnapshot[];
|
|
214
|
-
/** Whether the named command is currently registered. */
|
|
215
|
-
has(name: string): boolean;
|
|
216
|
-
}
|
|
217
|
-
export interface EditorOptions {
|
|
218
|
-
initialDocument?: SobreeDocument;
|
|
219
|
-
changeDebounceMs?: number;
|
|
220
|
-
/**
|
|
221
|
-
* Elements whose children are editable blocks, in document order. Called
|
|
222
|
-
* fresh each time — the list can grow/shrink (e.g. during pagination).
|
|
223
|
-
*/
|
|
224
|
-
contentHosts?: () => HTMLElement[];
|
|
225
|
-
/**
|
|
226
|
-
* Y.Doc backing the document. Optional — if absent, the editor creates
|
|
227
|
-
* one internally. Embedders pass their own when they need to attach
|
|
228
|
-
* a provider (`y-websocket`, `y-indexeddb`, `y-webrtc`, …) for
|
|
229
|
-
* persistence or collaboration.
|
|
230
|
-
*
|
|
231
|
-
* When supplied, the editor checks whether the Y.Doc already has body
|
|
232
|
-
* content. If empty, it seeds from `initialDocument`. If non-empty
|
|
233
|
-
* (Phase 2+: a peer joined an active room), the existing Y.Doc state
|
|
234
|
-
* wins and `initialDocument` is ignored. See `editor.ydoc` for the
|
|
235
|
-
* public escape hatch.
|
|
236
|
-
*/
|
|
237
|
-
ydoc?: Y.Doc;
|
|
238
|
-
/**
|
|
239
|
-
* Optional content-hashed `BlobStore` for binary parts (images, fonts).
|
|
240
|
-
*
|
|
241
|
-
* Without one (default): bytes live inline in the Y.Doc's `parts`
|
|
242
|
-
* Y.Map and replicate to every peer through Y updates. Fine for
|
|
243
|
-
* small docs.
|
|
244
|
-
*
|
|
245
|
-
* With one (Phase 3.2+): the editor hashes binary parts, uploads
|
|
246
|
-
* the bytes to the store, and writes only the hash into the Y.Doc's
|
|
247
|
-
* `partRefs` Y.Map. Y updates stay small regardless of image size.
|
|
248
|
-
* The editor maintains a local `BlobCache` that synchronously serves
|
|
249
|
-
* already-fetched bytes to the renderer; `editor.ensurePartsLoaded()`
|
|
250
|
-
* is the async hook for explicit pre-fetching (e.g. before
|
|
251
|
-
* `toDocx()`).
|
|
252
|
-
*
|
|
253
|
-
* See `@sobree/core/blob` for the interface + reference impls
|
|
254
|
-
* (`inMemoryBlobStore`, `fetchBlobStore`).
|
|
255
|
-
*/
|
|
256
|
-
blobStore?: BlobStore;
|
|
257
|
-
/**
|
|
258
|
-
* Initial track-changes mode. When omitted, the editor starts in
|
|
259
|
-
* direct-edit mode (`{ enabled: false }`) and embedders can flip it
|
|
260
|
-
* later via `editor.setTrackChanges`. See `TrackChangesState`.
|
|
261
|
-
*/
|
|
262
|
-
trackChanges?: TrackChangesState;
|
|
263
|
-
}
|
|
16
|
+
export type { ApiRangeType, BlockInfo, ChangePayload, CommandBus, CommandDefinition, CommandSnapshot, EditorEvent, EditorEventPayload, EditorOptions, KeyDownPayload, OutlineItem, ParagraphPropertiesPatch, RevisionSpan, SelectionPayload, TrackChangesState, Unsubscribe, WrapTag, };
|
|
17
|
+
export type { CellRef, InsertAt, InsertColumnOpts, InsertRowOpts, MergeCellsOpts, } from './types';
|
|
264
18
|
export { runsLength } from '../doc/runs';
|
|
265
19
|
export type { RunPropertiesPatch };
|
|
266
20
|
/**
|
|
@@ -349,7 +103,9 @@ export declare class Editor {
|
|
|
349
103
|
private dragOverListener;
|
|
350
104
|
private dropListener;
|
|
351
105
|
private revision;
|
|
352
|
-
|
|
106
|
+
/** The editor's observable event surface (change / selection / keydown
|
|
107
|
+
* / track-changes-change). See `./events.ts`. */
|
|
108
|
+
private readonly events;
|
|
353
109
|
/**
|
|
354
110
|
* Authoring mode for revisions. Off by default — mutations apply
|
|
355
111
|
* plainly. On, `insertRun` / `deleteRange` route through
|
|
@@ -358,26 +114,13 @@ export declare class Editor {
|
|
|
358
114
|
*/
|
|
359
115
|
private trackChanges;
|
|
360
116
|
/**
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
*
|
|
117
|
+
* Track-changes authoring input handler — routes tracked-mode
|
|
118
|
+
* `beforeinput` / IME composition / paste through the typed API so
|
|
119
|
+
* resulting runs carry revision markers. Holds the IME composition
|
|
120
|
+
* snapshot + warn-once state. Built in the constructor. See
|
|
121
|
+
* `ops/trackedInput`.
|
|
366
122
|
*/
|
|
367
|
-
private
|
|
368
|
-
/**
|
|
369
|
-
* Active IME composition state (`compositionstart` → `compositionend`).
|
|
370
|
-
* `null` outside composition or in non-tracked mode.
|
|
371
|
-
*
|
|
372
|
-
* Snapshot-then-restore is the only practical way to track IME-typed
|
|
373
|
-
* text: we can't intercept `beforeinput` during composition without
|
|
374
|
-
* breaking input methods on most platforms, so we let the browser
|
|
375
|
-
* mutate the DOM natively during composition, then on `compositionend`
|
|
376
|
-
* we roll back to the pre-composition AST and re-insert the final
|
|
377
|
-
* composed string (`event.data`) through `insertRun` — which stamps
|
|
378
|
-
* the `revision: ins` marker per `TrackChangesState`.
|
|
379
|
-
*/
|
|
380
|
-
private composition;
|
|
123
|
+
private trackedInput;
|
|
381
124
|
private compositionStartListener;
|
|
382
125
|
private compositionEndListener;
|
|
383
126
|
/** Document-level `selectionchange` listener. Funnels every cursor
|
|
@@ -408,7 +151,20 @@ export declare class Editor {
|
|
|
408
151
|
* and `emitChangeNow` sync only when this flag is set.
|
|
409
152
|
*/
|
|
410
153
|
private domDirty;
|
|
154
|
+
/**
|
|
155
|
+
* Kernel seam handed to the behaviour modules (`ops/*`, `query`). Built
|
|
156
|
+
* once in the constructor; closes over this instance's privates so the
|
|
157
|
+
* `commit` pipeline / lock checks stay private to the class. See
|
|
158
|
+
* `./context.ts`.
|
|
159
|
+
*/
|
|
160
|
+
private readonly ctx;
|
|
411
161
|
constructor(host: HTMLElement, options?: EditorOptions);
|
|
162
|
+
/**
|
|
163
|
+
* Assemble the {@link EditorContext} the behaviour modules operate on.
|
|
164
|
+
* Closes over `this` so the kernel methods (`commit`, `checkRefs`, …)
|
|
165
|
+
* stay private to the class while modules get a curated surface.
|
|
166
|
+
*/
|
|
167
|
+
private buildContext;
|
|
412
168
|
/**
|
|
413
169
|
* Re-project the Y.Doc into `this.doc`, sync the BlockRegistry to
|
|
414
170
|
* the projected ids, re-render the DOM, and fire `change`. Called
|
|
@@ -421,21 +177,11 @@ export declare class Editor {
|
|
|
421
177
|
* is owned by the caller. Missing hashes stay out of `rawParts`;
|
|
422
178
|
* the renderer handles missing parts gracefully (placeholder).
|
|
423
179
|
*/
|
|
424
|
-
private resolveCachedPartRefsInto;
|
|
425
180
|
/**
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*/
|
|
431
|
-
private onBlobResolved;
|
|
432
|
-
/**
|
|
433
|
-
* Wait for every currently-referenced binary part to be available
|
|
434
|
-
* in the local cache. Useful before `toDocx()` so the exported
|
|
435
|
-
* file contains all images / fonts.
|
|
436
|
-
*
|
|
437
|
-
* Returns a resolved Promise immediately when no `blobStore` is
|
|
438
|
-
* configured (today's default — bytes are always inline).
|
|
181
|
+
* Wait for every currently-referenced binary part to be available in
|
|
182
|
+
* the local cache. Useful before `toDocx()` so the exported file
|
|
183
|
+
* contains all images / fonts. Resolves immediately when no
|
|
184
|
+
* `blobStore` is configured (bytes are always inline).
|
|
439
185
|
*/
|
|
440
186
|
ensurePartsLoaded(): Promise<void>;
|
|
441
187
|
/**
|
|
@@ -455,6 +201,20 @@ export declare class Editor {
|
|
|
455
201
|
* operations that Y.UndoManager turns into a single stack item.
|
|
456
202
|
*/
|
|
457
203
|
private applyDocument;
|
|
204
|
+
/**
|
|
205
|
+
* Re-render the current `doc` into the content hosts. Syncs
|
|
206
|
+
* `@font-face` registrations BEFORE rendering so newly-embedded fonts
|
|
207
|
+
* are available to the render pass. No selection restore, no change
|
|
208
|
+
* emit — callers sequence those.
|
|
209
|
+
*/
|
|
210
|
+
private renderCurrent;
|
|
211
|
+
/**
|
|
212
|
+
* Soft-revert to a doc `snapshot` and re-render. Resets the
|
|
213
|
+
* serialised-block cache + dom-dirty flag; no registry reset, mirror, or
|
|
214
|
+
* change emit. Used to undo native IME mutations before a tracked
|
|
215
|
+
* re-insert (see `ops/trackedInput`).
|
|
216
|
+
*/
|
|
217
|
+
private restoreSnapshot;
|
|
458
218
|
/**
|
|
459
219
|
* Drop entries from `rawParts` that nothing in the AST references.
|
|
460
220
|
* Useful after deleting images (or font embeds — Phase 3) to keep the
|
|
@@ -469,15 +229,10 @@ export declare class Editor {
|
|
|
469
229
|
pruned: string[];
|
|
470
230
|
};
|
|
471
231
|
/**
|
|
472
|
-
* Embed a TTF/OTF font into the document.
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
* Refuses (with a warning) when the font's OS/2 `fsType` field
|
|
478
|
-
* marks it as restricted, unless `opts.allowRestricted` is true.
|
|
479
|
-
* Pass any subset of {regular, bold, italic, boldItalic}; missing
|
|
480
|
-
* faces are simply not embedded.
|
|
232
|
+
* Embed a TTF/OTF font into the document. Refuses (with a warning)
|
|
233
|
+
* restricted fonts unless `opts.allowRestricted` is true. Pass any
|
|
234
|
+
* subset of {regular, bold, italic, boldItalic}; missing faces are
|
|
235
|
+
* simply not embedded.
|
|
481
236
|
*/
|
|
482
237
|
embedFont(name: string, faces: EmbedFontFaces, opts?: EmbedFontOptions): {
|
|
483
238
|
warnings: string[];
|
|
@@ -502,40 +257,19 @@ export declare class Editor {
|
|
|
502
257
|
/** Replace the block at `target`'s index with `block`. */
|
|
503
258
|
replaceBlock(target: BlockRef, block: Block): EditResult<BlockRef>;
|
|
504
259
|
/**
|
|
505
|
-
* Insert `block` before the target block. Returns the new ref.
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
* paragraph it gets stamped with `revision: { type: "ins", author }`
|
|
509
|
-
* on its properties — the same paragraph-mark semantics as
|
|
510
|
-
* `splitBlock`. Non-paragraph blocks (table, section_break) don't
|
|
511
|
-
* carry the marker in v1 and insert plain.
|
|
260
|
+
* Insert `block` before the target block. Returns the new ref. In
|
|
261
|
+
* track-changes mode a paragraph block is stamped `revision: ins`;
|
|
262
|
+
* non-paragraph blocks insert plain.
|
|
512
263
|
*/
|
|
513
264
|
insertBlockBefore(target: BlockRef, block: Block): EditResult<BlockRef>;
|
|
514
|
-
/**
|
|
515
|
-
* Insert `block` after the target block. Returns the new ref.
|
|
516
|
-
* Tracked-mode behaviour matches `insertBlockBefore`.
|
|
517
|
-
*/
|
|
265
|
+
/** Insert `block` after the target block. Returns the new ref. */
|
|
518
266
|
insertBlockAfter(target: BlockRef, block: Block): EditResult<BlockRef>;
|
|
519
267
|
/**
|
|
520
|
-
* Delete the target block.
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
* `properties.revision` is stamped `del` (the renderer shows the
|
|
524
|
-
* paragraph mark with a strikethrough ¶ glyph; the body text stays
|
|
525
|
-
* visible). If the paragraph carries the *current author's* pending
|
|
526
|
-
* `ins` marker (a paragraph the user themselves just created), the
|
|
527
|
-
* block is removed outright — cancelling an un-committed insert,
|
|
528
|
-
* matching the inline `deleteRange` semantics. Non-paragraph blocks
|
|
529
|
-
* (tables, section breaks) bypass tracking in v1 — they remove plainly.
|
|
268
|
+
* Delete the target block. In track-changes mode paragraph blocks are
|
|
269
|
+
* stamped `del` (kept visible) rather than removed; tables / section
|
|
270
|
+
* breaks remove plainly.
|
|
530
271
|
*/
|
|
531
272
|
deleteBlock(target: BlockRef): EditResult<void>;
|
|
532
|
-
/**
|
|
533
|
-
* Stamp `revision: ins` on a paragraph block if tracked mode is on
|
|
534
|
-
* and the block doesn't already carry one. Helper for
|
|
535
|
-
* `insertBlockBefore` / `insertBlockAfter`. Non-paragraph blocks
|
|
536
|
-
* pass through unchanged.
|
|
537
|
-
*/
|
|
538
|
-
private stampInsertedBlockIfTracked;
|
|
539
273
|
/** Merge a patch into each target paragraph's properties. */
|
|
540
274
|
applyBlockProperties(targets: BlockRef[], patch: ParagraphPropertiesPatch): EditResult<void>;
|
|
541
275
|
/**
|
|
@@ -557,48 +291,21 @@ export declare class Editor {
|
|
|
557
291
|
expect?: Record<string, number>;
|
|
558
292
|
}): EditResult<void>;
|
|
559
293
|
/**
|
|
560
|
-
* Insert a run at `at`.
|
|
561
|
-
*
|
|
562
|
-
* In track-changes mode (see `setTrackChanges`), the run is stamped
|
|
563
|
-
* with `revision: { type: "ins", author }` before insertion (unless
|
|
564
|
-
* it already carries a `revision` — caller-provided revisions are
|
|
565
|
-
* never overwritten).
|
|
294
|
+
* Insert a run at `at`. In track-changes mode the run is stamped
|
|
295
|
+
* `revision: ins` unless it already carries one.
|
|
566
296
|
*/
|
|
567
297
|
insertRun(at: InlinePosition, run: InlineRun): EditResult<BlockRef>;
|
|
568
298
|
/**
|
|
569
|
-
* Split a paragraph at `at
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
* paragraph
|
|
573
|
-
* shape of the split is what the user expects from pressing Enter.
|
|
574
|
-
*
|
|
575
|
-
* In track-changes mode (see `setTrackChanges`), the new paragraph's
|
|
576
|
-
* `properties.revision` is stamped `{ type: "ins", author }` — the
|
|
577
|
-
* "this paragraph break is a tracked insert" marker. The original
|
|
578
|
-
* paragraph is left clean; only the *new* paragraph carries the mark,
|
|
579
|
-
* mirroring how Word stores `<w:rPr><w:ins/></w:rPr>` inside `<w:pPr>`.
|
|
580
|
-
*
|
|
581
|
-
* `at.offset` is clamped to `[0, block-length]`. A split at offset 0
|
|
582
|
-
* inserts an empty paragraph *before* the cursor; a split at the
|
|
583
|
-
* block's full length inserts an empty paragraph *after*.
|
|
584
|
-
*
|
|
585
|
-
* Returns the ref of the *new* (second) block — callers typically
|
|
586
|
-
* place the caret at its offset 0.
|
|
299
|
+
* Split a paragraph at `at`; runs after the offset move into a new
|
|
300
|
+
* paragraph inserted after, inheriting the original's properties.
|
|
301
|
+
* Returns the new (second) block's ref. In track-changes mode the new
|
|
302
|
+
* paragraph is stamped `revision: ins`.
|
|
587
303
|
*/
|
|
588
304
|
splitBlock(at: InlinePosition): EditResult<BlockRef>;
|
|
589
305
|
/**
|
|
590
|
-
* Insert an image at `at`.
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
* When a `blobStore` is configured (Phase 3.2+), the bytes also
|
|
595
|
-
* migrate in the background: hashed, uploaded to the store, and a
|
|
596
|
-
* `partRefs[partPath] = hash` entry written to the Y.Doc. Once the
|
|
597
|
-
* migration lands, the Y.Doc's inline `parts[partPath]` is cleared —
|
|
598
|
-
* so the bytes ride the side-channel, not the Y update stream.
|
|
599
|
-
* The local renderer keeps reading `doc.rawParts[partPath]`
|
|
600
|
-
* throughout (the value is stable from the moment `insertImage`
|
|
601
|
-
* returns).
|
|
306
|
+
* Insert an image at `at`. Bytes are stored in `doc.rawParts` and a
|
|
307
|
+
* `DrawingRun` is inserted; with a `blobStore` configured the bytes
|
|
308
|
+
* migrate to the store in the background.
|
|
602
309
|
*/
|
|
603
310
|
insertImage(at: InlinePosition, bytes: Uint8Array, opts: {
|
|
604
311
|
mime: string;
|
|
@@ -630,20 +337,6 @@ export declare class Editor {
|
|
|
630
337
|
deleteRange(range: ApiRange, opts?: {
|
|
631
338
|
expect?: Record<string, number>;
|
|
632
339
|
}): EditResult<void>;
|
|
633
|
-
/**
|
|
634
|
-
* Tracked cross-paragraph delete. Walks each paragraph in the range:
|
|
635
|
-
* stamps `del` on the affected runs (first-block tail / intermediate
|
|
636
|
-
* full / last-block head), and on every paragraph *after the first*
|
|
637
|
-
* stamps the paragraph-mark `del` so `acceptAllRevisions` later
|
|
638
|
-
* merges them all into the first block. Single commit.
|
|
639
|
-
*/
|
|
640
|
-
private deleteRangeAcrossBlocksTracked;
|
|
641
|
-
/**
|
|
642
|
-
* Non-tracked cross-paragraph delete. Keeps the head of the first
|
|
643
|
-
* block + the tail of the last block, splices them into the first
|
|
644
|
-
* block as one paragraph, and removes everything in between.
|
|
645
|
-
*/
|
|
646
|
-
private deleteRangeAcrossBlocksPlain;
|
|
647
340
|
/**
|
|
648
341
|
* Read the current track-changes mode. Defaults to `{ enabled: false }`
|
|
649
342
|
* — the editor mutates the document plainly. See `setTrackChanges`.
|
|
@@ -663,110 +356,6 @@ export declare class Editor {
|
|
|
663
356
|
* to a toolbar pill / mode badge.
|
|
664
357
|
*/
|
|
665
358
|
setTrackChanges(state: TrackChangesState): void;
|
|
666
|
-
/**
|
|
667
|
-
* Route a tracked-mode `beforeinput` event through the typed API so
|
|
668
|
-
* the resulting runs carry revision markers. Returns `true` if the
|
|
669
|
-
* event was consumed (caller should `preventDefault`), `false` to
|
|
670
|
-
* let the browser handle it natively (untracked).
|
|
671
|
-
*
|
|
672
|
-
* **Handled inputTypes** (the 95% case — typing and deleting text):
|
|
673
|
-
*
|
|
674
|
-
* - `insertText`, `insertReplacementText` — typed characters,
|
|
675
|
-
* dictation / autocomplete replacements.
|
|
676
|
-
* - `deleteContentBackward`, `deleteContentForward` — Backspace
|
|
677
|
-
* and Delete keys, including over a selection.
|
|
678
|
-
* - `deleteWordBackward`, `deleteWordForward` — Option-Backspace
|
|
679
|
-
* style word deletions; the browser collapses to the right
|
|
680
|
-
* selection range before firing, we just delete it.
|
|
681
|
-
* - `deleteByCut` — Cmd-X. The clipboard side has already been
|
|
682
|
-
* populated by the browser; we mark the source range deleted.
|
|
683
|
-
*
|
|
684
|
-
* **Unhandled** (return `false`, fall through, warn-once):
|
|
685
|
-
*
|
|
686
|
-
* - `insertParagraph` / `insertLineBreak` — block split / soft
|
|
687
|
-
* break. Word tracks these as `<w:ins>` on the paragraph mark;
|
|
688
|
-
* the corresponding AST mutation (split-block as a tracked op)
|
|
689
|
-
* hasn't landed yet.
|
|
690
|
-
* - `insertFromPaste` — paste is handled at the `paste` event level
|
|
691
|
-
* in `onPaste` (not here), where tracked-mode plain-text paste is
|
|
692
|
-
* already routed through `insertRun` / `splitBlock`. Rich-paste
|
|
693
|
-
* (HTML) in tracked mode falls back to plain text by design.
|
|
694
|
-
* - `insertCompositionText` — handled separately via
|
|
695
|
-
* `compositionstart` / `compositionend` listeners
|
|
696
|
-
* (`handleCompositionStart` / `handleCompositionEnd`). We let the
|
|
697
|
-
* IME render natively during composition, then on end we restore
|
|
698
|
-
* the pre-composition AST and re-insert the final composed string
|
|
699
|
-
* through this `insertRun` path.
|
|
700
|
-
*
|
|
701
|
-
* Falling through means the keystroke still works (no broken UX in
|
|
702
|
-
* tracked mode), it just doesn't get a revision marker. The console
|
|
703
|
-
* warning makes the gap visible.
|
|
704
|
-
*
|
|
705
|
-
* Caret restoration: after every routed mutation we set the model
|
|
706
|
-
* selection to where the caret would have ended up on the equivalent
|
|
707
|
-
* direct-edit operation. Because tracked-mode `deleteRange` leaves
|
|
708
|
-
* the runs in place (marked `del`), offsets don't shift — caret math
|
|
709
|
-
* is straightforward.
|
|
710
|
-
*/
|
|
711
|
-
private handleTrackedInput;
|
|
712
|
-
/**
|
|
713
|
-
* Snapshot the pre-composition AST + caret so `handleCompositionEnd`
|
|
714
|
-
* can roll back the browser's native IME mutations and re-insert the
|
|
715
|
-
* final composed string through the tracked-mode `insertRun`. No-op
|
|
716
|
-
* when tracked mode is off — IME falls through to the browser as
|
|
717
|
-
* always (untracked, but functional).
|
|
718
|
-
*/
|
|
719
|
-
private handleCompositionStart;
|
|
720
|
-
/**
|
|
721
|
-
* Commit a tracked IME composition. Restores the AST to its
|
|
722
|
-
* pre-composition snapshot, re-renders, then inserts `event.data`
|
|
723
|
-
* through `insertRun` at the captured caret — so the final composed
|
|
724
|
-
* string lands as a tracked `ins` instead of as plain text from the
|
|
725
|
-
* browser's native IME commit.
|
|
726
|
-
*
|
|
727
|
-
* Bails out (and clears state) if tracked mode was toggled off
|
|
728
|
-
* mid-composition or the snapshot is missing; the browser's native
|
|
729
|
-
* commit then stands as-is (untracked, but functional).
|
|
730
|
-
*/
|
|
731
|
-
private handleCompositionEnd;
|
|
732
|
-
/**
|
|
733
|
-
* Resolve the position to insert at when the user types over the
|
|
734
|
-
* current selection. For a caret, that's the caret itself; for a
|
|
735
|
-
* range, we delete the range first (which in tracked mode marks the
|
|
736
|
-
* runs `del` but keeps them in place — so the `from` offset is still
|
|
737
|
-
* the right insertion point afterwards). Returns `null` if the
|
|
738
|
-
* selection spans blocks or the delete failed.
|
|
739
|
-
*/
|
|
740
|
-
private markedRangeForReplace;
|
|
741
|
-
/**
|
|
742
|
-
* Range a Backspace-style key should delete. Range-selection wins
|
|
743
|
-
* if there is one (just delete the selection). Otherwise step one
|
|
744
|
-
* character left of the caret — at offset 0 we have nothing to do
|
|
745
|
-
* (and Word does nothing in that position too, in v1; cross-block
|
|
746
|
-
* backspace is a follow-up).
|
|
747
|
-
*/
|
|
748
|
-
private rangeForBackwardDelete;
|
|
749
|
-
/** Forward-delete equivalent of `rangeForBackwardDelete`. */
|
|
750
|
-
private rangeForForwardDelete;
|
|
751
|
-
/** Re-lookup the block by id to get a fresh `BlockRef` (current version). */
|
|
752
|
-
private refreshedPosition;
|
|
753
|
-
/** Place the caret at `(blockId, offset)` using a fresh block ref. */
|
|
754
|
-
private placeCaret;
|
|
755
|
-
/**
|
|
756
|
-
* True when the current DOM selection's caret sits inside an `<ins>`,
|
|
757
|
-
* `<del>`, or `<span.sobree-revision-format>` wrapper — the markup
|
|
758
|
-
* the renderer emits for tracked revisions. Used by `beforeinput` in
|
|
759
|
-
* mode-off to detect when we have to take over the insert path: if
|
|
760
|
-
* we don't, the browser's contenteditable inserts the new character
|
|
761
|
-
* INSIDE the wrapper and the post-input DOM-sync stamps it with the
|
|
762
|
-
* wrapper's revision marker (an edit the user explicitly opted out
|
|
763
|
-
* of tracking).
|
|
764
|
-
*
|
|
765
|
-
* Returns `false` for a normal caret in plain text, in a `<strong>`
|
|
766
|
-
* / `<em>` / etc. — those wrappers *should* inherit (formatting),
|
|
767
|
-
* unlike revision wrappers which encode "edit history."
|
|
768
|
-
*/
|
|
769
|
-
private caretInsideRevisionWrapper;
|
|
770
359
|
/**
|
|
771
360
|
* Accept the tracked changes inside `range`: insertions become
|
|
772
361
|
* permanent (the revision marker is stripped, text kept), deletions
|
|
@@ -777,112 +366,38 @@ export declare class Editor {
|
|
|
777
366
|
acceptRevision(range: ApiRange, opts?: {
|
|
778
367
|
expect?: Record<string, number>;
|
|
779
368
|
}): EditResult<void>;
|
|
780
|
-
/**
|
|
781
|
-
* Reject the tracked changes inside `range`: insertions are removed
|
|
782
|
-
* (the inserted text is dropped), deletions are restored (the
|
|
783
|
-
* revision marker is stripped, deleted text kept). The inverse of
|
|
784
|
-
* `acceptRevision`.
|
|
785
|
-
*/
|
|
369
|
+
/** Reject the tracked changes inside `range`. Inverse of `acceptRevision`. */
|
|
786
370
|
rejectRevision(range: ApiRange, opts?: {
|
|
787
371
|
expect?: Record<string, number>;
|
|
788
372
|
}): EditResult<void>;
|
|
789
|
-
/**
|
|
790
|
-
* Accept tracked format changes inside `range`: each text run with a
|
|
791
|
-
* `revisionFormat` snapshot drops the snapshot; the current
|
|
792
|
-
* `properties` stay. Runs without one pass through.
|
|
793
|
-
*/
|
|
373
|
+
/** Accept tracked format changes inside `range` (drop the snapshot). */
|
|
794
374
|
acceptFormatRevision(range: ApiRange, opts?: {
|
|
795
375
|
expect?: Record<string, number>;
|
|
796
376
|
}): EditResult<void>;
|
|
797
|
-
/**
|
|
798
|
-
* Reject tracked format changes inside `range`: each run reverts its
|
|
799
|
-
* `properties` to `revisionFormat.before`. Inverse of
|
|
800
|
-
* `acceptFormatRevision`.
|
|
801
|
-
*/
|
|
377
|
+
/** Reject tracked format changes inside `range` (revert to `before`). */
|
|
802
378
|
rejectFormatRevision(range: ApiRange, opts?: {
|
|
803
379
|
expect?: Record<string, number>;
|
|
804
380
|
}): EditResult<void>;
|
|
805
381
|
/**
|
|
806
|
-
* Accept the paragraph-mark revision on `target`.
|
|
807
|
-
*
|
|
808
|
-
*
|
|
809
|
-
* - `ins` → strip the marker; the paragraph break stays permanent.
|
|
810
|
-
* - `del` → merge this paragraph's content into the *previous*
|
|
811
|
-
* paragraph; the paragraph break is consumed.
|
|
812
|
-
*
|
|
813
|
-
* Returns `range-empty`-coded failure if the block has no paragraph
|
|
814
|
-
* revision, and `invalid-state` if a `del` accept would require
|
|
815
|
-
* merging with a non-paragraph (table, section break) — those merges
|
|
816
|
-
* aren't well-defined yet.
|
|
382
|
+
* Accept the paragraph-mark revision on `target`. `ins` strips the
|
|
383
|
+
* marker (the break stays); `del` merges this paragraph into the
|
|
384
|
+
* previous one.
|
|
817
385
|
*/
|
|
818
386
|
acceptParagraphRevision(target: BlockRef): EditResult<void>;
|
|
819
387
|
/**
|
|
820
|
-
* Reject the paragraph-mark revision on `target`.
|
|
821
|
-
*
|
|
822
|
-
* introduced by the tracked Enter is undone).
|
|
823
|
-
* - `del` → strip the marker; the paragraph break stays.
|
|
388
|
+
* Reject the paragraph-mark revision on `target`. `ins` undoes the
|
|
389
|
+
* split (merge into previous); `del` strips the marker.
|
|
824
390
|
*/
|
|
825
391
|
rejectParagraphRevision(target: BlockRef): EditResult<void>;
|
|
826
392
|
/**
|
|
827
|
-
*
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
* paragraph-mark revisions where the decision means "this paragraph
|
|
831
|
-
* break should not exist".
|
|
832
|
-
*/
|
|
833
|
-
private mergeWithPrevious;
|
|
834
|
-
/**
|
|
835
|
-
* Strip the `revision` marker from `body[index]`'s paragraph
|
|
836
|
-
* properties, leaving the block (and its content) in place.
|
|
837
|
-
* Fallback for merge-impossible cases — see `mergeWithPrevious`'s
|
|
838
|
-
* `index <= 0` branch and `applyAllRevisions`' second pass.
|
|
839
|
-
*/
|
|
840
|
-
private stripParagraphMarker;
|
|
841
|
-
/**
|
|
842
|
-
* Flag `body[index]`'s paragraph break as a tracked deletion —
|
|
843
|
-
* stamp `properties.revision = { type: "del", author }`. Used by
|
|
844
|
-
* `handleTrackedInput` for the Backspace-at-start-of-paragraph
|
|
845
|
-
* keystroke.
|
|
846
|
-
*
|
|
847
|
-
* Two short-circuits:
|
|
848
|
-
* - If the paragraph already carries the *same author's* pending
|
|
849
|
-
* `ins` (the user is backspacing into a split they themselves
|
|
850
|
-
* just made), drop the marker and merge into the previous
|
|
851
|
-
* paragraph — cancelling an un-committed insert rather than
|
|
852
|
-
* layering del on top of ins.
|
|
853
|
-
* - If the paragraph carries some OTHER revision (peer's ins, an
|
|
854
|
-
* existing del), leave it alone with a no-op success. The
|
|
855
|
-
* reviewer should resolve those via accept/reject first.
|
|
856
|
-
*/
|
|
857
|
-
private markParagraphBreakForDelete;
|
|
858
|
-
/**
|
|
859
|
-
* Enumerate every logical tracked change in the document.
|
|
860
|
-
*
|
|
861
|
-
* Consecutive revision-bearing runs by the same author coalesce into
|
|
862
|
-
* one `RevisionSpan` — so a delete-then-insert replacement is one
|
|
863
|
-
* span, and two unrelated insertions in a paragraph (separated by
|
|
864
|
-
* plain text) are two. Each span's `range` carries fresh, versioned
|
|
865
|
-
* `BlockRef`s, ready to hand to `acceptRevision` / `rejectRevision`.
|
|
866
|
-
*
|
|
867
|
-
* Call after each `change` — the ranges are positional, so re-query
|
|
868
|
-
* rather than caching across edits.
|
|
393
|
+
* Enumerate every logical tracked change. Consecutive same-author
|
|
394
|
+
* revision runs coalesce into one `RevisionSpan` with fresh versioned
|
|
395
|
+
* refs. Re-query after each `change`.
|
|
869
396
|
*/
|
|
870
397
|
getRevisions(): RevisionSpan[];
|
|
871
398
|
/**
|
|
872
|
-
*
|
|
873
|
-
* `
|
|
874
|
-
* paragraph's own BlockRef) and for paragraphs inside table cells
|
|
875
|
-
* (where `ref` is the *containing table's* BlockRef as a sentinel —
|
|
876
|
-
* cell paragraphs don't have their own registry entry yet).
|
|
877
|
-
*
|
|
878
|
-
* Emits the same three-level span shape as the inline walker:
|
|
879
|
-
* paragraph-mark first, then coalesced inline ins/del spans, then
|
|
880
|
-
* coalesced format-change spans.
|
|
881
|
-
*/
|
|
882
|
-
private collectParagraphRevisions;
|
|
883
|
-
/**
|
|
884
|
-
* Accept every tracked change in the document. With `opts.author`,
|
|
885
|
-
* accept only that author's changes. One commit for the whole sweep.
|
|
399
|
+
* Accept every tracked change in the document (optionally filtered by
|
|
400
|
+
* `opts.author`). One commit for the whole sweep.
|
|
886
401
|
*/
|
|
887
402
|
acceptAllRevisions(opts?: {
|
|
888
403
|
author?: string;
|
|
@@ -891,21 +406,10 @@ export declare class Editor {
|
|
|
891
406
|
rejectAllRevisions(opts?: {
|
|
892
407
|
author?: string;
|
|
893
408
|
}): EditResult<void>;
|
|
894
|
-
private applyAllRevisions;
|
|
895
|
-
/**
|
|
896
|
-
* Walk a table's cell paragraphs and apply the accept/reject
|
|
897
|
-
* decision to inline + format + paragraph-mark revisions inside.
|
|
898
|
-
* Returns `{ next, changed }` so the caller knows whether to bump
|
|
899
|
-
* the table block. Paragraph-mark del within a cell falls back to
|
|
900
|
-
* strip-the-marker rather than attempting a cross-cell-paragraph
|
|
901
|
-
* merge — that structural edit is out of v1 scope for tables.
|
|
902
|
-
*/
|
|
903
|
-
private sweepTableCellRevisions;
|
|
904
409
|
/** Mark comment `id` resolved (`Comment.done = true`). */
|
|
905
410
|
resolveComment(id: number): EditResult<void>;
|
|
906
411
|
/** Re-open a resolved comment `id` (`Comment.done = false`). */
|
|
907
412
|
reopenComment(id: number): EditResult<void>;
|
|
908
|
-
private setCommentDone;
|
|
909
413
|
setBlockPropertiesAtSelection(patch: ParagraphPropertiesPatch): EditResult<void>;
|
|
910
414
|
setRunPropertiesAtSelection(patch: RunPropertiesPatch): EditResult<void>;
|
|
911
415
|
wrapSelection(tag: WrapTag): EditResult<void>;
|
|
@@ -917,8 +421,8 @@ export declare class Editor {
|
|
|
917
421
|
}): EditResult<BlockRef>;
|
|
918
422
|
/**
|
|
919
423
|
* Unwrap span ancestors intersecting the selection, up to the block.
|
|
920
|
-
* Best-effort DOM-level cleanup — preserves the
|
|
921
|
-
*
|
|
424
|
+
* Best-effort DOM-level cleanup — preserves the in-place UX without a
|
|
425
|
+
* re-render.
|
|
922
426
|
*/
|
|
923
427
|
clearInlineFormattingAtSelection(): void;
|
|
924
428
|
on<E extends EditorEvent>(event: E, cb: (p: EditorEventPayload[E]) => void): Unsubscribe;
|
|
@@ -938,12 +442,6 @@ export declare class Editor {
|
|
|
938
442
|
private blockIdsArray;
|
|
939
443
|
private checkRefs;
|
|
940
444
|
private checkRange;
|
|
941
|
-
/**
|
|
942
|
-
* Apply a runs transform to the runs covered by `range`. Returns
|
|
943
|
-
* `EditResult<void>`. Handles both single- and multi-block ranges.
|
|
944
|
-
* Assumes locks have already been checked.
|
|
945
|
-
*/
|
|
946
|
-
private mutateRunsInRange;
|
|
947
445
|
/**
|
|
948
446
|
* Apply a mutation to `this.doc`, update the registry, re-render, fire
|
|
949
447
|
* change. Returns the affected refs (post-bump).
|
|
@@ -990,27 +488,6 @@ export declare class Editor {
|
|
|
990
488
|
* driven mutations (already rendered) from remote ones (need re-render).
|
|
991
489
|
*/
|
|
992
490
|
private mirrorToYDoc;
|
|
993
|
-
/**
|
|
994
|
-
* Returns the set of part paths that mirror should NOT write
|
|
995
|
-
* inline — they're (or will soon be) tracked via the partRefs
|
|
996
|
-
* Y.Map instead. Returns `undefined` when there's nothing to skip
|
|
997
|
-
* (the common no-BlobStore case) so the mirror takes its
|
|
998
|
-
* fastest path.
|
|
999
|
-
*/
|
|
1000
|
-
private computePartPathSkipSet;
|
|
1001
|
-
/**
|
|
1002
|
-
* Background migrate inline part bytes into the BlobStore. Called
|
|
1003
|
-
* by mutators (`insertImage`, `embedFont`) when a `BlobStore` is
|
|
1004
|
-
* configured. The local `doc.rawParts` keeps its inline copy so
|
|
1005
|
-
* the renderer stays synchronous; the Y.Doc gets a `partRefs`
|
|
1006
|
-
* entry referencing the BlobStore content hash, and any stale
|
|
1007
|
-
* `parts` entry is deleted.
|
|
1008
|
-
*
|
|
1009
|
-
* Robust against errors: an upload failure logs and leaves the
|
|
1010
|
-
* path in the pending set so a future call can retry. The local
|
|
1011
|
-
* renderer is unaffected (bytes are still in `doc.rawParts`).
|
|
1012
|
-
*/
|
|
1013
|
-
private migratePartToBlobStore;
|
|
1014
491
|
/**
|
|
1015
492
|
* Compose the current selection into a {@link SelectionPayload} and
|
|
1016
493
|
* dispatch to subscribers. Called from the document-level
|
|
@@ -1018,61 +495,6 @@ export declare class Editor {
|
|
|
1018
495
|
* even when no subscribers exist (the early-return keeps it cheap).
|
|
1019
496
|
*/
|
|
1020
497
|
private fireSelection;
|
|
1021
|
-
/**
|
|
1022
|
-
* Normalise a DOM `KeyboardEvent` into a {@link KeyDownPayload} and
|
|
1023
|
-
* dispatch to subscribers in registration order. Subscribers can
|
|
1024
|
-
* `preventDefault()` (browser default) and / or `stopPropagation()`
|
|
1025
|
-
* (further subscribers). The editor itself binds no shortcuts —
|
|
1026
|
-
* everything goes through plugins.
|
|
1027
|
-
*/
|
|
1028
498
|
private fireKeyDown;
|
|
1029
|
-
private summariseBlock;
|
|
1030
|
-
private onPaste;
|
|
1031
|
-
/**
|
|
1032
|
-
* Insert `text` at the current selection in track-changes mode, with
|
|
1033
|
-
* each `\n` becoming a `splitBlock`. Used by `onPaste` for plain-text
|
|
1034
|
-
* paste; could be reused for tracked drop (a follow-up). Splits the
|
|
1035
|
-
* line list once up-front and walks it so each insertRun lands at the
|
|
1036
|
-
* caret of the *current* paragraph (which may be a fresh one from a
|
|
1037
|
-
* preceding splitBlock).
|
|
1038
|
-
*/
|
|
1039
|
-
private pasteTrackedText;
|
|
1040
|
-
private onDragOver;
|
|
1041
|
-
private onDrop;
|
|
1042
|
-
private insertImageFromFile;
|
|
1043
|
-
}
|
|
1044
|
-
/**
|
|
1045
|
-
* Read and write the caret / selection in model terms. Lives on
|
|
1046
|
-
* `editor.selection`. Wraps `window.getSelection()` so callers never
|
|
1047
|
-
* touch the DOM directly.
|
|
1048
|
-
*/
|
|
1049
|
-
export declare class EditorSelection {
|
|
1050
|
-
private readonly editor;
|
|
1051
|
-
constructor(editor: Editor);
|
|
1052
|
-
/** Current selection as a model `Selection`. Returns `null` when focus is outside. */
|
|
1053
|
-
get(): Selection;
|
|
1054
|
-
/** Apply a model selection to the DOM. */
|
|
1055
|
-
set(sel: Selection): boolean;
|
|
1056
|
-
/** Shortcut: current selection as a `Range`, or `null` when collapsed/absent. */
|
|
1057
|
-
currentRange(): ApiRange | null;
|
|
1058
|
-
/** Shortcut: the caret position (collapses a range to its `from`). */
|
|
1059
|
-
currentCaret(): InlinePosition | null;
|
|
1060
|
-
/** Shortcut: ref of the block containing the caret. */
|
|
1061
|
-
currentBlock(): BlockRef | null;
|
|
1062
|
-
/** Legacy: current block index (for code still using indices). */
|
|
1063
|
-
currentBlockIndex(): number | null;
|
|
1064
|
-
}
|
|
1065
|
-
/**
|
|
1066
|
-
* Default {@link CommandBus} implementation. Plain in-memory map; no
|
|
1067
|
-
* editor coupling beyond the closure plugins use when registering.
|
|
1068
|
-
* Replacing it would mean swapping a field on Editor — the rest of
|
|
1069
|
-
* the surface stays the same.
|
|
1070
|
-
*/
|
|
1071
|
-
export declare class EditorCommands implements CommandBus {
|
|
1072
|
-
private readonly commands;
|
|
1073
|
-
register<Args = void>(def: CommandDefinition<Args>): () => void;
|
|
1074
|
-
execute<Args = void>(name: string, args?: Args): void;
|
|
1075
|
-
list(): CommandSnapshot[];
|
|
1076
|
-
has(name: string): boolean;
|
|
1077
499
|
}
|
|
1078
500
|
export { countBlocks };
|