@docx-editor.dev/core 2.20.0 → 2.21.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/README.md +11 -32
- package/dist/automation.cjs +1 -1
- package/dist/automation.d.ts +11 -10
- package/dist/automation.js +1 -1
- package/dist/binding.cjs +1 -1
- package/dist/binding.d.ts +9 -9
- package/dist/binding.js +1 -1
- package/dist/chunk-44LQJIKH.cjs +20 -0
- package/dist/chunk-4EHMMSFR.cjs +1 -0
- package/dist/{chunk-D2V4YBWJ.cjs → chunk-AFG7Q622.cjs} +1 -1
- package/dist/chunk-AJCCS53D.js +1 -0
- package/dist/{chunk-3EZO3O6I.js → chunk-AYMSP25Q.js} +3 -3
- package/dist/{chunk-44SIVFJT.cjs → chunk-B4KZSKF7.cjs} +5 -5
- package/dist/chunk-BDAY2ETZ.js +1 -0
- package/dist/chunk-BNZF6DYC.cjs +18 -0
- package/dist/chunk-BQXF2PFF.js +2 -0
- package/dist/chunk-GIHKVXEO.js +2 -0
- package/dist/chunk-ITNK6C5M.cjs +3 -0
- package/dist/chunk-MP3K4LC5.js +1 -0
- package/dist/chunk-MXOO7KRI.cjs +11 -0
- package/dist/chunk-NG6IQ4SI.js +11 -0
- package/dist/{chunk-2HQXLL5L.cjs → chunk-PYXMAUNR.cjs} +1 -1
- package/dist/chunk-Q2B6HX3R.js +1 -0
- package/dist/chunk-Q5JPPUNR.js +5 -0
- package/dist/chunk-S35UK656.cjs +2 -0
- package/dist/chunk-S6J4O5XP.js +1 -0
- package/dist/{chunk-GSEUM6AI.cjs → chunk-TE43S3LX.cjs} +1 -1
- package/dist/chunk-TKQH7BNE.cjs +1 -0
- package/dist/chunk-UKVVUHZL.cjs +1 -0
- package/dist/chunk-VH2DLEZK.js +20 -0
- package/dist/{chunk-OHVJYJOA.js → chunk-VUNFWXHF.js} +1 -1
- package/dist/{chunk-OA6LFCTG.cjs → chunk-WQFNWLNY.cjs} +3 -3
- package/dist/chunk-WZX4UGRQ.js +3 -0
- package/dist/{chunk-CAIWEQLC.js → chunk-X5QNSISI.js} +1 -1
- package/dist/chunk-XS4FOHH6.js +18 -0
- package/dist/{chunk-PIBYJZIH.cjs → chunk-XZY4Q6PJ.cjs} +1 -1
- package/dist/{chunk-WTILOUPG.cjs → chunk-Z2ETEZRU.cjs} +1 -1
- package/dist/collaboration/replication.cjs +1 -1
- package/dist/collaboration/replication.d.ts +13 -4
- package/dist/collaboration/replication.js +1 -1
- package/dist/collaboration.d.ts +4 -3
- package/dist/contracts/document.d.ts +3 -2
- package/dist/contracts/editor.cjs +1 -1
- package/dist/contracts/editor.d.ts +9 -9
- package/dist/contracts/editor.js +1 -1
- package/dist/contracts/interaction.d.ts +2 -2
- package/dist/contracts/modules.cjs +1 -1
- package/dist/contracts/modules.d.ts +9 -7
- package/dist/contracts/modules.js +1 -1
- package/dist/contracts/types.d.ts +2 -1
- package/dist/{custom-node-writes-piokwVR5.d.ts → custom-node-writes-05qS32px.d.ts} +2 -2
- package/dist/{document-protection-C6RvCHx-.d.ts → document-protection-Cr59VKLO.d.ts} +1 -1
- package/dist/{editor-BgtcHulQ.d.ts → editor-BsLSz_7y.d.ts} +28 -29
- package/dist/editor-scope-OHPwVQ5l.d.ts +84 -0
- package/dist/editor.cjs +1 -1
- package/dist/editor.css +1 -1
- package/dist/editor.d.ts +130 -27
- package/dist/editor.js +1 -1
- package/dist/export.cjs +2 -2
- package/dist/export.d.ts +13 -13
- package/dist/export.js +1 -1
- package/dist/{font-resolver-Bv2Z25-J.d.ts → font-resolver-CzwdBJDE.d.ts} +1 -1
- package/dist/{headless-document-view-DHKMN_3Y.d.ts → headless-document-view-B7nAiR7P.d.ts} +2 -2
- package/dist/{image-resources-C51LuAAu.d.ts → image-resources-C4ilLzog.d.ts} +1 -1
- package/dist/{index-3lr8xXF8.d.ts → index-zkvqBQ9o.d.ts} +117 -26
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +18 -18
- package/dist/index.js +1 -1
- package/dist/{layout-shaping-CKBUSaS7.d.ts → layout-shaping-BJKVTI6i.d.ts} +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.d.ts +41 -18
- package/dist/layout.js +1 -1
- package/dist/{note-properties-CcXUgqr8.d.ts → note-properties-MNztEj5s.d.ts} +1 -1
- package/dist/{omml-equation-C5P6Ym3v.d.ts → omml-equation-CbnW9yXd.d.ts} +1 -1
- package/dist/output.cjs +1 -1
- package/dist/output.d.ts +8 -7
- package/dist/output.js +1 -1
- package/dist/{protocol-CsawNZkt.d.ts → protocol-Co_r0SZQ.d.ts} +2 -2
- package/dist/{review-paragraph-order-BCIqjopY.d.ts → review-paragraph-order-EFaU7TqH.d.ts} +1 -1
- package/dist/{revision-projection-BcRnC4Yj.d.ts → revision-projection-DEIvpxiq.d.ts} +16 -2
- package/dist/{semantic-cell-selection-R9wrenwR.d.ts → semantic-cell-selection-DXmfnDCw.d.ts} +9 -4
- package/dist/{semantic-interaction-B7beVwH7.d.ts → semantic-interaction-BLu3M6Nn.d.ts} +1 -1
- package/dist/{semantic-paint-CLvHwf8y.d.ts → semantic-paint-CPsihA6k.d.ts} +18 -2
- package/dist/{semantic-records-CbXwnS80.d.ts → semantic-records-CqD0b5Ex.d.ts} +146 -6
- package/dist/store.cjs +1 -1
- package/dist/store.d.ts +462 -427
- package/dist/store.js +1 -1
- package/dist/{note-lifecycle-D4AOFCAt.d.ts → tree-package-fragment-CwJDixNs.d.ts} +183 -143
- package/dist/{tree-session-contract-DTQxw2zL.d.ts → tree-session-contract-D9RRWE0C.d.ts} +8 -8
- package/dist/{types-barrel-CEOy-Jv0.d.ts → types-barrel-DLB11iSY.d.ts} +1470 -1426
- package/package.json +2 -2
- package/dist/chunk-2H4ABRMB.cjs +0 -20
- package/dist/chunk-6UCDHGXI.js +0 -1
- package/dist/chunk-7VMVDRRU.js +0 -2
- package/dist/chunk-CEXC2VHI.cjs +0 -1
- package/dist/chunk-CF3JR35B.js +0 -11
- package/dist/chunk-D5EHDHYV.js +0 -1
- package/dist/chunk-DGSJZMAE.cjs +0 -11
- package/dist/chunk-EHBPYFRE.js +0 -20
- package/dist/chunk-GOEBQ26R.js +0 -1
- package/dist/chunk-H6WDEAOJ.js +0 -18
- package/dist/chunk-I6LSEDUL.cjs +0 -18
- package/dist/chunk-IW35GWJN.js +0 -1
- package/dist/chunk-JRBGCIR2.js +0 -5
- package/dist/chunk-K5HIOS6J.cjs +0 -3
- package/dist/chunk-KLQXP27K.js +0 -3
- package/dist/chunk-MZFFU66H.cjs +0 -2
- package/dist/chunk-MZPNLIP3.js +0 -2
- package/dist/chunk-OHJQ7GPZ.cjs +0 -1
- package/dist/chunk-P4TGGDK3.js +0 -1
- package/dist/chunk-ZKWRCLT2.cjs +0 -1
- package/dist/editor-scope-DZJT4ukT.d.ts +0 -53
|
@@ -1,225 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Why a part or relationship name was refused.
|
|
3
|
-
*
|
|
4
|
-
* Path traversal is the reason this exists: a name with `..` or a leading `/` is refused rather
|
|
5
|
-
* than normalized, because normalizing is how a crafted package reaches outside itself.
|
|
6
|
-
*/
|
|
7
|
-
type NameRejection = 'empty' | 'control-char' | 'backslash' | 'drive-or-unc' | 'encoded-separator' | 'encoded-dot' | 'bad-encoding' | 'empty-segment' | 'dot-segment' | 'unsafe-key' | 'segment-trailing-dot' | 'traversal-escape' | 'not-absolute-uri' | 'unsafe-scheme';
|
|
8
|
-
/** A validated OPC name, or the typed reason it was refused. */
|
|
9
|
-
type NameResult = {
|
|
10
|
-
readonly ok: true;
|
|
11
|
-
readonly partName: string;
|
|
12
|
-
} | {
|
|
13
|
-
readonly ok: false;
|
|
14
|
-
readonly reason: NameRejection;
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* Normalize a ZIP entry name or OPC part name into a canonical part name
|
|
18
|
-
* (`/word/document.xml`). Accepts leading-slash and no-leading-slash inputs;
|
|
19
|
-
* rejects traversal, dot segments, and the attack surface. Duplicate detection
|
|
20
|
-
* folds ASCII case (OPC part-name equivalence).
|
|
21
|
-
*/
|
|
22
|
-
declare function normalizePartName(raw: string): NameResult;
|
|
23
|
-
/**
|
|
24
|
-
* ASCII-only lowercase fold. OPC part-name/extension equivalence is US-ASCII
|
|
25
|
-
* case-insensitive; a locale `toLowerCase()` mis-folds e.g. Turkish `I`/`İ` and
|
|
26
|
-
* could let two "equivalent" part names evade duplicate detection.
|
|
27
|
-
*/
|
|
28
|
-
declare function asciiFold(s: string): string;
|
|
29
|
-
/** Case-folded key for OPC part-name equivalence / duplicate detection. */
|
|
30
|
-
declare function partNameKey(partName: string): string;
|
|
31
|
-
/**
|
|
32
|
-
* Detect archive entries that collide after normalization (before inflation).
|
|
33
|
-
* Returns the case-folded keys that more than one raw name maps to.
|
|
34
|
-
*/
|
|
35
|
-
declare function detectDuplicateNames(rawNames: readonly string[]): {
|
|
36
|
-
readonly duplicates: readonly string[];
|
|
37
|
-
readonly rejected: readonly {
|
|
38
|
-
raw: string;
|
|
39
|
-
reason: NameRejection;
|
|
40
|
-
}[];
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Resolve an internal relationship target against its owner part, without
|
|
44
|
-
* escaping the package root. `ownerPartName` is a canonical part name; the base
|
|
45
|
-
* is its containing folder. A leading "/" target is package-absolute. `.`/`..`
|
|
46
|
-
* segments resolve on a stack; popping above root is `traversal-escape`.
|
|
47
|
-
*/
|
|
48
|
-
declare function resolveInternalTarget(ownerPartName: string, rawTarget: string): NameResult;
|
|
49
|
-
/**
|
|
50
|
-
* Validate an external-mode relationship target. It MUST be an absolute URI, is
|
|
51
|
-
* retained verbatim by the caller, and is NEVER owner-resolved or fetched here.
|
|
52
|
-
* Unsafe schemes (javascript/vbscript/data/file) are rejected for runtime sinks;
|
|
53
|
-
* the raw lexical form is still preserved separately by the authored record.
|
|
54
|
-
*/
|
|
55
|
-
declare function validateExternalTarget(raw: string): NameResult;
|
|
56
|
-
|
|
57
|
-
/** One `<Default>`: a file extension mapped to a content type. */
|
|
58
|
-
interface DefaultRecord {
|
|
59
|
-
readonly extension: string;
|
|
60
|
-
readonly contentType: string;
|
|
61
|
-
readonly order: number;
|
|
62
|
-
}
|
|
63
|
-
/** One `<Override>`: a specific part name mapped to a content type. Beats any Default. */
|
|
64
|
-
interface OverrideRecord {
|
|
65
|
-
readonly partName: string;
|
|
66
|
-
readonly contentType: string;
|
|
67
|
-
readonly order: number;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* The authored `[Content_Types].xml` records, in significant order.
|
|
71
|
-
*
|
|
72
|
-
* Retained rather than collapsed into a lookup, because the file's lexical form and ordering are
|
|
73
|
-
* part of what a lossless save re-emits.
|
|
74
|
-
*/
|
|
75
|
-
interface ContentTypeRecords {
|
|
76
|
-
readonly defaults: readonly DefaultRecord[];
|
|
77
|
-
readonly overrides: readonly OverrideRecord[];
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Why content-type records could not be indexed.
|
|
81
|
-
*
|
|
82
|
-
* All fail CLOSED: conflicting Defaults on one extension, duplicate normalized Override names, or
|
|
83
|
-
* invalid MIME syntax are refused rather than resolved by picking one.
|
|
84
|
-
*/
|
|
85
|
-
type ContentTypeError = {
|
|
86
|
-
readonly code: 'invalid-mime';
|
|
87
|
-
readonly value: string;
|
|
88
|
-
} | {
|
|
89
|
-
readonly code: 'conflicting-default';
|
|
90
|
-
readonly extension: string;
|
|
91
|
-
} | {
|
|
92
|
-
readonly code: 'duplicate-override';
|
|
93
|
-
readonly partName: string;
|
|
94
|
-
} | {
|
|
95
|
-
readonly code: 'invalid-override-name';
|
|
96
|
-
readonly partName: string;
|
|
97
|
-
} | {
|
|
98
|
-
readonly code: 'too-many-records';
|
|
99
|
-
readonly limit: number;
|
|
100
|
-
};
|
|
101
|
-
/** Whether a string is syntactically a MIME type. Syntax only — no registry lookup. */
|
|
102
|
-
declare function isValidMime(value: string): boolean;
|
|
103
|
-
/** ASCII-case-insensitive extension key (leading dot removed; ASCII-only fold). */
|
|
104
|
-
declare function extensionKey(extension: string): string;
|
|
105
|
-
/** The resolved lookup: Override by case-folded part name, Default by case-insensitive extension. */
|
|
106
|
-
interface ContentTypeIndex {
|
|
107
|
-
/** ext key -> single MIME (identical duplicates collapsed). */
|
|
108
|
-
readonly defaults: ReadonlyMap<string, string>;
|
|
109
|
-
/** case-folded part name -> MIME. */
|
|
110
|
-
readonly overrides: ReadonlyMap<string, string>;
|
|
111
|
-
}
|
|
112
|
-
/** The built index, or the conflict that made it impossible. */
|
|
113
|
-
type IndexResult = {
|
|
114
|
-
readonly ok: true;
|
|
115
|
-
readonly index: ContentTypeIndex;
|
|
116
|
-
} | {
|
|
117
|
-
readonly ok: false;
|
|
118
|
-
readonly error: ContentTypeError;
|
|
119
|
-
};
|
|
120
|
-
/**
|
|
121
|
-
* Build a resolved content-type index, failing closed on conflict/duplicate/MIME
|
|
122
|
-
* errors. `maxRecords` bounds the combined record count (N/N+1 gate).
|
|
123
|
-
*/
|
|
124
|
-
declare function buildContentTypeIndex(records: ContentTypeRecords, maxRecords?: number): IndexResult;
|
|
125
|
-
/**
|
|
126
|
-
* A part's content type, or why it has none.
|
|
127
|
-
*
|
|
128
|
-
* An orphan record never determines a part's type — a Default with no matching part is preserved
|
|
129
|
-
* inertly rather than applied.
|
|
130
|
-
*/
|
|
131
|
-
type ResolveResult = {
|
|
132
|
-
readonly ok: true;
|
|
133
|
-
readonly contentType: string;
|
|
134
|
-
readonly source: 'override' | 'default';
|
|
135
|
-
} | {
|
|
136
|
-
readonly ok: false;
|
|
137
|
-
readonly reason: 'unknown';
|
|
138
|
-
};
|
|
139
|
-
/** Resolve a part's content type: Override wins over Default; else unknown. */
|
|
140
|
-
declare function resolveContentType(index: ContentTypeIndex, partName: string): ResolveResult;
|
|
141
|
-
|
|
142
|
-
/** OOXML image relationship type for embedded or linked media parts. */
|
|
143
|
-
declare const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
144
|
-
/**
|
|
145
|
-
* Whether a relationship points inside the package or out of it.
|
|
146
|
-
*
|
|
147
|
-
* The security-relevant distinction: an `External` target is retained VERBATIM and never
|
|
148
|
-
* owner-resolved or fetched, because auto-loading a file-supplied remote target is a zero-click
|
|
149
|
-
* external fetch.
|
|
150
|
-
*/
|
|
151
|
-
type TargetMode = 'Internal' | 'External';
|
|
152
|
-
/**
|
|
153
|
-
* One authored relationship, with nothing materialized away: owner part, id, type, raw target
|
|
154
|
-
* lexical form, mode, and position.
|
|
155
|
-
*/
|
|
156
|
-
interface RelationshipRecord {
|
|
157
|
-
readonly ownerPart: string;
|
|
158
|
-
readonly id: string;
|
|
159
|
-
readonly type: string;
|
|
160
|
-
readonly rawTarget: string;
|
|
161
|
-
readonly targetMode: TargetMode;
|
|
162
|
-
readonly order: number;
|
|
163
|
-
}
|
|
164
|
-
/** Why a relationship set is invalid. Duplicate ids within one owner fail closed. */
|
|
165
|
-
type RelationshipError = {
|
|
166
|
-
readonly code: 'duplicate-id';
|
|
167
|
-
readonly ownerPart: string;
|
|
168
|
-
readonly id: string;
|
|
169
|
-
};
|
|
170
|
-
/** The validated relationship set, or the conflict that rejected it. */
|
|
171
|
-
type RelationshipSetResult = {
|
|
172
|
-
readonly ok: true;
|
|
173
|
-
readonly byOwner: ReadonlyMap<string, readonly RelationshipRecord[]>;
|
|
174
|
-
} | {
|
|
175
|
-
readonly ok: false;
|
|
176
|
-
readonly error: RelationshipError;
|
|
177
|
-
};
|
|
178
|
-
/** Group relationships by owner in authored order; reject duplicate ids per owner. */
|
|
179
|
-
declare function buildRelationshipSet(records: readonly RelationshipRecord[]): RelationshipSetResult;
|
|
180
|
-
/**
|
|
181
|
-
* A relationship resolved to a part, or the reason it could not be.
|
|
182
|
-
*
|
|
183
|
-
* External targets resolve to a refusal by design: they are never followed from a file.
|
|
184
|
-
*/
|
|
185
|
-
type ResolvedRelationship = {
|
|
186
|
-
readonly mode: 'Internal';
|
|
187
|
-
readonly target: NameResult;
|
|
188
|
-
readonly raw: string;
|
|
189
|
-
} | {
|
|
190
|
-
readonly mode: 'External';
|
|
191
|
-
readonly sinkSafe: NameResult;
|
|
192
|
-
readonly raw: string;
|
|
193
|
-
};
|
|
194
|
-
/**
|
|
195
|
-
* Resolve a relationship to a runtime projection while the raw target stays
|
|
196
|
-
* authored. Internal -> owner-relative part name; External -> sink-safe
|
|
197
|
-
* validation only (never owner-resolved, never fetched). `raw` is always the
|
|
198
|
-
* verbatim authored target.
|
|
199
|
-
*/
|
|
200
|
-
declare function resolveRelationship(rec: RelationshipRecord): ResolvedRelationship;
|
|
201
|
-
/**
|
|
202
|
-
* An image relationship resolved to package bytes, or why it was refused.
|
|
203
|
-
*
|
|
204
|
-
* External-mode image rels are refused rather than fetched — the no-zero-click-external-fetch
|
|
205
|
-
* rule applies to images exactly as it does to links.
|
|
206
|
-
*/
|
|
207
|
-
type ImageRelationshipResolution = {
|
|
208
|
-
readonly mode: 'internal';
|
|
209
|
-
readonly partName: string;
|
|
210
|
-
readonly raw: string;
|
|
211
|
-
} | {
|
|
212
|
-
readonly mode: 'external';
|
|
213
|
-
readonly sinkSafe: boolean;
|
|
214
|
-
readonly raw: string;
|
|
215
|
-
} | {
|
|
216
|
-
readonly mode: 'missing';
|
|
217
|
-
};
|
|
218
|
-
/**
|
|
219
|
-
* Resolve an image relationship id from an owner part. Internal targets resolve
|
|
220
|
-
* owner-relative; external targets are never fetched; a missing id is `missing`.
|
|
221
|
-
*/
|
|
222
|
-
declare function resolveImageRelationship(records: readonly RelationshipRecord[] | undefined, ownerPart: string, relationshipId: string): ImageRelationshipResolution;
|
|
1
|
+
import { c as HistoryGroupOutcome } from './editor-scope-OHPwVQ5l.js';
|
|
223
2
|
|
|
224
3
|
/**
|
|
225
4
|
* One parsed XML node, preserving significant order, whitespace and raw lexical values.
|
|
@@ -1092,38 +871,433 @@ type OoxmlInvariantResult = {
|
|
|
1092
871
|
*/
|
|
1093
872
|
declare function readOoxmlPart(xml: string, metadata: OoxmlPartMetadata, limits?: XmlLimits): OoxmlReadResult;
|
|
1094
873
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
* `too-large` and `too-many-entries` are the zip-bomb guards; `bad-name` catches path traversal —
|
|
1099
|
-
* an entry with `..` or a leading `/` is rejected rather than normalized.
|
|
1100
|
-
*/
|
|
1101
|
-
type ZipRejection = 'too-many-entries' | 'too-large' | 'bad-name' | 'inflate-error';
|
|
1102
|
-
/** Archive caps: entry count, total decompressed bytes, and the decompression ratio. */
|
|
1103
|
-
interface ZipLimits {
|
|
1104
|
-
readonly maxEntries: number;
|
|
1105
|
-
/** Max total UNCOMPRESSED bytes across the archive. */
|
|
1106
|
-
readonly maxTotalBytes: number;
|
|
1107
|
-
/** Max per-entry uncompressed:compressed ratio (zip-bomb guard). */
|
|
1108
|
-
readonly maxRatio?: number;
|
|
1109
|
-
}
|
|
1110
|
-
/** The archive caps in force when a host configures none. Conservative and finite. */
|
|
1111
|
-
declare const DEFAULT_ZIP_LIMITS: ZipLimits;
|
|
1112
|
-
/** The read entries, or the typed refusal. Never throws — the bytes are untrusted. */
|
|
1113
|
-
type ZipReadResult = {
|
|
1114
|
-
readonly ok: true;
|
|
1115
|
-
readonly entries: ReadonlyMap<string, Uint8Array>;
|
|
874
|
+
type AutomationTableMutation = {
|
|
875
|
+
readonly kind: 'values';
|
|
876
|
+
readonly values: readonly (readonly string[])[];
|
|
1116
877
|
} | {
|
|
1117
|
-
readonly
|
|
1118
|
-
readonly
|
|
1119
|
-
readonly
|
|
1120
|
-
readonly
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
878
|
+
readonly kind: 'addRows' | 'addColumns';
|
|
879
|
+
readonly location: 'start' | 'end';
|
|
880
|
+
readonly count: number;
|
|
881
|
+
readonly values?: readonly (readonly string[])[];
|
|
882
|
+
} | {
|
|
883
|
+
readonly kind: 'deleteRows' | 'deleteColumns';
|
|
884
|
+
readonly index: number;
|
|
885
|
+
readonly count: number;
|
|
886
|
+
} | {
|
|
887
|
+
readonly kind: 'delete';
|
|
888
|
+
} | {
|
|
889
|
+
readonly kind: 'properties';
|
|
890
|
+
readonly styleId?: string;
|
|
891
|
+
readonly headerRowCount?: number;
|
|
892
|
+
} | {
|
|
893
|
+
readonly kind: 'cell';
|
|
894
|
+
readonly cellId: string;
|
|
895
|
+
readonly value?: string;
|
|
896
|
+
readonly columnWidth?: number;
|
|
897
|
+
readonly shadingColor?: string;
|
|
898
|
+
readonly verticalAlignment?: 'Top' | 'Center' | 'Bottom';
|
|
899
|
+
};
|
|
900
|
+
|
|
901
|
+
/** Select one declared entry of a legacy Word dropdown form field. */
|
|
902
|
+
interface SetLegacyDropdownOp {
|
|
903
|
+
readonly op: 'setLegacyDropdown';
|
|
904
|
+
readonly paragraphId: string;
|
|
905
|
+
readonly fieldNodeId: string;
|
|
906
|
+
readonly selectedIndex: number;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
interface SetFieldCodeOp {
|
|
910
|
+
readonly op: 'setFieldCode';
|
|
911
|
+
readonly paragraphId: string;
|
|
912
|
+
readonly fieldNodeId: string;
|
|
913
|
+
readonly code: string;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
type InsertTextOp = {
|
|
917
|
+
readonly op: 'insertText';
|
|
918
|
+
readonly paragraphId: string;
|
|
919
|
+
/** Legacy text form identity for protected filling; never an inline wrapper owner. */
|
|
920
|
+
readonly textFormFieldId?: string;
|
|
921
|
+
readonly offset: number;
|
|
922
|
+
readonly text: string;
|
|
923
|
+
/**
|
|
924
|
+
* Write this as a TRACKED insertion, attributed here.
|
|
925
|
+
*
|
|
926
|
+
* On the op rather than on the store, so suggesting stays a decision the surface makes
|
|
927
|
+
* per edit and the write vocabulary stays explicit — a global "everything is tracked
|
|
928
|
+
* now" flag is exactly what `DocEdits` refuses, because it makes the meaning of an op
|
|
929
|
+
* depend on state the op does not carry.
|
|
930
|
+
*/
|
|
931
|
+
readonly revision?: RevisionAttributionInput;
|
|
932
|
+
/**
|
|
933
|
+
* When set, the text belongs INSIDE this content control, whatever sits at the offset.
|
|
934
|
+
*
|
|
935
|
+
* A boundary offset is owned by the run that starts there, which at a control's trailing
|
|
936
|
+
* edge is the run after the control — so an offset alone cannot say "append to this field",
|
|
937
|
+
* the way it cannot say which run of a field result to format (see `targetRunIds`). A
|
|
938
|
+
* caller that names the control gets the text in the control; one that does not gets the
|
|
939
|
+
* plain offset rule, which is what a keystroke beside a field means.
|
|
940
|
+
*/
|
|
941
|
+
readonly inside?: string;
|
|
942
|
+
/**
|
|
943
|
+
* Which side of a run BOUNDARY the text joins. Default `'left'` — Word's typing rule:
|
|
944
|
+
* the next character takes the formatting of the character before the caret.
|
|
945
|
+
*
|
|
946
|
+
* `'right'` is for a caller that is not typing but placing text inside the run that
|
|
947
|
+
* STARTS at the offset — the hyperlink editor rewriting a link's display text, where
|
|
948
|
+
* landing left of the boundary would put the new text outside the link. Ignored when
|
|
949
|
+
* the offset falls strictly inside a run, which has no boundary to choose.
|
|
950
|
+
*/
|
|
951
|
+
readonly bias?: 'left' | 'right';
|
|
952
|
+
};
|
|
953
|
+
type DeleteTextOp = {
|
|
954
|
+
readonly op: 'deleteText';
|
|
955
|
+
readonly paragraphId: string;
|
|
956
|
+
/** Legacy text form identity for protected filling; never an inline wrapper owner. */
|
|
957
|
+
readonly textFormFieldId?: string;
|
|
958
|
+
readonly start: number;
|
|
959
|
+
readonly end: number;
|
|
960
|
+
/** Write this as a TRACKED deletion — the characters stay, wrapped in `w:del`. */
|
|
961
|
+
readonly revision?: RevisionAttributionInput;
|
|
962
|
+
};
|
|
963
|
+
|
|
964
|
+
/** Editable legacy text input types. Other authored types remain inert. */
|
|
965
|
+
type TextFormFieldType = 'regular' | 'number' | 'date';
|
|
966
|
+
/** Options stored in the legacy field definition. Zero means unlimited length. */
|
|
967
|
+
interface TextFormFieldOptions {
|
|
968
|
+
readonly type: TextFormFieldType;
|
|
969
|
+
readonly maxLength: number;
|
|
970
|
+
readonly format: string;
|
|
971
|
+
readonly enabled: boolean;
|
|
972
|
+
}
|
|
973
|
+
/** Supported format choices for legacy text input fields. @public */
|
|
974
|
+
declare const TEXT_FORM_FORMATS: {
|
|
975
|
+
readonly regular: readonly ["", "Uppercase", "Lowercase", "First capital", "Title case"];
|
|
976
|
+
readonly number: readonly ["", "0", "0.00", "#,##0", "#,##0.00", "0%", "0.00%"];
|
|
977
|
+
readonly date: readonly ["", "M/d/yyyy", "MM/dd/yyyy", "d/M/yyyy", "dd/MM/yyyy", "yyyy-MM-dd", "d MMMM yyyy", "MMMM d, yyyy"];
|
|
978
|
+
};
|
|
979
|
+
|
|
980
|
+
/** A legacy text input in the shared paragraph offset space. */
|
|
981
|
+
interface TextFormFieldRange {
|
|
982
|
+
readonly fieldNodeId: string;
|
|
983
|
+
readonly start: number;
|
|
984
|
+
readonly end: number;
|
|
985
|
+
readonly enabled: boolean;
|
|
986
|
+
readonly defaultText: string;
|
|
987
|
+
readonly type: string;
|
|
988
|
+
readonly maxLength: number;
|
|
989
|
+
readonly format: string;
|
|
990
|
+
readonly chromeIds: readonly string[];
|
|
991
|
+
}
|
|
992
|
+
/** Uses the field parser and offset index; never introduces another inline walk. */
|
|
993
|
+
declare function textFormFieldsOf(paragraph: OoxmlParagraphNode): readonly TextFormFieldRange[];
|
|
994
|
+
/** Options edit for an existing legacy text form. */
|
|
995
|
+
interface SetTextFormFieldDefaultOp {
|
|
996
|
+
readonly op: 'setTextFormFieldDefault';
|
|
997
|
+
/** Regional conventions for new date input; defaults to en-US. */
|
|
998
|
+
readonly locale?: string;
|
|
999
|
+
readonly paragraphId: string;
|
|
1000
|
+
readonly fieldNodeId: string;
|
|
1001
|
+
readonly text: string;
|
|
1002
|
+
readonly options?: TextFormFieldOptions;
|
|
1003
|
+
}
|
|
1004
|
+
/** Validate and format the existing result when a user finishes filling a field. */
|
|
1005
|
+
interface CommitTextFormFieldOp {
|
|
1006
|
+
readonly op: 'commitTextFormField';
|
|
1007
|
+
/** Regional conventions for new date input; defaults to en-US. */
|
|
1008
|
+
readonly locale?: string;
|
|
1009
|
+
readonly paragraphId: string;
|
|
1010
|
+
readonly fieldNodeId: string;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
/** One FORMCHECKBOX in the shared paragraph offset space. */
|
|
1014
|
+
interface LegacyCheckboxFieldRange {
|
|
1015
|
+
/** The begin `w:fldChar` node: what the op addresses. */
|
|
1016
|
+
readonly fieldNodeId: string;
|
|
1017
|
+
readonly start: number;
|
|
1018
|
+
readonly end: number;
|
|
1019
|
+
readonly checked: boolean;
|
|
1020
|
+
/** `w:enabled` under `w:ffData`; a disabled field renders but refuses the toggle. */
|
|
1021
|
+
readonly enabled: boolean;
|
|
1022
|
+
}
|
|
1023
|
+
/** Flip a FORMCHECKBOX's state; the only write into `w:ffData` a checkbox permits. */
|
|
1024
|
+
interface SetLegacyCheckboxOp {
|
|
1025
|
+
readonly op: 'setLegacyCheckbox';
|
|
1026
|
+
readonly paragraphId: string;
|
|
1027
|
+
readonly fieldNodeId: string;
|
|
1028
|
+
readonly checked: boolean;
|
|
1029
|
+
}
|
|
1030
|
+
/** Every FORMCHECKBOX in a paragraph, in document order; uses the shared field parser. */
|
|
1031
|
+
declare function legacyCheckboxFieldsOf(paragraph: OoxmlParagraphNode): readonly LegacyCheckboxFieldRange[];
|
|
1032
|
+
|
|
1033
|
+
/** Replace a building block gallery control's content with one block's body. */
|
|
1034
|
+
interface InsertBuildingBlockOp {
|
|
1035
|
+
readonly op: 'insertBuildingBlock';
|
|
1036
|
+
readonly controlId: string;
|
|
1037
|
+
/** `w:docPartPr/w:name` of the picked block, for the journal and the host. */
|
|
1038
|
+
readonly name: string;
|
|
1039
|
+
/**
|
|
1040
|
+
* Self-contained `w:docPartBody` children, cloned with fresh ids at apply.
|
|
1041
|
+
* Resource, style, field, bookmark, note and revision references return `unsupported`.
|
|
1042
|
+
*/
|
|
1043
|
+
readonly blocks: readonly OoxmlNode[];
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* Why a part or relationship name was refused.
|
|
1048
|
+
*
|
|
1049
|
+
* Path traversal is the reason this exists: a name with `..` or a leading `/` is refused rather
|
|
1050
|
+
* than normalized, because normalizing is how a crafted package reaches outside itself.
|
|
1051
|
+
*/
|
|
1052
|
+
type NameRejection = 'empty' | 'control-char' | 'backslash' | 'drive-or-unc' | 'encoded-separator' | 'encoded-dot' | 'bad-encoding' | 'empty-segment' | 'dot-segment' | 'unsafe-key' | 'segment-trailing-dot' | 'traversal-escape' | 'not-absolute-uri' | 'unsafe-scheme';
|
|
1053
|
+
/** A validated OPC name, or the typed reason it was refused. */
|
|
1054
|
+
type NameResult = {
|
|
1055
|
+
readonly ok: true;
|
|
1056
|
+
readonly partName: string;
|
|
1057
|
+
} | {
|
|
1058
|
+
readonly ok: false;
|
|
1059
|
+
readonly reason: NameRejection;
|
|
1060
|
+
};
|
|
1061
|
+
/**
|
|
1062
|
+
* Normalize a ZIP entry name or OPC part name into a canonical part name
|
|
1063
|
+
* (`/word/document.xml`). Accepts leading-slash and no-leading-slash inputs;
|
|
1064
|
+
* rejects traversal, dot segments, and the attack surface. Duplicate detection
|
|
1065
|
+
* folds ASCII case (OPC part-name equivalence).
|
|
1066
|
+
*/
|
|
1067
|
+
declare function normalizePartName(raw: string): NameResult;
|
|
1068
|
+
/**
|
|
1069
|
+
* ASCII-only lowercase fold. OPC part-name/extension equivalence is US-ASCII
|
|
1070
|
+
* case-insensitive; a locale `toLowerCase()` mis-folds e.g. Turkish `I`/`İ` and
|
|
1071
|
+
* could let two "equivalent" part names evade duplicate detection.
|
|
1072
|
+
*/
|
|
1073
|
+
declare function asciiFold(s: string): string;
|
|
1074
|
+
/** Case-folded key for OPC part-name equivalence / duplicate detection. */
|
|
1075
|
+
declare function partNameKey(partName: string): string;
|
|
1076
|
+
/**
|
|
1077
|
+
* Detect archive entries that collide after normalization (before inflation).
|
|
1078
|
+
* Returns the case-folded keys that more than one raw name maps to.
|
|
1079
|
+
*/
|
|
1080
|
+
declare function detectDuplicateNames(rawNames: readonly string[]): {
|
|
1081
|
+
readonly duplicates: readonly string[];
|
|
1082
|
+
readonly rejected: readonly {
|
|
1083
|
+
raw: string;
|
|
1084
|
+
reason: NameRejection;
|
|
1085
|
+
}[];
|
|
1086
|
+
};
|
|
1087
|
+
/**
|
|
1088
|
+
* Resolve an internal relationship target against its owner part, without
|
|
1089
|
+
* escaping the package root. `ownerPartName` is a canonical part name; the base
|
|
1090
|
+
* is its containing folder. A leading "/" target is package-absolute. `.`/`..`
|
|
1091
|
+
* segments resolve on a stack; popping above root is `traversal-escape`.
|
|
1092
|
+
*/
|
|
1093
|
+
declare function resolveInternalTarget(ownerPartName: string, rawTarget: string): NameResult;
|
|
1094
|
+
/**
|
|
1095
|
+
* Validate an external-mode relationship target. It MUST be an absolute URI, is
|
|
1096
|
+
* retained verbatim by the caller, and is NEVER owner-resolved or fetched here.
|
|
1097
|
+
* Unsafe schemes (javascript/vbscript/data/file) are rejected for runtime sinks;
|
|
1098
|
+
* the raw lexical form is still preserved separately by the authored record.
|
|
1099
|
+
*/
|
|
1100
|
+
declare function validateExternalTarget(raw: string): NameResult;
|
|
1101
|
+
|
|
1102
|
+
/** One `<Default>`: a file extension mapped to a content type. */
|
|
1103
|
+
interface DefaultRecord {
|
|
1104
|
+
readonly extension: string;
|
|
1105
|
+
readonly contentType: string;
|
|
1106
|
+
readonly order: number;
|
|
1107
|
+
}
|
|
1108
|
+
/** One `<Override>`: a specific part name mapped to a content type. Beats any Default. */
|
|
1109
|
+
interface OverrideRecord {
|
|
1110
|
+
readonly partName: string;
|
|
1111
|
+
readonly contentType: string;
|
|
1112
|
+
readonly order: number;
|
|
1113
|
+
}
|
|
1114
|
+
/**
|
|
1115
|
+
* The authored `[Content_Types].xml` records, in significant order.
|
|
1116
|
+
*
|
|
1117
|
+
* Retained rather than collapsed into a lookup, because the file's lexical form and ordering are
|
|
1118
|
+
* part of what a lossless save re-emits.
|
|
1119
|
+
*/
|
|
1120
|
+
interface ContentTypeRecords {
|
|
1121
|
+
readonly defaults: readonly DefaultRecord[];
|
|
1122
|
+
readonly overrides: readonly OverrideRecord[];
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Why content-type records could not be indexed.
|
|
1126
|
+
*
|
|
1127
|
+
* All fail CLOSED: conflicting Defaults on one extension, duplicate normalized Override names, or
|
|
1128
|
+
* invalid MIME syntax are refused rather than resolved by picking one.
|
|
1129
|
+
*/
|
|
1130
|
+
type ContentTypeError = {
|
|
1131
|
+
readonly code: 'invalid-mime';
|
|
1132
|
+
readonly value: string;
|
|
1133
|
+
} | {
|
|
1134
|
+
readonly code: 'conflicting-default';
|
|
1135
|
+
readonly extension: string;
|
|
1136
|
+
} | {
|
|
1137
|
+
readonly code: 'duplicate-override';
|
|
1138
|
+
readonly partName: string;
|
|
1139
|
+
} | {
|
|
1140
|
+
readonly code: 'invalid-override-name';
|
|
1141
|
+
readonly partName: string;
|
|
1142
|
+
} | {
|
|
1143
|
+
readonly code: 'too-many-records';
|
|
1144
|
+
readonly limit: number;
|
|
1145
|
+
};
|
|
1146
|
+
/** Whether a string is syntactically a MIME type. Syntax only — no registry lookup. */
|
|
1147
|
+
declare function isValidMime(value: string): boolean;
|
|
1148
|
+
/** ASCII-case-insensitive extension key (leading dot removed; ASCII-only fold). */
|
|
1149
|
+
declare function extensionKey(extension: string): string;
|
|
1150
|
+
/** The resolved lookup: Override by case-folded part name, Default by case-insensitive extension. */
|
|
1151
|
+
interface ContentTypeIndex {
|
|
1152
|
+
/** ext key -> single MIME (identical duplicates collapsed). */
|
|
1153
|
+
readonly defaults: ReadonlyMap<string, string>;
|
|
1154
|
+
/** case-folded part name -> MIME. */
|
|
1155
|
+
readonly overrides: ReadonlyMap<string, string>;
|
|
1156
|
+
}
|
|
1157
|
+
/** The built index, or the conflict that made it impossible. */
|
|
1158
|
+
type IndexResult = {
|
|
1159
|
+
readonly ok: true;
|
|
1160
|
+
readonly index: ContentTypeIndex;
|
|
1161
|
+
} | {
|
|
1162
|
+
readonly ok: false;
|
|
1163
|
+
readonly error: ContentTypeError;
|
|
1164
|
+
};
|
|
1165
|
+
/**
|
|
1166
|
+
* Build a resolved content-type index, failing closed on conflict/duplicate/MIME
|
|
1167
|
+
* errors. `maxRecords` bounds the combined record count (N/N+1 gate).
|
|
1168
|
+
*/
|
|
1169
|
+
declare function buildContentTypeIndex(records: ContentTypeRecords, maxRecords?: number): IndexResult;
|
|
1170
|
+
/**
|
|
1171
|
+
* A part's content type, or why it has none.
|
|
1172
|
+
*
|
|
1173
|
+
* An orphan record never determines a part's type — a Default with no matching part is preserved
|
|
1174
|
+
* inertly rather than applied.
|
|
1175
|
+
*/
|
|
1176
|
+
type ResolveResult = {
|
|
1177
|
+
readonly ok: true;
|
|
1178
|
+
readonly contentType: string;
|
|
1179
|
+
readonly source: 'override' | 'default';
|
|
1180
|
+
} | {
|
|
1181
|
+
readonly ok: false;
|
|
1182
|
+
readonly reason: 'unknown';
|
|
1183
|
+
};
|
|
1184
|
+
/** Resolve a part's content type: Override wins over Default; else unknown. */
|
|
1185
|
+
declare function resolveContentType(index: ContentTypeIndex, partName: string): ResolveResult;
|
|
1186
|
+
|
|
1187
|
+
/** OOXML image relationship type for embedded or linked media parts. */
|
|
1188
|
+
declare const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
1189
|
+
/**
|
|
1190
|
+
* Whether a relationship points inside the package or out of it.
|
|
1191
|
+
*
|
|
1192
|
+
* The security-relevant distinction: an `External` target is retained VERBATIM and never
|
|
1193
|
+
* owner-resolved or fetched, because auto-loading a file-supplied remote target is a zero-click
|
|
1194
|
+
* external fetch.
|
|
1195
|
+
*/
|
|
1196
|
+
type TargetMode = 'Internal' | 'External';
|
|
1197
|
+
/**
|
|
1198
|
+
* One authored relationship, with nothing materialized away: owner part, id, type, raw target
|
|
1199
|
+
* lexical form, mode, and position.
|
|
1200
|
+
*/
|
|
1201
|
+
interface RelationshipRecord {
|
|
1202
|
+
readonly ownerPart: string;
|
|
1203
|
+
readonly id: string;
|
|
1204
|
+
readonly type: string;
|
|
1205
|
+
readonly rawTarget: string;
|
|
1206
|
+
readonly targetMode: TargetMode;
|
|
1207
|
+
readonly order: number;
|
|
1208
|
+
}
|
|
1209
|
+
/** Why a relationship set is invalid. Duplicate ids within one owner fail closed. */
|
|
1210
|
+
type RelationshipError = {
|
|
1211
|
+
readonly code: 'duplicate-id';
|
|
1212
|
+
readonly ownerPart: string;
|
|
1213
|
+
readonly id: string;
|
|
1214
|
+
};
|
|
1215
|
+
/** The validated relationship set, or the conflict that rejected it. */
|
|
1216
|
+
type RelationshipSetResult = {
|
|
1217
|
+
readonly ok: true;
|
|
1218
|
+
readonly byOwner: ReadonlyMap<string, readonly RelationshipRecord[]>;
|
|
1219
|
+
} | {
|
|
1220
|
+
readonly ok: false;
|
|
1221
|
+
readonly error: RelationshipError;
|
|
1222
|
+
};
|
|
1223
|
+
/** Group relationships by owner in authored order; reject duplicate ids per owner. */
|
|
1224
|
+
declare function buildRelationshipSet(records: readonly RelationshipRecord[]): RelationshipSetResult;
|
|
1225
|
+
/**
|
|
1226
|
+
* A relationship resolved to a part, or the reason it could not be.
|
|
1227
|
+
*
|
|
1228
|
+
* External targets resolve to a refusal by design: they are never followed from a file.
|
|
1229
|
+
*/
|
|
1230
|
+
type ResolvedRelationship = {
|
|
1231
|
+
readonly mode: 'Internal';
|
|
1232
|
+
readonly target: NameResult;
|
|
1233
|
+
readonly raw: string;
|
|
1234
|
+
} | {
|
|
1235
|
+
readonly mode: 'External';
|
|
1236
|
+
readonly sinkSafe: NameResult;
|
|
1237
|
+
readonly raw: string;
|
|
1238
|
+
};
|
|
1239
|
+
/**
|
|
1240
|
+
* Resolve a relationship to a runtime projection while the raw target stays
|
|
1241
|
+
* authored. Internal -> owner-relative part name; External -> sink-safe
|
|
1242
|
+
* validation only (never owner-resolved, never fetched). `raw` is always the
|
|
1243
|
+
* verbatim authored target.
|
|
1244
|
+
*/
|
|
1245
|
+
declare function resolveRelationship(rec: RelationshipRecord): ResolvedRelationship;
|
|
1246
|
+
/**
|
|
1247
|
+
* An image relationship resolved to package bytes, or why it was refused.
|
|
1248
|
+
*
|
|
1249
|
+
* External-mode image rels are refused rather than fetched — the no-zero-click-external-fetch
|
|
1250
|
+
* rule applies to images exactly as it does to links.
|
|
1251
|
+
*/
|
|
1252
|
+
type ImageRelationshipResolution = {
|
|
1253
|
+
readonly mode: 'internal';
|
|
1254
|
+
readonly partName: string;
|
|
1255
|
+
readonly raw: string;
|
|
1256
|
+
} | {
|
|
1257
|
+
readonly mode: 'external';
|
|
1258
|
+
readonly sinkSafe: boolean;
|
|
1259
|
+
readonly raw: string;
|
|
1260
|
+
} | {
|
|
1261
|
+
readonly mode: 'missing';
|
|
1262
|
+
};
|
|
1263
|
+
/**
|
|
1264
|
+
* Resolve an image relationship id from an owner part. Internal targets resolve
|
|
1265
|
+
* owner-relative; external targets are never fetched; a missing id is `missing`.
|
|
1266
|
+
*/
|
|
1267
|
+
declare function resolveImageRelationship(records: readonly RelationshipRecord[] | undefined, ownerPart: string, relationshipId: string): ImageRelationshipResolution;
|
|
1268
|
+
|
|
1269
|
+
/**
|
|
1270
|
+
* Why a zip was refused at the trust boundary.
|
|
1271
|
+
*
|
|
1272
|
+
* `too-large` and `too-many-entries` are the zip-bomb guards; `bad-name` catches path traversal —
|
|
1273
|
+
* an entry with `..` or a leading `/` is rejected rather than normalized.
|
|
1274
|
+
*/
|
|
1275
|
+
type ZipRejection = 'too-many-entries' | 'too-large' | 'bad-name' | 'inflate-error';
|
|
1276
|
+
/** Archive caps: entry count, total decompressed bytes, and the decompression ratio. */
|
|
1277
|
+
interface ZipLimits {
|
|
1278
|
+
readonly maxEntries: number;
|
|
1279
|
+
/** Max total UNCOMPRESSED bytes across the archive. */
|
|
1280
|
+
readonly maxTotalBytes: number;
|
|
1281
|
+
/** Max per-entry uncompressed:compressed ratio (zip-bomb guard). */
|
|
1282
|
+
readonly maxRatio?: number;
|
|
1283
|
+
}
|
|
1284
|
+
/** The archive caps in force when a host configures none. Conservative and finite. */
|
|
1285
|
+
declare const DEFAULT_ZIP_LIMITS: ZipLimits;
|
|
1286
|
+
/** The read entries, or the typed refusal. Never throws — the bytes are untrusted. */
|
|
1287
|
+
type ZipReadResult = {
|
|
1288
|
+
readonly ok: true;
|
|
1289
|
+
readonly entries: ReadonlyMap<string, Uint8Array>;
|
|
1290
|
+
} | {
|
|
1291
|
+
readonly ok: false;
|
|
1292
|
+
readonly reason: ZipRejection;
|
|
1293
|
+
readonly detail?: string;
|
|
1294
|
+
readonly limit?: 'zip.maxTotalBytes' | 'zip.maxRatio';
|
|
1295
|
+
};
|
|
1296
|
+
/**
|
|
1297
|
+
* Inflate a ZIP archive with bounds + OPC name normalization. Entry name, count,
|
|
1298
|
+
* compression-ratio, and total-uncompressed-size limits are enforced BEFORE each
|
|
1299
|
+
* entry is decompressed (via fflate's pre-inflation filter), so a zip bomb or a
|
|
1300
|
+
* traversal name is rejected without ever being inflated. Keys are canonical part
|
|
1127
1301
|
* names.
|
|
1128
1302
|
*/
|
|
1129
1303
|
declare function readZip(bytes: Uint8Array, limits?: ZipLimits): ZipReadResult;
|
|
@@ -1515,212 +1689,81 @@ declare function projectDrawing(drawing: OoxmlDrawingNode, context: Readonly<{
|
|
|
1515
1689
|
resolveRelationship?: RelationshipTargetResolver;
|
|
1516
1690
|
resolveSchemeColor?: ShapeSchemeColorResolver;
|
|
1517
1691
|
resolveStyleMatrixReference?: ShapeStyleMatrixResolver;
|
|
1518
|
-
}>): DrawingProjection | null;
|
|
1519
|
-
|
|
1520
|
-
/** Caps applied while loading a package: zip, XML, part count and relationship count. */
|
|
1521
|
-
interface OoxmlPackageLimits {
|
|
1522
|
-
readonly zip?: ZipLimits;
|
|
1523
|
-
readonly xml?: XmlLimits;
|
|
1524
|
-
/** Cap on parts converted into canonical trees (N/N+1 gate, not a soft target). */
|
|
1525
|
-
readonly maxXmlParts?: number;
|
|
1526
|
-
/** Cap on relationship records across every rels part. */
|
|
1527
|
-
readonly maxRelationships?: number;
|
|
1528
|
-
}
|
|
1529
|
-
/** The limits in force when a host configures none. Conservative and finite. */
|
|
1530
|
-
declare const DEFAULT_OOXML_PACKAGE_LIMITS: Required<Pick<OoxmlPackageLimits, 'maxXmlParts' | 'maxRelationships'>>;
|
|
1531
|
-
/**
|
|
1532
|
-
* An external relationship target. Retained verbatim as authored evidence, with the
|
|
1533
|
-
* sink-safety verdict alongside it. Never resolved against the package, never fetched.
|
|
1534
|
-
*/
|
|
1535
|
-
interface OoxmlExternalTarget {
|
|
1536
|
-
readonly ownerPart: string;
|
|
1537
|
-
readonly id: string;
|
|
1538
|
-
readonly type: string;
|
|
1539
|
-
readonly rawTarget: string;
|
|
1540
|
-
/** False when the target is not a safe sink (javascript:, file:, ...). Still not fetched. */
|
|
1541
|
-
readonly sinkSafe: boolean;
|
|
1542
|
-
}
|
|
1543
|
-
/**
|
|
1544
|
-
* A loaded package: every XML part as a canonical tree, plus the non-XML parts kept verbatim.
|
|
1545
|
-
*
|
|
1546
|
-
* The preservation model in one value. Modelled parts re-emit normalized; everything else is
|
|
1547
|
-
* byte-identical, which is why an unrecognized part never costs a document anything.
|
|
1548
|
-
*/
|
|
1549
|
-
interface OoxmlPackage {
|
|
1550
|
-
/** Canonical trees, keyed by canonical part name. Non-XML parts are absent by design. */
|
|
1551
|
-
readonly parts: ReadonlyMap<string, OoxmlPart>;
|
|
1552
|
-
/** Raw bytes of every entry, including the non-XML parts that have no tree. */
|
|
1553
|
-
readonly partBytes: ReadonlyMap<string, Uint8Array>;
|
|
1554
|
-
/** Internal relationships by owner part, in authored order. */
|
|
1555
|
-
readonly relationships: ReadonlyMap<string, readonly RelationshipRecord[]>;
|
|
1556
|
-
readonly externalTargets: readonly OoxmlExternalTarget[];
|
|
1557
|
-
readonly contentTypes: ContentTypeIndex;
|
|
1558
|
-
/** Canonical name of the part the root `officeDocument` relationship points at. */
|
|
1559
|
-
readonly mainDocumentPart: string;
|
|
1560
|
-
}
|
|
1561
|
-
/** Why a package could not be loaded. Every code describes the FILE, not the caller. */
|
|
1562
|
-
type OoxmlPackageRejection = ZipRejection | OoxmlReadRejection | 'no-content-types' | 'bad-content-types' | 'no-main-document' | 'bad-relationship-target' | 'duplicate-relationship-id' | 'too-many-relationships' | 'too-many-xml-parts';
|
|
1563
|
-
/** A loaded package, or a typed refusal. Never throws. */
|
|
1564
|
-
type OoxmlPackageResult = {
|
|
1565
|
-
readonly ok: true;
|
|
1566
|
-
readonly package: OoxmlPackage;
|
|
1567
|
-
} | {
|
|
1568
|
-
readonly ok: false;
|
|
1569
|
-
readonly reason: OoxmlPackageRejection;
|
|
1570
|
-
readonly detail?: string;
|
|
1571
|
-
readonly limit?: 'zip.maxTotalBytes' | 'zip.maxRatio';
|
|
1572
|
-
};
|
|
1573
|
-
declare function readOoxmlPackage(bytes: Uint8Array, limits?: OoxmlPackageLimits): OoxmlPackageResult;
|
|
1574
|
-
/**
|
|
1575
|
-
* Serialize a canonical package back to DOCX bytes.
|
|
1576
|
-
*
|
|
1577
|
-
* Starts from the ORIGINAL entry bytes and overwrites only the parts held as trees. A part
|
|
1578
|
-
* the loader did not model — media, fonts, an XML part outside the modeled set — passes
|
|
1579
|
-
* through untouched, so round-tripping a document cannot lose a part the engine never
|
|
1580
|
-
* claimed to understand.
|
|
1581
|
-
*
|
|
1582
|
-
* The modeled parts are re-emitted NORMALIZED from the tree rather than patched as text.
|
|
1583
|
-
* That is the whole point of the canonical tree: correctness is judged by the two D9
|
|
1584
|
-
* oracles (the namespace-aware fingerprint and the save/reopen semantic digest), not by
|
|
1585
|
-
* byte equality, so a different-but-equivalent spelling is not a defect.
|
|
1586
|
-
*
|
|
1587
|
-
* `writeZip` re-validates every part name, so a name that became unsafe between load and
|
|
1588
|
-
* save cannot be smuggled into the archive.
|
|
1589
|
-
*/
|
|
1590
|
-
declare function writeOoxmlPackage(pkg: OoxmlPackage): Uint8Array;
|
|
1591
|
-
/** Replace one part's tree, returning a new package. Pure, like the tree edits themselves. */
|
|
1592
|
-
declare function withPart(pkg: OoxmlPackage, part: OoxmlPart): OoxmlPackage;
|
|
1593
|
-
|
|
1594
|
-
type AutomationTableMutation = {
|
|
1595
|
-
readonly kind: 'values';
|
|
1596
|
-
readonly values: readonly (readonly string[])[];
|
|
1597
|
-
} | {
|
|
1598
|
-
readonly kind: 'addRows' | 'addColumns';
|
|
1599
|
-
readonly location: 'start' | 'end';
|
|
1600
|
-
readonly count: number;
|
|
1601
|
-
readonly values?: readonly (readonly string[])[];
|
|
1602
|
-
} | {
|
|
1603
|
-
readonly kind: 'deleteRows' | 'deleteColumns';
|
|
1604
|
-
readonly index: number;
|
|
1605
|
-
readonly count: number;
|
|
1606
|
-
} | {
|
|
1607
|
-
readonly kind: 'delete';
|
|
1608
|
-
} | {
|
|
1609
|
-
readonly kind: 'properties';
|
|
1610
|
-
readonly styleId?: string;
|
|
1611
|
-
readonly headerRowCount?: number;
|
|
1612
|
-
} | {
|
|
1613
|
-
readonly kind: 'cell';
|
|
1614
|
-
readonly cellId: string;
|
|
1615
|
-
readonly value?: string;
|
|
1616
|
-
readonly columnWidth?: number;
|
|
1617
|
-
readonly shadingColor?: string;
|
|
1618
|
-
readonly verticalAlignment?: 'Top' | 'Center' | 'Bottom';
|
|
1619
|
-
};
|
|
1620
|
-
|
|
1621
|
-
interface SetFieldCodeOp {
|
|
1622
|
-
readonly op: 'setFieldCode';
|
|
1623
|
-
readonly paragraphId: string;
|
|
1624
|
-
readonly fieldNodeId: string;
|
|
1625
|
-
readonly code: string;
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
type InsertTextOp = {
|
|
1629
|
-
readonly op: 'insertText';
|
|
1630
|
-
readonly paragraphId: string;
|
|
1631
|
-
/** Legacy text form identity for protected filling; never an inline wrapper owner. */
|
|
1632
|
-
readonly textFormFieldId?: string;
|
|
1633
|
-
readonly offset: number;
|
|
1634
|
-
readonly text: string;
|
|
1635
|
-
/**
|
|
1636
|
-
* Write this as a TRACKED insertion, attributed here.
|
|
1637
|
-
*
|
|
1638
|
-
* On the op rather than on the store, so suggesting stays a decision the surface makes
|
|
1639
|
-
* per edit and the write vocabulary stays explicit — a global "everything is tracked
|
|
1640
|
-
* now" flag is exactly what `DocEdits` refuses, because it makes the meaning of an op
|
|
1641
|
-
* depend on state the op does not carry.
|
|
1642
|
-
*/
|
|
1643
|
-
readonly revision?: RevisionAttributionInput;
|
|
1644
|
-
/**
|
|
1645
|
-
* When set, the text belongs INSIDE this content control, whatever sits at the offset.
|
|
1646
|
-
*
|
|
1647
|
-
* A boundary offset is owned by the run that starts there, which at a control's trailing
|
|
1648
|
-
* edge is the run after the control — so an offset alone cannot say "append to this field",
|
|
1649
|
-
* the way it cannot say which run of a field result to format (see `targetRunIds`). A
|
|
1650
|
-
* caller that names the control gets the text in the control; one that does not gets the
|
|
1651
|
-
* plain offset rule, which is what a keystroke beside a field means.
|
|
1652
|
-
*/
|
|
1653
|
-
readonly inside?: string;
|
|
1654
|
-
/**
|
|
1655
|
-
* Which side of a run BOUNDARY the text joins. Default `'left'` — Word's typing rule:
|
|
1656
|
-
* the next character takes the formatting of the character before the caret.
|
|
1657
|
-
*
|
|
1658
|
-
* `'right'` is for a caller that is not typing but placing text inside the run that
|
|
1659
|
-
* STARTS at the offset — the hyperlink editor rewriting a link's display text, where
|
|
1660
|
-
* landing left of the boundary would put the new text outside the link. Ignored when
|
|
1661
|
-
* the offset falls strictly inside a run, which has no boundary to choose.
|
|
1662
|
-
*/
|
|
1663
|
-
readonly bias?: 'left' | 'right';
|
|
1664
|
-
};
|
|
1665
|
-
type DeleteTextOp = {
|
|
1666
|
-
readonly op: 'deleteText';
|
|
1667
|
-
readonly paragraphId: string;
|
|
1668
|
-
/** Legacy text form identity for protected filling; never an inline wrapper owner. */
|
|
1669
|
-
readonly textFormFieldId?: string;
|
|
1670
|
-
readonly start: number;
|
|
1671
|
-
readonly end: number;
|
|
1672
|
-
/** Write this as a TRACKED deletion — the characters stay, wrapped in `w:del`. */
|
|
1673
|
-
readonly revision?: RevisionAttributionInput;
|
|
1674
|
-
};
|
|
1692
|
+
}>): DrawingProjection | null;
|
|
1675
1693
|
|
|
1676
|
-
/**
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
readonly
|
|
1682
|
-
|
|
1683
|
-
readonly
|
|
1694
|
+
/** Caps applied while loading a package: zip, XML, part count and relationship count. */
|
|
1695
|
+
interface OoxmlPackageLimits {
|
|
1696
|
+
readonly zip?: ZipLimits;
|
|
1697
|
+
readonly xml?: XmlLimits;
|
|
1698
|
+
/** Cap on parts converted into canonical trees (N/N+1 gate, not a soft target). */
|
|
1699
|
+
readonly maxXmlParts?: number;
|
|
1700
|
+
/** Cap on relationship records across every rels part. */
|
|
1701
|
+
readonly maxRelationships?: number;
|
|
1684
1702
|
}
|
|
1685
|
-
/**
|
|
1686
|
-
declare const
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
readonly fieldNodeId: string;
|
|
1695
|
-
readonly start: number;
|
|
1696
|
-
readonly end: number;
|
|
1697
|
-
readonly enabled: boolean;
|
|
1698
|
-
readonly defaultText: string;
|
|
1703
|
+
/** The limits in force when a host configures none. Conservative and finite. */
|
|
1704
|
+
declare const DEFAULT_OOXML_PACKAGE_LIMITS: Required<Pick<OoxmlPackageLimits, 'maxXmlParts' | 'maxRelationships'>>;
|
|
1705
|
+
/**
|
|
1706
|
+
* An external relationship target. Retained verbatim as authored evidence, with the
|
|
1707
|
+
* sink-safety verdict alongside it. Never resolved against the package, never fetched.
|
|
1708
|
+
*/
|
|
1709
|
+
interface OoxmlExternalTarget {
|
|
1710
|
+
readonly ownerPart: string;
|
|
1711
|
+
readonly id: string;
|
|
1699
1712
|
readonly type: string;
|
|
1700
|
-
readonly
|
|
1701
|
-
|
|
1702
|
-
readonly
|
|
1703
|
-
}
|
|
1704
|
-
/** Uses the field parser and offset index; never introduces another inline walk. */
|
|
1705
|
-
declare function textFormFieldsOf(paragraph: OoxmlParagraphNode): readonly TextFormFieldRange[];
|
|
1706
|
-
/** Options edit for an existing legacy text form. */
|
|
1707
|
-
interface SetTextFormFieldDefaultOp {
|
|
1708
|
-
readonly op: 'setTextFormFieldDefault';
|
|
1709
|
-
/** Regional conventions for new date input; defaults to en-US. */
|
|
1710
|
-
readonly locale?: string;
|
|
1711
|
-
readonly paragraphId: string;
|
|
1712
|
-
readonly fieldNodeId: string;
|
|
1713
|
-
readonly text: string;
|
|
1714
|
-
readonly options?: TextFormFieldOptions;
|
|
1713
|
+
readonly rawTarget: string;
|
|
1714
|
+
/** False when the target is not a safe sink (javascript:, file:, ...). Still not fetched. */
|
|
1715
|
+
readonly sinkSafe: boolean;
|
|
1715
1716
|
}
|
|
1716
|
-
/**
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1717
|
+
/**
|
|
1718
|
+
* A loaded package: every XML part as a canonical tree, plus the non-XML parts kept verbatim.
|
|
1719
|
+
*
|
|
1720
|
+
* The preservation model in one value. Modelled parts re-emit normalized; everything else is
|
|
1721
|
+
* byte-identical, which is why an unrecognized part never costs a document anything.
|
|
1722
|
+
*/
|
|
1723
|
+
interface OoxmlPackage {
|
|
1724
|
+
/** Canonical trees, keyed by canonical part name. Non-XML parts are absent by design. */
|
|
1725
|
+
readonly parts: ReadonlyMap<string, OoxmlPart>;
|
|
1726
|
+
/** Raw bytes of every entry, including the non-XML parts that have no tree. */
|
|
1727
|
+
readonly partBytes: ReadonlyMap<string, Uint8Array>;
|
|
1728
|
+
/** Internal relationships by owner part, in authored order. */
|
|
1729
|
+
readonly relationships: ReadonlyMap<string, readonly RelationshipRecord[]>;
|
|
1730
|
+
readonly externalTargets: readonly OoxmlExternalTarget[];
|
|
1731
|
+
readonly contentTypes: ContentTypeIndex;
|
|
1732
|
+
/** Canonical name of the part the root `officeDocument` relationship points at. */
|
|
1733
|
+
readonly mainDocumentPart: string;
|
|
1723
1734
|
}
|
|
1735
|
+
/** Why a package could not be loaded. Every code describes the FILE, not the caller. */
|
|
1736
|
+
type OoxmlPackageRejection = ZipRejection | OoxmlReadRejection | 'no-content-types' | 'bad-content-types' | 'no-main-document' | 'bad-relationship-target' | 'duplicate-relationship-id' | 'too-many-relationships' | 'too-many-xml-parts';
|
|
1737
|
+
/** A loaded package, or a typed refusal. Never throws. */
|
|
1738
|
+
type OoxmlPackageResult = {
|
|
1739
|
+
readonly ok: true;
|
|
1740
|
+
readonly package: OoxmlPackage;
|
|
1741
|
+
} | {
|
|
1742
|
+
readonly ok: false;
|
|
1743
|
+
readonly reason: OoxmlPackageRejection;
|
|
1744
|
+
readonly detail?: string;
|
|
1745
|
+
readonly limit?: 'zip.maxTotalBytes' | 'zip.maxRatio';
|
|
1746
|
+
};
|
|
1747
|
+
declare function readOoxmlPackage(bytes: Uint8Array, limits?: OoxmlPackageLimits): OoxmlPackageResult;
|
|
1748
|
+
/**
|
|
1749
|
+
* Serialize a canonical package back to DOCX bytes.
|
|
1750
|
+
*
|
|
1751
|
+
* Starts from the ORIGINAL entry bytes and overwrites only the parts held as trees. A part
|
|
1752
|
+
* the loader did not model — media, fonts, an XML part outside the modeled set — passes
|
|
1753
|
+
* through untouched, so round-tripping a document cannot lose a part the engine never
|
|
1754
|
+
* claimed to understand.
|
|
1755
|
+
*
|
|
1756
|
+
* The modeled parts are re-emitted NORMALIZED from the tree rather than patched as text.
|
|
1757
|
+
* That is the whole point of the canonical tree: correctness is judged by the two D9
|
|
1758
|
+
* oracles (the namespace-aware fingerprint and the save/reopen semantic digest), not by
|
|
1759
|
+
* byte equality, so a different-but-equivalent spelling is not a defect.
|
|
1760
|
+
*
|
|
1761
|
+
* `writeZip` re-validates every part name, so a name that became unsafe between load and
|
|
1762
|
+
* save cannot be smuggled into the archive.
|
|
1763
|
+
*/
|
|
1764
|
+
declare function writeOoxmlPackage(pkg: OoxmlPackage): Uint8Array;
|
|
1765
|
+
/** Replace one part's tree, returning a new package. Pure, like the tree edits themselves. */
|
|
1766
|
+
declare function withPart(pkg: OoxmlPackage, part: OoxmlPart): OoxmlPackage;
|
|
1724
1767
|
|
|
1725
1768
|
/** The `w15` namespace: `commentsExtended.xml` — thread parent and resolved state. */
|
|
1726
1769
|
declare const W15_NAMESPACE_URI = "http://schemas.microsoft.com/office/word/2012/wordml";
|
|
@@ -1799,1146 +1842,1147 @@ declare function threadStateOfPart(part: OoxmlPart): Map<string, CommentThreadSt
|
|
|
1799
1842
|
*/
|
|
1800
1843
|
declare function hasAnyComment(pkg: OoxmlPackage): boolean;
|
|
1801
1844
|
|
|
1802
|
-
/**
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
readonly partName: string;
|
|
1810
|
-
readonly start: ReviewPosition;
|
|
1811
|
-
readonly end: ReviewPosition;
|
|
1812
|
-
}
|
|
1813
|
-
/**
|
|
1814
|
-
* What kind of decision a revision card represents.
|
|
1815
|
-
*
|
|
1816
|
-
* Wider than the four content wrappers, because a reviewer has to be shown every pending
|
|
1817
|
-
* decision, including the ones that decorate no characters. A card the surface cannot show is
|
|
1818
|
-
* a change the reviewer never learns about — and `acceptAllRevisions` refuses if ANY revision
|
|
1819
|
-
* in the document is one the engine cannot resolve, so an invisible one makes Accept All fail
|
|
1820
|
-
* for a reason nothing on screen explains.
|
|
1821
|
-
*/
|
|
1822
|
-
type ReviewRevisionKind = 'insert' | 'delete'
|
|
1845
|
+
/** How deep controls may nest before a walk stops descending. Shared by every lane. */
|
|
1846
|
+
declare const MAX_CONTENT_CONTROL_NESTING = 32;
|
|
1847
|
+
/** Cap on controls one walk reports, so a hostile file cannot make a read unbounded. */
|
|
1848
|
+
declare const MAX_CONTENT_CONTROLS_PER_PART = 10000;
|
|
1849
|
+
/** `CT_SdtPr/w:id` is `ST_DecimalNumber`; Word treats it as a signed 32-bit integer. */
|
|
1850
|
+
declare const CONTENT_CONTROL_ID_MAX = 2147483647;
|
|
1851
|
+
/** `ST_Lock` (§17.5.2.24). An absent `w:lock` is `unlocked`. */
|
|
1823
1852
|
/**
|
|
1824
|
-
*
|
|
1853
|
+
* `w:lock` — what a control refuses.
|
|
1825
1854
|
*
|
|
1826
|
-
*
|
|
1827
|
-
*
|
|
1828
|
-
* leaves the replacement text unproposed, rejecting it alone leaves both.
|
|
1855
|
+
* `sdtLocked` protects the wrapper, `contentLocked` the text inside it, and `sdtContentLocked`
|
|
1856
|
+
* both. A control inside a locked one is locked in effect regardless of its own value.
|
|
1829
1857
|
*/
|
|
1830
|
-
| '
|
|
1831
|
-
/** `w:rPrChange` / `w:pPrChange` — the words are unchanged, their formatting is not. */
|
|
1832
|
-
| 'format'
|
|
1833
|
-
/** `w:pPr/w:rPr/w:ins|w:del` — a paragraph split or merge. */
|
|
1834
|
-
| 'paragraphMark'
|
|
1835
|
-
/** A row, cell, section or grid revision. Supported row revisions are resolvable. */
|
|
1836
|
-
| 'structural';
|
|
1858
|
+
type ContentControlLock = 'unlocked' | 'sdtLocked' | 'contentLocked' | 'sdtContentLocked';
|
|
1837
1859
|
/**
|
|
1838
|
-
*
|
|
1860
|
+
* What kind of control this is.
|
|
1839
1861
|
*
|
|
1840
|
-
*
|
|
1841
|
-
*
|
|
1862
|
+
* `checkbox` is the Microsoft `w14:checkbox` extension rather than an ECMA-376 type
|
|
1863
|
+
* element, and the two are not mutually exclusive with "declares no type": four controls
|
|
1864
|
+
* in the comprehensive fixture declare the extension and no `w:`-prefixed type, so a scan
|
|
1865
|
+
* that read only the ECMA-376 choice reported them untyped. `untyped` means the control
|
|
1866
|
+
* declares neither — a rich-text container, which is what Word treats it as.
|
|
1842
1867
|
*/
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
readonly
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
readonly
|
|
1857
|
-
/** The words a replacement removes. Empty for every other kind. */
|
|
1858
|
-
readonly replacedText: string;
|
|
1859
|
-
readonly revisionKind: ReviewRevisionKind;
|
|
1860
|
-
/** OOXML property-change element, used to resolve independently numbered formatting kinds. */
|
|
1861
|
-
readonly formattingKind?: string;
|
|
1862
|
-
/** Changed direct formatting values, ready for localized review summaries. */
|
|
1863
|
-
readonly formattingChanges?: readonly {
|
|
1864
|
-
readonly property: 'bold' | 'italic' | 'underline' | 'strike' | 'fontFamily' | 'fontSize' | 'color' | 'alignment' | 'leftIndent' | 'rightIndent' | 'firstLineIndent' | 'hangingIndent' | 'spaceBefore' | 'spaceAfter';
|
|
1865
|
-
/** New direct value; null means inherit. Sizes and distances are in points. */
|
|
1866
|
-
readonly value: string | null;
|
|
1867
|
-
}[];
|
|
1868
|
-
/** Newly applied proofing language codes in a tracked formatting change. */
|
|
1869
|
-
readonly formattingLanguages?: readonly string[];
|
|
1870
|
-
/**
|
|
1871
|
-
* WHICH decision a `paragraphMark` records, absent for every other kind.
|
|
1872
|
-
*
|
|
1873
|
-
* `EG_ParaRPrTrackChanges` is `ins? del? moveFrom? moveTo?`, and the four say opposite
|
|
1874
|
-
* things about one break. Without this a card called a deleted break an inserted one, which
|
|
1875
|
-
* is the reverse of what Accept on that card does.
|
|
1876
|
-
*/
|
|
1877
|
-
readonly markDirection?: 'insert' | 'delete' | 'moveFrom' | 'moveTo';
|
|
1878
|
-
readonly author: string;
|
|
1879
|
-
readonly date?: string;
|
|
1880
|
-
/** Text the revision covers, for the card summary. Empty for changes with no characters. */
|
|
1881
|
-
readonly text: string;
|
|
1882
|
-
/** Every site this decision touches, in document order. */
|
|
1883
|
-
readonly ranges: readonly ReviewRange[];
|
|
1884
|
-
/**
|
|
1885
|
-
* How deeply this change is NESTED inside other changes, 0 for an unenclosed one.
|
|
1886
|
-
*
|
|
1887
|
-
* `w:ins` wrapping `w:del` is content one reviewer added and another struck. Both stay
|
|
1888
|
-
* pending, so both are cards, over one identical range — and a range then cannot say which
|
|
1889
|
-
* change a caret is in. Word treats the innermost as the operative one, so it wins the caret
|
|
1890
|
-
* and the change enclosing it stays listed and reachable.
|
|
1891
|
-
*/
|
|
1892
|
-
readonly nesting: number;
|
|
1893
|
-
/**
|
|
1894
|
-
* How many leading `ranges` are the STRUCK half of a replacement.
|
|
1895
|
-
*
|
|
1896
|
-
* A replacement's card is one decision but its ranges are two colours — red over what is
|
|
1897
|
-
* going, green over what takes its place. ABSENT when the halves do not split at a single
|
|
1898
|
-
* point, which is what a file recording both under one revision id can produce; a surface
|
|
1899
|
-
* then has no basis for two colours and should paint one neutral band rather than guess.
|
|
1900
|
-
*/
|
|
1901
|
-
readonly replacedRangeCount?: number;
|
|
1902
|
-
/**
|
|
1903
|
-
* True when the engine cannot resolve this kind, so accept and reject must not be offered.
|
|
1904
|
-
*
|
|
1905
|
-
* Derived by the DERIVATION rather than from a caller-supplied predicate: the refusal list
|
|
1906
|
-
* is internal, and a surface asked to compute it would have to guess. A card that offers a
|
|
1907
|
-
* button the engine will refuse is worse than one that explains why it cannot.
|
|
1908
|
-
*/
|
|
1909
|
-
readonly readOnly: boolean;
|
|
1910
|
-
/** The other half of a move, or the other side of a delete/insert replacement. */
|
|
1911
|
-
readonly pairedWith?: string;
|
|
1912
|
-
/**
|
|
1913
|
-
* Comments answering this change, in document order.
|
|
1914
|
-
*
|
|
1915
|
-
* A reply to a tracked change IS a comment: `w:ins` and `w:del` carry no body, so the text
|
|
1916
|
-
* is written as a comment over the revision's own range and the range is what links them.
|
|
1917
|
-
*/
|
|
1918
|
-
readonly replyIds: readonly string[];
|
|
1868
|
+
/** Which kind of control a `w:sdt` is, and therefore what a written value must look like. */
|
|
1869
|
+
type ContentControlKind = 'richText' | 'plainText' | 'checkbox' | 'dropDownList' | 'comboBox' | 'date' | 'picture' | 'docPartObj' | 'docPartList' | 'group' | 'citation' | 'bibliography' | 'equation' | 'untyped';
|
|
1870
|
+
/** One declared option of a dropdown or combo box: its display text and its stored value. */
|
|
1871
|
+
interface ContentControlListItem {
|
|
1872
|
+
readonly displayText: string;
|
|
1873
|
+
readonly value: string;
|
|
1874
|
+
}
|
|
1875
|
+
/** A date picker's authored format and locale, for rendering and for parsing what it stores. */
|
|
1876
|
+
interface ContentControlDateFormat {
|
|
1877
|
+
readonly fullDate?: string;
|
|
1878
|
+
readonly dateFormat?: string;
|
|
1879
|
+
readonly lid?: string;
|
|
1880
|
+
readonly storeMappedDataAs?: string;
|
|
1881
|
+
readonly calendar?: string;
|
|
1919
1882
|
}
|
|
1920
|
-
/**
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
readonly kind: 'comment';
|
|
1926
|
-
readonly id: string;
|
|
1927
|
-
readonly comment: CommentRecord;
|
|
1928
|
-
readonly range: ReviewRange | null;
|
|
1929
|
-
readonly resolved: boolean;
|
|
1930
|
-
/** The comment this replies to, absent for a top-level comment. */
|
|
1931
|
-
readonly parentId?: string;
|
|
1932
|
-
/** The REVISION this comment answers, when it covers exactly that change's characters. */
|
|
1933
|
-
readonly parentRevisionId?: string;
|
|
1934
|
-
/** Replies to this comment, in document order. Empty for a reply or a childless comment. */
|
|
1935
|
-
readonly replyIds: readonly string[];
|
|
1936
|
-
/** True when the file gave this comment no usable range. */
|
|
1937
|
-
readonly orphaned: boolean;
|
|
1883
|
+
/** One of a checkbox's two glyphs: the font and code point it is drawn with. */
|
|
1884
|
+
interface ContentControlCheckboxState {
|
|
1885
|
+
/** The `w14:val` hex code point of the glyph, exactly as the control declares it. */
|
|
1886
|
+
readonly value: string;
|
|
1887
|
+
readonly font?: string;
|
|
1938
1888
|
}
|
|
1939
1889
|
/**
|
|
1940
|
-
* A
|
|
1941
|
-
* hook), anchored at the node's range.
|
|
1890
|
+
* A checkbox's state and the two glyphs it chooses between.
|
|
1942
1891
|
*
|
|
1943
|
-
*
|
|
1944
|
-
*
|
|
1945
|
-
* produced them), but `attrs` and `text` originate in a file an attacker controls — a
|
|
1946
|
-
* surface renders every one of these as text, never markup.
|
|
1892
|
+
* Both glyphs matter on a write: setting the value has to update `w14:checked` AND the run's
|
|
1893
|
+
* character, or the document's glyph and its recorded state disagree.
|
|
1947
1894
|
*/
|
|
1948
|
-
interface
|
|
1949
|
-
readonly
|
|
1950
|
-
|
|
1951
|
-
readonly
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
readonly
|
|
1958
|
-
|
|
1959
|
-
readonly text: string;
|
|
1960
|
-
/**
|
|
1961
|
-
* The payload the node's control binds to, after the definition validated it.
|
|
1962
|
-
*
|
|
1963
|
-
* Undefined when the node carries none or the payload did not match — see the pro package's
|
|
1964
|
-
* `RecognizedCustomNode.data`, which this is carried from.
|
|
1965
|
-
*/
|
|
1966
|
-
readonly data?: unknown;
|
|
1967
|
-
/**
|
|
1968
|
-
* Whether this node asked for a sidebar card.
|
|
1969
|
-
*
|
|
1970
|
-
* False for a definition with no `reviewCard`: the item exists so the chip's own surfaces can
|
|
1971
|
-
* read `attrs`, `text` and `data` off it, and the rail leaves it out. A surface listing cards
|
|
1972
|
-
* filters on this rather than on an empty `title`.
|
|
1973
|
-
*/
|
|
1974
|
-
readonly carded: boolean;
|
|
1975
|
-
/** Card title, from the definition's `reviewCard` hook. Empty when `carded` is false. */
|
|
1976
|
-
readonly title: string;
|
|
1977
|
-
/** Card body, from the definition's `reviewCard` hook. */
|
|
1978
|
-
readonly detail?: string;
|
|
1979
|
-
/**
|
|
1980
|
-
* Glyph for this node in the collapsed rail, as an SVG path in a `0 -960 960 960` viewBox.
|
|
1981
|
-
*
|
|
1982
|
-
* A PATH rather than a rendered node because this item crosses core, which is DOM-free and
|
|
1983
|
-
* React-free — the same reason `title` and `detail` are strings. A host that wants arbitrary
|
|
1984
|
-
* markup overrides the `Markers` part's `icon` instead, which lives in the adapter where JSX
|
|
1985
|
-
* belongs. Absent falls back to the generic custom-node glyph.
|
|
1986
|
-
*
|
|
1987
|
-
* HOST-AUTHORED, never file data: it is interpolated into an SVG `d` attribute, and a path
|
|
1988
|
-
* taken from a document would be attacker-controlled markup.
|
|
1989
|
-
*/
|
|
1990
|
-
readonly icon?: string;
|
|
1991
|
-
readonly range: ReviewRange | null;
|
|
1895
|
+
interface ContentControlCheckbox {
|
|
1896
|
+
readonly checked: boolean;
|
|
1897
|
+
readonly checkedState?: ContentControlCheckboxState;
|
|
1898
|
+
readonly uncheckedState?: ContentControlCheckboxState;
|
|
1899
|
+
}
|
|
1900
|
+
/** `CT_DataBinding` — preserved metadata. Never resolved, never fetched. */
|
|
1901
|
+
/** `w:dataBinding` — the custom-XML part and XPath a control's value is bound to. */
|
|
1902
|
+
interface ContentControlDataBinding {
|
|
1903
|
+
readonly xpath?: string;
|
|
1904
|
+
readonly storeItemID?: string;
|
|
1905
|
+
readonly prefixMappings?: string;
|
|
1992
1906
|
}
|
|
1993
1907
|
/**
|
|
1994
|
-
*
|
|
1995
|
-
* custom-node card. Discriminate on `kind`.
|
|
1908
|
+
* A control's whole `w:sdtPr`, projected into one typed shape.
|
|
1996
1909
|
*
|
|
1997
|
-
*
|
|
1998
|
-
*
|
|
1910
|
+
* What every other lane reads instead of walking `localName` strings — which also means a Word
|
|
1911
|
+
* re-save that demotes the properties node to generic does not break the projection.
|
|
1999
1912
|
*/
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
readonly
|
|
2011
|
-
|
|
2012
|
-
readonly
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
* `kind: 'custom'` cards for definitions that opted in.
|
|
2021
|
-
*/
|
|
2022
|
-
readonly customNodes?: readonly unknown[] | undefined;
|
|
2023
|
-
/**
|
|
2024
|
-
* Where a capability package reports a node it could not read. Supplied per editor, so a page
|
|
2025
|
-
* with two of them keeps their diagnostics apart.
|
|
2026
|
-
*/
|
|
2027
|
-
readonly reportCustomNodeDiagnostic?: ((diagnostic: unknown) => void) | undefined;
|
|
2028
|
-
/**
|
|
2029
|
-
* The payload each of the story's controls binds to, keyed by the control's node id.
|
|
2030
|
-
*
|
|
2031
|
-
* Resolved by the ENGINE and handed over, because a payload lives in a customXml data part
|
|
2032
|
-
* and a derivation that only receives story parts has no way to reach one. Untrusted file
|
|
2033
|
-
* input on both members; a capability package validates it against whatever shape it
|
|
2034
|
-
* declared before handing it to a host.
|
|
2035
|
-
*/
|
|
2036
|
-
readonly customNodePayloads?: ReadonlyMap<string, {
|
|
2037
|
-
readonly nodeId: string;
|
|
2038
|
-
readonly label: string;
|
|
2039
|
-
readonly data: string;
|
|
2040
|
-
}> | undefined;
|
|
1913
|
+
interface ContentControlProperties {
|
|
1914
|
+
readonly type: ContentControlKind;
|
|
1915
|
+
readonly alias?: string;
|
|
1916
|
+
readonly tag?: string;
|
|
1917
|
+
/** `@w:val` of `w:id` when the file declares a parseable one. Never fabricated. */
|
|
1918
|
+
readonly id?: number;
|
|
1919
|
+
readonly lock: ContentControlLock;
|
|
1920
|
+
/** The glossary entry named by `w:placeholder/w:docPart`. Preserved, never loaded. */
|
|
1921
|
+
readonly placeholderDocPart?: string;
|
|
1922
|
+
readonly temporary: boolean;
|
|
1923
|
+
readonly showingPlaceholder: boolean;
|
|
1924
|
+
readonly dataBinding?: ContentControlDataBinding;
|
|
1925
|
+
readonly label?: string;
|
|
1926
|
+
readonly tabIndex?: number;
|
|
1927
|
+
/** Items a dropdown or combo box offers. Empty for every other type. */
|
|
1928
|
+
readonly listItems: readonly ContentControlListItem[];
|
|
1929
|
+
readonly lastValue?: string;
|
|
1930
|
+
readonly date?: ContentControlDateFormat;
|
|
1931
|
+
readonly multiLine?: boolean;
|
|
1932
|
+
readonly checkbox?: ContentControlCheckbox;
|
|
2041
1933
|
}
|
|
2042
|
-
/**
|
|
2043
|
-
declare function
|
|
2044
|
-
/**
|
|
2045
|
-
declare function
|
|
2046
|
-
/** The first range of an item, in authored order, or null when it has none. */
|
|
2047
|
-
declare function firstReviewRange(item: ReviewItem): ReviewRange | null;
|
|
1934
|
+
/** Whether a node is a `w:sdt` wrapper. */
|
|
1935
|
+
declare function isContentControlNode(node: OoxmlNode): node is OoxmlContentControlNode;
|
|
1936
|
+
/** Whether a node is a `w:sdtContent` — the container holding a control's actual content. */
|
|
1937
|
+
declare function isContentControlContentNode(node: OoxmlNode): node is OoxmlContentControlContentNode;
|
|
2048
1938
|
/**
|
|
2049
|
-
* A
|
|
1939
|
+
* A `w:sdt` wrapper, TYPED or DEMOTED.
|
|
2050
1940
|
*
|
|
2051
|
-
*
|
|
2052
|
-
*
|
|
2053
|
-
*
|
|
1941
|
+
* Flattening predates typing and must not stop at a control the reader refused to type: a
|
|
1942
|
+
* demoted wrapper still renders its content in place in Word, so a walk that only saw the
|
|
1943
|
+
* typed kind would drop every paragraph inside a malformed control out of the story.
|
|
2054
1944
|
*/
|
|
2055
|
-
declare function
|
|
1945
|
+
declare function isContentControlWrapper(node: OoxmlNode): boolean;
|
|
2056
1946
|
/**
|
|
2057
|
-
*
|
|
1947
|
+
* The children of a wrapper's `w:sdtContent`, typed or demoted, in order.
|
|
2058
1948
|
*
|
|
2059
|
-
*
|
|
2060
|
-
*
|
|
2061
|
-
*
|
|
1949
|
+
* The one place that knows a control's content is reached through an intermediate element,
|
|
1950
|
+
* so the four flattening walks (story blocks, layout, header/footer references, list
|
|
1951
|
+
* resolution) ask the same question rather than each re-deriving it.
|
|
2062
1952
|
*/
|
|
2063
|
-
declare function
|
|
1953
|
+
declare function contentControlContentChildren(wrapper: OoxmlNode): readonly OoxmlNode[];
|
|
2064
1954
|
/**
|
|
2065
|
-
*
|
|
1955
|
+
* A container's children with every content-control wrapper flattened away, bounded in depth.
|
|
2066
1956
|
*
|
|
2067
|
-
*
|
|
2068
|
-
*
|
|
1957
|
+
* ONE unwrap rule, for the places where a control sits between a container and the children that
|
|
1958
|
+
* container is defined in terms of. `CT_SdtRow` puts it between `w:tbl` and `w:tr`, `CT_SdtCell`
|
|
1959
|
+
* between `w:tr` and `w:tc`, and a walk that filtered on the child's kind dropped the row or cell
|
|
1960
|
+
* entirely: not measured, not painted, not addressable. Flattening at the point of the filter
|
|
1961
|
+
* means a controlled row is the same row to the grid pass, the pagination pass and the story walk.
|
|
2069
1962
|
*
|
|
2070
|
-
*
|
|
2071
|
-
*
|
|
2072
|
-
*
|
|
2073
|
-
* nothing on screen showing it: the reply box vanished from a comment the moment somebody
|
|
2074
|
-
* replied to it.
|
|
1963
|
+
* Returns the SAME array identity when there is nothing to unwrap, so the tables that carry no
|
|
1964
|
+
* controls — nearly all of them — allocate nothing and the incremental layout cache still sees
|
|
1965
|
+
* its own inputs.
|
|
2075
1966
|
*/
|
|
2076
|
-
declare function
|
|
1967
|
+
declare function flattenContentControls(children: readonly OoxmlNode[], maxDepth?: number): readonly OoxmlNode[];
|
|
1968
|
+
/** A control's `w:sdtPr`, or null. Matches structurally, so a Word-demoted node still resolves. */
|
|
1969
|
+
declare function contentControlPropertiesNodeOf(control: OoxmlNode): OoxmlContentControlPropertiesNode | undefined;
|
|
1970
|
+
/** A control's `w:sdtEndPr` — the run properties applied to its closing marker. */
|
|
1971
|
+
declare function contentControlEndPropertiesNodeOf(control: OoxmlNode): OoxmlContentControlEndPropertiesNode | undefined;
|
|
1972
|
+
/** A control's `w:sdtContent`, or null when the wrapper has none. */
|
|
1973
|
+
declare function contentControlContentNodeOf(control: OoxmlNode): OoxmlContentControlContentNode | undefined;
|
|
1974
|
+
/** A signed 32-bit `ST_DecimalNumber`, or undefined when the file wrote something else. */
|
|
1975
|
+
declare function parseContentControlId(raw: string | undefined): number | undefined;
|
|
2077
1976
|
/**
|
|
2078
|
-
*
|
|
2079
|
-
*
|
|
2080
|
-
* The head is not always a comment. A reply to a tracked change renders inside the REVISION's
|
|
2081
|
-
* card, so resolving it to itself opened an item nothing on screen was drawing — the reply box
|
|
2082
|
-
* vanished the moment somebody answered a change.
|
|
1977
|
+
* Read a control's properties.
|
|
2083
1978
|
*
|
|
2084
|
-
*
|
|
2085
|
-
*
|
|
2086
|
-
* innermost-wins rule was survivable while a reply could only be a comment — the parent came
|
|
2087
|
-
* first in `comments.xml` order and won the tie by accident. It stopped being survivable the
|
|
2088
|
-
* moment a reply could answer a revision, which outranks it outright.
|
|
1979
|
+
* Total: a control with no `w:sdtPr` at all answers the same shape with the defaults an
|
|
1980
|
+
* absent property means, so no caller has to branch on the container's existence.
|
|
2089
1981
|
*/
|
|
2090
|
-
declare function
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
interface RevisionBatchEntry {
|
|
2094
|
-
readonly key: string;
|
|
2095
|
-
readonly author: string;
|
|
2096
|
-
readonly partName: string;
|
|
2097
|
-
readonly revisionKind: ReviewRevisionItem['revisionKind'];
|
|
2098
|
-
}
|
|
2099
|
-
/** Why a requested decision remains pending. @public */
|
|
2100
|
-
type RevisionBatchSkipReason = 'unsupported-revision' | 'incomplete-group' | 'unknown-revision';
|
|
2101
|
-
/** Outcome of one selected-set decision. Counts refer to review decisions, not XML markers. @public */
|
|
2102
|
-
interface RevisionBatchResult {
|
|
2103
|
-
readonly resolved: readonly RevisionBatchEntry[];
|
|
2104
|
-
readonly skipped: readonly {
|
|
2105
|
-
readonly key: string;
|
|
2106
|
-
readonly reason: RevisionBatchSkipReason;
|
|
2107
|
-
readonly revision?: RevisionBatchEntry;
|
|
2108
|
-
}[];
|
|
2109
|
-
/** All pending decisions in the addressed scope, including excluded and unsupported changes. */
|
|
2110
|
-
readonly remaining: number;
|
|
2111
|
-
}
|
|
2112
|
-
/** @internal Pure preflight; callers commit its operations through their normal write guards. */
|
|
2113
|
-
declare function planRevisionBatch(part: OoxmlPart, action: 'accept' | 'reject', keys?: readonly string[], scopeRoot?: OoxmlNode): {
|
|
2114
|
-
ops: readonly TreeDocOp[];
|
|
2115
|
-
result: RevisionBatchResult;
|
|
2116
|
-
};
|
|
2117
|
-
|
|
1982
|
+
declare function contentControlPropertiesOf(control: OoxmlNode): ContentControlProperties;
|
|
1983
|
+
/** Where a control sits, read off what its content holds. */
|
|
1984
|
+
type ContentControlLevel = 'block' | 'inline' | 'row' | 'cell' | 'empty';
|
|
2118
1985
|
/**
|
|
2119
|
-
*
|
|
1986
|
+
* How deeply a control is nested inside other controls.
|
|
2120
1987
|
*
|
|
2121
|
-
*
|
|
2122
|
-
*
|
|
1988
|
+
* Bounded by {@link MAX_CONTENT_CONTROL_NESTING}: nesting depth comes from a file and is a
|
|
1989
|
+
* recursion bound.
|
|
2123
1990
|
*/
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
readonly
|
|
2128
|
-
|
|
2129
|
-
readonly
|
|
2130
|
-
|
|
1991
|
+
declare function contentControlLevelOf(control: OoxmlNode): ContentControlLevel;
|
|
1992
|
+
/** One control, plus how deeply it is nested and the controls that enclose it. */
|
|
1993
|
+
interface ContentControlEntry {
|
|
1994
|
+
readonly node: OoxmlContentControlNode;
|
|
1995
|
+
/** 0 for a top-level control; the nesting depth otherwise. */
|
|
1996
|
+
readonly depth: number;
|
|
1997
|
+
/** Enclosing controls, outermost first. Empty at depth 0. */
|
|
1998
|
+
readonly ancestors: readonly OoxmlContentControlNode[];
|
|
2131
1999
|
}
|
|
2132
2000
|
/**
|
|
2133
|
-
*
|
|
2134
|
-
*
|
|
2135
|
-
* `contextualSpacing` is Word's "Don't add space between paragraphs of the same style";
|
|
2136
|
-
* the rest are its Pagination block. `null` means the selection disagrees.
|
|
2001
|
+
* Every control under a node, in document order, bounded in depth and in count.
|
|
2137
2002
|
*
|
|
2138
|
-
*
|
|
2003
|
+
* ONE walk, shared. The nesting bound is the same one layout flattens with, so a control
|
|
2004
|
+
* a lane can address is a control every lane can address — and a file that nests past it
|
|
2005
|
+
* keeps its content in the tree (the serializer never stops) while no walk recurses
|
|
2006
|
+
* further.
|
|
2139
2007
|
*/
|
|
2140
|
-
|
|
2141
|
-
readonly
|
|
2142
|
-
readonly
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
}
|
|
2008
|
+
declare function contentControlsIn(root: OoxmlNode, options?: {
|
|
2009
|
+
readonly maxDepth?: number;
|
|
2010
|
+
readonly limit?: number;
|
|
2011
|
+
}): readonly ContentControlEntry[];
|
|
2012
|
+
/** Find one control by canonical node id, with the same bounded walk. */
|
|
2013
|
+
declare function findContentControl(root: OoxmlNode, nodeId: string): ContentControlEntry | null;
|
|
2147
2014
|
/**
|
|
2148
|
-
*
|
|
2149
|
-
*
|
|
2150
|
-
* An omitted field is left as authored. `null` REMOVES a setting so the style supplies it
|
|
2151
|
-
* again — not the same as a zero, which blocks the cascade.
|
|
2015
|
+
* The plain text a control's content holds, in reading order.
|
|
2152
2016
|
*
|
|
2153
|
-
*
|
|
2017
|
+
* `w:delText` is excluded: struck text is not the control's value, and a dropdown whose
|
|
2018
|
+
* old item is still present as a tracked deletion would otherwise report both.
|
|
2154
2019
|
*/
|
|
2155
|
-
|
|
2156
|
-
alignment?: 'left' | 'center' | 'right' | 'justify';
|
|
2157
|
-
spaceBeforePt?: number | null;
|
|
2158
|
-
spaceAfterPt?: number | null;
|
|
2159
|
-
lineSpacing?: {
|
|
2160
|
-
rule: 'multiple' | 'exact' | 'atLeast';
|
|
2161
|
-
value: number;
|
|
2162
|
-
} | null;
|
|
2163
|
-
indentLeftTwips?: number | null;
|
|
2164
|
-
indentRightTwips?: number | null;
|
|
2165
|
-
/** ONE signed first-line offset: negative is a hanging indent. */
|
|
2166
|
-
indentFirstLineTwips?: number | null;
|
|
2167
|
-
contextualSpacing?: boolean;
|
|
2168
|
-
keepNext?: boolean;
|
|
2169
|
-
keepLines?: boolean;
|
|
2170
|
-
widowControl?: boolean;
|
|
2171
|
-
pageBreakBefore?: boolean;
|
|
2172
|
-
/**
|
|
2173
|
-
* Replace the paragraph's custom tab stops. An empty list CLEARS them, which is what
|
|
2174
|
-
* "Clear All" does; omit the field to leave them as authored.
|
|
2175
|
-
*/
|
|
2176
|
-
tabStops?: readonly ParagraphTabStop[];
|
|
2177
|
-
}
|
|
2178
|
-
/** One custom tab stop, as a command states it. @public */
|
|
2179
|
-
interface ParagraphTabStop {
|
|
2180
|
-
readonly positionTwips: number;
|
|
2181
|
-
readonly alignment: 'left' | 'center' | 'right' | 'decimal' | 'bar';
|
|
2182
|
-
readonly leader?: 'none' | 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot';
|
|
2183
|
-
}
|
|
2184
|
-
/** Ownership token for one retained selection highlight. @public */
|
|
2185
|
-
type SelectionPin = symbol;
|
|
2020
|
+
declare function contentControlTextOf(control: OoxmlNode): string;
|
|
2186
2021
|
/**
|
|
2187
|
-
*
|
|
2022
|
+
* Resolve the lock a position inherits from the controls enclosing it.
|
|
2188
2023
|
*
|
|
2189
|
-
*
|
|
2190
|
-
*
|
|
2191
|
-
*
|
|
2192
|
-
*
|
|
2024
|
+
* CONSERVATIVE, because a template that says a field cannot be edited and sits inside a
|
|
2025
|
+
* section that says it cannot be removed means both. Each half of `ST_Lock` is taken
|
|
2026
|
+
* independently and the strongest wins, so an unlocked control inside a `contentLocked`
|
|
2027
|
+
* one is still content-locked — a nested control cannot grant a permission its parent
|
|
2028
|
+
* withheld, which is the only reading under which a lock is a lock.
|
|
2029
|
+
*/
|
|
2030
|
+
declare function resolveContentControlLock(chain: readonly ContentControlLock[]): ContentControlLock;
|
|
2031
|
+
/** Whether a resolved lock forbids editing the content it covers. */
|
|
2032
|
+
declare function lockForbidsEdit(lock: ContentControlLock): boolean;
|
|
2033
|
+
/** Whether a resolved lock forbids removing the control itself. */
|
|
2034
|
+
declare function lockForbidsRemoval(lock: ContentControlLock): boolean;
|
|
2035
|
+
/**
|
|
2036
|
+
* `CT_SdtPr`'s declared child order (§17.5.2.38), followed by the type choice.
|
|
2193
2037
|
*
|
|
2194
|
-
*
|
|
2195
|
-
*
|
|
2196
|
-
*
|
|
2038
|
+
* Serialization re-emits children in tree order, so the ONLY way a write keeps the
|
|
2039
|
+
* sequence valid is to place the child it authors at its schema position — which is what
|
|
2040
|
+
* {@link orderedContentControlProperties} does.
|
|
2197
2041
|
*/
|
|
2198
|
-
|
|
2199
|
-
paraId: string;
|
|
2200
|
-
search?: string;
|
|
2201
|
-
/** Opt-in disambiguation. Omit to require uniqueness. */
|
|
2202
|
-
occurrence?: number;
|
|
2203
|
-
}
|
|
2204
|
-
/** Structural addressing for content the paraId map cannot reach. */
|
|
2205
|
-
interface DocLocation {
|
|
2206
|
-
container: ContainerRef;
|
|
2207
|
-
/** Block indices, descending into tables and content controls. */
|
|
2208
|
-
path: number[];
|
|
2209
|
-
offset?: number;
|
|
2210
|
-
}
|
|
2042
|
+
declare const CONTENT_CONTROL_PROPERTY_ORDER: readonly string[];
|
|
2211
2043
|
/**
|
|
2212
|
-
*
|
|
2044
|
+
* Rebuild a `w:sdtPr`'s children in schema order.
|
|
2213
2045
|
*
|
|
2214
|
-
*
|
|
2215
|
-
*
|
|
2046
|
+
* Modelled children sort to their declared position and the type element follows them,
|
|
2047
|
+
* as the sequence requires. Everything else — a `w15:repeatingSection`, a vendor
|
|
2048
|
+
* extension, the `w14:checkbox` that is not part of the ECMA-376 choice — keeps the order
|
|
2049
|
+
* it was authored in and follows the modelled block, so a write that touches one property
|
|
2050
|
+
* neither drops nor reorders anything it does not name.
|
|
2216
2051
|
*/
|
|
2217
|
-
|
|
2218
|
-
part: 'body';
|
|
2219
|
-
} | {
|
|
2220
|
-
part: 'header' | 'footer';
|
|
2221
|
-
rId: string;
|
|
2222
|
-
} | {
|
|
2223
|
-
part: 'footnote' | 'endnote';
|
|
2224
|
-
noteId: number;
|
|
2225
|
-
};
|
|
2052
|
+
declare function orderedContentControlProperties(children: readonly OoxmlNode[]): readonly OoxmlNode[];
|
|
2226
2053
|
/**
|
|
2227
|
-
*
|
|
2228
|
-
*
|
|
2054
|
+
* The next `w:id` to write.
|
|
2055
|
+
*
|
|
2056
|
+
* Solo: one past the document's own maximum. Never a clock, a timestamp, a random source
|
|
2057
|
+
* or a hash: those collide with ids already in the file and produce values Word rejects.
|
|
2058
|
+
* Null when the document already reaches the signed 32-bit bound, so the caller refuses
|
|
2059
|
+
* rather than wrapping into a negative id. Hostile or out-of-range existing values are
|
|
2060
|
+
* ignored for seeding rather than counted past.
|
|
2061
|
+
*
|
|
2062
|
+
* When a collaboration actor is bound (explicit argument or the open store transaction),
|
|
2063
|
+
* the next id is the next unused value in that actor's stripe. Two peers inserting a
|
|
2064
|
+
* generic content control — including a custom node authored as `w:sdt` — from the same
|
|
2065
|
+
* snapshot then cannot share a `w:id`.
|
|
2229
2066
|
*/
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2067
|
+
declare function allocateContentControlId(root: OoxmlNode, actorId?: string): number | null;
|
|
2068
|
+
|
|
2069
|
+
/** A position in the model offset space of one story. */
|
|
2070
|
+
interface ReviewPosition {
|
|
2071
|
+
readonly paragraphId: string;
|
|
2072
|
+
readonly offset: number;
|
|
2073
|
+
}
|
|
2074
|
+
/** Where an item is anchored: a range in one story. */
|
|
2075
|
+
interface ReviewRange {
|
|
2076
|
+
readonly partName: string;
|
|
2077
|
+
readonly start: ReviewPosition;
|
|
2078
|
+
readonly end: ReviewPosition;
|
|
2235
2079
|
}
|
|
2236
2080
|
/**
|
|
2237
|
-
*
|
|
2081
|
+
* What kind of decision a revision card represents.
|
|
2238
2082
|
*
|
|
2239
|
-
*
|
|
2240
|
-
*
|
|
2241
|
-
*
|
|
2083
|
+
* Wider than the four content wrappers, because a reviewer has to be shown every pending
|
|
2084
|
+
* decision, including the ones that decorate no characters. A card the surface cannot show is
|
|
2085
|
+
* a change the reviewer never learns about — and `acceptAllRevisions` refuses if ANY revision
|
|
2086
|
+
* in the document is one the engine cannot resolve, so an invisible one makes Accept All fail
|
|
2087
|
+
* for a reason nothing on screen explains.
|
|
2242
2088
|
*/
|
|
2243
|
-
type
|
|
2244
|
-
ok: true;
|
|
2245
|
-
changed: boolean;
|
|
2246
|
-
revisions?: RevisionBatchResult;
|
|
2247
|
-
} | {
|
|
2248
|
-
ok: false;
|
|
2249
|
-
code: ExecErrorCode;
|
|
2250
|
-
reason: string;
|
|
2251
|
-
target?: DocTarget;
|
|
2252
|
-
revisions?: RevisionBatchResult;
|
|
2253
|
-
};
|
|
2089
|
+
type ReviewRevisionKind = 'insert' | 'delete'
|
|
2254
2090
|
/**
|
|
2255
|
-
*
|
|
2091
|
+
* A deletion and an insertion that are one edit: text typed over a selection.
|
|
2256
2092
|
*
|
|
2257
|
-
*
|
|
2258
|
-
*
|
|
2093
|
+
* Word shows these as a single `Replaced "x" with "y"` card, and resolving one half
|
|
2094
|
+
* without the other is never what the reviewer meant — accepting the deletion alone
|
|
2095
|
+
* leaves the replacement text unproposed, rejecting it alone leaves both.
|
|
2259
2096
|
*/
|
|
2260
|
-
|
|
2097
|
+
| 'replace' | 'moveFrom' | 'moveTo'
|
|
2098
|
+
/** `w:rPrChange` / `w:pPrChange` — the words are unchanged, their formatting is not. */
|
|
2099
|
+
| 'format'
|
|
2100
|
+
/** `w:pPr/w:rPr/w:ins|w:del` — a paragraph split or merge. */
|
|
2101
|
+
| 'paragraphMark'
|
|
2102
|
+
/** A row, cell, section or grid revision. Supported row revisions are resolvable. */
|
|
2103
|
+
| 'structural';
|
|
2261
2104
|
/**
|
|
2262
|
-
*
|
|
2105
|
+
* One tracked change as a review card.
|
|
2263
2106
|
*
|
|
2264
|
-
*
|
|
2265
|
-
*
|
|
2266
|
-
* `fromJSON` before sending it over JSON-RPC or handing it to a model.
|
|
2107
|
+
* Keyed per DECISION rather than per site: a revision spanning three ranges is one card, because
|
|
2108
|
+
* accepting it accepts all three.
|
|
2267
2109
|
*/
|
|
2268
|
-
interface
|
|
2269
|
-
readonly
|
|
2270
|
-
|
|
2271
|
-
readonly
|
|
2272
|
-
|
|
2273
|
-
readonly
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2110
|
+
interface ReviewRevisionItem {
|
|
2111
|
+
readonly kind: 'revision';
|
|
2112
|
+
/** Stable across renders and unique per DECISION, not per site. */
|
|
2113
|
+
readonly id: string;
|
|
2114
|
+
/** The payload `acceptRevision` / `rejectRevision` take. */
|
|
2115
|
+
readonly address: RevisionAddress;
|
|
2116
|
+
/**
|
|
2117
|
+
* EVERY address this decision covers, `address` first.
|
|
2118
|
+
*
|
|
2119
|
+
* More than one only for a replacement, whose halves a foreign editor may have written
|
|
2120
|
+
* as two independent revisions. Accept and reject walk all of them in one transaction:
|
|
2121
|
+
* resolving one half and leaving the other is a state no reviewer asked for.
|
|
2122
|
+
*/
|
|
2123
|
+
readonly addresses: readonly RevisionAddress[];
|
|
2124
|
+
/** The words a replacement removes. Empty for every other kind. */
|
|
2125
|
+
readonly replacedText: string;
|
|
2126
|
+
readonly revisionKind: ReviewRevisionKind;
|
|
2127
|
+
/** OOXML property-change element, used to resolve independently numbered formatting kinds. */
|
|
2128
|
+
readonly formattingKind?: string;
|
|
2129
|
+
/** Changed direct formatting values, ready for localized review summaries. */
|
|
2130
|
+
readonly formattingChanges?: readonly {
|
|
2131
|
+
readonly property: 'bold' | 'italic' | 'underline' | 'strike' | 'fontFamily' | 'fontSize' | 'color' | 'alignment' | 'leftIndent' | 'rightIndent' | 'firstLineIndent' | 'hangingIndent' | 'spaceBefore' | 'spaceAfter';
|
|
2132
|
+
/** New direct value; null means inherit. Sizes and distances are in points. */
|
|
2133
|
+
readonly value: string | null;
|
|
2134
|
+
}[];
|
|
2135
|
+
/** Newly applied proofing language codes in a tracked formatting change. */
|
|
2136
|
+
readonly formattingLanguages?: readonly string[];
|
|
2137
|
+
/**
|
|
2138
|
+
* WHICH decision a `paragraphMark` records, absent for every other kind.
|
|
2139
|
+
*
|
|
2140
|
+
* `EG_ParaRPrTrackChanges` is `ins? del? moveFrom? moveTo?`, and the four say opposite
|
|
2141
|
+
* things about one break. Without this a card called a deleted break an inserted one, which
|
|
2142
|
+
* is the reverse of what Accept on that card does.
|
|
2143
|
+
*/
|
|
2144
|
+
readonly markDirection?: 'insert' | 'delete' | 'moveFrom' | 'moveTo';
|
|
2145
|
+
readonly author: string;
|
|
2146
|
+
readonly date?: string;
|
|
2147
|
+
/** Text the revision covers, for the card summary. Empty for changes with no characters. */
|
|
2148
|
+
readonly text: string;
|
|
2149
|
+
/** Every site this decision touches, in document order. */
|
|
2150
|
+
readonly ranges: readonly ReviewRange[];
|
|
2278
2151
|
/**
|
|
2279
|
-
*
|
|
2280
|
-
*
|
|
2152
|
+
* How deeply this change is NESTED inside other changes, 0 for an unenclosed one.
|
|
2153
|
+
*
|
|
2154
|
+
* `w:ins` wrapping `w:del` is content one reviewer added and another struck. Both stay
|
|
2155
|
+
* pending, so both are cards, over one identical range — and a range then cannot say which
|
|
2156
|
+
* change a caret is in. Word treats the innermost as the operative one, so it wins the caret
|
|
2157
|
+
* and the change enclosing it stays listed and reachable.
|
|
2281
2158
|
*/
|
|
2282
|
-
readonly
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
readonly
|
|
2292
|
-
|
|
2159
|
+
readonly nesting: number;
|
|
2160
|
+
/**
|
|
2161
|
+
* How many leading `ranges` are the STRUCK half of a replacement.
|
|
2162
|
+
*
|
|
2163
|
+
* A replacement's card is one decision but its ranges are two colours — red over what is
|
|
2164
|
+
* going, green over what takes its place. ABSENT when the halves do not split at a single
|
|
2165
|
+
* point, which is what a file recording both under one revision id can produce; a surface
|
|
2166
|
+
* then has no basis for two colours and should paint one neutral band rather than guess.
|
|
2167
|
+
*/
|
|
2168
|
+
readonly replacedRangeCount?: number;
|
|
2169
|
+
/**
|
|
2170
|
+
* True when the engine cannot resolve this kind, so accept and reject must not be offered.
|
|
2171
|
+
*
|
|
2172
|
+
* Derived by the DERIVATION rather than from a caller-supplied predicate: the refusal list
|
|
2173
|
+
* is internal, and a surface asked to compute it would have to guess. A card that offers a
|
|
2174
|
+
* button the engine will refuse is worse than one that explains why it cannot.
|
|
2175
|
+
*/
|
|
2176
|
+
readonly readOnly: boolean;
|
|
2177
|
+
/** The other half of a move, or the other side of a delete/insert replacement. */
|
|
2178
|
+
readonly pairedWith?: string;
|
|
2179
|
+
/**
|
|
2180
|
+
* Comments answering this change, in document order.
|
|
2181
|
+
*
|
|
2182
|
+
* A reply to a tracked change IS a comment: `w:ins` and `w:del` carry no body, so the text
|
|
2183
|
+
* is written as a comment over the revision's own range and the range is what links them.
|
|
2184
|
+
*/
|
|
2185
|
+
readonly replyIds: readonly string[];
|
|
2293
2186
|
}
|
|
2294
2187
|
/**
|
|
2295
|
-
*
|
|
2296
|
-
*
|
|
2297
|
-
* All optional: a variant a section does not declare inherits the previous section's, and one
|
|
2298
|
-
* absent everywhere means the document simply has none.
|
|
2188
|
+
* One comment as a review card. A reply carries `parentId`; OOXML gives replies no separate
|
|
2189
|
+
* element, so threads are reconstructed from that link.
|
|
2299
2190
|
*/
|
|
2300
|
-
interface
|
|
2301
|
-
readonly
|
|
2302
|
-
readonly
|
|
2303
|
-
readonly
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
readonly
|
|
2310
|
-
/**
|
|
2311
|
-
readonly
|
|
2312
|
-
|
|
2313
|
-
readonly
|
|
2314
|
-
readonly numbering?: NumberingRef;
|
|
2315
|
-
}
|
|
2316
|
-
/** A stretch of text sharing one set of character properties. */
|
|
2317
|
-
interface Run {
|
|
2318
|
-
readonly text: string;
|
|
2319
|
-
readonly formatting?: RunFormatting;
|
|
2320
|
-
/** Set when the run carries a tracked change. Unique only within its part. */
|
|
2321
|
-
readonly revisionId?: number;
|
|
2191
|
+
interface ReviewCommentItem {
|
|
2192
|
+
readonly kind: 'comment';
|
|
2193
|
+
readonly id: string;
|
|
2194
|
+
readonly comment: CommentRecord;
|
|
2195
|
+
readonly range: ReviewRange | null;
|
|
2196
|
+
readonly resolved: boolean;
|
|
2197
|
+
/** The comment this replies to, absent for a top-level comment. */
|
|
2198
|
+
readonly parentId?: string;
|
|
2199
|
+
/** The REVISION this comment answers, when it covers exactly that change's characters. */
|
|
2200
|
+
readonly parentRevisionId?: string;
|
|
2201
|
+
/** Replies to this comment, in document order. Empty for a reply or a childless comment. */
|
|
2202
|
+
readonly replyIds: readonly string[];
|
|
2203
|
+
/** True when the file gave this comment no usable range. */
|
|
2204
|
+
readonly orphaned: boolean;
|
|
2322
2205
|
}
|
|
2323
2206
|
/**
|
|
2324
|
-
*
|
|
2325
|
-
*
|
|
2207
|
+
* A card contributed by a recognized custom node (`defineCustomNode` with a `reviewCard`
|
|
2208
|
+
* hook), anchored at the node's range.
|
|
2326
2209
|
*
|
|
2327
|
-
*
|
|
2328
|
-
*
|
|
2329
|
-
*
|
|
2210
|
+
* Informational, never resolvable: there is nothing to accept or reject, so the engine
|
|
2211
|
+
* refuses those verbs on it. `title` and `detail` are HOST-authored (the definition's hook
|
|
2212
|
+
* produced them), but `attrs` and `text` originate in a file an attacker controls — a
|
|
2213
|
+
* surface renders every one of these as text, never markup.
|
|
2330
2214
|
*/
|
|
2331
|
-
interface
|
|
2332
|
-
readonly
|
|
2333
|
-
|
|
2334
|
-
readonly
|
|
2335
|
-
|
|
2336
|
-
readonly
|
|
2337
|
-
|
|
2338
|
-
readonly
|
|
2339
|
-
|
|
2340
|
-
readonly
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
readonly alignment?: 'left' | 'center' | 'right' | 'both';
|
|
2344
|
-
/** Paragraph style id (`w:pStyle`) at the selection. */
|
|
2345
|
-
readonly styleId?: string;
|
|
2215
|
+
interface ReviewCustomItem {
|
|
2216
|
+
readonly kind: 'custom';
|
|
2217
|
+
/** The SDT node's stable id in the canonical tree. */
|
|
2218
|
+
readonly id: string;
|
|
2219
|
+
/** The definition's `name`. */
|
|
2220
|
+
readonly name: string;
|
|
2221
|
+
/** The raw `w:tag` the node was recognized from. Untrusted input. */
|
|
2222
|
+
readonly tag: string;
|
|
2223
|
+
/** Attrs decoded from the tag, after the definition's recognition hook. Untrusted input. */
|
|
2224
|
+
readonly attrs: Readonly<Record<string, string>>;
|
|
2225
|
+
/** The SDT's literal content text. Untrusted input. */
|
|
2226
|
+
readonly text: string;
|
|
2346
2227
|
/**
|
|
2347
|
-
*
|
|
2348
|
-
*
|
|
2349
|
-
*
|
|
2350
|
-
*
|
|
2228
|
+
* The payload the node's control binds to, after the definition validated it.
|
|
2229
|
+
*
|
|
2230
|
+
* Undefined when the node carries none or the payload did not match — see the pro package's
|
|
2231
|
+
* `RecognizedCustomNode.data`, which this is carried from.
|
|
2351
2232
|
*/
|
|
2352
|
-
readonly
|
|
2353
|
-
readonly rule: 'multiple' | 'exact' | 'atLeast';
|
|
2354
|
-
readonly value: number;
|
|
2355
|
-
};
|
|
2233
|
+
readonly data?: unknown;
|
|
2356
2234
|
/**
|
|
2357
|
-
*
|
|
2235
|
+
* Whether this node asked for a sidebar card.
|
|
2358
2236
|
*
|
|
2359
|
-
*
|
|
2360
|
-
*
|
|
2361
|
-
*
|
|
2362
|
-
* ignores the measurement, and again where two paragraphs collapse their adjacent spacing.
|
|
2363
|
-
* Absent when the selection's paragraphs disagree or no level states it.
|
|
2237
|
+
* False for a definition with no `reviewCard`: the item exists so the chip's own surfaces can
|
|
2238
|
+
* read `attrs`, `text` and `data` off it, and the rail leaves it out. A surface listing cards
|
|
2239
|
+
* filters on this rather than on an empty `title`.
|
|
2364
2240
|
*/
|
|
2365
|
-
readonly
|
|
2366
|
-
|
|
2241
|
+
readonly carded: boolean;
|
|
2242
|
+
/** Card title, from the definition's `reviewCard` hook. Empty when `carded` is false. */
|
|
2243
|
+
readonly title: string;
|
|
2244
|
+
/** Card body, from the definition's `reviewCard` hook. */
|
|
2245
|
+
readonly detail?: string;
|
|
2367
2246
|
/**
|
|
2368
|
-
*
|
|
2247
|
+
* Glyph for this node in the collapsed rail, as an SVG path in a `0 -960 960 960` viewBox.
|
|
2369
2248
|
*
|
|
2370
|
-
*
|
|
2371
|
-
*
|
|
2372
|
-
*
|
|
2373
|
-
*
|
|
2249
|
+
* A PATH rather than a rendered node because this item crosses core, which is DOM-free and
|
|
2250
|
+
* React-free — the same reason `title` and `detail` are strings. A host that wants arbitrary
|
|
2251
|
+
* markup overrides the `Markers` part's `icon` instead, which lives in the adapter where JSX
|
|
2252
|
+
* belongs. Absent falls back to the generic custom-node glyph.
|
|
2253
|
+
*
|
|
2254
|
+
* HOST-AUTHORED, never file data: it is interpolated into an SVG `d` attribute, and a path
|
|
2255
|
+
* taken from a document would be attacker-controlled markup.
|
|
2374
2256
|
*/
|
|
2375
|
-
readonly
|
|
2257
|
+
readonly icon?: string;
|
|
2258
|
+
readonly range: ReviewRange | null;
|
|
2259
|
+
}
|
|
2260
|
+
/**
|
|
2261
|
+
* One pending decision in the review queue: a tracked change, a comment thread, or a pro
|
|
2262
|
+
* custom-node card. Discriminate on `kind`.
|
|
2263
|
+
*
|
|
2264
|
+
* The store's own derivation (`collectReviewItems`) only ever produces the first two; the
|
|
2265
|
+
* `kind: 'custom'` card is contributed by the pro review module, which recognizes the node.
|
|
2266
|
+
*/
|
|
2267
|
+
type ReviewItem = ReviewRevisionItem | ReviewCommentItem | ReviewCustomItem;
|
|
2268
|
+
/** What the review queue derivation reads: one story part plus its comment parts. */
|
|
2269
|
+
interface ReviewModelInput {
|
|
2270
|
+
/** The story the ranges live in — the main document, a header, a note. */
|
|
2271
|
+
readonly storyPart: OoxmlPart;
|
|
2376
2272
|
/**
|
|
2377
|
-
*
|
|
2378
|
-
*
|
|
2273
|
+
* Header/footer story parts, in section order. Their revisions and comment anchors join
|
|
2274
|
+
* the queue: a tracked change in a header is a pending decision like any other, and a
|
|
2275
|
+
* queue that only walked the body silently hid it from the rail AND from Accept All.
|
|
2276
|
+
*/
|
|
2277
|
+
readonly furnitureParts?: readonly OoxmlPart[] | undefined;
|
|
2278
|
+
/** `word/comments.xml`, absent when the package has none. */
|
|
2279
|
+
readonly commentsPart?: OoxmlPart | undefined;
|
|
2280
|
+
/** `word/commentsExtended.xml`, absent when the package has none. */
|
|
2281
|
+
readonly commentsExtendedPart?: OoxmlPart | undefined;
|
|
2282
|
+
/**
|
|
2283
|
+
* Custom node definitions from the module registry, forwarded OPAQUELY.
|
|
2379
2284
|
*
|
|
2380
|
-
*
|
|
2381
|
-
*
|
|
2382
|
-
*
|
|
2383
|
-
* tells a single paragraph it disagrees with itself.
|
|
2285
|
+
* Core carries them the way the registry does — as unknowns — so the definition shape
|
|
2286
|
+
* stays a capability-package concern. The pro derivation narrows them and contributes
|
|
2287
|
+
* `kind: 'custom'` cards for definitions that opted in.
|
|
2384
2288
|
*/
|
|
2385
|
-
readonly
|
|
2289
|
+
readonly customNodes?: readonly unknown[] | undefined;
|
|
2386
2290
|
/**
|
|
2387
|
-
*
|
|
2388
|
-
*
|
|
2291
|
+
* Where a capability package reports a node it could not read. Supplied per editor, so a page
|
|
2292
|
+
* with two of them keeps their diagnostics apart.
|
|
2389
2293
|
*/
|
|
2390
|
-
readonly
|
|
2294
|
+
readonly reportCustomNodeDiagnostic?: ((diagnostic: unknown) => void) | undefined;
|
|
2391
2295
|
/**
|
|
2392
|
-
* The
|
|
2393
|
-
*
|
|
2394
|
-
*
|
|
2395
|
-
*
|
|
2296
|
+
* The payload each of the story's controls binds to, keyed by the control's node id.
|
|
2297
|
+
*
|
|
2298
|
+
* Resolved by the ENGINE and handed over, because a payload lives in a customXml data part
|
|
2299
|
+
* and a derivation that only receives story parts has no way to reach one. Untrusted file
|
|
2300
|
+
* input on both members; a capability package validates it against whatever shape it
|
|
2301
|
+
* declared before handing it to a host.
|
|
2396
2302
|
*/
|
|
2397
|
-
readonly
|
|
2303
|
+
readonly customNodePayloads?: ReadonlyMap<string, {
|
|
2304
|
+
readonly nodeId: string;
|
|
2305
|
+
readonly label: string;
|
|
2306
|
+
readonly data: string;
|
|
2307
|
+
}> | undefined;
|
|
2398
2308
|
}
|
|
2309
|
+
/** The stable key a surface uses for the active item and for a React list. */
|
|
2310
|
+
declare function reviewItemKey(item: ReviewItem): string;
|
|
2311
|
+
/** Every range a decision touches. One card can cover several, in different paragraphs. */
|
|
2312
|
+
declare function reviewItemRanges(item: ReviewItem): readonly ReviewRange[];
|
|
2313
|
+
/** The first range of an item, in authored order, or null when it has none. */
|
|
2314
|
+
declare function firstReviewRange(item: ReviewItem): ReviewRange | null;
|
|
2315
|
+
/**
|
|
2316
|
+
* A single comparable number for document order.
|
|
2317
|
+
*
|
|
2318
|
+
* Paragraph index dominates offset, so a revision spanning paragraphs still sorts by where it
|
|
2319
|
+
* STARTS. An item with no resolvable range sorts last rather than to position zero, which is
|
|
2320
|
+
* where an orphan used to land — tearing an orphaned reply out of its own thread.
|
|
2321
|
+
*/
|
|
2322
|
+
declare function reviewItemPositionRank(item: ReviewItem, order: ReadonlyMap<string, number>): number;
|
|
2323
|
+
/**
|
|
2324
|
+
* Every item covering a position, innermost first.
|
|
2325
|
+
*
|
|
2326
|
+
* Returning the whole stack rather than one winner is what lets a surface offer cycling, a
|
|
2327
|
+
* stacked card, or a "1 of 3" affordance. A comment wrapping a revision used to be unreachable
|
|
2328
|
+
* because only the tightest range was ever returned.
|
|
2329
|
+
*/
|
|
2330
|
+
declare function reviewItemsAt(items: readonly ReviewItem[], position: ReviewPosition, order: ReadonlyMap<string, number>): ReviewItem[];
|
|
2399
2331
|
/**
|
|
2400
|
-
*
|
|
2332
|
+
* The item the caret is in, or null.
|
|
2401
2333
|
*
|
|
2402
|
-
*
|
|
2403
|
-
*
|
|
2404
|
-
* selected paragraph's values — Select All is the commonest indent gesture, and hiding the
|
|
2405
|
-
* handles for it would be worse than showing one paragraph's truth. The values are
|
|
2406
|
-
* therefore always the first touched paragraph's, and {@link mixed} records per field
|
|
2407
|
-
* whether the rest agree.
|
|
2334
|
+
* A resolved comment never activates: a settled thread must not reopen itself as the reviewer
|
|
2335
|
+
* types near it.
|
|
2408
2336
|
*
|
|
2409
|
-
*
|
|
2410
|
-
*
|
|
2411
|
-
*
|
|
2337
|
+
* A REPLY resolves to the thread it belongs to. A reply is anchored over its parent's range,
|
|
2338
|
+
* so both cover the caret — and the reply, being newer, wins the innermost test. It is not a
|
|
2339
|
+
* card of its own (it renders inside its parent's), so the thread would have gone active with
|
|
2340
|
+
* nothing on screen showing it: the reply box vanished from a comment the moment somebody
|
|
2341
|
+
* replied to it.
|
|
2342
|
+
*/
|
|
2343
|
+
declare function activeReviewItem(items: readonly ReviewItem[], position: ReviewPosition, order: ReadonlyMap<string, number>): ReviewItem | null;
|
|
2344
|
+
/**
|
|
2345
|
+
* Walk a reply up to the card that heads its thread. Guarded against a cyclic file.
|
|
2412
2346
|
*
|
|
2413
|
-
*
|
|
2414
|
-
*
|
|
2415
|
-
*
|
|
2347
|
+
* The head is not always a comment. A reply to a tracked change renders inside the REVISION's
|
|
2348
|
+
* card, so resolving it to itself opened an item nothing on screen was drawing — the reply box
|
|
2349
|
+
* vanished the moment somebody answered a change.
|
|
2350
|
+
*
|
|
2351
|
+
* EXPORTED because the paginated surface answers "which card is open" itself, against its own
|
|
2352
|
+
* dismissed-key state, rather than through {@link activeReviewItem}. Two copies of the
|
|
2353
|
+
* innermost-wins rule was survivable while a reply could only be a comment — the parent came
|
|
2354
|
+
* first in `comments.xml` order and won the tie by accident. It stopped being survivable the
|
|
2355
|
+
* moment a reply could answer a revision, which outranks it outright.
|
|
2416
2356
|
*/
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
readonly
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
readonly
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
};
|
|
2357
|
+
declare function reviewThreadRootOf(items: readonly ReviewItem[], comment: ReviewCommentItem): ReviewItem;
|
|
2358
|
+
|
|
2359
|
+
/** The value a control accepts, by what kind of control it is. */
|
|
2360
|
+
type ContentControlValueInput = {
|
|
2361
|
+
readonly kind: 'text';
|
|
2362
|
+
readonly text: string;
|
|
2363
|
+
} | {
|
|
2364
|
+
readonly kind: 'listItem';
|
|
2365
|
+
readonly value: string;
|
|
2366
|
+
} | {
|
|
2367
|
+
readonly kind: 'checkbox';
|
|
2368
|
+
readonly checked: boolean;
|
|
2430
2369
|
}
|
|
2431
|
-
/** A
|
|
2432
|
-
|
|
2433
|
-
readonly kind: '
|
|
2434
|
-
readonly
|
|
2435
|
-
|
|
2370
|
+
/** A calendar date, `YYYY-MM-DD` or a full ISO-8601 instant. */
|
|
2371
|
+
| {
|
|
2372
|
+
readonly kind: 'date';
|
|
2373
|
+
readonly iso: string;
|
|
2374
|
+
};
|
|
2375
|
+
/** The control types an insertion may author. Picture and repeating section are deferred. */
|
|
2376
|
+
declare const INSERTABLE_CONTENT_CONTROL_TYPES: readonly ["richText", "plainText", "dropDownList", "comboBox", "date"];
|
|
2377
|
+
/**
|
|
2378
|
+
* The OOXML spellings the store writes.
|
|
2379
|
+
*
|
|
2380
|
+
* NOT the contract's `InsertableContentControlType`, which is the same set of kinds in the
|
|
2381
|
+
* READ vocabulary (`dropdown`) plus this lane's spelling of it (`dropDownList`). The editor
|
|
2382
|
+
* maps between the two; the names differ so a reader can tell which vocabulary a value is in.
|
|
2383
|
+
*/
|
|
2384
|
+
type InsertableContentControlKind = (typeof INSERTABLE_CONTENT_CONTROL_TYPES)[number];
|
|
2385
|
+
|
|
2386
|
+
/** A canonical review decision. Keys are valid only in the open document. @public */
|
|
2387
|
+
interface RevisionBatchEntry {
|
|
2388
|
+
readonly key: string;
|
|
2389
|
+
readonly author: string;
|
|
2390
|
+
readonly partName: string;
|
|
2391
|
+
readonly revisionKind: ReviewRevisionItem['revisionKind'];
|
|
2436
2392
|
}
|
|
2437
|
-
/**
|
|
2438
|
-
|
|
2439
|
-
|
|
2393
|
+
/** Why a requested decision remains pending. @public */
|
|
2394
|
+
type RevisionBatchSkipReason = 'unsupported-revision' | 'incomplete-group' | 'unknown-revision';
|
|
2395
|
+
/** Outcome of one selected-set decision. Counts refer to review decisions, not XML markers. @public */
|
|
2396
|
+
interface RevisionBatchResult {
|
|
2397
|
+
readonly resolved: readonly RevisionBatchEntry[];
|
|
2398
|
+
readonly skipped: readonly {
|
|
2399
|
+
readonly key: string;
|
|
2400
|
+
readonly reason: RevisionBatchSkipReason;
|
|
2401
|
+
readonly revision?: RevisionBatchEntry;
|
|
2402
|
+
}[];
|
|
2403
|
+
/** All pending decisions in the addressed scope, including excluded and unsupported changes. */
|
|
2404
|
+
readonly remaining: number;
|
|
2440
2405
|
}
|
|
2406
|
+
/** @internal Pure preflight; callers commit its operations through their normal write guards. */
|
|
2407
|
+
declare function planRevisionBatch(part: OoxmlPart, action: 'accept' | 'reject', keys?: readonly string[], scopeRoot?: OoxmlNode): {
|
|
2408
|
+
ops: readonly TreeDocOp[];
|
|
2409
|
+
result: RevisionBatchResult;
|
|
2410
|
+
};
|
|
2411
|
+
|
|
2412
|
+
/** Allowlisted OOXML table border line styles — store/layout authority. */
|
|
2413
|
+
declare const TABLE_BORDER_STYLES: readonly ["single", "dashed", "dotted", "double", "triple", "thick"];
|
|
2441
2414
|
/**
|
|
2442
|
-
* One
|
|
2443
|
-
*
|
|
2415
|
+
* One of the border line styles this engine draws.
|
|
2416
|
+
*
|
|
2417
|
+
* An ALLOWLIST, not the full `ST_Border` enumeration: a file may name any of the seventy-odd
|
|
2418
|
+
* OOXML border styles, and anything outside this set falls back rather than being passed through
|
|
2419
|
+
* to paint.
|
|
2444
2420
|
*/
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2421
|
+
type TableBorderStyle = (typeof TABLE_BORDER_STYLES)[number];
|
|
2422
|
+
|
|
2423
|
+
/**
|
|
2424
|
+
* Shared types for the `@docx-editor.dev/core` contract. Type-only, zero runtime.
|
|
2425
|
+
*
|
|
2426
|
+
* `@docx-editor.dev/core/contracts/types` re-exports this module verbatim, through
|
|
2427
|
+
* `types-barrel.ts`. There is no `@docx-editor.dev/core/types` subpath.
|
|
2428
|
+
*/
|
|
2429
|
+
/** Which paragraph-level reads the selection disagrees about. @public */
|
|
2430
|
+
interface ParagraphDisagreements {
|
|
2431
|
+
readonly alignment: boolean;
|
|
2432
|
+
readonly spaceBeforePt: boolean;
|
|
2433
|
+
readonly spaceAfterPt: boolean;
|
|
2434
|
+
readonly lineSpacing: boolean;
|
|
2435
|
+
readonly tabStops: boolean;
|
|
2451
2436
|
}
|
|
2452
|
-
/**
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2437
|
+
/**
|
|
2438
|
+
* The five paragraph flags a Paragraph dialog shows as checkboxes.
|
|
2439
|
+
*
|
|
2440
|
+
* `contextualSpacing` is Word's "Don't add space between paragraphs of the same style";
|
|
2441
|
+
* the rest are its Pagination block. `null` means the selection disagrees.
|
|
2442
|
+
*
|
|
2443
|
+
* @public
|
|
2444
|
+
*/
|
|
2445
|
+
interface ParagraphFlags {
|
|
2446
|
+
readonly contextualSpacing: boolean | null;
|
|
2447
|
+
readonly keepNext: boolean | null;
|
|
2448
|
+
readonly keepLines: boolean | null;
|
|
2449
|
+
readonly widowControl: boolean | null;
|
|
2450
|
+
readonly pageBreakBefore: boolean | null;
|
|
2461
2451
|
}
|
|
2462
|
-
/** Which kind of control a `w:sdt` is, and therefore what a value written into it must be. */
|
|
2463
|
-
type ContentControlType = 'richText' | 'plainText' | 'checkbox' | 'dropdown' | 'comboBox' | 'date' | 'picture' | 'repeatingSection';
|
|
2464
2452
|
/**
|
|
2465
|
-
*
|
|
2453
|
+
* Every field of the Paragraph dialog, as `setParagraphFormat` takes it.
|
|
2466
2454
|
*
|
|
2467
|
-
*
|
|
2468
|
-
*
|
|
2469
|
-
* absent because an insertion would have to invent what they carry — a checkbox needs its two
|
|
2470
|
-
* declared glyph states, a picture needs an image part, and a repeating section is a container
|
|
2471
|
-
* whose items have their own verbs. Reading still answers the wider type; a document may hold
|
|
2472
|
-
* kinds this cannot create.
|
|
2455
|
+
* An omitted field is left as authored. `null` REMOVES a setting so the style supplies it
|
|
2456
|
+
* again — not the same as a zero, which blocks the cascade.
|
|
2473
2457
|
*
|
|
2474
|
-
*
|
|
2475
|
-
* so a type read off a control can be handed back without translating it — and the OOXML
|
|
2476
|
-
* spelling is the one the automation protocol takes, so a caller who uses both surfaces can
|
|
2477
|
-
* write that one everywhere.
|
|
2458
|
+
* @public
|
|
2478
2459
|
*/
|
|
2479
|
-
|
|
2460
|
+
interface ParagraphFormatCommand {
|
|
2461
|
+
alignment?: 'left' | 'center' | 'right' | 'justify';
|
|
2462
|
+
spaceBeforePt?: number | null;
|
|
2463
|
+
spaceAfterPt?: number | null;
|
|
2464
|
+
lineSpacing?: {
|
|
2465
|
+
rule: 'multiple' | 'exact' | 'atLeast';
|
|
2466
|
+
value: number;
|
|
2467
|
+
} | null;
|
|
2468
|
+
indentLeftTwips?: number | null;
|
|
2469
|
+
indentRightTwips?: number | null;
|
|
2470
|
+
/** ONE signed first-line offset: negative is a hanging indent. */
|
|
2471
|
+
indentFirstLineTwips?: number | null;
|
|
2472
|
+
contextualSpacing?: boolean;
|
|
2473
|
+
keepNext?: boolean;
|
|
2474
|
+
keepLines?: boolean;
|
|
2475
|
+
widowControl?: boolean;
|
|
2476
|
+
pageBreakBefore?: boolean;
|
|
2477
|
+
/**
|
|
2478
|
+
* Replace the paragraph's custom tab stops. An empty list CLEARS them, which is what
|
|
2479
|
+
* "Clear All" does; omit the field to leave them as authored.
|
|
2480
|
+
*/
|
|
2481
|
+
tabStops?: readonly ParagraphTabStop[];
|
|
2482
|
+
}
|
|
2483
|
+
/** One custom tab stop, as a command states it. @public */
|
|
2484
|
+
interface ParagraphTabStop {
|
|
2485
|
+
readonly positionTwips: number;
|
|
2486
|
+
readonly alignment: 'left' | 'center' | 'right' | 'decimal' | 'bar';
|
|
2487
|
+
readonly leader?: 'none' | 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot';
|
|
2488
|
+
}
|
|
2489
|
+
/** Ownership token for one retained selection highlight. @public */
|
|
2490
|
+
type SelectionPin = symbol;
|
|
2480
2491
|
/**
|
|
2481
|
-
*
|
|
2482
|
-
*
|
|
2492
|
+
* The LLM- and JSON-facing address for a piece of a document.
|
|
2493
|
+
*
|
|
2494
|
+
* `paraId` is the 8-hex `w14:paraId`, matched case-insensitively. `search` is a
|
|
2495
|
+
* phrase that must match EXACTLY ONCE inside that paragraph; ambiguous or
|
|
2496
|
+
* missing matches fail with `'ambiguous'` / `'notFound'` rather than falling
|
|
2497
|
+
* back to first-match.
|
|
2498
|
+
*
|
|
2499
|
+
* Offset-based addressing was tried and abandoned: an agent cannot compute a
|
|
2500
|
+
* character offset it has not seen, and offsets do not survive concurrent
|
|
2501
|
+
* edits. Do not reintroduce `{ blockId, offset }`.
|
|
2483
2502
|
*/
|
|
2484
|
-
interface
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2503
|
+
interface DocAnchor {
|
|
2504
|
+
paraId: string;
|
|
2505
|
+
search?: string;
|
|
2506
|
+
/** Opt-in disambiguation. Omit to require uniqueness. */
|
|
2507
|
+
occurrence?: number;
|
|
2508
|
+
}
|
|
2509
|
+
/** Structural addressing for content the paraId map cannot reach. */
|
|
2510
|
+
interface DocLocation {
|
|
2511
|
+
container: ContainerRef;
|
|
2512
|
+
/** Block indices, descending into tables and content controls. */
|
|
2513
|
+
path: number[];
|
|
2514
|
+
offset?: number;
|
|
2488
2515
|
}
|
|
2489
2516
|
/**
|
|
2490
|
-
*
|
|
2517
|
+
* Which STORY a location belongs to.
|
|
2491
2518
|
*
|
|
2492
|
-
* The
|
|
2493
|
-
*
|
|
2519
|
+
* The body is one container; every header, footer and note is another. A path alone is
|
|
2520
|
+
* ambiguous without it, because block index 0 exists in every story a document has.
|
|
2521
|
+
*/
|
|
2522
|
+
type ContainerRef = {
|
|
2523
|
+
part: 'body';
|
|
2524
|
+
} | {
|
|
2525
|
+
part: 'header' | 'footer';
|
|
2526
|
+
rId: string;
|
|
2527
|
+
} | {
|
|
2528
|
+
part: 'footnote' | 'endnote';
|
|
2529
|
+
noteId: number;
|
|
2530
|
+
};
|
|
2531
|
+
/**
|
|
2532
|
+
* Anything an operation can be pointed at: a paragraph-relative {@link DocAnchor}, a structural
|
|
2533
|
+
* {@link DocLocation}, or a {@link DocRange} spanning two of them.
|
|
2494
2534
|
*/
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
/** May sit in a later paragraph: the range markers are independent elements. */
|
|
2501
|
-
readonly endParagraphId: string;
|
|
2502
|
-
readonly endOffset: number;
|
|
2535
|
+
type DocTarget = DocAnchor | DocLocation | DocRange;
|
|
2536
|
+
/** A span between two positions. The endpoints may be addressed either way, independently. */
|
|
2537
|
+
interface DocRange {
|
|
2538
|
+
from: DocAnchor | DocLocation;
|
|
2539
|
+
to: DocAnchor | DocLocation;
|
|
2503
2540
|
}
|
|
2504
2541
|
/**
|
|
2505
|
-
*
|
|
2542
|
+
* Every write returns this rather than `boolean`.
|
|
2506
2543
|
*
|
|
2507
|
-
* A
|
|
2508
|
-
* is
|
|
2544
|
+
* A bare boolean cannot distinguish "no-op" from "target not found" from
|
|
2545
|
+
* "content control is locked", and the editor layer already throws eight
|
|
2546
|
+
* distinct ContentControl error classes that a boolean would flatten.
|
|
2509
2547
|
*/
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
* Where the comment is anchored, absent when the file gave it no usable range.
|
|
2523
|
-
*
|
|
2524
|
-
* A comment lives in `comments.xml` and is placed by markers in a STORY, so the story is
|
|
2525
|
-
* part of the address: a comment anchored in a header belongs to a part the body never saw.
|
|
2526
|
-
*/
|
|
2527
|
-
readonly anchor?: DocAnchorRange;
|
|
2528
|
-
/**
|
|
2529
|
-
* True when the file gave this comment no usable range — a reference with no markers, or a
|
|
2530
|
-
* start with no end. Reported rather than dropped: a reviewer's remark vanishing silently
|
|
2531
|
-
* is worse than one that says it lost its text.
|
|
2532
|
-
*/
|
|
2533
|
-
readonly orphaned?: boolean;
|
|
2534
|
-
}
|
|
2548
|
+
type ExecResult = {
|
|
2549
|
+
ok: true;
|
|
2550
|
+
changed: boolean;
|
|
2551
|
+
revisions?: RevisionBatchResult;
|
|
2552
|
+
history?: HistoryGroupOutcome;
|
|
2553
|
+
} | {
|
|
2554
|
+
ok: false;
|
|
2555
|
+
code: ExecErrorCode;
|
|
2556
|
+
reason: string;
|
|
2557
|
+
target?: DocTarget;
|
|
2558
|
+
revisions?: RevisionBatchResult;
|
|
2559
|
+
};
|
|
2535
2560
|
/**
|
|
2536
|
-
*
|
|
2561
|
+
* Why a write was refused, as a value to branch on.
|
|
2537
2562
|
*
|
|
2538
|
-
*
|
|
2539
|
-
*
|
|
2540
|
-
* `w:pPr/w:rPr/w:ins|w:del` decorates no characters at all and merges paragraphs when
|
|
2541
|
-
* resolved; a row or cell revision is structural. A reviewer shown only three kinds is a
|
|
2542
|
-
* reviewer who never learns about the rest.
|
|
2563
|
+
* Deliberately finer-grained than a boolean: "no-op", "target not found" and "content control is
|
|
2564
|
+
* locked" are different outcomes, and a caller retrying the first should not retry the third.
|
|
2543
2565
|
*/
|
|
2544
|
-
type
|
|
2545
|
-
/** A deletion and an insertion that are one edit: text typed over a selection. */
|
|
2546
|
-
| 'replace' | 'moveFrom' | 'moveTo'
|
|
2547
|
-
/** `w:rPrChange` / `w:pPrChange` — the words are unchanged, their formatting is not. */
|
|
2548
|
-
| 'format'
|
|
2549
|
-
/** `w:pPr/w:rPr/w:ins|w:del` — a paragraph split or merge. */
|
|
2550
|
-
| 'paragraphMark'
|
|
2551
|
-
/** A row, cell, section or grid revision. */
|
|
2552
|
-
| 'structural';
|
|
2566
|
+
type ExecErrorCode = 'notFound' | 'ambiguous' | 'locked' | 'bound' | 'typeMismatch' | 'kindMismatch' | 'outOfBounds' | 'unsupported' | 'invalidArgs';
|
|
2553
2567
|
/**
|
|
2554
|
-
*
|
|
2568
|
+
* A parsed .docx.
|
|
2555
2569
|
*
|
|
2556
|
-
*
|
|
2557
|
-
*
|
|
2570
|
+
* NOT JSON-round-trippable: it holds `Map`s and `Date`s, plus an internal
|
|
2571
|
+
* side-table of verbatim XML used for lossless round-tripping. Use `toJSON` /
|
|
2572
|
+
* `fromJSON` before sending it over JSON-RPC or handing it to a model.
|
|
2558
2573
|
*/
|
|
2559
|
-
interface
|
|
2560
|
-
|
|
2561
|
-
readonly
|
|
2562
|
-
readonly
|
|
2563
|
-
readonly
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
readonly date?: string;
|
|
2574
|
+
interface DocxDocument {
|
|
2575
|
+
readonly body: DocumentBody;
|
|
2576
|
+
readonly styles: StyleDefinitions;
|
|
2577
|
+
readonly theme?: Theme;
|
|
2578
|
+
readonly comments: readonly DocComment[];
|
|
2579
|
+
readonly revisions: readonly Revision[];
|
|
2580
|
+
}
|
|
2581
|
+
/** The main story: its blocks in reading order, plus the sections derived from them. */
|
|
2582
|
+
interface DocumentBody {
|
|
2583
|
+
readonly content: readonly Block[];
|
|
2570
2584
|
/**
|
|
2571
|
-
*
|
|
2572
|
-
*
|
|
2573
|
-
* `@w:id` is unique only within a part, so an address without one names two revisions in a
|
|
2574
|
-
* package that has both. The enum could not express the parts revisions actually occur in:
|
|
2575
|
-
* `header3.xml`, `footer1.xml`, `comments.xml`, and `styles.xml`, which carries
|
|
2576
|
-
* `w:pPrChange` inside style definitions with ids that collide with `document.xml`.
|
|
2585
|
+
* Derived, not stored: recomputed on read from section-break markers and
|
|
2586
|
+
* section inheritance. Never treat it as a spreadable field.
|
|
2577
2587
|
*/
|
|
2578
|
-
readonly
|
|
2588
|
+
readonly sections: readonly Section[];
|
|
2579
2589
|
}
|
|
2580
|
-
/**
|
|
2581
|
-
interface
|
|
2582
|
-
readonly
|
|
2583
|
-
widthTwips: number;
|
|
2584
|
-
heightTwips: number;
|
|
2585
|
-
};
|
|
2586
|
-
readonly margins: PageMargins;
|
|
2587
|
-
readonly columns?: {
|
|
2588
|
-
count: number;
|
|
2589
|
-
gapTwips: number;
|
|
2590
|
-
};
|
|
2591
|
-
/** `w:titlePg` — whether the section's first page takes the `first` header/footer variant. */
|
|
2592
|
-
readonly titlePage?: boolean;
|
|
2590
|
+
/** The JSON-safe projection of a document. */
|
|
2591
|
+
interface DocxDocumentJSON {
|
|
2592
|
+
readonly [key: string]: unknown;
|
|
2593
2593
|
}
|
|
2594
|
-
/**
|
|
2595
|
-
interface
|
|
2596
|
-
readonly
|
|
2597
|
-
readonly
|
|
2598
|
-
readonly
|
|
2599
|
-
readonly leftTwips: number;
|
|
2594
|
+
/** One section: the page it lays out on, and the header/footer stories it declares. */
|
|
2595
|
+
interface Section {
|
|
2596
|
+
readonly properties: SectionProperties;
|
|
2597
|
+
readonly headers: HeaderFooterSet;
|
|
2598
|
+
readonly footers: HeaderFooterSet;
|
|
2600
2599
|
}
|
|
2601
2600
|
/**
|
|
2602
|
-
*
|
|
2601
|
+
* A section's three header (or footer) variants, each a relationship id.
|
|
2603
2602
|
*
|
|
2604
|
-
*
|
|
2605
|
-
*
|
|
2603
|
+
* All optional: a variant a section does not declare inherits the previous section's, and one
|
|
2604
|
+
* absent everywhere means the document simply has none.
|
|
2606
2605
|
*/
|
|
2607
|
-
interface
|
|
2608
|
-
readonly
|
|
2609
|
-
readonly
|
|
2610
|
-
readonly
|
|
2606
|
+
interface HeaderFooterSet {
|
|
2607
|
+
readonly default?: string;
|
|
2608
|
+
readonly first?: string;
|
|
2609
|
+
readonly even?: string;
|
|
2611
2610
|
}
|
|
2612
|
-
/**
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2611
|
+
/** Anything that can sit at block level in a story. Discriminate on `kind`. */
|
|
2612
|
+
type Block = Paragraph | Table | ContentControl;
|
|
2613
|
+
/** One paragraph: its runs, the style it names, and its list membership. */
|
|
2614
|
+
interface Paragraph {
|
|
2615
|
+
readonly kind: 'paragraph';
|
|
2616
|
+
/** `w14:paraId`. The stable handle `DocAnchor` addresses. */
|
|
2617
|
+
readonly paraId?: string;
|
|
2618
|
+
readonly runs: readonly Run[];
|
|
2619
|
+
readonly styleId?: string;
|
|
2620
|
+
readonly numbering?: NumberingRef;
|
|
2618
2621
|
}
|
|
2619
|
-
/** A
|
|
2620
|
-
interface
|
|
2621
|
-
readonly
|
|
2622
|
-
|
|
2623
|
-
|
|
2622
|
+
/** A stretch of text sharing one set of character properties. */
|
|
2623
|
+
interface Run {
|
|
2624
|
+
readonly text: string;
|
|
2625
|
+
readonly formatting?: RunFormatting;
|
|
2626
|
+
/** Set when the run carries a tracked change. Unique only within its part. */
|
|
2627
|
+
readonly revisionId?: number;
|
|
2624
2628
|
}
|
|
2625
2629
|
/**
|
|
2626
|
-
*
|
|
2630
|
+
* Character formatting, and — at selection level — the paragraph properties a toolbar reads
|
|
2631
|
+
* alongside it.
|
|
2627
2632
|
*
|
|
2628
|
-
*
|
|
2629
|
-
*
|
|
2630
|
-
*
|
|
2631
|
-
* on white.
|
|
2633
|
+
* One type serves both roles so a toolbar reads alignment, style and script state from the same
|
|
2634
|
+
* object as bold and italic. On a {@link Run} the selection-level fields stay absent: a run has
|
|
2635
|
+
* no alignment or paragraph style of its own.
|
|
2632
2636
|
*/
|
|
2633
|
-
|
|
2634
|
-
readonly
|
|
2635
|
-
readonly
|
|
2636
|
-
|
|
2637
|
-
readonly
|
|
2638
|
-
readonly
|
|
2639
|
-
readonly
|
|
2640
|
-
readonly
|
|
2641
|
-
|
|
2642
|
-
readonly
|
|
2643
|
-
|
|
2644
|
-
/**
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
readonly
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
readonly
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
readonly
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2637
|
+
interface RunFormatting {
|
|
2638
|
+
readonly bold?: boolean;
|
|
2639
|
+
readonly italic?: boolean;
|
|
2640
|
+
readonly underline?: boolean;
|
|
2641
|
+
readonly strike?: boolean;
|
|
2642
|
+
readonly color?: ColorValue;
|
|
2643
|
+
readonly highlight?: string;
|
|
2644
|
+
readonly fontFamily?: string;
|
|
2645
|
+
readonly fontSizePt?: number;
|
|
2646
|
+
readonly superscript?: boolean;
|
|
2647
|
+
readonly subscript?: boolean;
|
|
2648
|
+
/** Paragraph alignment at the selection. `both` is OOXML's spelling of justify. */
|
|
2649
|
+
readonly alignment?: 'left' | 'center' | 'right' | 'both';
|
|
2650
|
+
/** Paragraph style id (`w:pStyle`) at the selection. */
|
|
2651
|
+
readonly styleId?: string;
|
|
2652
|
+
/**
|
|
2653
|
+
* Line spacing at the selection, in the unit its rule implies — LINES for `multiple`,
|
|
2654
|
+
* points for `exact` and `atLeast`. The same vocabulary `setLineSpacing` takes, so a
|
|
2655
|
+
* control can show what it reads and send back what it shows. Absent when the
|
|
2656
|
+
* selection's paragraphs disagree or state no line spacing.
|
|
2657
|
+
*/
|
|
2658
|
+
readonly lineSpacing?: {
|
|
2659
|
+
readonly rule: 'multiple' | 'exact' | 'atLeast';
|
|
2660
|
+
readonly value: number;
|
|
2661
|
+
};
|
|
2662
|
+
/**
|
|
2663
|
+
* Space above and below the paragraph at the selection, in points.
|
|
2664
|
+
*
|
|
2665
|
+
* The measurement the cascade STATES — `w:docDefaults`, the style chain and direct
|
|
2666
|
+
* formatting resolved together — not the gap the page finally draws. The two differ for a
|
|
2667
|
+
* paragraph carrying `w:beforeAutospacing`, where Word substitutes its own value and
|
|
2668
|
+
* ignores the measurement, and again where two paragraphs collapse their adjacent spacing.
|
|
2669
|
+
* Absent when the selection's paragraphs disagree or no level states it.
|
|
2670
|
+
*/
|
|
2671
|
+
readonly spaceBeforePt?: number;
|
|
2672
|
+
readonly spaceAfterPt?: number;
|
|
2673
|
+
/**
|
|
2674
|
+
* The paragraph flags the Paragraph dialog shows as checkboxes.
|
|
2675
|
+
*
|
|
2676
|
+
* Each is `true`, `false`, or `null` when the selection's paragraphs disagree — a
|
|
2677
|
+
* checkbox needs all three. Read through the cascade, so a flag a STYLE sets reads as on,
|
|
2678
|
+
* which is what the box has to show over a paragraph the page is visibly keeping with the
|
|
2679
|
+
* next. Absent on a `Run`, like every other selection-level field here.
|
|
2680
|
+
*/
|
|
2681
|
+
readonly paragraphFlags?: ParagraphFlags;
|
|
2682
|
+
/**
|
|
2683
|
+
* Which paragraph-level fields above are absent because the selection DISAGREES, as
|
|
2684
|
+
* opposed to because nothing states them.
|
|
2685
|
+
*
|
|
2686
|
+
* A `null`/absent value alone cannot tell those apart, and both readings have shipped as
|
|
2687
|
+
* bugs: a disagreement rendered as a concrete value is uncorrectable, because the value
|
|
2688
|
+
* that would fix it is the one already on screen; an absent value rendered as "mixed"
|
|
2689
|
+
* tells a single paragraph it disagrees with itself.
|
|
2690
|
+
*/
|
|
2691
|
+
readonly disagrees?: ParagraphDisagreements;
|
|
2692
|
+
/**
|
|
2693
|
+
* The paragraph's custom tab stops at the selection, cascade included. Absent when the
|
|
2694
|
+
* selection disagrees or the paragraphs have none.
|
|
2695
|
+
*/
|
|
2696
|
+
readonly tabStops?: readonly ParagraphTabStop[];
|
|
2697
|
+
/**
|
|
2698
|
+
* The EFFECTIVE paragraph indent at the selection — cascade and numbering merge
|
|
2699
|
+
* included, so a numbered item that authors no `w:ind` reports the indent its list
|
|
2700
|
+
* definition gives it. Absent when nothing is loaded, or when the selection is inside a
|
|
2701
|
+
* table (see {@link IndentFormatting}).
|
|
2702
|
+
*/
|
|
2703
|
+
readonly indent?: IndentFormatting;
|
|
2677
2704
|
}
|
|
2678
|
-
/** What every subscription returns. Calling it twice is safe. */
|
|
2679
|
-
type Unsubscribe = () => void;
|
|
2680
|
-
|
|
2681
|
-
/** How deep controls may nest before a walk stops descending. Shared by every lane. */
|
|
2682
|
-
declare const MAX_CONTENT_CONTROL_NESTING = 32;
|
|
2683
|
-
/** Cap on controls one walk reports, so a hostile file cannot make a read unbounded. */
|
|
2684
|
-
declare const MAX_CONTENT_CONTROLS_PER_PART = 10000;
|
|
2685
|
-
/** `CT_SdtPr/w:id` is `ST_DecimalNumber`; Word treats it as a signed 32-bit integer. */
|
|
2686
|
-
declare const CONTENT_CONTROL_ID_MAX = 2147483647;
|
|
2687
|
-
/** `ST_Lock` (§17.5.2.24). An absent `w:lock` is `unlocked`. */
|
|
2688
2705
|
/**
|
|
2689
|
-
*
|
|
2706
|
+
* Indent at the selection, in twips.
|
|
2690
2707
|
*
|
|
2691
|
-
*
|
|
2692
|
-
*
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
*
|
|
2708
|
+
* Unlike every other field here, this does NOT go absent when the selection's paragraphs
|
|
2709
|
+
* disagree. A ruler has to draw its handles somewhere, and Word draws them at the FIRST
|
|
2710
|
+
* selected paragraph's values — Select All is the commonest indent gesture, and hiding the
|
|
2711
|
+
* handles for it would be worse than showing one paragraph's truth. The values are
|
|
2712
|
+
* therefore always the first touched paragraph's, and {@link mixed} records per field
|
|
2713
|
+
* whether the rest agree.
|
|
2697
2714
|
*
|
|
2698
|
-
* `
|
|
2699
|
-
*
|
|
2700
|
-
*
|
|
2701
|
-
*
|
|
2702
|
-
*
|
|
2715
|
+
* `firstLine` is ONE SIGNED offset: negative is a hanging indent. OOXML spells it as two
|
|
2716
|
+
* mutually exclusive attributes and this collapses them hanging-wins (§17.3.1.12), which
|
|
2717
|
+
* is the model Word itself keeps.
|
|
2718
|
+
*
|
|
2719
|
+
* Absent inside a table. The value would be correct there, but it is measured from the
|
|
2720
|
+
* cell's content edge while a ruler is drawn against the page's margin, and the ruler does
|
|
2721
|
+
* not know the cell.
|
|
2703
2722
|
*/
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
readonly
|
|
2709
|
-
|
|
2723
|
+
interface IndentFormatting {
|
|
2724
|
+
/** Left indent, signed. Negative pulls text into the margin, as Word allows. */
|
|
2725
|
+
readonly left: number;
|
|
2726
|
+
/** Right indent, signed. */
|
|
2727
|
+
readonly right: number;
|
|
2728
|
+
/** First-line offset from {@link left}, signed. Negative is a hanging indent. */
|
|
2729
|
+
readonly firstLine: number;
|
|
2730
|
+
/** Per field, whether the selection's paragraphs disagree about it. */
|
|
2731
|
+
readonly mixed: {
|
|
2732
|
+
readonly left: boolean;
|
|
2733
|
+
readonly right: boolean;
|
|
2734
|
+
readonly firstLine: boolean;
|
|
2735
|
+
};
|
|
2710
2736
|
}
|
|
2711
|
-
/** A
|
|
2712
|
-
interface
|
|
2713
|
-
readonly
|
|
2714
|
-
readonly
|
|
2715
|
-
readonly
|
|
2716
|
-
readonly storeMappedDataAs?: string;
|
|
2717
|
-
readonly calendar?: string;
|
|
2737
|
+
/** A table: its rows, and the table style they resolve through. */
|
|
2738
|
+
interface Table {
|
|
2739
|
+
readonly kind: 'table';
|
|
2740
|
+
readonly rows: readonly TableRow[];
|
|
2741
|
+
readonly styleId?: string;
|
|
2718
2742
|
}
|
|
2719
|
-
/** One
|
|
2720
|
-
interface
|
|
2721
|
-
|
|
2722
|
-
readonly value: string;
|
|
2723
|
-
readonly font?: string;
|
|
2743
|
+
/** One table row. Cell count may vary between rows: `colSpan` and vertical merges reshape it. */
|
|
2744
|
+
interface TableRow {
|
|
2745
|
+
readonly cells: readonly TableCell[];
|
|
2724
2746
|
}
|
|
2725
2747
|
/**
|
|
2726
|
-
*
|
|
2727
|
-
*
|
|
2728
|
-
* Both glyphs matter on a write: setting the value has to update `w14:checked` AND the run's
|
|
2729
|
-
* character, or the document's glyph and its recorded state disagree.
|
|
2748
|
+
* One cell. Its `content` is ordinary blocks, so a cell may hold paragraphs, nested tables and
|
|
2749
|
+
* content controls alike.
|
|
2730
2750
|
*/
|
|
2731
|
-
interface
|
|
2732
|
-
readonly
|
|
2733
|
-
|
|
2734
|
-
readonly
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
/** `w:dataBinding` — the custom-XML part and XPath a control's value is bound to. */
|
|
2738
|
-
interface ContentControlDataBinding {
|
|
2739
|
-
readonly xpath?: string;
|
|
2740
|
-
readonly storeItemID?: string;
|
|
2741
|
-
readonly prefixMappings?: string;
|
|
2751
|
+
interface TableCell {
|
|
2752
|
+
readonly content: readonly Block[];
|
|
2753
|
+
/** Vertical merge span. Absent means 1. */
|
|
2754
|
+
readonly rowSpan?: number;
|
|
2755
|
+
/** `w:gridSpan`. Absent means 1. */
|
|
2756
|
+
readonly colSpan?: number;
|
|
2742
2757
|
}
|
|
2743
|
-
/**
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
* re-save that demotes the properties node to generic does not break the projection.
|
|
2748
|
-
*/
|
|
2749
|
-
interface ContentControlProperties {
|
|
2750
|
-
readonly type: ContentControlKind;
|
|
2751
|
-
readonly alias?: string;
|
|
2758
|
+
/** Structured document tag (`w:sdt`). */
|
|
2759
|
+
interface ContentControl {
|
|
2760
|
+
readonly kind: 'contentControl';
|
|
2761
|
+
readonly id: string;
|
|
2752
2762
|
readonly tag?: string;
|
|
2753
|
-
|
|
2754
|
-
readonly
|
|
2755
|
-
readonly
|
|
2756
|
-
|
|
2757
|
-
readonly placeholderDocPart?: string;
|
|
2758
|
-
readonly temporary: boolean;
|
|
2759
|
-
readonly showingPlaceholder: boolean;
|
|
2760
|
-
readonly dataBinding?: ContentControlDataBinding;
|
|
2761
|
-
readonly label?: string;
|
|
2762
|
-
readonly tabIndex?: number;
|
|
2763
|
-
/** Items a dropdown or combo box offers. Empty for every other type. */
|
|
2764
|
-
readonly listItems: readonly ContentControlListItem[];
|
|
2765
|
-
readonly lastValue?: string;
|
|
2766
|
-
readonly date?: ContentControlDateFormat;
|
|
2767
|
-
readonly multiLine?: boolean;
|
|
2768
|
-
readonly checkbox?: ContentControlCheckbox;
|
|
2763
|
+
readonly alias?: string;
|
|
2764
|
+
readonly controlType: ContentControlType;
|
|
2765
|
+
readonly locked?: boolean;
|
|
2766
|
+
readonly content: readonly Block[];
|
|
2769
2767
|
}
|
|
2770
|
-
/**
|
|
2771
|
-
|
|
2772
|
-
/** Whether a node is a `w:sdtContent` — the container holding a control's actual content. */
|
|
2773
|
-
declare function isContentControlContentNode(node: OoxmlNode): node is OoxmlContentControlContentNode;
|
|
2774
|
-
/**
|
|
2775
|
-
* A `w:sdt` wrapper, TYPED or DEMOTED.
|
|
2776
|
-
*
|
|
2777
|
-
* Flattening predates typing and must not stop at a control the reader refused to type: a
|
|
2778
|
-
* demoted wrapper still renders its content in place in Word, so a walk that only saw the
|
|
2779
|
-
* typed kind would drop every paragraph inside a malformed control out of the story.
|
|
2780
|
-
*/
|
|
2781
|
-
declare function isContentControlWrapper(node: OoxmlNode): boolean;
|
|
2782
|
-
/**
|
|
2783
|
-
* The children of a wrapper's `w:sdtContent`, typed or demoted, in order.
|
|
2784
|
-
*
|
|
2785
|
-
* The one place that knows a control's content is reached through an intermediate element,
|
|
2786
|
-
* so the four flattening walks (story blocks, layout, header/footer references, list
|
|
2787
|
-
* resolution) ask the same question rather than each re-deriving it.
|
|
2788
|
-
*/
|
|
2789
|
-
declare function contentControlContentChildren(wrapper: OoxmlNode): readonly OoxmlNode[];
|
|
2768
|
+
/** Which kind of control a `w:sdt` is, and therefore what a value written into it must be. */
|
|
2769
|
+
type ContentControlType = 'richText' | 'plainText' | 'checkbox' | 'dropdown' | 'comboBox' | 'date' | 'picture' | 'buildingBlockGallery' | 'repeatingSection';
|
|
2790
2770
|
/**
|
|
2791
|
-
*
|
|
2792
|
-
*
|
|
2793
|
-
* ONE unwrap rule, for the places where a control sits between a container and the children that
|
|
2794
|
-
* container is defined in terms of. `CT_SdtRow` puts it between `w:tbl` and `w:tr`, `CT_SdtCell`
|
|
2795
|
-
* between `w:tr` and `w:tc`, and a walk that filtered on the child's kind dropped the row or cell
|
|
2796
|
-
* entirely: not measured, not painted, not addressable. Flattening at the point of the filter
|
|
2797
|
-
* means a controlled row is the same row to the grid pass, the pagination pass and the story walk.
|
|
2771
|
+
* The control kinds an insertion can author.
|
|
2798
2772
|
*
|
|
2799
|
-
*
|
|
2800
|
-
*
|
|
2801
|
-
* its
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
declare function contentControlPropertiesNodeOf(control: OoxmlNode): OoxmlContentControlPropertiesNode | undefined;
|
|
2806
|
-
/** A control's `w:sdtEndPr` — the run properties applied to its closing marker. */
|
|
2807
|
-
declare function contentControlEndPropertiesNodeOf(control: OoxmlNode): OoxmlContentControlEndPropertiesNode | undefined;
|
|
2808
|
-
/** A control's `w:sdtContent`, or null when the wrapper has none. */
|
|
2809
|
-
declare function contentControlContentNodeOf(control: OoxmlNode): OoxmlContentControlContentNode | undefined;
|
|
2810
|
-
/** A signed 32-bit `ST_DecimalNumber`, or undefined when the file wrote something else. */
|
|
2811
|
-
declare function parseContentControlId(raw: string | undefined): number | undefined;
|
|
2812
|
-
/**
|
|
2813
|
-
* Read a control's properties.
|
|
2773
|
+
* A NARROWING of {@link ContentControlType}, not a separate vocabulary: a kind read off an
|
|
2774
|
+
* existing control can be handed straight back to `insertContentControl`. Three kinds are
|
|
2775
|
+
* absent because an insertion would have to invent what they carry — a checkbox needs its two
|
|
2776
|
+
* declared glyph states, a picture needs an image part, a building block gallery needs a
|
|
2777
|
+
* glossary to list, and a repeating section is a container whose items have their own verbs. Reading still answers the wider type; a document may hold
|
|
2778
|
+
* kinds this cannot create.
|
|
2814
2779
|
*
|
|
2815
|
-
*
|
|
2816
|
-
*
|
|
2780
|
+
* `dropDownList` is the same kind as `dropdown`, spelt as OOXML spells it. Both are accepted,
|
|
2781
|
+
* so a type read off a control can be handed back without translating it — and the OOXML
|
|
2782
|
+
* spelling is the one the automation protocol takes, so a caller who uses both surfaces can
|
|
2783
|
+
* write that one everywhere.
|
|
2817
2784
|
*/
|
|
2818
|
-
|
|
2819
|
-
/** Where a control sits, read off what its content holds. */
|
|
2820
|
-
type ContentControlLevel = 'block' | 'inline' | 'row' | 'cell' | 'empty';
|
|
2785
|
+
type InsertableContentControlType = Extract<ContentControlType, 'richText' | 'plainText' | 'dropdown' | 'comboBox' | 'date'> | 'dropDownList';
|
|
2821
2786
|
/**
|
|
2822
|
-
*
|
|
2823
|
-
*
|
|
2824
|
-
* Bounded by {@link MAX_CONTENT_CONTROL_NESTING}: nesting depth comes from a file and is a
|
|
2825
|
-
* recursion bound.
|
|
2787
|
+
* Narrows a content-control query. Fields combine with AND; an empty filter matches every
|
|
2788
|
+
* control.
|
|
2826
2789
|
*/
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
readonly
|
|
2831
|
-
/** 0 for a top-level control; the nesting depth otherwise. */
|
|
2832
|
-
readonly depth: number;
|
|
2833
|
-
/** Enclosing controls, outermost first. Empty at depth 0. */
|
|
2834
|
-
readonly ancestors: readonly OoxmlContentControlNode[];
|
|
2790
|
+
interface ContentControlFilter {
|
|
2791
|
+
readonly tag?: string;
|
|
2792
|
+
readonly alias?: string;
|
|
2793
|
+
readonly controlType?: ContentControlType;
|
|
2835
2794
|
}
|
|
2836
2795
|
/**
|
|
2837
|
-
*
|
|
2796
|
+
* A position in one story: a paragraph and a UTF-16 offset inside it.
|
|
2838
2797
|
*
|
|
2839
|
-
*
|
|
2840
|
-
*
|
|
2841
|
-
* keeps its content in the tree (the serializer never stops) while no walk recurses
|
|
2842
|
-
* further.
|
|
2798
|
+
* The same offset space the ops and the caret use, so an anchor read here can be handed
|
|
2799
|
+
* straight back to a selection without re-deriving anything.
|
|
2843
2800
|
*/
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
readonly
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2801
|
+
interface DocAnchorRange {
|
|
2802
|
+
/** Canonical part name of the story the range lives in, e.g. `/word/document.xml`. */
|
|
2803
|
+
readonly part: string;
|
|
2804
|
+
readonly startParagraphId: string;
|
|
2805
|
+
readonly startOffset: number;
|
|
2806
|
+
/** May sit in a later paragraph: the range markers are independent elements. */
|
|
2807
|
+
readonly endParagraphId: string;
|
|
2808
|
+
readonly endOffset: number;
|
|
2809
|
+
}
|
|
2850
2810
|
/**
|
|
2851
|
-
*
|
|
2811
|
+
* One comment or reply, as `comments.xml` records it.
|
|
2852
2812
|
*
|
|
2853
|
-
*
|
|
2854
|
-
*
|
|
2813
|
+
* A reply is a comment with a `parentId`; OOXML gives replies no separate element, so the thread
|
|
2814
|
+
* is reconstructed from that link rather than from nesting.
|
|
2855
2815
|
*/
|
|
2856
|
-
|
|
2816
|
+
interface DocComment {
|
|
2817
|
+
readonly id: string;
|
|
2818
|
+
readonly author: string;
|
|
2819
|
+
/**
|
|
2820
|
+
* OPTIONAL, because `CT_Comment` makes `@w:date` optional and files omit it. A comment
|
|
2821
|
+
* with no date is a comment, not a defect, and fabricating one is a content change.
|
|
2822
|
+
*/
|
|
2823
|
+
readonly date?: string;
|
|
2824
|
+
readonly text: string;
|
|
2825
|
+
readonly parentId?: string;
|
|
2826
|
+
readonly resolved?: boolean;
|
|
2827
|
+
/**
|
|
2828
|
+
* Where the comment is anchored, absent when the file gave it no usable range.
|
|
2829
|
+
*
|
|
2830
|
+
* A comment lives in `comments.xml` and is placed by markers in a STORY, so the story is
|
|
2831
|
+
* part of the address: a comment anchored in a header belongs to a part the body never saw.
|
|
2832
|
+
*/
|
|
2833
|
+
readonly anchor?: DocAnchorRange;
|
|
2834
|
+
/**
|
|
2835
|
+
* True when the file gave this comment no usable range — a reference with no markers, or a
|
|
2836
|
+
* start with no end. Reported rather than dropped: a reviewer's remark vanishing silently
|
|
2837
|
+
* is worse than one that says it lost its text.
|
|
2838
|
+
*/
|
|
2839
|
+
readonly orphaned?: boolean;
|
|
2840
|
+
}
|
|
2857
2841
|
/**
|
|
2858
|
-
*
|
|
2842
|
+
* What kind of decision a revision represents.
|
|
2859
2843
|
*
|
|
2860
|
-
*
|
|
2861
|
-
*
|
|
2862
|
-
*
|
|
2863
|
-
*
|
|
2864
|
-
*
|
|
2844
|
+
* Wider than insert/delete/format, and it has to be. `w:moveFrom`/`w:moveTo` are not a
|
|
2845
|
+
* deletion and an insertion — resolving one half alone duplicates or loses the content;
|
|
2846
|
+
* `w:pPr/w:rPr/w:ins|w:del` decorates no characters at all and merges paragraphs when
|
|
2847
|
+
* resolved; a row or cell revision is structural. A reviewer shown only three kinds is a
|
|
2848
|
+
* reviewer who never learns about the rest.
|
|
2865
2849
|
*/
|
|
2866
|
-
|
|
2867
|
-
/**
|
|
2868
|
-
|
|
2869
|
-
/**
|
|
2870
|
-
|
|
2850
|
+
type RevisionType = 'insert' | 'delete'
|
|
2851
|
+
/** A deletion and an insertion that are one edit: text typed over a selection. */
|
|
2852
|
+
| 'replace' | 'moveFrom' | 'moveTo'
|
|
2853
|
+
/** `w:rPrChange` / `w:pPrChange` — the words are unchanged, their formatting is not. */
|
|
2854
|
+
| 'format'
|
|
2855
|
+
/** `w:pPr/w:rPr/w:ins|w:del` — a paragraph split or merge. */
|
|
2856
|
+
| 'paragraphMark'
|
|
2857
|
+
/** A row, cell, section or grid revision. */
|
|
2858
|
+
| 'structural';
|
|
2871
2859
|
/**
|
|
2872
|
-
*
|
|
2860
|
+
* One tracked change.
|
|
2873
2861
|
*
|
|
2874
|
-
*
|
|
2875
|
-
*
|
|
2876
|
-
* {@link orderedContentControlProperties} does.
|
|
2862
|
+
* Addressing needs BOTH `id` and `part`: `@w:id` is unique only within a part, so an id alone
|
|
2863
|
+
* names two revisions in any package that has a header or a comments part.
|
|
2877
2864
|
*/
|
|
2878
|
-
|
|
2865
|
+
interface Revision {
|
|
2866
|
+
/** Numeric, and unique only WITHIN a part. Pair with `part` to address one. */
|
|
2867
|
+
readonly id: number;
|
|
2868
|
+
readonly type: RevisionType;
|
|
2869
|
+
readonly author: string;
|
|
2870
|
+
/**
|
|
2871
|
+
* OPTIONAL. `CT_TrackChange` requires `@w:id` and `@w:author` and makes `@w:date`
|
|
2872
|
+
* optional, and producers that omit it are ordinary. Requiring it here forced either a
|
|
2873
|
+
* fabricated date — a content change — or dropping the revision from the list.
|
|
2874
|
+
*/
|
|
2875
|
+
readonly date?: string;
|
|
2876
|
+
/**
|
|
2877
|
+
* REQUIRED, and a canonical PART NAME rather than a three-value enum.
|
|
2878
|
+
*
|
|
2879
|
+
* `@w:id` is unique only within a part, so an address without one names two revisions in a
|
|
2880
|
+
* package that has both. The enum could not express the parts revisions actually occur in:
|
|
2881
|
+
* `header3.xml`, `footer1.xml`, `comments.xml`, and `styles.xml`, which carries
|
|
2882
|
+
* `w:pPrChange` inside style definitions with ids that collide with `document.xml`.
|
|
2883
|
+
*/
|
|
2884
|
+
readonly part: string;
|
|
2885
|
+
}
|
|
2886
|
+
/** `w:sectPr`: the page a section lays out on. Twips throughout, as the file stores them. */
|
|
2887
|
+
interface SectionProperties {
|
|
2888
|
+
readonly pageSize: {
|
|
2889
|
+
widthTwips: number;
|
|
2890
|
+
heightTwips: number;
|
|
2891
|
+
};
|
|
2892
|
+
readonly margins: PageMargins;
|
|
2893
|
+
readonly columns?: {
|
|
2894
|
+
count: number;
|
|
2895
|
+
gapTwips: number;
|
|
2896
|
+
};
|
|
2897
|
+
/** `w:titlePg` — whether the section's first page takes the `first` header/footer variant. */
|
|
2898
|
+
readonly titlePage?: boolean;
|
|
2899
|
+
}
|
|
2900
|
+
/** Page margins in twips. */
|
|
2901
|
+
interface PageMargins {
|
|
2902
|
+
readonly topTwips: number;
|
|
2903
|
+
readonly rightTwips: number;
|
|
2904
|
+
readonly bottomTwips: number;
|
|
2905
|
+
readonly leftTwips: number;
|
|
2906
|
+
}
|
|
2879
2907
|
/**
|
|
2880
|
-
*
|
|
2908
|
+
* `styles.xml`, split by the three style families that address separately.
|
|
2881
2909
|
*
|
|
2882
|
-
*
|
|
2883
|
-
*
|
|
2884
|
-
* extension, the `w14:checkbox` that is not part of the ECMA-376 choice — keeps the order
|
|
2885
|
-
* it was authored in and follows the modelled block, so a write that touches one property
|
|
2886
|
-
* neither drops nor reorders anything it does not name.
|
|
2910
|
+
* Keyed by style ID rather than by the name a reader sees, because the ID is what a paragraph or
|
|
2911
|
+
* run actually references.
|
|
2887
2912
|
*/
|
|
2888
|
-
|
|
2913
|
+
interface StyleDefinitions {
|
|
2914
|
+
readonly paragraph: ReadonlyMap<string, StyleDefinition>;
|
|
2915
|
+
readonly character: ReadonlyMap<string, StyleDefinition>;
|
|
2916
|
+
readonly table: ReadonlyMap<string, StyleDefinition>;
|
|
2917
|
+
}
|
|
2918
|
+
/** One style: the ID content references, the name a reader sees, and its inheritance link. */
|
|
2919
|
+
interface StyleDefinition {
|
|
2920
|
+
readonly id: string;
|
|
2921
|
+
readonly name: string;
|
|
2922
|
+
/** `w:basedOn` — the style this one inherits from. Absent at the root of a chain. */
|
|
2923
|
+
readonly basedOn?: string;
|
|
2924
|
+
}
|
|
2925
|
+
/** A paragraph's list membership: which `numbering.xml` definition, and at which level. */
|
|
2926
|
+
interface NumberingRef {
|
|
2927
|
+
readonly numId: string;
|
|
2928
|
+
/** Zero-based. OOXML numbering has nine levels, 0 through 8. */
|
|
2929
|
+
readonly level: number;
|
|
2930
|
+
}
|
|
2889
2931
|
/**
|
|
2890
|
-
*
|
|
2891
|
-
*
|
|
2892
|
-
* Solo: one past the document's own maximum. Never a clock, a timestamp, a random source
|
|
2893
|
-
* or a hash: those collide with ids already in the file and produce values Word rejects.
|
|
2894
|
-
* Null when the document already reaches the signed 32-bit bound, so the caller refuses
|
|
2895
|
-
* rather than wrapping into a negative id. Hostile or out-of-range existing values are
|
|
2896
|
-
* ignored for seeding rather than counted past.
|
|
2932
|
+
* A colour as the FILE expresses it, not as a resolved RGB string.
|
|
2897
2933
|
*
|
|
2898
|
-
*
|
|
2899
|
-
* the
|
|
2900
|
-
*
|
|
2901
|
-
*
|
|
2934
|
+
* A theme colour stays a theme reference — slot plus tint or shade — so that changing the theme
|
|
2935
|
+
* repaints the document the way Word does. Flattening to hex at read time would freeze the
|
|
2936
|
+
* resolved value and break that link. `auto` is Word's "let the renderer decide", usually black
|
|
2937
|
+
* on white.
|
|
2902
2938
|
*/
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
/** The value a control accepts, by what kind of control it is. */
|
|
2906
|
-
type ContentControlValueInput = {
|
|
2907
|
-
readonly kind: 'text';
|
|
2908
|
-
readonly text: string;
|
|
2909
|
-
} | {
|
|
2910
|
-
readonly kind: 'listItem';
|
|
2939
|
+
type ColorValue = {
|
|
2940
|
+
readonly kind: 'hex';
|
|
2911
2941
|
readonly value: string;
|
|
2912
2942
|
} | {
|
|
2913
|
-
readonly kind: '
|
|
2914
|
-
readonly
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
| {
|
|
2918
|
-
readonly kind: '
|
|
2919
|
-
readonly iso: string;
|
|
2943
|
+
readonly kind: 'theme';
|
|
2944
|
+
readonly slot: string;
|
|
2945
|
+
readonly tint?: number;
|
|
2946
|
+
readonly shade?: number;
|
|
2947
|
+
} | {
|
|
2948
|
+
readonly kind: 'auto';
|
|
2920
2949
|
};
|
|
2921
|
-
/**
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2950
|
+
/** `theme1.xml` — what a {@link ColorValue} of kind `theme` resolves against. */
|
|
2951
|
+
interface Theme {
|
|
2952
|
+
readonly colorScheme: ThemeColorScheme;
|
|
2953
|
+
readonly fontScheme?: Record<string, string>;
|
|
2954
|
+
}
|
|
2955
|
+
/** Theme colour slots (`accent1`, `dk1`, `lt2`, …) to hex. */
|
|
2956
|
+
type ThemeColorScheme = Readonly<Record<string, string>>;
|
|
2957
|
+
/** A watermark, which OOXML expresses as either text or an image — never both meaningfully. */
|
|
2958
|
+
interface Watermark {
|
|
2959
|
+
readonly text?: string;
|
|
2960
|
+
readonly imageData?: Uint8Array;
|
|
2961
|
+
}
|
|
2962
|
+
/** A size in EMUs, the unit DrawingML stores extents in. 914400 EMU = 1 inch. */
|
|
2963
|
+
interface Extent {
|
|
2964
|
+
readonly widthEmu: number;
|
|
2965
|
+
readonly heightEmu: number;
|
|
2966
|
+
}
|
|
2967
|
+
/** A font the document names, and whether its bytes travel inside the package. */
|
|
2968
|
+
interface FontDefinition {
|
|
2969
|
+
readonly family: string;
|
|
2970
|
+
readonly embedded: boolean;
|
|
2971
|
+
}
|
|
2972
|
+
/** An axis-aligned rectangle in points, the unit layout works in throughout. */
|
|
2973
|
+
interface Rect {
|
|
2974
|
+
readonly x: number;
|
|
2975
|
+
readonly y: number;
|
|
2976
|
+
readonly width: number;
|
|
2977
|
+
readonly height: number;
|
|
2978
|
+
}
|
|
2979
|
+
/** A position in points. */
|
|
2980
|
+
interface Point {
|
|
2981
|
+
readonly x: number;
|
|
2982
|
+
readonly y: number;
|
|
2983
|
+
}
|
|
2984
|
+
/** What every subscription returns. Calling it twice is safe. */
|
|
2985
|
+
type Unsubscribe = () => void;
|
|
2942
2986
|
|
|
2943
2987
|
/**
|
|
2944
2988
|
* How a tracked change is addressed: `@w:id`, `@w:author` and `@w:date` together, within a
|
|
@@ -3849,7 +3893,7 @@ type TreeDocOp = SetFieldCodeOp | {
|
|
|
3849
3893
|
readonly paragraphId: string;
|
|
3850
3894
|
readonly pageNumberText: string;
|
|
3851
3895
|
}[];
|
|
3852
|
-
} | SetTextFormFieldDefaultOp | CommitTextFormFieldOp | {
|
|
3896
|
+
} | SetTextFormFieldDefaultOp | CommitTextFormFieldOp | SetLegacyCheckboxOp | SetLegacyDropdownOp | InsertBuildingBlockOp | {
|
|
3853
3897
|
/**
|
|
3854
3898
|
* Rewrite recognized fields' cached RESULT runs in place — between the `separate` and
|
|
3855
3899
|
* `end` fldChars, or a `w:fldSimple`'s content. The instruction is never modified; a
|
|
@@ -4013,4 +4057,4 @@ type TreeOpResult = {
|
|
|
4013
4057
|
readonly detail?: string;
|
|
4014
4058
|
};
|
|
4015
4059
|
|
|
4016
|
-
export { type RevisionBatchSkipReason as $, type IndentFormatting as A, type Block as B, type CommentRecord as C, type DocxDocument as D, type ExecResult as E, type ParagraphFlags as F, type ParagraphTabStop as G, type HeaderFooterSet as H, type InsertableContentControlType as I, type RevisionType as J, type Section as K, type SectionProperties as L, type StyleDefinition as M, type Theme as N, type OoxmlPart as O, type Paragraph as P, type ThemeColorScheme as Q, type ReviewModelInput as R, type StyleDefinitions as S, type Table as T, type OoxmlNodeId as U, type OoxmlGenericElementNode as V, type TreeDocOp as W, type OoxmlPackageLimits as X, type OoxmlPackageRejection as Y, type RevisionBatchEntry as Z, type RevisionBatchResult as _, type ReviewItem as a, type CommentPosition as a$, type OoxmlProperty as a0, type OoxmlElement as a1, type OoxmlContentControlNode as a2, type OoxmlContentControlContentNode as a3, type DrawingProjection as a4, type TreeOpRejection as a5, type AutomationTableMutation as a6, type SourceCrop as a7, type DrawingKind as a8, type ImageWrapTarget as a9, type OoxmlSeparatorNode as aA, type DrawingTreeDocOp as aB, type ImpactClass as aC, type TreeDocColorValue as aD, IMAGE_WRAP_TARGETS as aE, TEXT_FORM_FORMATS as aF, type TableBorderStyle as aG, type DrawingAccessibility as aH, type DrawingImageEffects as aI, type DrawingTransform as aJ, type VectorShapeProjection as aK, type OoxmlDrawingNode as aL, type OoxmlInvariantResult as aM, type
|
|
4060
|
+
export { type RevisionBatchSkipReason as $, type IndentFormatting as A, type Block as B, type CommentRecord as C, type DocxDocument as D, type ExecResult as E, type ParagraphFlags as F, type ParagraphTabStop as G, type HeaderFooterSet as H, type InsertableContentControlType as I, type RevisionType as J, type Section as K, type SectionProperties as L, type StyleDefinition as M, type Theme as N, type OoxmlPart as O, type Paragraph as P, type ThemeColorScheme as Q, type ReviewModelInput as R, type StyleDefinitions as S, type Table as T, type OoxmlNodeId as U, type OoxmlGenericElementNode as V, type TreeDocOp as W, type OoxmlPackageLimits as X, type OoxmlPackageRejection as Y, type RevisionBatchEntry as Z, type RevisionBatchResult as _, type ReviewItem as a, type CommentPosition as a$, type OoxmlProperty as a0, type OoxmlElement as a1, type OoxmlContentControlNode as a2, type OoxmlContentControlContentNode as a3, type DrawingProjection as a4, type TreeOpRejection as a5, type AutomationTableMutation as a6, type SourceCrop as a7, type DrawingKind as a8, type ImageWrapTarget as a9, type OoxmlSeparatorNode as aA, type DrawingTreeDocOp as aB, type ImpactClass as aC, type TreeDocColorValue as aD, IMAGE_WRAP_TARGETS as aE, TEXT_FORM_FORMATS as aF, type TableBorderStyle as aG, type DrawingAccessibility as aH, type DrawingImageEffects as aI, type DrawingTransform as aJ, type VectorShapeProjection as aK, type OoxmlDrawingNode as aL, type OoxmlInvariantResult as aM, type OoxmlFldCharNode as aN, type OoxmlFldSimpleNode as aO, type OoxmlInstrTextNode as aP, type OoxmlInvariantIssue as aQ, type TreeOpResult as aR, type RelationshipRecord as aS, type OoxmlHardBreakNode as aT, type OoxmlAttribute as aU, type CommentThreadState as aV, ACCEPTED_PARAGRAPH_PROPERTIES as aW, ACCEPTED_RUN_PROPERTIES as aX, CONTENT_CONTROL_ID_MAX as aY, CONTENT_CONTROL_PROPERTY_ORDER as aZ, type CommentAnchor as a_, type DrawingPositionInput as aa, type DrawingLocks as ab, type ParagraphFormatCommand as ac, type Watermark as ad, type Rect as ae, type SelectionPin as af, type Unsubscribe as ag, type DocxDocumentJSON as ah, type DrawingHorizontalReferenceFrame as ai, type DrawingVerticalReferenceFrame as aj, type FontDefinition as ak, type NumberingRef as al, type PageMargins as am, type ParagraphDisagreements as an, type Point as ao, type Run as ap, type TableCell as aq, type TableRow as ar, type RevisionAttributionInput as as, type OoxmlParagraphNode as at, type OoxmlNoteNode as au, type OoxmlContinuationSeparatorNode as av, type OoxmlEndnotesNode as aw, type OoxmlFootnotesNode as ax, type OoxmlNoteRefNode as ay, type OoxmlNoteReferenceNode as az, type ReviewRevisionItem as b, type OoxmlReadRejection as b$, type CommitTextFormFieldOp as b0, type ContentControlCheckbox as b1, type ContentControlCheckboxState as b2, type ContentControlDataBinding as b3, type ContentControlDateFormat as b4, type ContentControlEntry as b5, type ContentControlKind as b6, type ContentControlLevel as b7, type ContentControlListItem as b8, type ContentControlLock as b9, type OoxmlContentControlCalendarNode as bA, type OoxmlContentControlCheckboxNode as bB, type OoxmlContentControlCheckedNode as bC, type OoxmlContentControlCheckedStateNode as bD, type OoxmlContentControlComboBoxNode as bE, type OoxmlContentControlDataBindingNode as bF, type OoxmlContentControlDateFormatNode as bG, type OoxmlContentControlDateNode as bH, type OoxmlContentControlDropDownListNode as bI, type OoxmlContentControlEndPropertiesNode as bJ, type OoxmlContentControlLidNode as bK, type OoxmlContentControlListItemNode as bL, type OoxmlContentControlPropertiesNode as bM, type OoxmlContentControlStoreMappedDataAsNode as bN, type OoxmlContentControlTextNode as bO, type OoxmlContentControlUncheckedStateNode as bP, type OoxmlDocumentNode as bQ, type OoxmlExternalTarget as bR, type OoxmlGenericExtensionAttribute as bS, type OoxmlHyperlinkNode as bT, type OoxmlInvariantIssueCode as bU, type OoxmlKnownNodeAttribute as bV, type OoxmlNamespaceBinding as bW, type OoxmlNodeIdentityRules as bX, type OoxmlPackageResult as bY, type OoxmlParagraphPropertiesNode as bZ, type OoxmlPartMetadata as b_, type ContentControlProperties as ba, type ContentTypeError as bb, type ContentTypeIndex as bc, type ContentTypeRecords as bd, DEFAULT_OOXML_PACKAGE_LIMITS as be, DEFAULT_ZIP_LIMITS as bf, type DefaultRecord as bg, type DeleteTextOp as bh, HYPERLINK_RELATIONSHIP_TYPE as bi, type HyperlinkKind as bj, type HyperlinkTarget as bk, IMAGE_RELATIONSHIP_TYPE as bl, type ImageRelationshipResolution as bm, type IndexResult as bn, type InsertBuildingBlockOp as bo, type InsertTextOp as bp, type LegacyCheckboxFieldRange as bq, MAX_CONTENT_CONTROLS_PER_PART as br, MAX_CONTENT_CONTROL_NESTING as bs, type NameRejection as bt, type NameResult as bu, OFFICE_RELATIONSHIP_NAMESPACE_URI as bv, OOXML_NODE_IDENTITY_RULES as bw, type OoxmlBodyNode as bx, type OoxmlBookmarkEndNode as by, type OoxmlBookmarkStartNode as bz, type ReviewCommentItem as c, isContentControlWrapper as c$, type OoxmlReadResult as c0, type OoxmlRunNode as c1, type OoxmlRunPropertiesNode as c2, type OoxmlTabNode as c3, type OoxmlTextElementNode as c4, type OoxmlTextNode as c5, type OoxmlWmlValAttribute as c6, type OoxmlXmlSpaceAttribute as c7, type OverrideRecord as c8, type RelationshipError as c9, allocateContentControlId as cA, asciiFold as cB, buildContentTypeIndex as cC, buildRelationshipSet as cD, childElements as cE, commentAnchorsOfStory as cF, commentsOfPart as cG, contentControlContentChildren as cH, contentControlContentNodeOf as cI, contentControlEndPropertiesNodeOf as cJ, contentControlLevelOf as cK, contentControlPropertiesNodeOf as cL, contentControlPropertiesOf as cM, contentControlTextOf as cN, contentControlsIn as cO, detectDuplicateNames as cP, extensionKey as cQ, findContentControl as cR, findElement as cS, firstReviewRange as cT, flattenContentControls as cU, hasAnyComment as cV, hyperlinkAnchorOf as cW, hyperlinkRelationshipIdOf as cX, hyperlinkTargetOf as cY, isContentControlContentNode as cZ, isContentControlNode as c_, type RelationshipSetResult as ca, type RelationshipTargetResolver as cb, type ResolveResult as cc, type ResolvedRelationship as cd, type SetLegacyCheckboxOp as ce, type SetLegacyDropdownOp as cf, type SetTextFormFieldDefaultOp as cg, TABLE_BORDER_STYLES as ch, type TabStopWrite as ci, type TargetMode as cj, type TextFormFieldOptions as ck, type TextFormFieldRange as cl, type TextFormFieldType as cm, type TreeDocOpKind as cn, type TreeOpEffect as co, W15_NAMESPACE_URI as cp, WML_NAMESPACE_URI as cq, XMLNS_NAMESPACE_URI as cr, XML_NAMESPACE_URI as cs, type XmlLimits as ct, type XmlNode as cu, type XmlRejection as cv, type XmlResult as cw, type ZipLimits as cx, type ZipReadResult as cy, type ZipRejection as cz, type ReviewCustomItem as d, isContentRevisionKind as d0, isHyperlinkNode as d1, isRangeMarkerKind as d2, isValidMime as d3, legacyCheckboxFieldsOf as d4, lockForbidsEdit as d5, lockForbidsRemoval as d6, normalizePartName as d7, orderedContentControlProperties as d8, parseContentControlId as d9, reviewItemsAt as dA, reviewThreadRootOf as dB, partNameKey as da, planRevisionBatch as db, projectDrawing as dc, readOnOffChild as dd, readOoxmlPackage as de, readOoxmlPart as df, readXml as dg, readZip as dh, resolveContentControlLock as di, resolveContentType as dj, resolveImageRelationship as dk, resolveInternalTarget as dl, resolveRelationship as dm, reviewItemKey as dn, reviewItemRanges as dp, textContent as dq, textFormFieldsOf as dr, threadStateOfPart as ds, validateExternalTarget as dt, withPart as du, writeOoxmlPackage as dv, writeZip as dw, type VectorShapeComponent as dx, activeReviewItem as dy, reviewItemPositionRank as dz, type ReviewPosition as e, type ReviewRange as f, type ReviewRevisionKind as g, type RevisionAddress as h, type OoxmlNode as i, type OoxmlPackage as j, type ContentControlType as k, type DocTarget as l, type RunFormatting as m, type Extent as n, type ContainerRef as o, type ContentControlFilter as p, type DocRange as q, type Revision as r, type DocComment as s, type ColorValue as t, type ContentControl as u, type DocAnchor as v, type DocAnchorRange as w, type DocLocation as x, type DocumentBody as y, type ExecErrorCode as z };
|