@docx-editor.dev/core 2.30.0 → 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/automation.cjs +1 -1
- package/dist/automation.d.ts +16 -25
- package/dist/automation.js +1 -1
- package/dist/binding.cjs +1 -1
- package/dist/binding.d.ts +15 -16
- package/dist/binding.js +1 -1
- package/dist/bookmark-names-DDuAra_V.d.ts +37 -0
- package/dist/{chrome-print-BM3Js-6X.d.ts → chrome-print-BWvaVEhD.d.ts} +318 -33
- package/dist/chunk-243W4WW2.cjs +2 -0
- package/dist/{chunk-RJCQGJR7.js → chunk-2E2RPEKX.js} +1 -1
- package/dist/chunk-4S24UOPG.js +30 -0
- package/dist/chunk-5JPIEN54.cjs +3 -0
- package/dist/{chunk-KJRTNY2Q.cjs → chunk-5SO5QDMV.cjs} +1 -1
- package/dist/{chunk-WF7JZ755.cjs → chunk-6IDOVU6L.cjs} +1 -1
- package/dist/chunk-DBOOTED4.cjs +30 -0
- package/dist/chunk-EOTAXOJY.cjs +5 -0
- package/dist/chunk-FDAKJ2SJ.cjs +30 -0
- package/dist/chunk-FNNOJNGY.js +3 -0
- package/dist/chunk-FT33HRZP.js +5 -0
- package/dist/{chunk-HYASLE2G.cjs → chunk-HC6YNKUI.cjs} +1 -1
- package/dist/chunk-HZ66UCIS.js +2 -0
- package/dist/{chunk-5RRAZMBU.cjs → chunk-IBRBNT37.cjs} +1 -1
- package/dist/chunk-IVIN7X43.js +30 -0
- package/dist/chunk-LZY6B6IV.js +4 -0
- package/dist/chunk-MOYYRVFV.cjs +2 -0
- package/dist/{chunk-YZGUBCHP.js → chunk-N6B3BXCL.js} +1 -1
- package/dist/chunk-Q5K2GGNG.js +2 -0
- package/dist/chunk-R2XINWVE.js +7 -0
- package/dist/chunk-SUEXVBPR.js +1 -0
- package/dist/chunk-T2QQHG5C.js +18 -0
- package/dist/{chunk-T32MGBJS.js → chunk-VWIJKH4A.js} +1 -1
- package/dist/chunk-WO4V6PNS.cjs +18 -0
- package/dist/chunk-XMJKFURD.cjs +4 -0
- package/dist/{chunk-FLBEJC6X.cjs → chunk-XSTGE3NI.cjs} +1 -1
- package/dist/chunk-YQWMI6J5.cjs +7 -0
- package/dist/{chunk-WPDD2Y32.js → chunk-ZCJS7D7S.js} +1 -1
- package/dist/collaboration/replication.cjs +1 -1
- package/dist/collaboration/replication.d.ts +4 -5
- package/dist/collaboration/replication.js +1 -1
- package/dist/collaboration.d.ts +3 -4
- package/dist/contracts/document.d.ts +3 -3
- package/dist/contracts/editor.d.ts +8 -9
- package/dist/contracts/interaction.d.ts +2 -2
- package/dist/contracts/modules.d.ts +12 -13
- package/dist/contracts/types.d.ts +2 -2
- package/dist/{custom-node-writes-0v0Kgw1T.d.ts → custom-node-writes-TeUvMP13.d.ts} +2 -2
- package/dist/{diagnostic-context-CcAO4q1s.d.ts → diagnostic-context-DJ0P1uZE.d.ts} +3 -2
- package/dist/{diagnostic-hints-2Bke6H_w.d.ts → diagnostic-hints-C9JlLz1L.d.ts} +1 -1
- package/dist/{document-protection-8eyMWIJ0.d.ts → document-protection-C8x3P2J6.d.ts} +1 -1
- package/dist/{editor-DaEJd2so.d.ts → editor-B2ShlO23.d.ts} +292 -50
- package/dist/{editor-scope-7o9xweiJ.d.ts → editor-scope-C7ke1KJG.d.ts} +57 -4
- package/dist/editor.cjs +1 -1
- package/dist/editor.css +5 -3
- package/dist/editor.d.ts +602 -31
- package/dist/editor.js +1 -1
- package/dist/export.cjs +2 -2
- package/dist/export.d.ts +13 -14
- package/dist/export.js +2 -2
- package/dist/{font-resolver-CL9BVKZo.d.ts → font-resolver-CWh40DYp.d.ts} +1 -1
- package/dist/{headless-document-view-DZQN8Bnx.d.ts → headless-document-view-qOpaCF82.d.ts} +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +22 -23
- package/dist/index.js +1 -1
- package/dist/{layout-shaping-cEnVrhWg.d.ts → layout-shaping-CWS3j0Xr.d.ts} +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.d.ts +87 -22
- package/dist/layout.js +1 -1
- package/dist/{note-properties-9FH8zAeG.d.ts → note-properties-QsKh24sM.d.ts} +1 -1
- package/dist/{omml-equation-DP2WpUbK.d.ts → omml-equation-BsLAa2lX.d.ts} +27 -9
- package/dist/output.cjs +1 -1
- package/dist/output.d.ts +20 -10
- package/dist/output.js +1 -1
- package/dist/{protocol-CZ1uUlPO.d.ts → protocol-COZJUKUY.d.ts} +94 -2
- package/dist/{review-paragraph-order-CqVelc5A.d.ts → review-paragraph-order-C_QbCKcH.d.ts} +1 -1
- package/dist/{semantic-cell-selection-Dr9yxFZt.d.ts → semantic-cell-selection-Cub9FDa8.d.ts} +2 -2
- package/dist/{semantic-interaction-Dc3pf3hr.d.ts → semantic-interaction-dApRIYpt.d.ts} +1 -1
- package/dist/{semantic-paint-Bz3FBAoH.d.ts → semantic-paint-DLzA8sjP.d.ts} +3 -3
- package/dist/{semantic-record-queries-Bx0pl6kL.d.ts → semantic-record-queries-3yp9o11g.d.ts} +1 -1
- package/dist/{semantic-records-CjcF26ZL.d.ts → semantic-records-B-akgRch.d.ts} +130 -87
- package/dist/store.cjs +1 -1
- package/dist/store.d.ts +48 -22
- package/dist/store.js +1 -1
- package/dist/{tree-package-store-DKhdEVym.d.ts → tree-package-store-B8l8DX3Z.d.ts} +675 -645
- package/dist/{tree-session-contract-CwnTEVLF.d.ts → tree-session-contract-DeLRqohz.d.ts} +26 -13
- package/dist/{types-barrel-CA0xB8kH.d.ts → types-barrel-CkF2JbU4.d.ts} +1146 -745
- package/package.json +2 -2
- package/dist/chunk-2PV5L5NJ.js +0 -5
- package/dist/chunk-5OTS2EJ7.js +0 -7
- package/dist/chunk-5P4223J4.cjs +0 -27
- package/dist/chunk-5SPITS5F.js +0 -18
- package/dist/chunk-7ATNKARV.js +0 -2
- package/dist/chunk-BGCUTKWE.cjs +0 -5
- package/dist/chunk-EBCXSH2W.js +0 -3
- package/dist/chunk-ERECKTIR.cjs +0 -2
- package/dist/chunk-JC47NRJC.cjs +0 -3
- package/dist/chunk-NKPUH3QJ.js +0 -1
- package/dist/chunk-PF5NJWS3.js +0 -2
- package/dist/chunk-PWTRJSES.cjs +0 -18
- package/dist/chunk-QFKGI242.cjs +0 -30
- package/dist/chunk-RPPV4S6T.cjs +0 -4
- package/dist/chunk-UM26GH5B.js +0 -30
- package/dist/chunk-VRCZBFLH.js +0 -27
- package/dist/chunk-WK5X2MMA.cjs +0 -7
- package/dist/chunk-YBMWBXST.cjs +0 -2
- package/dist/chunk-ZOS2PM4A.js +0 -4
- package/dist/image-resources-Bipz8toD.d.ts +0 -211
|
@@ -1,152 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { O as OoxmlPart, ay as OoxmlInvariantIssue, N as OoxmlNode, ah as OoxmlElement, Q as OoxmlPackage, ax as RevisionAttributionInput, az as DrawingTreeDocOp, aA as OoxmlParagraphNode, aB as OoxmlNoteNode, aC as OoxmlContinuationSeparatorNode, aD as OoxmlEndnotesNode, aE as OoxmlFootnotesNode, aF as OoxmlNoteRefNode, aG as OoxmlNoteReferenceNode, aH as OoxmlSeparatorNode, aI as ImpactClass, ag as TreeDocOp, av as TreeOpRejection } from './types-barrel-CA0xB8kH.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* How saved field results are addressed.
|
|
6
|
-
*
|
|
7
|
-
* - `atomic`: every closed field is one offset unit.
|
|
8
|
-
* - `editable`: the results of CREATEDATE, DATE, FILENAME, FILLIN, HYPERLINK, MERGEFIELD,
|
|
9
|
-
* PRINTDATE, QUOTE, SAVEDATE, SEQ, and TIME fields are text when their results are unnested.
|
|
10
|
-
* Simple fields inside complex field results are not supported in this mode. Other nested
|
|
11
|
-
* results, other field types, and legacy FORMTEXT inputs keep their existing addressing.
|
|
12
|
-
*/
|
|
13
|
-
type FieldResultsMode = 'atomic' | 'editable';
|
|
14
|
-
|
|
15
|
-
/** An edited part, or the invariant violations that rejected the edit. */
|
|
16
|
-
type OoxmlEditResult = {
|
|
17
|
-
readonly ok: true;
|
|
18
|
-
readonly part: OoxmlPart;
|
|
19
|
-
} | {
|
|
20
|
-
readonly ok: false;
|
|
21
|
-
readonly issues: readonly OoxmlInvariantIssue[];
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* An opt-in relaxation of `ST_Lock` for hosts that protect WHAT a control says, not how it looks.
|
|
25
|
-
*
|
|
26
|
-
* ECMA-376 `contentLocked` forbids editing the control's contents and Word reads formatting as
|
|
27
|
-
* part of that, which is the default here. A host that puts protected text in a control (a
|
|
28
|
-
* template placeholder the user must not retype) but lets authors style it sets
|
|
29
|
-
* `allowFormattingInLockedContent`: a run-property write (bold, colour, font, size, highlight …),
|
|
30
|
-
* on runs or on a paragraph mark, then passes the CONTENT half of the lock. The exception never
|
|
31
|
-
* admits a property that hides text (`w:vanish`, `w:specVanish`, `w:webHidden`), which the
|
|
32
|
-
* run-property vocabulary refuses today anyway. Text edits, deletion of the content, paragraph properties,
|
|
33
|
-
* removal of a `sdtLocked` wrapper and `w:dataBinding` refusals are unchanged.
|
|
34
|
-
*
|
|
35
|
-
* @public
|
|
36
|
-
*/
|
|
37
|
-
interface ContentLockPolicy {
|
|
38
|
-
/** Let run formatting pass a content lock; text and removal stay refused. Default `false`. */
|
|
39
|
-
readonly allowFormattingInLockedContent?: boolean;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* How an edit primitive validates its result.
|
|
43
|
-
*
|
|
44
|
-
* By default every primitive runs the full-part invariant validation before handing its
|
|
45
|
-
* result back — the safe reading for an isolated call. A TRANSACTION applying many ops pays
|
|
46
|
-
* that full-tree walk once per primitive, which is what made a hundred-paragraph paste
|
|
47
|
-
* quadratic; it defers instead, and runs the same validation ONCE on the final tree before
|
|
48
|
-
* anything is published. Deferring is only sound for a caller that owns a commit boundary:
|
|
49
|
-
* nothing may escape between the unvalidated intermediate and the validated result.
|
|
50
|
-
*/
|
|
51
|
-
interface EditOptions {
|
|
52
|
-
readonly deferValidation?: boolean;
|
|
53
|
-
/**
|
|
54
|
-
* How a content control's `w:lock` is read for ops that only restyle text. Absent means
|
|
55
|
-
* the default: `contentLocked` / `sdtContentLocked` refuse every write, formatting included.
|
|
56
|
-
*/
|
|
57
|
-
readonly contentLockPolicy?: ContentLockPolicy;
|
|
58
|
-
/**
|
|
59
|
-
* A shared minter for `@w:id` on a NEW revision, for the ops of one transaction.
|
|
60
|
-
*
|
|
61
|
-
* `nextRevisionId` walks the whole part to find the highest id in use, and a formatting
|
|
62
|
-
* write emits one op per run — so a Select All + Bold in suggesting mode paid a
|
|
63
|
-
* document-wide walk thousands of times over. The transaction hands its ops one minter
|
|
64
|
-
* instead, and it is DROPPED the moment an op that can import foreign revision ids runs
|
|
65
|
-
* (a paste carries its own), because a stale minter would hand out an id the document had
|
|
66
|
-
* just started using — and two revisions sharing an address are one card in the pane.
|
|
67
|
-
*
|
|
68
|
-
* Absent means "mint your own": every applier falls back to its own walk, which is what a
|
|
69
|
-
* caller outside a transaction gets.
|
|
70
|
-
*/
|
|
71
|
-
readonly revisionIds?: () => string;
|
|
72
|
-
/**
|
|
73
|
-
* The transaction's revision-id bookkeeping for the tracked TEXT ops, where `revisionIds`
|
|
74
|
-
* above hands the property ops one shared id for their whole group.
|
|
75
|
-
*
|
|
76
|
-
* Absent means "mint your own and remember nothing", which is what a caller outside a
|
|
77
|
-
* transaction gets: every applier falls back to its own walk of the part.
|
|
78
|
-
*/
|
|
79
|
-
readonly trackedRevisionIds?: TransactionRevisionIds;
|
|
80
|
-
/**
|
|
81
|
-
* How the op addresses saved field results (`field-result-mode.ts`). Absent keeps the mode
|
|
82
|
-
* of the enclosing store call, which is `atomic` outside any editable transaction.
|
|
83
|
-
*/
|
|
84
|
-
readonly fieldResults?: FieldResultsMode;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* What one transaction knows about the revision ids its tracked text ops write.
|
|
88
|
-
*
|
|
89
|
-
* TWO questions, and they are the same bookkeeping. `nextRevisionId` walks the whole part, so
|
|
90
|
-
* a replacement — a `deleteText` and an `insertText` in one transaction — walked it twice, and
|
|
91
|
-
* on a five-hundred-page document that doubled the cost of every one. And an insertion aimed
|
|
92
|
-
* at the front edge of a deletion relocates past it only when that deletion is THIS
|
|
93
|
-
* transaction's own: typing over a selection. Backspace, then a keystroke, is two
|
|
94
|
-
* transactions, and there the typed text belongs in FRONT of the struck character, as Word
|
|
95
|
-
* writes it. Adjacency alone cannot tell the two apart; the ids can.
|
|
96
|
-
*/
|
|
97
|
-
interface TransactionRevisionIds {
|
|
98
|
-
/** A fresh `@w:id`, from this transaction's one walk of the part. */
|
|
99
|
-
mint(): string;
|
|
100
|
-
/**
|
|
101
|
-
* Record a wrapper this transaction wrote, by its FULL `CT_TrackChange` identity — id,
|
|
102
|
-
* author and date, as `revisionKey` spells it. Not by the id alone: that number comes out
|
|
103
|
-
* of the file, nothing makes it unique, and a strike joining `w:id="3"` in one paragraph
|
|
104
|
-
* would otherwise claim an unrelated `w:id="3"` elsewhere as this edit's own.
|
|
105
|
-
*/
|
|
106
|
-
wrote(key: string): void;
|
|
107
|
-
/** Whether this transaction wrote a wrapper with that identity. */
|
|
108
|
-
wroteUnder(key: string): boolean;
|
|
109
|
-
}
|
|
110
|
-
/** Every node id currently present in the part. */
|
|
111
|
-
declare function collectNodeIds(part: OoxmlPart): Set<string>;
|
|
112
|
-
/**
|
|
113
|
-
* Mint ids for nodes an edit introduces.
|
|
114
|
-
*
|
|
115
|
-
* Deterministic and collision-checked against the whole part: a structural-path id from the
|
|
116
|
-
* original parse (`/word/document.xml#0.1.2`) and a minted one (`/word/document.xml#new:3`)
|
|
117
|
-
* can never coincide, and the counter skips anything already taken so repeated edits in one
|
|
118
|
-
* session stay unique.
|
|
119
|
-
*
|
|
120
|
-
* Allocators share reservations across edited roots and restored roots. Preview edits,
|
|
121
|
-
* detached nodes, and undo branches must not reuse an identity that collaboration retains.
|
|
122
|
-
*
|
|
123
|
-
* Checks the part's node index directly rather than copying every id into a fresh set: the
|
|
124
|
-
* copy was O(document) per op, and an allocator is created for every op.
|
|
125
|
-
*/
|
|
126
|
-
declare function createNodeIdAllocator(part: OoxmlPart, family?: 'new' | 'paste'): () => string;
|
|
127
|
-
/** Whether a node id exists in the part. */
|
|
128
|
-
declare function hasNode(part: OoxmlPart, nodeId: string): boolean;
|
|
129
|
-
/** Read a node back out of a part by id. */
|
|
130
|
-
declare function findNode(part: OoxmlPart, nodeId: string): OoxmlNode | null;
|
|
131
|
-
/** The element that holds a node, or null for the root and for unknown ids. */
|
|
132
|
-
declare function parentNodeOf(part: OoxmlPart, nodeId: string): OoxmlElement | null;
|
|
133
|
-
/** Replace one node's children wholesale. */
|
|
134
|
-
declare function replaceChildren(part: OoxmlPart, nodeId: string, children: readonly OoxmlNode[], options?: EditOptions): OoxmlEditResult;
|
|
135
|
-
/** Insert children into a node at `index` (clamped to the child list). */
|
|
136
|
-
declare function insertChildren(part: OoxmlPart, nodeId: string, index: number, children: readonly OoxmlNode[], options?: EditOptions): OoxmlEditResult;
|
|
137
|
-
/** Replace one node with another, keeping its position among its siblings. */
|
|
138
|
-
declare function replaceNode(part: OoxmlPart, nodeId: string, replacement: OoxmlNode, options?: EditOptions): OoxmlEditResult;
|
|
139
|
-
/** Remove a node and its subtree. */
|
|
140
|
-
declare function removeNode(part: OoxmlPart, nodeId: string, options?: EditOptions): OoxmlEditResult;
|
|
141
|
-
/**
|
|
142
|
-
* Apply several primitives as ONE atomic step.
|
|
143
|
-
*
|
|
144
|
-
* Each edit runs against the result of the previous one, and the whole sequence is
|
|
145
|
-
* validated once at the end. If any step fails, the ORIGINAL part is what the caller keeps
|
|
146
|
-
* — there is no partially-edited intermediate to publish. This is the shape a multi-`DocOp`
|
|
147
|
-
* store transaction needs.
|
|
148
|
-
*/
|
|
149
|
-
declare function applyEdits(part: OoxmlPart, edits: readonly ((current: OoxmlPart) => OoxmlEditResult)[], options?: EditOptions): OoxmlEditResult;
|
|
1
|
+
import { Q as OoxmlPackage, af as SupportedImageMime, O as OoxmlPart, N as OoxmlNode, ap as OoxmlElement, aH as PackageWatermarkWrite, aI as OoxmlInvariantIssue, aE as ImageDecodePort, aG as RevisionAttributionInput, aJ as DrawingTreeDocOp, aK as ImpactClass, ao as TreeDocOp, aC as TreeOpRejection, aL as OoxmlParagraphNode, aM as OoxmlNoteNode, aN as OoxmlContinuationSeparatorNode, aO as OoxmlEndnotesNode, aP as OoxmlFootnotesNode, aQ as OoxmlNoteRefNode, aR as OoxmlNoteReferenceNode, aS as OoxmlSeparatorNode } from './types-barrel-CkF2JbU4.js';
|
|
150
2
|
|
|
151
3
|
/** A freshly allocated drawing property id, or the reason one could not be minted. */
|
|
152
4
|
type DrawingPropertyIdResult = {
|
|
@@ -210,52 +62,6 @@ interface ExternalImageFetchPort {
|
|
|
210
62
|
}>>;
|
|
211
63
|
}
|
|
212
64
|
|
|
213
|
-
interface InsertImageInput {
|
|
214
|
-
readonly paragraphId: string;
|
|
215
|
-
readonly offset: number;
|
|
216
|
-
readonly bytes: Uint8Array;
|
|
217
|
-
readonly mime: SupportedImageMime;
|
|
218
|
-
readonly widthPoints: number;
|
|
219
|
-
readonly heightPoints: number;
|
|
220
|
-
readonly decodePort: ImageDecodePort;
|
|
221
|
-
readonly expectedPackageRevision: number;
|
|
222
|
-
readonly commitGuard?: () => boolean;
|
|
223
|
-
readonly title?: string;
|
|
224
|
-
readonly description?: string;
|
|
225
|
-
readonly hyperlink?: string;
|
|
226
|
-
/** Present in suggesting mode: the inserted drawing's run goes into a `w:ins`. */
|
|
227
|
-
readonly revision?: RevisionAttributionInput;
|
|
228
|
-
/**
|
|
229
|
-
* Collaboration actor for the ids this insert mints — `wp:docPr/@id`, the image
|
|
230
|
-
* relationship, and a hyperlink relationship when one is asked for.
|
|
231
|
-
*
|
|
232
|
-
* EXPLICIT, and not the ambient `runWithTransactionActor` binding, because this entry is
|
|
233
|
-
* async: the mint runs after `await validateEmbeddedImageForCommit` and the ambient actor
|
|
234
|
-
* is synchronous-only. A wrap around the call would compile, read as correct, and be gone
|
|
235
|
-
* by the time the id is taken. Omitted (solo) keeps Word's dense `highest + 1` sequence.
|
|
236
|
-
*/
|
|
237
|
-
readonly actorId?: string;
|
|
238
|
-
}
|
|
239
|
-
interface ReplaceImageOptions {
|
|
240
|
-
readonly expectedPackageRevision: number;
|
|
241
|
-
readonly commitGuard?: () => boolean;
|
|
242
|
-
/** Collaboration actor for the replacement's minted ids. See {@link InsertImageInput.actorId}. */
|
|
243
|
-
readonly actorId?: string;
|
|
244
|
-
}
|
|
245
|
-
type ImageIntentResult = (Extract<PackageTransactResult, {
|
|
246
|
-
ok: true;
|
|
247
|
-
}> & {
|
|
248
|
-
readonly drawingNodeId?: string;
|
|
249
|
-
readonly mediaPartName?: string;
|
|
250
|
-
}) | Extract<PackageTransactResult, {
|
|
251
|
-
ok: false;
|
|
252
|
-
}>;
|
|
253
|
-
interface ApplyImagePropertiesInput {
|
|
254
|
-
readonly drawingNodeId: string;
|
|
255
|
-
readonly ops: readonly DrawingTreeDocOp[];
|
|
256
|
-
readonly hyperlink: string | null;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
65
|
/** `w:headerReference w:type` vocabulary (ECMA-376 §17.10.5): default, first page, even pages. */
|
|
260
66
|
type HeaderFooterVariant = 'default' | 'first' | 'even';
|
|
261
67
|
/** Header vs footer region kind for chrome and lifecycle ops. */
|
|
@@ -369,6 +175,13 @@ type HeaderFooterLifecycleOp = {
|
|
|
369
175
|
*/
|
|
370
176
|
readonly op: 'setDocumentProtection';
|
|
371
177
|
readonly enforce: boolean;
|
|
178
|
+
} | {
|
|
179
|
+
/**
|
|
180
|
+
* Replace the document watermark in every header a section shows; null removes it.
|
|
181
|
+
* It may create a section's default header, so it rides this lane's package undo unit.
|
|
182
|
+
*/
|
|
183
|
+
readonly op: 'setWatermark';
|
|
184
|
+
readonly watermark: PackageWatermarkWrite | null;
|
|
372
185
|
};
|
|
373
186
|
/** Why a header/footer lifecycle op was refused. */
|
|
374
187
|
type HeaderFooterLifecycleRejection = 'invalidArgs' | 'tree-invariant';
|
|
@@ -394,42 +207,600 @@ declare function isHeaderFooterLifecycleOp(op: {
|
|
|
394
207
|
*/
|
|
395
208
|
declare function applyHeaderFooterLifecycleOp(pkg: OoxmlPackage, op: HeaderFooterLifecycleOp): HeaderFooterLifecycleResult;
|
|
396
209
|
|
|
397
|
-
/** UTF-16 placeholder for one atomic note unit in `paragraphTextOf` / segments. */
|
|
398
|
-
declare const NOTE_ATOM_CHAR = "\uFFFC";
|
|
399
|
-
/** Signed 32-bit Word-compatible note id range (positive allocation only). */
|
|
400
|
-
declare const NOTE_ID_MIN = 1;
|
|
401
|
-
/** Largest note id Word accepts — signed 32-bit. */
|
|
402
|
-
declare const NOTE_ID_MAX = 2147483647;
|
|
403
|
-
/** Reserved separator / continuation ids — never allocated for normal notes. */
|
|
404
|
-
declare const NOTE_SEPARATOR_ID = -1;
|
|
405
|
-
/** Reserved id of the continuation-separator entry. Never allocated to a real note. */
|
|
406
|
-
declare const NOTE_CONTINUATION_SEPARATOR_ID = 0;
|
|
407
|
-
/** Which notes part a note lives in. Decides both placement and numbering rules. */
|
|
408
|
-
type NoteKind = 'footnote' | 'endnote';
|
|
409
|
-
/** Authored `ST_FtnEdn` including explicit `normal`. Absent means Word default (normal). */
|
|
410
210
|
/**
|
|
411
|
-
*
|
|
211
|
+
* How saved field results are addressed.
|
|
412
212
|
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
213
|
+
* - `atomic`: every closed field is one offset unit.
|
|
214
|
+
* - `editable`: the results of CREATEDATE, DATE, FILENAME, FILLIN, HYPERLINK, MERGEFIELD,
|
|
215
|
+
* PRINTDATE, QUOTE, SAVEDATE, SEQ, and TIME fields are text when their results are unnested.
|
|
216
|
+
* Simple fields inside complex field results are not supported in this mode. Other nested
|
|
217
|
+
* results, other field types, and legacy FORMTEXT inputs keep their existing addressing.
|
|
415
218
|
*/
|
|
416
|
-
type
|
|
417
|
-
|
|
418
|
-
|
|
219
|
+
type FieldResultsMode = 'atomic' | 'editable';
|
|
220
|
+
|
|
221
|
+
/** An edited part, or the invariant violations that rejected the edit. */
|
|
222
|
+
type OoxmlEditResult = {
|
|
223
|
+
readonly ok: true;
|
|
224
|
+
readonly part: OoxmlPart;
|
|
225
|
+
} | {
|
|
226
|
+
readonly ok: false;
|
|
227
|
+
readonly issues: readonly OoxmlInvariantIssue[];
|
|
228
|
+
};
|
|
419
229
|
/**
|
|
420
|
-
*
|
|
230
|
+
* An opt-in relaxation of `ST_Lock` for hosts that protect WHAT a control says, not how it looks.
|
|
421
231
|
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
232
|
+
* ECMA-376 `contentLocked` forbids editing the control's contents and Word reads formatting as
|
|
233
|
+
* part of that, which is the default here. A host that puts protected text in a control (a
|
|
234
|
+
* template placeholder the user must not retype) but lets authors style it sets
|
|
235
|
+
* `allowFormattingInLockedContent`: a run-property write (bold, colour, font, size, highlight …),
|
|
236
|
+
* on runs or on a paragraph mark, then passes the CONTENT half of the lock. The exception never
|
|
237
|
+
* admits a property that hides text (`w:vanish`, `w:specVanish`, `w:webHidden`), which the
|
|
238
|
+
* run-property vocabulary refuses today anyway. Text edits, deletion of the content, paragraph properties,
|
|
239
|
+
* removal of a `sdtLocked` wrapper and `w:dataBinding` refusals are unchanged.
|
|
240
|
+
*
|
|
241
|
+
* @public
|
|
424
242
|
*/
|
|
425
|
-
|
|
243
|
+
interface ContentLockPolicy {
|
|
244
|
+
/** Let run formatting pass a content lock; text and removal stay refused. Default `false`. */
|
|
245
|
+
readonly allowFormattingInLockedContent?: boolean;
|
|
246
|
+
}
|
|
426
247
|
/**
|
|
427
|
-
*
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
248
|
+
* How an edit primitive validates its result.
|
|
249
|
+
*
|
|
250
|
+
* By default every primitive runs the full-part invariant validation before handing its
|
|
251
|
+
* result back — the safe reading for an isolated call. A TRANSACTION applying many ops pays
|
|
252
|
+
* that full-tree walk once per primitive, which is what made a hundred-paragraph paste
|
|
253
|
+
* quadratic; it defers instead, and runs the same validation ONCE on the final tree before
|
|
254
|
+
* anything is published. Deferring is only sound for a caller that owns a commit boundary:
|
|
255
|
+
* nothing may escape between the unvalidated intermediate and the validated result.
|
|
256
|
+
*/
|
|
257
|
+
interface EditOptions {
|
|
258
|
+
readonly deferValidation?: boolean;
|
|
259
|
+
/**
|
|
260
|
+
* How a content control's `w:lock` is read for ops that only restyle text. Absent means
|
|
261
|
+
* the default: `contentLocked` / `sdtContentLocked` refuse every write, formatting included.
|
|
262
|
+
*/
|
|
263
|
+
readonly contentLockPolicy?: ContentLockPolicy;
|
|
264
|
+
/**
|
|
265
|
+
* A shared minter for `@w:id` on a NEW revision, for the ops of one transaction.
|
|
266
|
+
*
|
|
267
|
+
* `nextRevisionId` walks the whole part to find the highest id in use, and a formatting
|
|
268
|
+
* write emits one op per run — so a Select All + Bold in suggesting mode paid a
|
|
269
|
+
* document-wide walk thousands of times over. The transaction hands its ops one minter
|
|
270
|
+
* instead, and it is DROPPED the moment an op that can import foreign revision ids runs
|
|
271
|
+
* (a paste carries its own), because a stale minter would hand out an id the document had
|
|
272
|
+
* just started using — and two revisions sharing an address are one card in the pane.
|
|
273
|
+
*
|
|
274
|
+
* Absent means "mint your own": every applier falls back to its own walk, which is what a
|
|
275
|
+
* caller outside a transaction gets.
|
|
276
|
+
*/
|
|
277
|
+
readonly revisionIds?: () => string;
|
|
278
|
+
/**
|
|
279
|
+
* The transaction's revision-id bookkeeping for the tracked TEXT ops, where `revisionIds`
|
|
280
|
+
* above hands the property ops one shared id for their whole group.
|
|
281
|
+
*
|
|
282
|
+
* Absent means "mint your own and remember nothing", which is what a caller outside a
|
|
283
|
+
* transaction gets: every applier falls back to its own walk of the part.
|
|
284
|
+
*/
|
|
285
|
+
readonly trackedRevisionIds?: TransactionRevisionIds;
|
|
286
|
+
/**
|
|
287
|
+
* How the op addresses saved field results (`field-result-mode.ts`). Absent keeps the mode
|
|
288
|
+
* of the enclosing store call, which is `atomic` outside any editable transaction.
|
|
289
|
+
*/
|
|
290
|
+
readonly fieldResults?: FieldResultsMode;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* What one transaction knows about the revision ids its tracked text ops write.
|
|
294
|
+
*
|
|
295
|
+
* TWO questions, and they are the same bookkeeping. `nextRevisionId` walks the whole part, so
|
|
296
|
+
* a replacement — a `deleteText` and an `insertText` in one transaction — walked it twice, and
|
|
297
|
+
* on a five-hundred-page document that doubled the cost of every one. And an insertion aimed
|
|
298
|
+
* at the front edge of a deletion relocates past it only when that deletion is THIS
|
|
299
|
+
* transaction's own: typing over a selection. Backspace, then a keystroke, is two
|
|
300
|
+
* transactions, and there the typed text belongs in FRONT of the struck character, as Word
|
|
301
|
+
* writes it. Adjacency alone cannot tell the two apart; the ids can.
|
|
302
|
+
*/
|
|
303
|
+
interface TransactionRevisionIds {
|
|
304
|
+
/** A fresh `@w:id`, from this transaction's one walk of the part. */
|
|
305
|
+
mint(): string;
|
|
306
|
+
/**
|
|
307
|
+
* Record a wrapper this transaction wrote, by its FULL `CT_TrackChange` identity — id,
|
|
308
|
+
* author and date, as `revisionKey` spells it. Not by the id alone: that number comes out
|
|
309
|
+
* of the file, nothing makes it unique, and a strike joining `w:id="3"` in one paragraph
|
|
310
|
+
* would otherwise claim an unrelated `w:id="3"` elsewhere as this edit's own.
|
|
311
|
+
*/
|
|
312
|
+
wrote(key: string): void;
|
|
313
|
+
/** Whether this transaction wrote a wrapper with that identity. */
|
|
314
|
+
wroteUnder(key: string): boolean;
|
|
315
|
+
}
|
|
316
|
+
/** Every node id currently present in the part. */
|
|
317
|
+
declare function collectNodeIds(part: OoxmlPart): Set<string>;
|
|
318
|
+
/**
|
|
319
|
+
* Mint ids for nodes an edit introduces.
|
|
320
|
+
*
|
|
321
|
+
* Deterministic and collision-checked against the whole part: a structural-path id from the
|
|
322
|
+
* original parse (`/word/document.xml#0.1.2`) and a minted one (`/word/document.xml#new:3`)
|
|
323
|
+
* can never coincide, and the counter skips anything already taken so repeated edits in one
|
|
324
|
+
* session stay unique.
|
|
325
|
+
*
|
|
326
|
+
* Allocators share reservations across edited roots and restored roots. Preview edits,
|
|
327
|
+
* detached nodes, and undo branches must not reuse an identity that collaboration retains.
|
|
328
|
+
*
|
|
329
|
+
* Checks the part's node index directly rather than copying every id into a fresh set: the
|
|
330
|
+
* copy was O(document) per op, and an allocator is created for every op.
|
|
331
|
+
*/
|
|
332
|
+
declare function createNodeIdAllocator(part: OoxmlPart, family?: 'new' | 'paste'): () => string;
|
|
333
|
+
/** Whether a node id exists in the part. */
|
|
334
|
+
declare function hasNode(part: OoxmlPart, nodeId: string): boolean;
|
|
335
|
+
/** Read a node back out of a part by id. */
|
|
336
|
+
declare function findNode(part: OoxmlPart, nodeId: string): OoxmlNode | null;
|
|
337
|
+
/** The element that holds a node, or null for the root and for unknown ids. */
|
|
338
|
+
declare function parentNodeOf(part: OoxmlPart, nodeId: string): OoxmlElement | null;
|
|
339
|
+
/** Replace one node's children wholesale. */
|
|
340
|
+
declare function replaceChildren(part: OoxmlPart, nodeId: string, children: readonly OoxmlNode[], options?: EditOptions): OoxmlEditResult;
|
|
341
|
+
/** Insert children into a node at `index` (clamped to the child list). */
|
|
342
|
+
declare function insertChildren(part: OoxmlPart, nodeId: string, index: number, children: readonly OoxmlNode[], options?: EditOptions): OoxmlEditResult;
|
|
343
|
+
/** Replace one node with another, keeping its position among its siblings. */
|
|
344
|
+
declare function replaceNode(part: OoxmlPart, nodeId: string, replacement: OoxmlNode, options?: EditOptions): OoxmlEditResult;
|
|
345
|
+
/** Remove a node and its subtree. */
|
|
346
|
+
declare function removeNode(part: OoxmlPart, nodeId: string, options?: EditOptions): OoxmlEditResult;
|
|
347
|
+
/**
|
|
348
|
+
* Apply several primitives as ONE atomic step.
|
|
349
|
+
*
|
|
350
|
+
* Each edit runs against the result of the previous one, and the whole sequence is
|
|
351
|
+
* validated once at the end. If any step fails, the ORIGINAL part is what the caller keeps
|
|
352
|
+
* — there is no partially-edited intermediate to publish. This is the shape a multi-`DocOp`
|
|
353
|
+
* store transaction needs.
|
|
354
|
+
*/
|
|
355
|
+
declare function applyEdits(part: OoxmlPart, edits: readonly ((current: OoxmlPart) => OoxmlEditResult)[], options?: EditOptions): OoxmlEditResult;
|
|
356
|
+
|
|
357
|
+
interface InsertImageInput {
|
|
358
|
+
readonly paragraphId: string;
|
|
359
|
+
readonly offset: number;
|
|
360
|
+
readonly bytes: Uint8Array;
|
|
361
|
+
readonly mime: SupportedImageMime;
|
|
362
|
+
readonly widthPoints: number;
|
|
363
|
+
readonly heightPoints: number;
|
|
364
|
+
readonly decodePort: ImageDecodePort;
|
|
365
|
+
readonly expectedPackageRevision: number;
|
|
366
|
+
readonly commitGuard?: () => boolean;
|
|
367
|
+
readonly title?: string;
|
|
368
|
+
readonly description?: string;
|
|
369
|
+
readonly hyperlink?: string;
|
|
370
|
+
/** Present in suggesting mode: the inserted drawing's run goes into a `w:ins`. */
|
|
371
|
+
readonly revision?: RevisionAttributionInput;
|
|
372
|
+
/**
|
|
373
|
+
* Collaboration actor for the ids this insert mints — `wp:docPr/@id`, the image
|
|
374
|
+
* relationship, and a hyperlink relationship when one is asked for.
|
|
375
|
+
*
|
|
376
|
+
* EXPLICIT, and not the ambient `runWithTransactionActor` binding, because this entry is
|
|
377
|
+
* async: the mint runs after `await validateEmbeddedImageForCommit` and the ambient actor
|
|
378
|
+
* is synchronous-only. A wrap around the call would compile, read as correct, and be gone
|
|
379
|
+
* by the time the id is taken. Omitted (solo) keeps Word's dense `highest + 1` sequence.
|
|
380
|
+
*/
|
|
381
|
+
readonly actorId?: string;
|
|
382
|
+
}
|
|
383
|
+
interface ReplaceImageOptions {
|
|
384
|
+
readonly expectedPackageRevision: number;
|
|
385
|
+
readonly commitGuard?: () => boolean;
|
|
386
|
+
/** Collaboration actor for the replacement's minted ids. See {@link InsertImageInput.actorId}. */
|
|
387
|
+
readonly actorId?: string;
|
|
388
|
+
}
|
|
389
|
+
type ImageIntentResult = (Extract<PackageTransactResult, {
|
|
390
|
+
ok: true;
|
|
391
|
+
}> & {
|
|
392
|
+
readonly drawingNodeId?: string;
|
|
393
|
+
readonly mediaPartName?: string;
|
|
394
|
+
}) | Extract<PackageTransactResult, {
|
|
395
|
+
ok: false;
|
|
396
|
+
}>;
|
|
397
|
+
interface ApplyImagePropertiesInput {
|
|
398
|
+
readonly drawingNodeId: string;
|
|
399
|
+
readonly ops: readonly DrawingTreeDocOp[];
|
|
400
|
+
readonly hyperlink: string | null;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/** How one transaction behaves: its story scope, its attribution, and its selection marks. */
|
|
404
|
+
interface TransactOptions {
|
|
405
|
+
readonly origin?: string;
|
|
406
|
+
/** Stable actor attribution for collaboration and audit correlation. */
|
|
407
|
+
readonly actorId?: string;
|
|
408
|
+
/** Stable constituent identity for collaboration duplicate correlation. */
|
|
409
|
+
readonly operationId?: string;
|
|
410
|
+
/**
|
|
411
|
+
* Whether this transaction enters the legacy snapshot undo stack.
|
|
412
|
+
*
|
|
413
|
+
* Collaboration commits set this to false because their actor-local undo authority is the
|
|
414
|
+
* CRDT undo manager. Omitted preserves the ordinary non-collaborative history behavior.
|
|
415
|
+
*/
|
|
416
|
+
readonly recordsHistory?: boolean;
|
|
417
|
+
/**
|
|
418
|
+
* A COMMAND is one user intent that may need several ops (a toolbar click applying a
|
|
419
|
+
* property across a multi-run selection). It is still exactly one history entry, which is
|
|
420
|
+
* the same rule a plain transaction follows — the option exists to say so explicitly at
|
|
421
|
+
* the call site rather than leaving it implied.
|
|
422
|
+
*/
|
|
423
|
+
readonly scope?: 'transaction' | 'command';
|
|
424
|
+
/**
|
|
425
|
+
* Floor on the published impact. Header/footer story edits use `global` so every page
|
|
426
|
+
* sharing the part invalidates rather than keeping stale furniture.
|
|
427
|
+
*/
|
|
428
|
+
readonly minimumImpact?: ImpactClass;
|
|
429
|
+
/** Story identity stamped onto the published ModelChange (package-aware targeting). */
|
|
430
|
+
readonly story?: TreeStoryRef;
|
|
431
|
+
/**
|
|
432
|
+
* The gesture this transaction belongs to: consecutive transactions carrying the SAME
|
|
433
|
+
* token extend one history entry (package from before the first, selection after the
|
|
434
|
+
* latest). Another token, none, undo or redo closes the group. See {@link HistoryGroup}.
|
|
435
|
+
*/
|
|
436
|
+
readonly historyGroup?: HistoryGroup;
|
|
437
|
+
/**
|
|
438
|
+
* How the transaction's ops address saved field results. `atomic` (the default) keeps
|
|
439
|
+
* every field one offset unit; `editable` addresses saved results as text. See
|
|
440
|
+
* `field-result-mode.ts`.
|
|
441
|
+
*/
|
|
442
|
+
readonly fieldResults?: FieldResultsMode;
|
|
443
|
+
}
|
|
444
|
+
/** How a store is constructed: its limits, its history depth, and its identity source. */
|
|
445
|
+
interface TreeDocumentStoreOptions {
|
|
446
|
+
/** Bound on retained history entries. Oldest entries drop first. */
|
|
447
|
+
readonly historyLimit?: number;
|
|
448
|
+
/**
|
|
449
|
+
* The document's `settings.xml`, for a store built from a PART rather than a package.
|
|
450
|
+
*
|
|
451
|
+
* Forms protection lives one part up from the op, and a store built from a part gets a
|
|
452
|
+
* synthetic one-part package that cannot see it — so `w:documentProtection w:edit="forms"`
|
|
453
|
+
* was enforced in the body and nowhere else, and a header, a footer or a note accepted every
|
|
454
|
+
* write a protected document is supposed to refuse. Read through a getter, not captured: a
|
|
455
|
+
* document can gain or lose protection while its stories stay open.
|
|
456
|
+
*/
|
|
457
|
+
readonly settingsPart?: () => OoxmlPart | null | undefined;
|
|
458
|
+
/**
|
|
459
|
+
* Opt-in relaxation of `w:lock` for run-property writes. See {@link ContentLockPolicy};
|
|
460
|
+
* absent, `contentLocked` and `sdtContentLocked` refuse formatting like any other write.
|
|
461
|
+
*/
|
|
462
|
+
readonly contentLockPolicy?: ContentLockPolicy;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/** A selection the caller wants restored when an entry is undone or redone. */
|
|
466
|
+
/** A selection captured with a transaction, so undo restores where the caret was. */
|
|
467
|
+
interface SelectionMark {
|
|
468
|
+
readonly paragraphId: string;
|
|
469
|
+
readonly start: number;
|
|
470
|
+
readonly end: number;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Which editable story a ModelChange came from.
|
|
474
|
+
*
|
|
475
|
+
* Mirrors `EditorScope` for body and header/footer — `{ kind: 'headerFooter'; rId }` —
|
|
476
|
+
* so package-aware mutation and the public scope contract stay one vocabulary. Body
|
|
477
|
+
* commits omit `rId`; header/footer commits carry the relationship id that addressed
|
|
478
|
+
* the part. Notes parts use `{ kind: 'notesPart'; noteKind }` (one store per part).
|
|
479
|
+
*/
|
|
480
|
+
/** Which story a transaction targets: the body, a header/footer part, or a notes part. */
|
|
481
|
+
type TreeStoryRef = {
|
|
482
|
+
readonly kind: 'body';
|
|
483
|
+
readonly partName: string;
|
|
484
|
+
} | {
|
|
485
|
+
readonly kind: 'headerFooter';
|
|
486
|
+
readonly partName: string;
|
|
487
|
+
readonly rId: string;
|
|
488
|
+
} | {
|
|
489
|
+
readonly kind: 'notesPart';
|
|
490
|
+
readonly partName: string;
|
|
491
|
+
readonly noteKind: 'footnote' | 'endnote';
|
|
492
|
+
};
|
|
493
|
+
/**
|
|
494
|
+
* What one committed transaction changed: the revision, the ids touched, and the impact class.
|
|
495
|
+
*
|
|
496
|
+
* The ids are what let layout and paint re-do only the affected blocks instead of the document.
|
|
497
|
+
*/
|
|
498
|
+
interface TreeModelChange {
|
|
499
|
+
readonly change: 'model-change';
|
|
500
|
+
readonly fromRevision: number;
|
|
501
|
+
readonly toRevision: number;
|
|
502
|
+
readonly commitId: string;
|
|
503
|
+
readonly origin: string;
|
|
504
|
+
/** Stable collaboration actor attribution, when the caller supplied it. */
|
|
505
|
+
readonly actorId?: string;
|
|
506
|
+
/** Stable collaboration operation identity, when the caller supplied it. */
|
|
507
|
+
readonly operationId?: string;
|
|
508
|
+
readonly dirty: readonly string[];
|
|
509
|
+
readonly created: readonly string[];
|
|
510
|
+
readonly deleted: readonly string[];
|
|
511
|
+
readonly splitJoin: readonly ({
|
|
512
|
+
readonly split: {
|
|
513
|
+
readonly from: string;
|
|
514
|
+
readonly tail: string;
|
|
515
|
+
};
|
|
516
|
+
} | {
|
|
517
|
+
readonly join: {
|
|
518
|
+
readonly kept: string;
|
|
519
|
+
readonly removed: string;
|
|
520
|
+
};
|
|
521
|
+
})[];
|
|
522
|
+
readonly dependencyKeys: readonly string[];
|
|
523
|
+
/** The widest impact among the transaction's ops — what layout must scope to. */
|
|
524
|
+
readonly impact: ImpactClass;
|
|
525
|
+
/**
|
|
526
|
+
* Story that published this change. Absent on body-only store publishes that predate
|
|
527
|
+
* package-aware targeting; `TreePackageStore` always sets it.
|
|
528
|
+
*/
|
|
529
|
+
readonly story?: TreeStoryRef;
|
|
530
|
+
/**
|
|
531
|
+
* Committed collapsed caret for this transaction, when one exists.
|
|
532
|
+
* Matches history `selectionAfter` when that mark is collapsed; absent for explicit
|
|
533
|
+
* null, non-collapsed explicit selection, or when no caret was committed.
|
|
534
|
+
*/
|
|
535
|
+
readonly caret?: SelectionMark;
|
|
536
|
+
}
|
|
537
|
+
/** Whether a transaction committed, or the typed reason it was refused. */
|
|
538
|
+
type TransactResult = {
|
|
539
|
+
readonly ok: true;
|
|
540
|
+
readonly change: TreeModelChange | null;
|
|
541
|
+
} | {
|
|
542
|
+
readonly ok: false;
|
|
543
|
+
readonly reason: TreeOpRejection;
|
|
544
|
+
readonly detail?: string;
|
|
545
|
+
};
|
|
546
|
+
/** What a transaction body is handed: the working tree, and the means to stage ops against it. */
|
|
547
|
+
interface TransactionContext {
|
|
548
|
+
/** Stage one op against the STORY part. Returns false once the transaction has failed. */
|
|
549
|
+
apply(op: TreeDocOp): boolean;
|
|
550
|
+
/**
|
|
551
|
+
* Stage one op against a named part.
|
|
552
|
+
*
|
|
553
|
+
* A comment body lives in `comments.xml` and is edited by the same ops that edit the story,
|
|
554
|
+
* so this is `apply` with the target named rather than a second vocabulary.
|
|
555
|
+
*/
|
|
556
|
+
applyTo(partName: string, op: TreeDocOp): boolean;
|
|
557
|
+
/**
|
|
558
|
+
* Stage a whole-package edit: a new part, a relationship, a content-type override.
|
|
559
|
+
*
|
|
560
|
+
* The edit is a pure function of the working package, so a rejected transaction discards it
|
|
561
|
+
* with everything else. Returning the SAME package is a no-op, not a failure — a primitive
|
|
562
|
+
* that finds nothing to do says so that way.
|
|
563
|
+
*
|
|
564
|
+
* Engine package edits refuse by throwing the internal `PackageEditRefusal`
|
|
565
|
+
* (`package-edit-refusal.ts`): the transaction is refused with its reason, `package-changed`
|
|
566
|
+
* by default, and nothing is applied. Any other throw escapes `transact` as a crash.
|
|
567
|
+
*/
|
|
568
|
+
applyPackage(edit: (pkg: OoxmlPackage) => OoxmlPackage): boolean;
|
|
569
|
+
/** The selection to restore when this entry is undone. */
|
|
570
|
+
selectionBefore(selection: SelectionMark | null): void;
|
|
571
|
+
/** The selection to restore when this entry is redone. */
|
|
572
|
+
selectionAfter(selection: SelectionMark | null): void;
|
|
573
|
+
}
|
|
574
|
+
interface HistoryEntry {
|
|
575
|
+
/**
|
|
576
|
+
* The whole package as it was, not just the story part.
|
|
577
|
+
*
|
|
578
|
+
* Affordable for the same reason a part snapshot was: parts are immutable and deep-frozen, so
|
|
579
|
+
* a package snapshot is a Map of references and every part the transaction did not touch is
|
|
580
|
+
* object-identical to the one before it. Undo stays a pointer swap, and it now reverses every
|
|
581
|
+
* part one intent wrote rather than only the story.
|
|
582
|
+
*/
|
|
583
|
+
readonly pkg: OoxmlPackage;
|
|
584
|
+
readonly revision: number;
|
|
585
|
+
readonly selectionBefore: SelectionMark | null;
|
|
586
|
+
readonly selectionAfter: SelectionMark | null;
|
|
587
|
+
/**
|
|
588
|
+
* The gesture this entry is still collecting, while it is the newest entry and nothing
|
|
589
|
+
* has closed it. Only ever set on the top of the undo stack: {@link closeHistoryGroup}
|
|
590
|
+
* strips it, and undo and redo never copy it onto the entries they push.
|
|
591
|
+
*/
|
|
592
|
+
readonly group?: HistoryGroup;
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Opaque document+history checkpoint for package-coordinator rollback.
|
|
596
|
+
* Used when a story mutation may promote to a package undo unit (note-ref cascade).
|
|
597
|
+
*/
|
|
598
|
+
/** A restorable point in history — one entry of the intent-scoped undo stack. */
|
|
599
|
+
interface TreeDocumentCheckpoint {
|
|
600
|
+
/**
|
|
601
|
+
* The whole package, not one part. The store owns the package so a transaction spanning
|
|
602
|
+
* several parts is one publication — a checkpoint of only the story part could not roll
|
|
603
|
+
* back the comment or numbering part the same transaction wrote.
|
|
604
|
+
*/
|
|
605
|
+
readonly pkg: OoxmlPackage;
|
|
606
|
+
readonly revision: number;
|
|
607
|
+
readonly undoStack: readonly HistoryEntry[];
|
|
608
|
+
readonly redoStack: readonly HistoryEntry[];
|
|
609
|
+
readonly composition: {
|
|
610
|
+
readonly entry: HistoryEntry;
|
|
611
|
+
readonly committed: boolean;
|
|
612
|
+
} | null;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* The document store: one transaction is one atomic publication and one history entry.
|
|
616
|
+
*
|
|
617
|
+
* `apply` STAGES ops against a working part and nothing is visible until `transact` returns, so a
|
|
618
|
+
* batch rejected halfway leaves the revision, the tree, the indexes and every subscriber exactly
|
|
619
|
+
* as they were. That all-or-nothing property is what lets a caller compose ops without having to
|
|
620
|
+
* reason about partial application.
|
|
621
|
+
*/
|
|
622
|
+
declare class TreeDocumentStore {
|
|
623
|
+
private current;
|
|
624
|
+
/** The part `apply` targets and `part` returns: the story this store is editing. */
|
|
625
|
+
private readonly storyPartName;
|
|
626
|
+
private rev;
|
|
627
|
+
private commitCounter;
|
|
628
|
+
private readonly undoStack;
|
|
629
|
+
private readonly redoStack;
|
|
630
|
+
private pushCount;
|
|
631
|
+
private readonly subscribers;
|
|
632
|
+
private readonly historyLimit;
|
|
633
|
+
/** See {@link TreeDocumentStoreOptions.settingsPart}. */
|
|
634
|
+
private readonly settingsPartOverride;
|
|
635
|
+
/** See {@link TreeDocumentStoreOptions.contentLockPolicy}. */
|
|
636
|
+
private readonly contentLockPolicy;
|
|
637
|
+
/** Package-aware story tag applied to publishes (including undo/redo). */
|
|
638
|
+
private storyRef;
|
|
639
|
+
/** Open composition, if any. While set, transactions extend one entry (task 5.5). */
|
|
640
|
+
private composition;
|
|
641
|
+
/**
|
|
642
|
+
* Open a store over a package, editing the named story part.
|
|
643
|
+
*
|
|
644
|
+
* A bare part is accepted and wrapped in a single-part package, so callers that never open a
|
|
645
|
+
* real package — tests, headless tooling — are unaffected by the widening.
|
|
646
|
+
*/
|
|
647
|
+
constructor(source: OoxmlPart | OoxmlPackage, storyPartNameOrOptions?: string | TreeDocumentStoreOptions, maybeOptions?: TreeDocumentStoreOptions);
|
|
648
|
+
/**
|
|
649
|
+
* Stamp story identity onto subsequent publishes for this store (including undo/redo).
|
|
650
|
+
* Used by the package coordinator so history navigation keeps the same scope tag.
|
|
651
|
+
*/
|
|
652
|
+
setStoryRef(story: TreeStoryRef | null): void;
|
|
653
|
+
/** The story part being edited. Unchanged for every caller that predates the widening. */
|
|
654
|
+
get part(): OoxmlPart;
|
|
655
|
+
/** Every part, including the ones a multi-part transaction wrote. */
|
|
656
|
+
get package(): OoxmlPackage;
|
|
657
|
+
get revision(): number;
|
|
658
|
+
get canUndo(): boolean;
|
|
659
|
+
get canRedo(): boolean;
|
|
660
|
+
/** Retained entries — the unit `undo()` reverses, so tests can assert grouping. */
|
|
661
|
+
get historyDepth(): number;
|
|
662
|
+
/**
|
|
663
|
+
* How many entries this store has ever pushed. Monotonic, unlike `historyDepth`, which
|
|
664
|
+
* stands still at the history limit because the oldest entry is shifted out.
|
|
665
|
+
* @internal
|
|
666
|
+
*/
|
|
667
|
+
get historyPushCount(): number;
|
|
668
|
+
get compositionActive(): boolean;
|
|
669
|
+
/**
|
|
670
|
+
* Replace the package OUTSIDE the transaction and history lanes.
|
|
671
|
+
*
|
|
672
|
+
* For package writes that are not a user intent and publish no revision: grafting
|
|
673
|
+
* `numbering.xml` into a document that never had one, which the caller performs as a
|
|
674
|
+
* precondition of the list op that follows. Those edits were previously kept in a package
|
|
675
|
+
* variable beside the store, which meant two owners of one value and, predictably, two
|
|
676
|
+
* values — a graft written to one and a save read from the other.
|
|
677
|
+
*
|
|
678
|
+
* Deliberately narrow and deliberately awkward to reach for: anything a user did belongs in
|
|
679
|
+
* `transact`, where it gets a revision, an undo entry and the invariant checks.
|
|
680
|
+
*/
|
|
681
|
+
graftPackage(edit: (pkg: OoxmlPackage) => OoxmlPackage): void;
|
|
682
|
+
/**
|
|
683
|
+
* Replace the current part without recording history, but advance the revision so
|
|
684
|
+
* revision-keyed projections cannot survive a package snapshot install.
|
|
685
|
+
*/
|
|
686
|
+
replacePart(part: OoxmlPart): void;
|
|
687
|
+
/**
|
|
688
|
+
* Snapshot part, revision, and undo/redo stacks so the package coordinator can roll
|
|
689
|
+
* back a story transaction that fails after commit (e.g. note-reference cascade) or
|
|
690
|
+
* discard a local history entry when promoting to a package undo unit.
|
|
691
|
+
*/
|
|
692
|
+
checkpoint(): TreeDocumentCheckpoint;
|
|
693
|
+
/** Full restore — part, revision, history stacks, and composition. */
|
|
694
|
+
restoreCheckpoint(checkpoint: TreeDocumentCheckpoint): void;
|
|
695
|
+
/**
|
|
696
|
+
* Restore undo/redo stacks only, keeping the current part and revision.
|
|
697
|
+
* Used when a story mutation is promoted to a package history pointer so the local
|
|
698
|
+
* orphan entry does not steal a later undo.
|
|
699
|
+
*/
|
|
700
|
+
restoreHistoryStacks(checkpoint: TreeDocumentCheckpoint): void;
|
|
701
|
+
subscribe(listener: (change: TreeModelChange) => void): () => void;
|
|
702
|
+
/**
|
|
703
|
+
* Run one atomic transaction.
|
|
704
|
+
*
|
|
705
|
+
* Ops are staged against a working copy. On the first rejection the whole transaction is
|
|
706
|
+
* abandoned: no revision, no history entry, no notification. On success exactly one
|
|
707
|
+
* revision is published and exactly one history entry is recorded — unless a composition
|
|
708
|
+
* is open, in which case the entry already exists and this transaction joins it.
|
|
709
|
+
*/
|
|
710
|
+
transact(build: (ctx: TransactionContext) => void, options?: TransactOptions): TransactResult;
|
|
711
|
+
private commitTransaction;
|
|
712
|
+
/**
|
|
713
|
+
* Open one history entry for an IME composition.
|
|
714
|
+
*
|
|
715
|
+
* Everything committed until `endComposition` collapses into this single entry, which is
|
|
716
|
+
* what makes a composed word one undo step rather than one per intermediate transaction.
|
|
717
|
+
*/
|
|
718
|
+
beginComposition(selectionBefore?: SelectionMark | null): void;
|
|
719
|
+
/** Close the composition, recording its entry only if anything actually committed. */
|
|
720
|
+
endComposition(): void;
|
|
721
|
+
/**
|
|
722
|
+
* Cancel an open composition without recording an entry, leaving whatever it committed
|
|
723
|
+
* in place. An IME cancel is not an undo request; the caller decides what to revert.
|
|
724
|
+
*/
|
|
725
|
+
cancelComposition(): void;
|
|
726
|
+
/**
|
|
727
|
+
* Close the open history group, if any: the next transaction records its own entry.
|
|
728
|
+
* The store does this itself for another token, none, undo and redo; the package
|
|
729
|
+
* coordinator does it for history moving ABOVE the store (a package unit, another
|
|
730
|
+
* story's pointer), which the store cannot see.
|
|
731
|
+
*/
|
|
732
|
+
closeHistoryGroup(): void;
|
|
733
|
+
undo(): TreeModelChange | null;
|
|
734
|
+
redo(): TreeModelChange | null;
|
|
735
|
+
/** The selection to restore for the entry `undo()` would reverse next. */
|
|
736
|
+
selectionForUndo(): SelectionMark | null;
|
|
737
|
+
/** The selection to restore for the entry `redo()` would reapply next. */
|
|
738
|
+
selectionForRedo(): SelectionMark | null;
|
|
739
|
+
/**
|
|
740
|
+
* Remove the newest undo entry and answer its selections, for the package coordinator
|
|
741
|
+
* when a package history group absorbs the story pointer that entry belonged to.
|
|
742
|
+
* @internal
|
|
743
|
+
*/
|
|
744
|
+
discardNewestUndoEntry(): Pick<HistoryEntry, 'selectionBefore' | 'selectionAfter'> | null;
|
|
745
|
+
private pushUndo;
|
|
746
|
+
private publish;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* The identity of one continuous user gesture, for history grouping.
|
|
751
|
+
*
|
|
752
|
+
* A live color picker, a font-size stepper or a spacing slider applies every intermediate
|
|
753
|
+
* value so the document updates under the pointer, and each of those writes is a
|
|
754
|
+
* transaction in its own right — it must render, and a collaborator must receive it. What
|
|
755
|
+
* they are NOT is separate undo steps. The caller mints one token when the gesture starts
|
|
756
|
+
* (`Symbol('color-drag')`) and passes it with every write until the gesture ends.
|
|
757
|
+
*
|
|
758
|
+
* A symbol rather than a string, so two unrelated callers cannot collide by naming their
|
|
759
|
+
* gesture the same way, and so a token cannot outlive its gesture by accident through
|
|
760
|
+
* serialization.
|
|
761
|
+
*/
|
|
762
|
+
type HistoryGroup = symbol;
|
|
763
|
+
type HistoryCaptureKind = 'started' | 'extended' | 'split';
|
|
764
|
+
type HistoryCaptureReason = 'package-unit' | 'composition';
|
|
765
|
+
declare function observeHistoryGroup<T>(group: HistoryGroup, report: (kind: HistoryCaptureKind, reason?: HistoryCaptureReason) => void, run: () => T): T;
|
|
766
|
+
declare function reportHistoryGroup(group: HistoryGroup | undefined, kind: HistoryCaptureKind, reason?: HistoryCaptureReason): void;
|
|
767
|
+
|
|
768
|
+
/** UTF-16 placeholder for one atomic note unit in `paragraphTextOf` / segments. */
|
|
769
|
+
declare const NOTE_ATOM_CHAR = "\uFFFC";
|
|
770
|
+
/** Signed 32-bit Word-compatible note id range (positive allocation only). */
|
|
771
|
+
declare const NOTE_ID_MIN = 1;
|
|
772
|
+
/** Largest note id Word accepts — signed 32-bit. */
|
|
773
|
+
declare const NOTE_ID_MAX = 2147483647;
|
|
774
|
+
/** Reserved separator / continuation ids — never allocated for normal notes. */
|
|
775
|
+
declare const NOTE_SEPARATOR_ID = -1;
|
|
776
|
+
/** Reserved id of the continuation-separator entry. Never allocated to a real note. */
|
|
777
|
+
declare const NOTE_CONTINUATION_SEPARATOR_ID = 0;
|
|
778
|
+
/** Which notes part a note lives in. Decides both placement and numbering rules. */
|
|
779
|
+
type NoteKind = 'footnote' | 'endnote';
|
|
780
|
+
/** Authored `ST_FtnEdn` including explicit `normal`. Absent means Word default (normal). */
|
|
781
|
+
/**
|
|
782
|
+
* What a note entry IS.
|
|
783
|
+
*
|
|
784
|
+
* Only `normal` is a note a reader sees. The others are the furniture Word stores in the same
|
|
785
|
+
* part — the rules and notices drawn around the note area — reached by reserved ids.
|
|
786
|
+
*/
|
|
787
|
+
type NoteType = 'normal' | 'separator' | 'continuationSeparator' | 'continuationNotice';
|
|
788
|
+
/** Parse a signed decimal note id; reject non-integers and out-of-int32 values. */
|
|
789
|
+
declare function parseNoteId(raw: string | undefined): number | null;
|
|
790
|
+
/**
|
|
791
|
+
* Canonical `EditorScope { kind: 'note'; id }` encoding.
|
|
792
|
+
*
|
|
793
|
+
* Footnote id `1` and endnote id `1` coexist, so the kind is part of the string:
|
|
794
|
+
* `footnote:2` / `endnote:-1`. Do not invent a parallel scope union arm.
|
|
795
|
+
*/
|
|
796
|
+
declare function formatNoteScopeId(noteKind: NoteKind, noteId: number): string;
|
|
797
|
+
/**
|
|
798
|
+
* Parse {@link formatNoteScopeId}. Returns `null` for malformed / out-of-range ids.
|
|
799
|
+
*/
|
|
800
|
+
declare function parseNoteScopeId(id: string): {
|
|
801
|
+
readonly noteKind: NoteKind;
|
|
802
|
+
readonly noteId: number;
|
|
803
|
+
} | null;
|
|
433
804
|
/** Whether a node is a `w:footnotes` part root. */
|
|
434
805
|
declare function isFootnotesNode(node: OoxmlNode): node is OoxmlFootnotesNode;
|
|
435
806
|
/** Whether a node is a `w:endnotes` part root. */
|
|
@@ -616,445 +987,97 @@ type NoteLifecycleOp = {
|
|
|
616
987
|
*/
|
|
617
988
|
readonly revision?: RevisionAttributionInput;
|
|
618
989
|
} | {
|
|
619
|
-
readonly op: 'deleteNote';
|
|
620
|
-
readonly noteKind: NoteKind;
|
|
621
|
-
readonly noteId: number;
|
|
622
|
-
} | {
|
|
623
|
-
readonly op: 'convertNote';
|
|
624
|
-
readonly fromKind: NoteKind;
|
|
625
|
-
readonly noteId: number;
|
|
626
|
-
} | {
|
|
627
|
-
/**
|
|
628
|
-
* Convert every normal note of `fromKind` in document order. One atomic package
|
|
629
|
-
* transaction / undo unit with the same validation as repeated `convertNote`.
|
|
630
|
-
*/
|
|
631
|
-
readonly op: 'convertAllNotes';
|
|
632
|
-
readonly fromKind: NoteKind;
|
|
633
|
-
} | {
|
|
634
|
-
readonly op: 'setNoteProperties';
|
|
635
|
-
readonly scope: 'document' | 'section';
|
|
636
|
-
readonly sectionIndex?: number;
|
|
637
|
-
readonly footnote?: {
|
|
638
|
-
readonly numFmt?: string;
|
|
639
|
-
readonly numRestart?: string;
|
|
640
|
-
readonly position?: string;
|
|
641
|
-
readonly numStart?: number;
|
|
642
|
-
};
|
|
643
|
-
readonly endnote?: {
|
|
644
|
-
readonly numFmt?: string;
|
|
645
|
-
readonly numRestart?: string;
|
|
646
|
-
readonly position?: string;
|
|
647
|
-
readonly numStart?: number;
|
|
648
|
-
};
|
|
649
|
-
};
|
|
650
|
-
/** Why a note lifecycle op was refused. */
|
|
651
|
-
type NoteLifecycleRejection = 'invalidArgs' | 'invalid-property-value' | 'tree-invariant';
|
|
652
|
-
/**
|
|
653
|
-
* A new package, or a typed rejection.
|
|
654
|
-
*
|
|
655
|
-
* Application is PURE and all-or-nothing: there are no partial writes, so a refused op leaves the
|
|
656
|
-
* caller's package untouched rather than half-migrated across four parts.
|
|
657
|
-
*/
|
|
658
|
-
type NoteLifecycleResult = {
|
|
659
|
-
readonly ok: true;
|
|
660
|
-
readonly package: OoxmlPackage;
|
|
661
|
-
readonly impact: NoteLifecycleImpact;
|
|
662
|
-
readonly noteId?: number;
|
|
663
|
-
readonly noteKind?: NoteKind;
|
|
664
|
-
readonly createdPartName?: string;
|
|
665
|
-
} | {
|
|
666
|
-
readonly ok: false;
|
|
667
|
-
readonly reason: NoteLifecycleRejection;
|
|
668
|
-
readonly detail?: string;
|
|
669
|
-
};
|
|
670
|
-
/** Whether an op is a note lifecycle op rather than a story-level one. */
|
|
671
|
-
declare function isNoteLifecycleOp(op: {
|
|
672
|
-
readonly op: string;
|
|
673
|
-
}): op is NoteLifecycleOp;
|
|
674
|
-
/** Attribution and limits applied to one note lifecycle op. */
|
|
675
|
-
interface NoteLifecycleOptions {
|
|
676
|
-
/**
|
|
677
|
-
* Shared part + visited-node budget for reference scans. When omitted a fresh default
|
|
678
|
-
* budget is used. Truncation rejects the op with the original package unchanged.
|
|
679
|
-
*/
|
|
680
|
-
readonly scanBudget?: NoteReferenceScanBudget;
|
|
681
|
-
}
|
|
682
|
-
/**
|
|
683
|
-
* Apply one note lifecycle op atomically. Rejected ops leave the input package untouched.
|
|
684
|
-
*/
|
|
685
|
-
declare function applyNoteLifecycleOp(pkg: OoxmlPackage, op: NoteLifecycleOp, options?: NoteLifecycleOptions): NoteLifecycleResult;
|
|
686
|
-
/**
|
|
687
|
-
* How deleting text cascades into the notes it referenced.
|
|
688
|
-
*
|
|
689
|
-
* A note's body and the citation reaching it are one thing to a reader, so removing the reference
|
|
690
|
-
* must remove the body too or the notes part keeps an entry nothing points at.
|
|
691
|
-
*/
|
|
692
|
-
interface CascadeDeletedNoteReferencesOptions {
|
|
693
|
-
/**
|
|
694
|
-
* Independent full budgets per snapshot. When omitted each snapshot gets its own
|
|
695
|
-
* default budget — never share one counter across before/after walks.
|
|
696
|
-
*/
|
|
697
|
-
readonly beforeBudget?: NoteReferenceScanBudget;
|
|
698
|
-
readonly afterBudget?: NoteReferenceScanBudget;
|
|
699
|
-
}
|
|
700
|
-
/**
|
|
701
|
-
* Remove note bodies for references that disappeared between two package snapshots.
|
|
702
|
-
* Used when `deleteText` or `deleteBlock` removes a `noteReference` atom so body+ref stay
|
|
703
|
-
* one undo unit.
|
|
704
|
-
*
|
|
705
|
-
* Each snapshot gets an independent full visited/part budget. If either scan truncates
|
|
706
|
-
* the cascade fails closed so a hostile package cannot skip body deletion silently —
|
|
707
|
-
* without accidentally halving capacity by charging both walks to one counter.
|
|
708
|
-
*/
|
|
709
|
-
declare function cascadeDeletedNoteReferences(before: OoxmlPackage, after: OoxmlPackage, options?: CascadeDeletedNoteReferencesOptions): OoxmlPackage | null;
|
|
710
|
-
|
|
711
|
-
/**
|
|
712
|
-
* The identity of one continuous user gesture, for history grouping.
|
|
713
|
-
*
|
|
714
|
-
* A live color picker, a font-size stepper or a spacing slider applies every intermediate
|
|
715
|
-
* value so the document updates under the pointer, and each of those writes is a
|
|
716
|
-
* transaction in its own right — it must render, and a collaborator must receive it. What
|
|
717
|
-
* they are NOT is separate undo steps. The caller mints one token when the gesture starts
|
|
718
|
-
* (`Symbol('color-drag')`) and passes it with every write until the gesture ends.
|
|
719
|
-
*
|
|
720
|
-
* A symbol rather than a string, so two unrelated callers cannot collide by naming their
|
|
721
|
-
* gesture the same way, and so a token cannot outlive its gesture by accident through
|
|
722
|
-
* serialization.
|
|
723
|
-
*/
|
|
724
|
-
type HistoryGroup = symbol;
|
|
725
|
-
type HistoryCaptureKind = 'started' | 'extended' | 'split';
|
|
726
|
-
type HistoryCaptureReason = 'package-unit' | 'composition';
|
|
727
|
-
declare function observeHistoryGroup<T>(group: HistoryGroup, report: (kind: HistoryCaptureKind, reason?: HistoryCaptureReason) => void, run: () => T): T;
|
|
728
|
-
declare function reportHistoryGroup(group: HistoryGroup | undefined, kind: HistoryCaptureKind, reason?: HistoryCaptureReason): void;
|
|
729
|
-
|
|
730
|
-
/** How one transaction behaves: its story scope, its attribution, and its selection marks. */
|
|
731
|
-
interface TransactOptions {
|
|
732
|
-
readonly origin?: string;
|
|
733
|
-
/** Stable actor attribution for collaboration and audit correlation. */
|
|
734
|
-
readonly actorId?: string;
|
|
735
|
-
/** Stable constituent identity for collaboration duplicate correlation. */
|
|
736
|
-
readonly operationId?: string;
|
|
737
|
-
/**
|
|
738
|
-
* Whether this transaction enters the legacy snapshot undo stack.
|
|
739
|
-
*
|
|
740
|
-
* Collaboration commits set this to false because their actor-local undo authority is the
|
|
741
|
-
* CRDT undo manager. Omitted preserves the ordinary non-collaborative history behavior.
|
|
742
|
-
*/
|
|
743
|
-
readonly recordsHistory?: boolean;
|
|
744
|
-
/**
|
|
745
|
-
* A COMMAND is one user intent that may need several ops (a toolbar click applying a
|
|
746
|
-
* property across a multi-run selection). It is still exactly one history entry, which is
|
|
747
|
-
* the same rule a plain transaction follows — the option exists to say so explicitly at
|
|
748
|
-
* the call site rather than leaving it implied.
|
|
749
|
-
*/
|
|
750
|
-
readonly scope?: 'transaction' | 'command';
|
|
751
|
-
/**
|
|
752
|
-
* Floor on the published impact. Header/footer story edits use `global` so every page
|
|
753
|
-
* sharing the part invalidates rather than keeping stale furniture.
|
|
754
|
-
*/
|
|
755
|
-
readonly minimumImpact?: ImpactClass;
|
|
756
|
-
/** Story identity stamped onto the published ModelChange (package-aware targeting). */
|
|
757
|
-
readonly story?: TreeStoryRef;
|
|
758
|
-
/**
|
|
759
|
-
* The gesture this transaction belongs to: consecutive transactions carrying the SAME
|
|
760
|
-
* token extend one history entry (package from before the first, selection after the
|
|
761
|
-
* latest). Another token, none, undo or redo closes the group. See {@link HistoryGroup}.
|
|
762
|
-
*/
|
|
763
|
-
readonly historyGroup?: HistoryGroup;
|
|
764
|
-
/**
|
|
765
|
-
* How the transaction's ops address saved field results. `atomic` (the default) keeps
|
|
766
|
-
* every field one offset unit; `editable` addresses saved results as text. See
|
|
767
|
-
* `field-result-mode.ts`.
|
|
768
|
-
*/
|
|
769
|
-
readonly fieldResults?: FieldResultsMode;
|
|
770
|
-
}
|
|
771
|
-
/** How a store is constructed: its limits, its history depth, and its identity source. */
|
|
772
|
-
interface TreeDocumentStoreOptions {
|
|
773
|
-
/** Bound on retained history entries. Oldest entries drop first. */
|
|
774
|
-
readonly historyLimit?: number;
|
|
775
|
-
/**
|
|
776
|
-
* The document's `settings.xml`, for a store built from a PART rather than a package.
|
|
777
|
-
*
|
|
778
|
-
* Forms protection lives one part up from the op, and a store built from a part gets a
|
|
779
|
-
* synthetic one-part package that cannot see it — so `w:documentProtection w:edit="forms"`
|
|
780
|
-
* was enforced in the body and nowhere else, and a header, a footer or a note accepted every
|
|
781
|
-
* write a protected document is supposed to refuse. Read through a getter, not captured: a
|
|
782
|
-
* document can gain or lose protection while its stories stay open.
|
|
783
|
-
*/
|
|
784
|
-
readonly settingsPart?: () => OoxmlPart | null | undefined;
|
|
785
|
-
/**
|
|
786
|
-
* Opt-in relaxation of `w:lock` for run-property writes. See {@link ContentLockPolicy};
|
|
787
|
-
* absent, `contentLocked` and `sdtContentLocked` refuse formatting like any other write.
|
|
788
|
-
*/
|
|
789
|
-
readonly contentLockPolicy?: ContentLockPolicy;
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
/** A selection the caller wants restored when an entry is undone or redone. */
|
|
793
|
-
/** A selection captured with a transaction, so undo restores where the caret was. */
|
|
794
|
-
interface SelectionMark {
|
|
795
|
-
readonly paragraphId: string;
|
|
796
|
-
readonly start: number;
|
|
797
|
-
readonly end: number;
|
|
798
|
-
}
|
|
799
|
-
/**
|
|
800
|
-
* Which editable story a ModelChange came from.
|
|
801
|
-
*
|
|
802
|
-
* Mirrors `EditorScope` for body and header/footer — `{ kind: 'headerFooter'; rId }` —
|
|
803
|
-
* so package-aware mutation and the public scope contract stay one vocabulary. Body
|
|
804
|
-
* commits omit `rId`; header/footer commits carry the relationship id that addressed
|
|
805
|
-
* the part. Notes parts use `{ kind: 'notesPart'; noteKind }` (one store per part).
|
|
806
|
-
*/
|
|
807
|
-
/** Which story a transaction targets: the body, a header/footer part, or a notes part. */
|
|
808
|
-
type TreeStoryRef = {
|
|
809
|
-
readonly kind: 'body';
|
|
810
|
-
readonly partName: string;
|
|
811
|
-
} | {
|
|
812
|
-
readonly kind: 'headerFooter';
|
|
813
|
-
readonly partName: string;
|
|
814
|
-
readonly rId: string;
|
|
815
|
-
} | {
|
|
816
|
-
readonly kind: 'notesPart';
|
|
817
|
-
readonly partName: string;
|
|
818
|
-
readonly noteKind: 'footnote' | 'endnote';
|
|
819
|
-
};
|
|
820
|
-
/**
|
|
821
|
-
* What one committed transaction changed: the revision, the ids touched, and the impact class.
|
|
822
|
-
*
|
|
823
|
-
* The ids are what let layout and paint re-do only the affected blocks instead of the document.
|
|
824
|
-
*/
|
|
825
|
-
interface TreeModelChange {
|
|
826
|
-
readonly change: 'model-change';
|
|
827
|
-
readonly fromRevision: number;
|
|
828
|
-
readonly toRevision: number;
|
|
829
|
-
readonly commitId: string;
|
|
830
|
-
readonly origin: string;
|
|
831
|
-
/** Stable collaboration actor attribution, when the caller supplied it. */
|
|
832
|
-
readonly actorId?: string;
|
|
833
|
-
/** Stable collaboration operation identity, when the caller supplied it. */
|
|
834
|
-
readonly operationId?: string;
|
|
835
|
-
readonly dirty: readonly string[];
|
|
836
|
-
readonly created: readonly string[];
|
|
837
|
-
readonly deleted: readonly string[];
|
|
838
|
-
readonly splitJoin: readonly ({
|
|
839
|
-
readonly split: {
|
|
840
|
-
readonly from: string;
|
|
841
|
-
readonly tail: string;
|
|
842
|
-
};
|
|
843
|
-
} | {
|
|
844
|
-
readonly join: {
|
|
845
|
-
readonly kept: string;
|
|
846
|
-
readonly removed: string;
|
|
847
|
-
};
|
|
848
|
-
})[];
|
|
849
|
-
readonly dependencyKeys: readonly string[];
|
|
850
|
-
/** The widest impact among the transaction's ops — what layout must scope to. */
|
|
851
|
-
readonly impact: ImpactClass;
|
|
852
|
-
/**
|
|
853
|
-
* Story that published this change. Absent on body-only store publishes that predate
|
|
854
|
-
* package-aware targeting; `TreePackageStore` always sets it.
|
|
855
|
-
*/
|
|
856
|
-
readonly story?: TreeStoryRef;
|
|
990
|
+
readonly op: 'deleteNote';
|
|
991
|
+
readonly noteKind: NoteKind;
|
|
992
|
+
readonly noteId: number;
|
|
993
|
+
} | {
|
|
994
|
+
readonly op: 'convertNote';
|
|
995
|
+
readonly fromKind: NoteKind;
|
|
996
|
+
readonly noteId: number;
|
|
997
|
+
} | {
|
|
857
998
|
/**
|
|
858
|
-
*
|
|
859
|
-
*
|
|
860
|
-
* null, non-collapsed explicit selection, or when no caret was committed.
|
|
999
|
+
* Convert every normal note of `fromKind` in document order. One atomic package
|
|
1000
|
+
* transaction / undo unit with the same validation as repeated `convertNote`.
|
|
861
1001
|
*/
|
|
862
|
-
readonly
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
1002
|
+
readonly op: 'convertAllNotes';
|
|
1003
|
+
readonly fromKind: NoteKind;
|
|
1004
|
+
} | {
|
|
1005
|
+
readonly op: 'setNoteProperties';
|
|
1006
|
+
readonly scope: 'document' | 'section';
|
|
1007
|
+
readonly sectionIndex?: number;
|
|
1008
|
+
readonly footnote?: {
|
|
1009
|
+
readonly numFmt?: string;
|
|
1010
|
+
readonly numRestart?: string;
|
|
1011
|
+
readonly position?: string;
|
|
1012
|
+
readonly numStart?: number;
|
|
1013
|
+
};
|
|
1014
|
+
readonly endnote?: {
|
|
1015
|
+
readonly numFmt?: string;
|
|
1016
|
+
readonly numRestart?: string;
|
|
1017
|
+
readonly position?: string;
|
|
1018
|
+
readonly numStart?: number;
|
|
1019
|
+
};
|
|
1020
|
+
};
|
|
1021
|
+
/** Why a note lifecycle op was refused. */
|
|
1022
|
+
type NoteLifecycleRejection = 'invalidArgs' | 'invalid-property-value' | 'tree-invariant';
|
|
1023
|
+
/**
|
|
1024
|
+
* A new package, or a typed rejection.
|
|
1025
|
+
*
|
|
1026
|
+
* Application is PURE and all-or-nothing: there are no partial writes, so a refused op leaves the
|
|
1027
|
+
* caller's package untouched rather than half-migrated across four parts.
|
|
1028
|
+
*/
|
|
1029
|
+
type NoteLifecycleResult = {
|
|
866
1030
|
readonly ok: true;
|
|
867
|
-
readonly
|
|
1031
|
+
readonly package: OoxmlPackage;
|
|
1032
|
+
readonly impact: NoteLifecycleImpact;
|
|
1033
|
+
readonly noteId?: number;
|
|
1034
|
+
readonly noteKind?: NoteKind;
|
|
1035
|
+
readonly createdPartName?: string;
|
|
868
1036
|
} | {
|
|
869
1037
|
readonly ok: false;
|
|
870
|
-
readonly reason:
|
|
1038
|
+
readonly reason: NoteLifecycleRejection;
|
|
871
1039
|
readonly detail?: string;
|
|
872
1040
|
};
|
|
873
|
-
/**
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
*
|
|
880
|
-
* A comment body lives in `comments.xml` and is edited by the same ops that edit the story,
|
|
881
|
-
* so this is `apply` with the target named rather than a second vocabulary.
|
|
882
|
-
*/
|
|
883
|
-
applyTo(partName: string, op: TreeDocOp): boolean;
|
|
884
|
-
/**
|
|
885
|
-
* Stage a whole-package edit: a new part, a relationship, a content-type override.
|
|
886
|
-
*
|
|
887
|
-
* The edit is a pure function of the working package, so a rejected transaction discards it
|
|
888
|
-
* with everything else. Returning the SAME package is a no-op, not a failure — a primitive
|
|
889
|
-
* that finds nothing to do says so that way.
|
|
890
|
-
*/
|
|
891
|
-
applyPackage(edit: (pkg: OoxmlPackage) => OoxmlPackage): boolean;
|
|
892
|
-
/** The selection to restore when this entry is undone. */
|
|
893
|
-
selectionBefore(selection: SelectionMark | null): void;
|
|
894
|
-
/** The selection to restore when this entry is redone. */
|
|
895
|
-
selectionAfter(selection: SelectionMark | null): void;
|
|
896
|
-
}
|
|
897
|
-
interface HistoryEntry {
|
|
898
|
-
/**
|
|
899
|
-
* The whole package as it was, not just the story part.
|
|
900
|
-
*
|
|
901
|
-
* Affordable for the same reason a part snapshot was: parts are immutable and deep-frozen, so
|
|
902
|
-
* a package snapshot is a Map of references and every part the transaction did not touch is
|
|
903
|
-
* object-identical to the one before it. Undo stays a pointer swap, and it now reverses every
|
|
904
|
-
* part one intent wrote rather than only the story.
|
|
905
|
-
*/
|
|
906
|
-
readonly pkg: OoxmlPackage;
|
|
907
|
-
readonly revision: number;
|
|
908
|
-
readonly selectionBefore: SelectionMark | null;
|
|
909
|
-
readonly selectionAfter: SelectionMark | null;
|
|
1041
|
+
/** Whether an op is a note lifecycle op rather than a story-level one. */
|
|
1042
|
+
declare function isNoteLifecycleOp(op: {
|
|
1043
|
+
readonly op: string;
|
|
1044
|
+
}): op is NoteLifecycleOp;
|
|
1045
|
+
/** Attribution and limits applied to one note lifecycle op. */
|
|
1046
|
+
interface NoteLifecycleOptions {
|
|
910
1047
|
/**
|
|
911
|
-
*
|
|
912
|
-
*
|
|
913
|
-
* strips it, and undo and redo never copy it onto the entries they push.
|
|
1048
|
+
* Shared part + visited-node budget for reference scans. When omitted a fresh default
|
|
1049
|
+
* budget is used. Truncation rejects the op with the original package unchanged.
|
|
914
1050
|
*/
|
|
915
|
-
readonly
|
|
1051
|
+
readonly scanBudget?: NoteReferenceScanBudget;
|
|
916
1052
|
}
|
|
917
1053
|
/**
|
|
918
|
-
*
|
|
919
|
-
* Used when a story mutation may promote to a package undo unit (note-ref cascade).
|
|
1054
|
+
* Apply one note lifecycle op atomically. Rejected ops leave the input package untouched.
|
|
920
1055
|
*/
|
|
921
|
-
|
|
922
|
-
interface TreeDocumentCheckpoint {
|
|
923
|
-
/**
|
|
924
|
-
* The whole package, not one part. The store owns the package so a transaction spanning
|
|
925
|
-
* several parts is one publication — a checkpoint of only the story part could not roll
|
|
926
|
-
* back the comment or numbering part the same transaction wrote.
|
|
927
|
-
*/
|
|
928
|
-
readonly pkg: OoxmlPackage;
|
|
929
|
-
readonly revision: number;
|
|
930
|
-
readonly undoStack: readonly HistoryEntry[];
|
|
931
|
-
readonly redoStack: readonly HistoryEntry[];
|
|
932
|
-
readonly composition: {
|
|
933
|
-
readonly entry: HistoryEntry;
|
|
934
|
-
readonly committed: boolean;
|
|
935
|
-
} | null;
|
|
936
|
-
}
|
|
1056
|
+
declare function applyNoteLifecycleOp(pkg: OoxmlPackage, op: NoteLifecycleOp, options?: NoteLifecycleOptions): NoteLifecycleResult;
|
|
937
1057
|
/**
|
|
938
|
-
*
|
|
1058
|
+
* How deleting text cascades into the notes it referenced.
|
|
939
1059
|
*
|
|
940
|
-
*
|
|
941
|
-
*
|
|
942
|
-
* as they were. That all-or-nothing property is what lets a caller compose ops without having to
|
|
943
|
-
* reason about partial application.
|
|
1060
|
+
* A note's body and the citation reaching it are one thing to a reader, so removing the reference
|
|
1061
|
+
* must remove the body too or the notes part keeps an entry nothing points at.
|
|
944
1062
|
*/
|
|
945
|
-
|
|
946
|
-
private current;
|
|
947
|
-
/** The part `apply` targets and `part` returns: the story this store is editing. */
|
|
948
|
-
private readonly storyPartName;
|
|
949
|
-
private rev;
|
|
950
|
-
private commitCounter;
|
|
951
|
-
private readonly undoStack;
|
|
952
|
-
private readonly redoStack;
|
|
953
|
-
private readonly subscribers;
|
|
954
|
-
private readonly historyLimit;
|
|
955
|
-
/** See {@link TreeDocumentStoreOptions.settingsPart}. */
|
|
956
|
-
private readonly settingsPartOverride;
|
|
957
|
-
/** See {@link TreeDocumentStoreOptions.contentLockPolicy}. */
|
|
958
|
-
private readonly contentLockPolicy;
|
|
959
|
-
/** Package-aware story tag applied to publishes (including undo/redo). */
|
|
960
|
-
private storyRef;
|
|
961
|
-
/** Open composition, if any. While set, transactions extend one entry (task 5.5). */
|
|
962
|
-
private composition;
|
|
963
|
-
/**
|
|
964
|
-
* Open a store over a package, editing the named story part.
|
|
965
|
-
*
|
|
966
|
-
* A bare part is accepted and wrapped in a single-part package, so callers that never open a
|
|
967
|
-
* real package — tests, headless tooling — are unaffected by the widening.
|
|
968
|
-
*/
|
|
969
|
-
constructor(source: OoxmlPart | OoxmlPackage, storyPartNameOrOptions?: string | TreeDocumentStoreOptions, maybeOptions?: TreeDocumentStoreOptions);
|
|
970
|
-
/**
|
|
971
|
-
* Stamp story identity onto subsequent publishes for this store (including undo/redo).
|
|
972
|
-
* Used by the package coordinator so history navigation keeps the same scope tag.
|
|
973
|
-
*/
|
|
974
|
-
setStoryRef(story: TreeStoryRef | null): void;
|
|
975
|
-
/** The story part being edited. Unchanged for every caller that predates the widening. */
|
|
976
|
-
get part(): OoxmlPart;
|
|
977
|
-
/** Every part, including the ones a multi-part transaction wrote. */
|
|
978
|
-
get package(): OoxmlPackage;
|
|
979
|
-
get revision(): number;
|
|
980
|
-
get canUndo(): boolean;
|
|
981
|
-
get canRedo(): boolean;
|
|
982
|
-
/** Retained entries — the unit `undo()` reverses, so tests can assert grouping. */
|
|
983
|
-
get historyDepth(): number;
|
|
984
|
-
get compositionActive(): boolean;
|
|
985
|
-
/**
|
|
986
|
-
* Replace the package OUTSIDE the transaction and history lanes.
|
|
987
|
-
*
|
|
988
|
-
* For package writes that are not a user intent and publish no revision: grafting
|
|
989
|
-
* `numbering.xml` into a document that never had one, which the caller performs as a
|
|
990
|
-
* precondition of the list op that follows. Those edits were previously kept in a package
|
|
991
|
-
* variable beside the store, which meant two owners of one value and, predictably, two
|
|
992
|
-
* values — a graft written to one and a save read from the other.
|
|
993
|
-
*
|
|
994
|
-
* Deliberately narrow and deliberately awkward to reach for: anything a user did belongs in
|
|
995
|
-
* `transact`, where it gets a revision, an undo entry and the invariant checks.
|
|
996
|
-
*/
|
|
997
|
-
graftPackage(edit: (pkg: OoxmlPackage) => OoxmlPackage): void;
|
|
998
|
-
/**
|
|
999
|
-
* Replace the current part without recording history, but advance the revision so
|
|
1000
|
-
* revision-keyed projections cannot survive a package snapshot install.
|
|
1001
|
-
*/
|
|
1002
|
-
replacePart(part: OoxmlPart): void;
|
|
1003
|
-
/**
|
|
1004
|
-
* Snapshot part, revision, and undo/redo stacks so the package coordinator can roll
|
|
1005
|
-
* back a story transaction that fails after commit (e.g. note-reference cascade) or
|
|
1006
|
-
* discard a local history entry when promoting to a package undo unit.
|
|
1007
|
-
*/
|
|
1008
|
-
checkpoint(): TreeDocumentCheckpoint;
|
|
1009
|
-
/** Full restore — part, revision, history stacks, and composition. */
|
|
1010
|
-
restoreCheckpoint(checkpoint: TreeDocumentCheckpoint): void;
|
|
1011
|
-
/**
|
|
1012
|
-
* Restore undo/redo stacks only, keeping the current part and revision.
|
|
1013
|
-
* Used when a story mutation is promoted to a package history pointer so the local
|
|
1014
|
-
* orphan entry does not steal a later undo.
|
|
1015
|
-
*/
|
|
1016
|
-
restoreHistoryStacks(checkpoint: TreeDocumentCheckpoint): void;
|
|
1017
|
-
subscribe(listener: (change: TreeModelChange) => void): () => void;
|
|
1018
|
-
/**
|
|
1019
|
-
* Run one atomic transaction.
|
|
1020
|
-
*
|
|
1021
|
-
* Ops are staged against a working copy. On the first rejection the whole transaction is
|
|
1022
|
-
* abandoned: no revision, no history entry, no notification. On success exactly one
|
|
1023
|
-
* revision is published and exactly one history entry is recorded — unless a composition
|
|
1024
|
-
* is open, in which case the entry already exists and this transaction joins it.
|
|
1025
|
-
*/
|
|
1026
|
-
transact(build: (ctx: TransactionContext) => void, options?: TransactOptions): TransactResult;
|
|
1027
|
-
private commitTransaction;
|
|
1028
|
-
/**
|
|
1029
|
-
* Open one history entry for an IME composition.
|
|
1030
|
-
*
|
|
1031
|
-
* Everything committed until `endComposition` collapses into this single entry, which is
|
|
1032
|
-
* what makes a composed word one undo step rather than one per intermediate transaction.
|
|
1033
|
-
*/
|
|
1034
|
-
beginComposition(selectionBefore?: SelectionMark | null): void;
|
|
1035
|
-
/** Close the composition, recording its entry only if anything actually committed. */
|
|
1036
|
-
endComposition(): void;
|
|
1037
|
-
/**
|
|
1038
|
-
* Cancel an open composition without recording an entry, leaving whatever it committed
|
|
1039
|
-
* in place. An IME cancel is not an undo request; the caller decides what to revert.
|
|
1040
|
-
*/
|
|
1041
|
-
cancelComposition(): void;
|
|
1063
|
+
interface CascadeDeletedNoteReferencesOptions {
|
|
1042
1064
|
/**
|
|
1043
|
-
*
|
|
1044
|
-
*
|
|
1045
|
-
* coordinator does it for history moving ABOVE the store (a package unit, another
|
|
1046
|
-
* story's pointer), which the store cannot see.
|
|
1065
|
+
* Independent full budgets per snapshot. When omitted each snapshot gets its own
|
|
1066
|
+
* default budget — never share one counter across before/after walks.
|
|
1047
1067
|
*/
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
redo(): TreeModelChange | null;
|
|
1051
|
-
/** The selection to restore for the entry `undo()` would reverse next. */
|
|
1052
|
-
selectionForUndo(): SelectionMark | null;
|
|
1053
|
-
/** The selection to restore for the entry `redo()` would reapply next. */
|
|
1054
|
-
selectionForRedo(): SelectionMark | null;
|
|
1055
|
-
private pushUndo;
|
|
1056
|
-
private publish;
|
|
1068
|
+
readonly beforeBudget?: NoteReferenceScanBudget;
|
|
1069
|
+
readonly afterBudget?: NoteReferenceScanBudget;
|
|
1057
1070
|
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Remove note bodies for references that disappeared between two package snapshots.
|
|
1073
|
+
* Used when `deleteText` or `deleteBlock` removes a `noteReference` atom so body+ref stay
|
|
1074
|
+
* one undo unit.
|
|
1075
|
+
*
|
|
1076
|
+
* Each snapshot gets an independent full visited/part budget. If either scan truncates
|
|
1077
|
+
* the cascade fails closed so a hostile package cannot skip body deletion silently —
|
|
1078
|
+
* without accidentally halving capacity by charging both walks to one counter.
|
|
1079
|
+
*/
|
|
1080
|
+
declare function cascadeDeletedNoteReferences(before: OoxmlPackage, after: OoxmlPackage, options?: CascadeDeletedNoteReferencesOptions): OoxmlPackage | null;
|
|
1058
1081
|
|
|
1059
1082
|
/** Decoded fragment payloads above this cap are refused before any package work. */
|
|
1060
1083
|
declare const MAX_FRAGMENT_DECODED_BYTES: number;
|
|
@@ -1170,6 +1193,7 @@ declare class TreePackageStore {
|
|
|
1170
1193
|
private readonly rIdToPartName;
|
|
1171
1194
|
private readonly undoOrder;
|
|
1172
1195
|
private readonly redoOrder;
|
|
1196
|
+
private readonly historyGroups;
|
|
1173
1197
|
private readonly subscribers;
|
|
1174
1198
|
private readonly historyLimit;
|
|
1175
1199
|
private readonly contentLockPolicy;
|
|
@@ -1254,6 +1278,8 @@ declare class TreePackageStore {
|
|
|
1254
1278
|
*/
|
|
1255
1279
|
applyLifecycleOp(op: HeaderFooterLifecycleOp | NoteLifecycleOp | TreeDocOp, options?: {
|
|
1256
1280
|
readonly actorId?: string;
|
|
1281
|
+
/** @internal */
|
|
1282
|
+
readonly historyGroup?: HistoryGroup;
|
|
1257
1283
|
}): PackageTransactResult;
|
|
1258
1284
|
private commitLifecycleOp;
|
|
1259
1285
|
undo(): TreeModelChange | null;
|
|
@@ -1324,6 +1350,8 @@ declare class TreePackageStore {
|
|
|
1324
1350
|
* started from to this instead, the same promotion the note cascade does.
|
|
1325
1351
|
*/
|
|
1326
1352
|
adoptPackageUnit(before: OoxmlPackage): void;
|
|
1353
|
+
/** {@link adoptPackageUnit} as a frame of a history group. @internal */
|
|
1354
|
+
adoptGroupedPackageUnit(before: OoxmlPackage, historyGroup: HistoryGroup | undefined): void;
|
|
1327
1355
|
/** Install a full package snapshot (public seam for post-fetch cleanup). */
|
|
1328
1356
|
installPackageSnapshot(snapshot: OoxmlPackage): void;
|
|
1329
1357
|
/**
|
|
@@ -1344,6 +1372,8 @@ declare class TreePackageStore {
|
|
|
1344
1372
|
private openHeaderFooterStore;
|
|
1345
1373
|
private storyRefForPart;
|
|
1346
1374
|
private syncPackageFromStore;
|
|
1375
|
+
/** Close every open history group: the story stores' and the coordinator's. */
|
|
1376
|
+
private closeHistoryGroups;
|
|
1347
1377
|
private pushUndoPointer;
|
|
1348
1378
|
/** Keep history-reachable stories and prune unreachable shell hyperlink owners. */
|
|
1349
1379
|
private evictUnreachableStories;
|