@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Block, ParagraphProperties, RunProperties, SectionProperties, SobreeDocument } from '../../doc/types';
|
|
2
|
-
import { ParagraphPropertiesPatch, WrapTag } from '../
|
|
2
|
+
import { ParagraphPropertiesPatch, WrapTag } from '../types';
|
|
3
3
|
import { RunPropertiesPatch } from '../../doc/runs';
|
|
4
4
|
/**
|
|
5
5
|
* One registry-level operation produced by a mutation. The caller
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { BlockRef, EditResult } from '../../doc/api';
|
|
2
|
+
import { Block } from '../../doc/types';
|
|
3
|
+
import { EditorContext } from '../context';
|
|
4
|
+
import { ParagraphPropertiesPatch } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* Block-level mutations: replace / insert / delete whole blocks and
|
|
7
|
+
* patch paragraph properties. All enforce optimistic locking via
|
|
8
|
+
* `ctx.checkRefs` and route through `ctx.commit`. Section-break removal
|
|
9
|
+
* merges the two sections it delimited. Track-changes mode stamps
|
|
10
|
+
* paragraph insert/delete markers instead of moving content outright.
|
|
11
|
+
*/
|
|
12
|
+
/** Replace the block at `target`'s index with `block`. */
|
|
13
|
+
export declare function replaceBlock(ctx: EditorContext, target: BlockRef, block: Block): EditResult<BlockRef>;
|
|
14
|
+
/**
|
|
15
|
+
* Insert `block` before the target block. Returns the new ref.
|
|
16
|
+
*
|
|
17
|
+
* In track-changes mode, if `block` is a paragraph it gets stamped with
|
|
18
|
+
* `revision: { type: "ins", author }` on its properties — the same
|
|
19
|
+
* paragraph-mark semantics as `splitBlock`. Non-paragraph blocks (table,
|
|
20
|
+
* section_break) don't carry the marker in v1 and insert plain.
|
|
21
|
+
*/
|
|
22
|
+
export declare function insertBlockBefore(ctx: EditorContext, target: BlockRef, block: Block): EditResult<BlockRef>;
|
|
23
|
+
/**
|
|
24
|
+
* Insert `block` after the target block. Returns the new ref.
|
|
25
|
+
* Tracked-mode behaviour matches `insertBlockBefore`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function insertBlockAfter(ctx: EditorContext, target: BlockRef, block: Block): EditResult<BlockRef>;
|
|
28
|
+
/**
|
|
29
|
+
* Delete the target block.
|
|
30
|
+
*
|
|
31
|
+
* In track-changes mode, paragraph blocks aren't removed — their
|
|
32
|
+
* `properties.revision` is stamped `del` (the renderer shows the
|
|
33
|
+
* paragraph mark with a strikethrough ¶ glyph; the body text stays
|
|
34
|
+
* visible). If the paragraph carries the *current author's* pending
|
|
35
|
+
* `ins` marker (a paragraph the user themselves just created), the block
|
|
36
|
+
* is removed outright — cancelling an un-committed insert, matching the
|
|
37
|
+
* inline `deleteRange` semantics. Non-paragraph blocks (tables, section
|
|
38
|
+
* breaks) bypass tracking in v1 — they remove plainly.
|
|
39
|
+
*/
|
|
40
|
+
export declare function deleteBlock(ctx: EditorContext, target: BlockRef): EditResult<void>;
|
|
41
|
+
/** Merge a patch into each target paragraph's properties. */
|
|
42
|
+
export declare function applyBlockProperties(ctx: EditorContext, targets: BlockRef[], patch: ParagraphPropertiesPatch): EditResult<void>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EditResult } from '../../doc/api';
|
|
2
|
+
import { EditorContext } from '../context';
|
|
3
|
+
/**
|
|
4
|
+
* Comment resolve/reopen — flips `Comment.done` on the document's
|
|
5
|
+
* comment map. Comments live outside the body registry, so no block
|
|
6
|
+
* version bumps are needed; the change still commits (and mirrors) so
|
|
7
|
+
* collaborators and the change event see it.
|
|
8
|
+
*/
|
|
9
|
+
/** Mark comment `id` resolved (`Comment.done = true`). */
|
|
10
|
+
export declare function resolveComment(ctx: EditorContext, id: number): EditResult<void>;
|
|
11
|
+
/** Re-open a resolved comment `id` (`Comment.done = false`). */
|
|
12
|
+
export declare function reopenComment(ctx: EditorContext, id: number): EditResult<void>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { SobreeDocument } from '../../doc/types';
|
|
2
|
+
import { EmbedFontFaces, EmbedFontOptions } from '../../fonts';
|
|
3
|
+
import { EditorContext } from '../context';
|
|
4
|
+
/**
|
|
5
|
+
* Binary-part lifecycle: font embedding, orphan pruning, and the
|
|
6
|
+
* content-blob (`BlobStore`) migration path. When a `BlobStore` is
|
|
7
|
+
* configured, inline part bytes are mirrored to the store by content
|
|
8
|
+
* hash and referenced via `partRefs` instead of living inline in the
|
|
9
|
+
* Y.Doc; `resolveCachedPartRefsInto` / `onBlobResolved` patch bytes
|
|
10
|
+
* back into `doc.rawParts` as they arrive so the renderer stays
|
|
11
|
+
* synchronous. With no `BlobStore` (the default) the migration paths are
|
|
12
|
+
* no-ops and bytes are always inline.
|
|
13
|
+
*/
|
|
14
|
+
/** Patch any cached blob bytes for known partRefs into `doc.rawParts`. */
|
|
15
|
+
export declare function resolveCachedPartRefsInto(ctx: EditorContext, doc: SobreeDocument): void;
|
|
16
|
+
/**
|
|
17
|
+
* Callback fired by the BlobCache when a background fetch lands. Walks
|
|
18
|
+
* `lastPartRefs` to find which paths reference this hash, patches
|
|
19
|
+
* `doc.rawParts`, and re-renders so the user sees the part appear.
|
|
20
|
+
*/
|
|
21
|
+
export declare function onBlobResolved(ctx: EditorContext, hash: string): void;
|
|
22
|
+
/**
|
|
23
|
+
* Wait for every currently-referenced binary part to be available in
|
|
24
|
+
* the local cache. Useful before `toDocx()` so the exported file
|
|
25
|
+
* contains all images / fonts. Resolves immediately when no `blobStore`
|
|
26
|
+
* is configured (bytes are always inline).
|
|
27
|
+
*/
|
|
28
|
+
export declare function ensurePartsLoaded(ctx: EditorContext): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Drop entries from `rawParts` that nothing in the AST references.
|
|
31
|
+
* Idempotent; reports the keys removed. Not auto-invoked — `exportDocx`
|
|
32
|
+
* filters at packaging time, so callers only need this when keeping the
|
|
33
|
+
* doc in-memory across many edits.
|
|
34
|
+
*/
|
|
35
|
+
export declare function pruneUnusedParts(ctx: EditorContext): {
|
|
36
|
+
kept: number;
|
|
37
|
+
pruned: string[];
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Embed a TTF/OTF font into the document. Thin wrapper around
|
|
41
|
+
* `embedFontIntoDoc()` — handles the `setDocument` round so the renderer
|
|
42
|
+
* + `@font-face` registry pick up the new face, and migrates the added
|
|
43
|
+
* part bytes to the BlobStore when one is configured. Refuses (with a
|
|
44
|
+
* warning) restricted fonts unless `opts.allowRestricted`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function embedFont(ctx: EditorContext, name: string, faces: EmbedFontFaces, opts?: EmbedFontOptions): {
|
|
47
|
+
warnings: string[];
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Drop a font declaration by name. The associated font parts aren't
|
|
51
|
+
* removed immediately — call `pruneUnusedParts()` (or export) to GC them.
|
|
52
|
+
*/
|
|
53
|
+
export declare function removeEmbeddedFont(ctx: EditorContext, name: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Part paths the Y.Doc mirror must NOT write inline — they're (or will
|
|
56
|
+
* soon be) tracked via `partRefs` instead. Returns `undefined` when
|
|
57
|
+
* there's nothing to skip (the common no-BlobStore case) so the mirror
|
|
58
|
+
* takes its fastest path.
|
|
59
|
+
*/
|
|
60
|
+
export declare function computePartPathSkipSet(ctx: EditorContext): ReadonlySet<string> | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Background-migrate inline part bytes into the BlobStore. Called by
|
|
63
|
+
* mutators (`insertImage`, `embedFont`) when a `BlobStore` is configured.
|
|
64
|
+
* The local `doc.rawParts` keeps its inline copy so the renderer stays
|
|
65
|
+
* synchronous; the Y.Doc gets a `partRefs` entry referencing the
|
|
66
|
+
* content hash and any stale `parts` entry is deleted.
|
|
67
|
+
*
|
|
68
|
+
* Robust against errors: an upload failure logs and leaves the path in
|
|
69
|
+
* the pending set so a future call can retry.
|
|
70
|
+
*/
|
|
71
|
+
export declare function migratePartToBlobStore(ctx: EditorContext, partPath: string, bytes: Uint8Array): Promise<void>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Range as ApiRange, BlockRef, EditResult } from '../../doc/api';
|
|
2
|
+
import { EditorContext } from '../context';
|
|
3
|
+
import { RevisionSpan } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Tracked-change review: accept/reject of inline, format, and
|
|
6
|
+
* paragraph-mark revisions (single-range, paragraph-level, or
|
|
7
|
+
* whole-document), plus `getRevisions` which enumerates every logical
|
|
8
|
+
* change as coalesced `RevisionSpan`s. The run-level decisions reuse the
|
|
9
|
+
* pure transforms in `revisionRuns`; the engine is `mutateRunsInRange`
|
|
10
|
+
* (shared with the authoring path in `ops/runs`).
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Accept the tracked changes inside `range`: insertions become permanent
|
|
14
|
+
* (marker stripped, text kept), deletions are applied (text dropped).
|
|
15
|
+
* Runs with no revision pass through, so a slightly-wider range is safe.
|
|
16
|
+
*/
|
|
17
|
+
export declare function acceptRevision(ctx: EditorContext, range: ApiRange, opts?: {
|
|
18
|
+
expect?: Record<string, number>;
|
|
19
|
+
}): EditResult<void>;
|
|
20
|
+
/** Reject the tracked changes inside `range`. Inverse of `acceptRevision`. */
|
|
21
|
+
export declare function rejectRevision(ctx: EditorContext, range: ApiRange, opts?: {
|
|
22
|
+
expect?: Record<string, number>;
|
|
23
|
+
}): EditResult<void>;
|
|
24
|
+
/** Accept tracked format changes inside `range` (drop the snapshot). */
|
|
25
|
+
export declare function acceptFormatRevision(ctx: EditorContext, range: ApiRange, opts?: {
|
|
26
|
+
expect?: Record<string, number>;
|
|
27
|
+
}): EditResult<void>;
|
|
28
|
+
/** Reject tracked format changes inside `range` (revert to `before`). */
|
|
29
|
+
export declare function rejectFormatRevision(ctx: EditorContext, range: ApiRange, opts?: {
|
|
30
|
+
expect?: Record<string, number>;
|
|
31
|
+
}): EditResult<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Accept the paragraph-mark revision on `target`:
|
|
34
|
+
* - `ins` → strip the marker; the paragraph break stays permanent.
|
|
35
|
+
* - `del` → merge this paragraph's content into the *previous* one.
|
|
36
|
+
*/
|
|
37
|
+
export declare function acceptParagraphRevision(ctx: EditorContext, target: BlockRef): EditResult<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Reject the paragraph-mark revision on `target`:
|
|
40
|
+
* - `ins` → merge this paragraph into the *previous* (undo the split).
|
|
41
|
+
* - `del` → strip the marker; the paragraph break stays.
|
|
42
|
+
*/
|
|
43
|
+
export declare function rejectParagraphRevision(ctx: EditorContext, target: BlockRef): EditResult<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Flag `body[index]`'s paragraph break as a tracked deletion. Used by
|
|
46
|
+
* the Backspace-at-start-of-paragraph keystroke. Cancels the author's
|
|
47
|
+
* own pending `ins` by merging instead; leaves peer revisions alone.
|
|
48
|
+
*/
|
|
49
|
+
export declare function markParagraphBreakForDelete(ctx: EditorContext, index: number): EditResult<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Enumerate every logical tracked change. Consecutive revision-bearing
|
|
52
|
+
* runs by the same author coalesce into one `RevisionSpan`; each span
|
|
53
|
+
* carries fresh versioned refs ready for accept/reject. Re-query after
|
|
54
|
+
* each `change` — the ranges are positional.
|
|
55
|
+
*/
|
|
56
|
+
export declare function getRevisions(ctx: EditorContext): RevisionSpan[];
|
|
57
|
+
/**
|
|
58
|
+
* Accept every tracked change (optionally filtered by author). One
|
|
59
|
+
* commit for the whole sweep.
|
|
60
|
+
*/
|
|
61
|
+
export declare function acceptAllRevisions(ctx: EditorContext, opts?: {
|
|
62
|
+
author?: string;
|
|
63
|
+
}): EditResult<void>;
|
|
64
|
+
/** Reject every tracked change (optionally filtered by author). */
|
|
65
|
+
export declare function rejectAllRevisions(ctx: EditorContext, opts?: {
|
|
66
|
+
author?: string;
|
|
67
|
+
}): EditResult<void>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Range as ApiRange, BlockRef, EditResult, InlinePosition } from '../../doc/api';
|
|
2
|
+
import { RunPropertiesPatch } from '../../doc/runs';
|
|
3
|
+
import { InlineRun } from '../../doc/types';
|
|
4
|
+
import { EditorContext } from '../context';
|
|
5
|
+
import { WrapTag } from '../types';
|
|
6
|
+
/**
|
|
7
|
+
* Inline (run-level) mutations — run properties, wrapping, run/image
|
|
8
|
+
* insertion, paragraph split, and range deletion — plus the image
|
|
9
|
+
* clipboard/drag handlers. `mutateRunsInRange` is the shared engine that
|
|
10
|
+
* applies a run transform to the slice a range covers (single- or
|
|
11
|
+
* multi-block); it's exported because the review module reuses it for
|
|
12
|
+
* accept/reject. Track-changes mode stamps `ins`/`del`/`revisionFormat`
|
|
13
|
+
* markers instead of mutating text outright.
|
|
14
|
+
*/
|
|
15
|
+
/** Apply run-level properties across `range`. */
|
|
16
|
+
export declare function applyRunProperties(ctx: EditorContext, range: ApiRange, patch: RunPropertiesPatch, opts?: {
|
|
17
|
+
expect?: Record<string, number>;
|
|
18
|
+
}): EditResult<void>;
|
|
19
|
+
/** Wrap the runs in `range` with semantic formatting. */
|
|
20
|
+
export declare function wrapRange(ctx: EditorContext, range: ApiRange, tag: WrapTag, opts?: {
|
|
21
|
+
expect?: Record<string, number>;
|
|
22
|
+
}): EditResult<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Insert a run at `at`. Splits the run list at the offset. In
|
|
25
|
+
* track-changes mode the run is stamped `revision: ins` (unless it
|
|
26
|
+
* already carries one — caller-provided revisions win).
|
|
27
|
+
*/
|
|
28
|
+
export declare function insertRun(ctx: EditorContext, at: InlinePosition, run: InlineRun): EditResult<BlockRef>;
|
|
29
|
+
/**
|
|
30
|
+
* Split a paragraph at `at`. Runs before the offset stay; runs after
|
|
31
|
+
* move into a fresh paragraph inserted immediately after, inheriting the
|
|
32
|
+
* original's properties. In track-changes mode the new paragraph's
|
|
33
|
+
* `properties.revision` is stamped `ins` (the "this break is a tracked
|
|
34
|
+
* insert" marker). Returns the ref of the *new* (second) block.
|
|
35
|
+
*/
|
|
36
|
+
export declare function splitBlock(ctx: EditorContext, at: InlinePosition): EditResult<BlockRef>;
|
|
37
|
+
/**
|
|
38
|
+
* Insert an image at `at`. Bytes go into `doc.rawParts` under a fresh
|
|
39
|
+
* `word/media/imageN.{ext}` path; a `DrawingRun` referencing it is
|
|
40
|
+
* inserted. When a `blobStore` is configured the bytes migrate in the
|
|
41
|
+
* background (hashed + uploaded + `partRefs` entry); the local renderer
|
|
42
|
+
* keeps reading the inline bytes throughout.
|
|
43
|
+
*/
|
|
44
|
+
export declare function insertImage(ctx: EditorContext, at: InlinePosition, bytes: Uint8Array, opts: {
|
|
45
|
+
mime: string;
|
|
46
|
+
widthPx?: number;
|
|
47
|
+
heightPx?: number;
|
|
48
|
+
altText?: string;
|
|
49
|
+
}): EditResult<BlockRef>;
|
|
50
|
+
/**
|
|
51
|
+
* Delete the content inside `range` (single- or cross-block). In
|
|
52
|
+
* track-changes mode the deletion is *recorded*: plain runs are stamped
|
|
53
|
+
* `del`, a run already marked as the same author's pending `ins` is
|
|
54
|
+
* dropped (cancelling an un-committed insert), peer revisions are left
|
|
55
|
+
* for accept/reject. Cross-paragraph tracked deletes also stamp each
|
|
56
|
+
* later paragraph-mark `del` so `acceptAllRevisions` collapses the range.
|
|
57
|
+
*/
|
|
58
|
+
export declare function deleteRange(ctx: EditorContext, range: ApiRange, opts?: {
|
|
59
|
+
expect?: Record<string, number>;
|
|
60
|
+
}): EditResult<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Apply a runs transform to the runs covered by `range`. Handles single-
|
|
63
|
+
* and multi-block ranges. Assumes locks have already been checked.
|
|
64
|
+
* Exported for reuse by the review (accept/reject) module.
|
|
65
|
+
*/
|
|
66
|
+
export declare function mutateRunsInRange(ctx: EditorContext, range: ApiRange, transform: (runs: InlineRun[]) => InlineRun[]): EditResult<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Unwrap span ancestors intersecting the selection, up to the block.
|
|
69
|
+
* Best-effort DOM-level cleanup — preserves the in-place UX without a
|
|
70
|
+
* re-render.
|
|
71
|
+
*/
|
|
72
|
+
export declare function clearInlineFormattingAtSelection(ctx: EditorContext): void;
|
|
73
|
+
/** Insert an image at the current caret. */
|
|
74
|
+
export declare function insertImageAtSelection(ctx: EditorContext, bytes: Uint8Array, opts: {
|
|
75
|
+
mime: string;
|
|
76
|
+
widthPx?: number;
|
|
77
|
+
heightPx?: number;
|
|
78
|
+
altText?: string;
|
|
79
|
+
}): EditResult<BlockRef>;
|
|
80
|
+
/** Read a File's bytes + intrinsic dimensions and insert it at the caret. */
|
|
81
|
+
export declare function insertImageFromFile(ctx: EditorContext, file: File): Promise<void>;
|
|
82
|
+
export declare function onDragOver(_ctx: EditorContext, e: DragEvent): void;
|
|
83
|
+
export declare function onDrop(ctx: EditorContext, e: DragEvent): Promise<void>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { EditorContext } from '../context';
|
|
2
|
+
/**
|
|
3
|
+
* Track-changes *authoring* input — the DOM event handlers that route
|
|
4
|
+
* tracked-mode keystrokes, IME composition, and paste through the typed
|
|
5
|
+
* API so the resulting runs carry revision markers. Stateful (it holds
|
|
6
|
+
* the IME composition snapshot + a warn-once set), so it's built once per
|
|
7
|
+
* editor via {@link createTrackedInput} rather than exposed as free
|
|
8
|
+
* functions like the other `ops/*` modules.
|
|
9
|
+
*
|
|
10
|
+
* Collaborators: `ops/runs` (insertRun / splitBlock / deleteRange /
|
|
11
|
+
* insertImageFromFile), `ops/review` (markParagraphBreakForDelete for the
|
|
12
|
+
* Backspace-at-start-of-paragraph merge), `query` (caret placement +
|
|
13
|
+
* position refresh), and the kernel `restoreSnapshot` for the IME
|
|
14
|
+
* rollback. The mode *config* (`getTrackChanges` / `setTrackChanges`)
|
|
15
|
+
* stays on the Editor — it only touches the listener registry.
|
|
16
|
+
*/
|
|
17
|
+
export interface TrackedInput {
|
|
18
|
+
/**
|
|
19
|
+
* Route a tracked-mode `beforeinput` through the typed API. Returns
|
|
20
|
+
* `true` if consumed (caller should `preventDefault`), `false` to let
|
|
21
|
+
* the browser handle it natively (untracked).
|
|
22
|
+
*/
|
|
23
|
+
handleBeforeInput(ie: InputEvent): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* True when the caret sits in a block containing any revision wrapper
|
|
26
|
+
* (`<ins>` / `<del>` / `.sobree-revision-format`). `beforeinput` uses
|
|
27
|
+
* this in mode-OFF to take over the insert path so the browser doesn't
|
|
28
|
+
* stamp the new character with the wrapper's marker.
|
|
29
|
+
*/
|
|
30
|
+
caretInsideRevisionWrapper(): boolean;
|
|
31
|
+
handleCompositionStart(e: CompositionEvent): void;
|
|
32
|
+
handleCompositionEnd(e: CompositionEvent): void;
|
|
33
|
+
onPaste(e: ClipboardEvent): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Insert `text` at the current selection as a tracked paste — each
|
|
36
|
+
* `\n` becomes a `splitBlock`, CRLF/CR normalised to LF. The plain-text
|
|
37
|
+
* core of `onPaste`, exposed directly because jsdom provides no
|
|
38
|
+
* `DataTransfer` to drive `onPaste` end-to-end in tests.
|
|
39
|
+
*/
|
|
40
|
+
pasteTrackedText(text: string): void;
|
|
41
|
+
/** Clear any in-flight composition state (called on editor destroy). */
|
|
42
|
+
reset(): void;
|
|
43
|
+
}
|
|
44
|
+
export declare function createTrackedInput(ctx: EditorContext): TrackedInput;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { InlinePosition } from '../doc/api';
|
|
2
|
+
import { Block } from '../doc/types';
|
|
3
|
+
import { EditorContext } from './context';
|
|
4
|
+
import { BlockInfo, OutlineItem } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Read-only projections of the document — block summaries, the heading
|
|
7
|
+
* outline, an HTML snapshot — plus the two position helpers
|
|
8
|
+
* (`placeCaret` / `refreshedPosition`) that resolve a block id to a live
|
|
9
|
+
* ref. All pull through `ctx.ensureCurrent()` so a pending DOM edit is
|
|
10
|
+
* folded in before the read. No mutation, no commit.
|
|
11
|
+
*/
|
|
12
|
+
export declare function toHtml(ctx: EditorContext): string;
|
|
13
|
+
export declare function getBlocks(ctx: EditorContext): BlockInfo[];
|
|
14
|
+
export declare function getBlock(ctx: EditorContext, index: number): BlockInfo;
|
|
15
|
+
/** Same summary, looked up by stable id. Returns `null` if unknown. */
|
|
16
|
+
export declare function getBlockById(ctx: EditorContext, id: string): BlockInfo | null;
|
|
17
|
+
export declare function getOutline(ctx: EditorContext): OutlineItem[];
|
|
18
|
+
export declare function summariseBlock(ctx: EditorContext, block: Block, index: number): BlockInfo;
|
|
19
|
+
/** Refresh a position's block ref to the live version (id stays stable). */
|
|
20
|
+
export declare function refreshedPosition(ctx: EditorContext, at: InlinePosition): InlinePosition | null;
|
|
21
|
+
/** Place the caret at `(blockId, offset)` using a fresh block ref. */
|
|
22
|
+
export declare function placeCaret(ctx: EditorContext, blockId: string, offset: number): void;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { InlineRun } from '../doc/types';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve one run against an accept/reject decision on its tracked
|
|
4
|
+
* change. Returns the replacement run list — `[run]` unchanged,
|
|
5
|
+
* `[stripped]` to keep the text minus the revision marker, or `[]` to
|
|
6
|
+
* drop the run entirely.
|
|
7
|
+
*
|
|
8
|
+
* accept + ins → keep text, strip marker (insertion confirmed)
|
|
9
|
+
* accept + del → drop run (deletion applied)
|
|
10
|
+
* reject + ins → drop run (insertion undone)
|
|
11
|
+
* reject + del → keep text, strip marker (deletion undone)
|
|
12
|
+
*
|
|
13
|
+
* Non-text runs and runs with no `revision` pass through untouched.
|
|
14
|
+
*/
|
|
15
|
+
export declare function decideRevisionRun(run: InlineRun, decision: "accept" | "reject"): InlineRun[];
|
|
16
|
+
/**
|
|
17
|
+
* Authoring helper for `insertRun` in track-changes mode. Stamps an
|
|
18
|
+
* `ins` revision on the run if it doesn't already carry one — a caller
|
|
19
|
+
* providing a pre-stamped run (e.g. an import code path replaying a
|
|
20
|
+
* revision) wins. Mirrors `decideRevisionRun`'s text-only contract:
|
|
21
|
+
* non-text runs (drawings, breaks, tabs, …) pass through unchanged in
|
|
22
|
+
* v1 — Word does track drawing inserts as revisions, but layering that
|
|
23
|
+
* on the non-uniform `properties` shape of non-text runs is a follow-up.
|
|
24
|
+
*/
|
|
25
|
+
export declare function stampInsertRevision(run: InlineRun, author: string | undefined): InlineRun;
|
|
26
|
+
/**
|
|
27
|
+
* Consumption helper for `acceptFormatRevision` / `rejectFormatRevision`.
|
|
28
|
+
*
|
|
29
|
+
* accept → drop `revisionFormat`; current `properties` stay.
|
|
30
|
+
* reject → restore `properties` to `revisionFormat.before`; the
|
|
31
|
+
* snapshot is then dropped too (the run is back to its
|
|
32
|
+
* pre-tracking state and there's nothing to undo).
|
|
33
|
+
*
|
|
34
|
+
* Runs without a `revisionFormat` snapshot pass through unchanged.
|
|
35
|
+
*/
|
|
36
|
+
export declare function decideFormatRun(run: InlineRun, decision: "accept" | "reject"): InlineRun;
|
|
37
|
+
/**
|
|
38
|
+
* Authoring helper for `applyRunProperties` in track-changes mode.
|
|
39
|
+
* Captures the run's current `properties` (excluding any existing
|
|
40
|
+
* `revisionFormat` so the snapshot stays self-contained) as
|
|
41
|
+
* `revisionFormat.before` if no snapshot is already in place.
|
|
42
|
+
* Subsequent tracked format edits skip re-snapshotting — the *original*
|
|
43
|
+
* pre-tracking state always wins on reject.
|
|
44
|
+
*/
|
|
45
|
+
export declare function snapshotFormatRevision(run: InlineRun, author: string | undefined): InlineRun;
|
|
46
|
+
/**
|
|
47
|
+
* Authoring helper for `deleteRange` in track-changes mode. Per the
|
|
48
|
+
* `TrackChangesState` semantics, applied per text run in range:
|
|
49
|
+
* - plain run (no revision) → stamp `del`
|
|
50
|
+
* - already-pending `ins` by same author → drop the run (cancel)
|
|
51
|
+
* - everything else (peer revision, peer
|
|
52
|
+
* `del`, anything pre-marked) → leave untouched
|
|
53
|
+
* Non-text runs pass through unchanged (same text-only contract as
|
|
54
|
+
* `stampInsertRevision`).
|
|
55
|
+
*/
|
|
56
|
+
export declare function stampDeleteRevision(run: InlineRun, author: string | undefined): InlineRun[];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Range as ApiRange, BlockRef, InlinePosition, Selection } from '../doc/api';
|
|
2
|
+
import { BlockRegistry } from './internal/blockRegistry';
|
|
3
|
+
/**
|
|
4
|
+
* The slice of Editor internals `EditorSelection` reads — its
|
|
5
|
+
* decoupling seam, so this module doesn't import the concrete `Editor`
|
|
6
|
+
* class (which would re-introduce an import cycle). The `Editor`
|
|
7
|
+
* structurally satisfies it via its `_hosts()` / `_registry()`
|
|
8
|
+
* accessors.
|
|
9
|
+
*/
|
|
10
|
+
export interface SelectionHost {
|
|
11
|
+
_hosts(): HTMLElement[];
|
|
12
|
+
_registry(): BlockRegistry;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Model-level view of the editor's live DOM selection. `editor.selection`
|
|
16
|
+
* is an instance of this; it translates between the browser selection
|
|
17
|
+
* and Sobree's `Selection` / `Range` / `InlinePosition` shapes.
|
|
18
|
+
*/
|
|
19
|
+
export declare class EditorSelection {
|
|
20
|
+
private readonly editor;
|
|
21
|
+
constructor(editor: SelectionHost);
|
|
22
|
+
/** Current selection as a model `Selection`. Returns `null` when focus is outside. */
|
|
23
|
+
get(): Selection;
|
|
24
|
+
/** Apply a model selection to the DOM. */
|
|
25
|
+
set(sel: Selection): boolean;
|
|
26
|
+
/** Shortcut: current selection as a `Range`, or `null` when collapsed/absent. */
|
|
27
|
+
currentRange(): ApiRange | null;
|
|
28
|
+
/** Shortcut: the caret position (collapses a range to its `from`). */
|
|
29
|
+
currentCaret(): InlinePosition | null;
|
|
30
|
+
/** Shortcut: ref of the block containing the caret. */
|
|
31
|
+
currentBlock(): BlockRef | null;
|
|
32
|
+
/** Legacy: current block index (for code still using indices). */
|
|
33
|
+
currentBlockIndex(): number | null;
|
|
34
|
+
}
|