@docx-editor.dev/core 2.30.0 → 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/automation.cjs +1 -1
- package/dist/automation.d.ts +16 -25
- package/dist/automation.js +1 -1
- package/dist/binding.cjs +1 -1
- package/dist/binding.d.ts +15 -16
- package/dist/binding.js +1 -1
- package/dist/bookmark-names-DDuAra_V.d.ts +37 -0
- package/dist/{chrome-print-BM3Js-6X.d.ts → chrome-print-BWvaVEhD.d.ts} +318 -33
- package/dist/chunk-243W4WW2.cjs +2 -0
- package/dist/{chunk-RJCQGJR7.js → chunk-2E2RPEKX.js} +1 -1
- package/dist/chunk-4S24UOPG.js +30 -0
- package/dist/chunk-5JPIEN54.cjs +3 -0
- package/dist/{chunk-KJRTNY2Q.cjs → chunk-5SO5QDMV.cjs} +1 -1
- package/dist/{chunk-WF7JZ755.cjs → chunk-6IDOVU6L.cjs} +1 -1
- package/dist/chunk-DBOOTED4.cjs +30 -0
- package/dist/chunk-EOTAXOJY.cjs +5 -0
- package/dist/chunk-FDAKJ2SJ.cjs +30 -0
- package/dist/chunk-FNNOJNGY.js +3 -0
- package/dist/chunk-FT33HRZP.js +5 -0
- package/dist/{chunk-HYASLE2G.cjs → chunk-HC6YNKUI.cjs} +1 -1
- package/dist/chunk-HZ66UCIS.js +2 -0
- package/dist/{chunk-5RRAZMBU.cjs → chunk-IBRBNT37.cjs} +1 -1
- package/dist/chunk-IVIN7X43.js +30 -0
- package/dist/chunk-LZY6B6IV.js +4 -0
- package/dist/chunk-MOYYRVFV.cjs +2 -0
- package/dist/{chunk-YZGUBCHP.js → chunk-N6B3BXCL.js} +1 -1
- package/dist/chunk-Q5K2GGNG.js +2 -0
- package/dist/chunk-R2XINWVE.js +7 -0
- package/dist/chunk-SUEXVBPR.js +1 -0
- package/dist/chunk-T2QQHG5C.js +18 -0
- package/dist/{chunk-T32MGBJS.js → chunk-VWIJKH4A.js} +1 -1
- package/dist/chunk-WO4V6PNS.cjs +18 -0
- package/dist/chunk-XMJKFURD.cjs +4 -0
- package/dist/{chunk-FLBEJC6X.cjs → chunk-XSTGE3NI.cjs} +1 -1
- package/dist/chunk-YQWMI6J5.cjs +7 -0
- package/dist/{chunk-WPDD2Y32.js → chunk-ZCJS7D7S.js} +1 -1
- package/dist/collaboration/replication.cjs +1 -1
- package/dist/collaboration/replication.d.ts +4 -5
- package/dist/collaboration/replication.js +1 -1
- package/dist/collaboration.d.ts +3 -4
- package/dist/contracts/document.d.ts +3 -3
- package/dist/contracts/editor.d.ts +8 -9
- package/dist/contracts/interaction.d.ts +2 -2
- package/dist/contracts/modules.d.ts +12 -13
- package/dist/contracts/types.d.ts +2 -2
- package/dist/{custom-node-writes-0v0Kgw1T.d.ts → custom-node-writes-TeUvMP13.d.ts} +2 -2
- package/dist/{diagnostic-context-CcAO4q1s.d.ts → diagnostic-context-DJ0P1uZE.d.ts} +3 -2
- package/dist/{diagnostic-hints-2Bke6H_w.d.ts → diagnostic-hints-C9JlLz1L.d.ts} +1 -1
- package/dist/{document-protection-8eyMWIJ0.d.ts → document-protection-C8x3P2J6.d.ts} +1 -1
- package/dist/{editor-DaEJd2so.d.ts → editor-B2ShlO23.d.ts} +292 -50
- package/dist/{editor-scope-7o9xweiJ.d.ts → editor-scope-C7ke1KJG.d.ts} +57 -4
- package/dist/editor.cjs +1 -1
- package/dist/editor.css +5 -3
- package/dist/editor.d.ts +602 -31
- package/dist/editor.js +1 -1
- package/dist/export.cjs +2 -2
- package/dist/export.d.ts +13 -14
- package/dist/export.js +2 -2
- package/dist/{font-resolver-CL9BVKZo.d.ts → font-resolver-CWh40DYp.d.ts} +1 -1
- package/dist/{headless-document-view-DZQN8Bnx.d.ts → headless-document-view-qOpaCF82.d.ts} +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +22 -23
- package/dist/index.js +1 -1
- package/dist/{layout-shaping-cEnVrhWg.d.ts → layout-shaping-CWS3j0Xr.d.ts} +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.d.ts +87 -22
- package/dist/layout.js +1 -1
- package/dist/{note-properties-9FH8zAeG.d.ts → note-properties-QsKh24sM.d.ts} +1 -1
- package/dist/{omml-equation-DP2WpUbK.d.ts → omml-equation-BsLAa2lX.d.ts} +27 -9
- package/dist/output.cjs +1 -1
- package/dist/output.d.ts +20 -10
- package/dist/output.js +1 -1
- package/dist/{protocol-CZ1uUlPO.d.ts → protocol-COZJUKUY.d.ts} +94 -2
- package/dist/{review-paragraph-order-CqVelc5A.d.ts → review-paragraph-order-C_QbCKcH.d.ts} +1 -1
- package/dist/{semantic-cell-selection-Dr9yxFZt.d.ts → semantic-cell-selection-Cub9FDa8.d.ts} +2 -2
- package/dist/{semantic-interaction-Dc3pf3hr.d.ts → semantic-interaction-dApRIYpt.d.ts} +1 -1
- package/dist/{semantic-paint-Bz3FBAoH.d.ts → semantic-paint-DLzA8sjP.d.ts} +3 -3
- package/dist/{semantic-record-queries-Bx0pl6kL.d.ts → semantic-record-queries-3yp9o11g.d.ts} +1 -1
- package/dist/{semantic-records-CjcF26ZL.d.ts → semantic-records-B-akgRch.d.ts} +130 -87
- package/dist/store.cjs +1 -1
- package/dist/store.d.ts +48 -22
- package/dist/store.js +1 -1
- package/dist/{tree-package-store-DKhdEVym.d.ts → tree-package-store-B8l8DX3Z.d.ts} +675 -645
- package/dist/{tree-session-contract-CwnTEVLF.d.ts → tree-session-contract-DeLRqohz.d.ts} +26 -13
- package/dist/{types-barrel-CA0xB8kH.d.ts → types-barrel-CkF2JbU4.d.ts} +1146 -745
- package/package.json +2 -2
- package/dist/chunk-2PV5L5NJ.js +0 -5
- package/dist/chunk-5OTS2EJ7.js +0 -7
- package/dist/chunk-5P4223J4.cjs +0 -27
- package/dist/chunk-5SPITS5F.js +0 -18
- package/dist/chunk-7ATNKARV.js +0 -2
- package/dist/chunk-BGCUTKWE.cjs +0 -5
- package/dist/chunk-EBCXSH2W.js +0 -3
- package/dist/chunk-ERECKTIR.cjs +0 -2
- package/dist/chunk-JC47NRJC.cjs +0 -3
- package/dist/chunk-NKPUH3QJ.js +0 -1
- package/dist/chunk-PF5NJWS3.js +0 -2
- package/dist/chunk-PWTRJSES.cjs +0 -18
- package/dist/chunk-QFKGI242.cjs +0 -30
- package/dist/chunk-RPPV4S6T.cjs +0 -4
- package/dist/chunk-UM26GH5B.js +0 -30
- package/dist/chunk-VRCZBFLH.js +0 -27
- package/dist/chunk-WK5X2MMA.cjs +0 -7
- package/dist/chunk-YBMWBXST.cjs +0 -2
- package/dist/chunk-ZOS2PM4A.js +0 -4
- package/dist/image-resources-Bipz8toD.d.ts +0 -211
|
@@ -1,27 +1,54 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as HistoryGroupOutcome } from './editor-scope-C7ke1KJG.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* part.
|
|
4
|
+
* Why a zip was refused at the trust boundary.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* either, so `(part, id)` would merge two authors' distinct revisions. One logical revision is
|
|
10
|
-
* also deliberately many elements sharing an id, as a tracked row insertion is, which no
|
|
11
|
-
* uniqueness rule could express.
|
|
6
|
+
* `too-large` and `too-many-entries` are the zip-bomb guards; `bad-name` catches path traversal —
|
|
7
|
+
* an entry with `..` or a leading `/` is rejected rather than normalized.
|
|
12
8
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
type ZipRejection = 'too-many-entries' | 'too-large' | 'bad-name' | 'inflate-error';
|
|
10
|
+
/** Archive caps: entry count, total decompressed bytes, and the decompression ratio. */
|
|
11
|
+
interface ZipLimits {
|
|
12
|
+
readonly maxEntries: number;
|
|
13
|
+
/** Max total UNCOMPRESSED bytes across the archive. */
|
|
14
|
+
readonly maxTotalBytes: number;
|
|
15
|
+
/**
|
|
16
|
+
* Max ratio of the archive's total declared uncompressed bytes to the archive's own byte
|
|
17
|
+
* length (zip-bomb guard). Applies once that total exceeds 8 MiB, so a small archive is
|
|
18
|
+
* never refused for compressing well.
|
|
19
|
+
*/
|
|
20
|
+
readonly maxRatio?: number;
|
|
24
21
|
}
|
|
22
|
+
/** The archive caps in force when a host configures none. Conservative and finite. */
|
|
23
|
+
declare const DEFAULT_ZIP_LIMITS: ZipLimits;
|
|
24
|
+
/** The read entries, or the typed refusal. Never throws — the bytes are untrusted. */
|
|
25
|
+
type ZipReadResult = {
|
|
26
|
+
readonly ok: true;
|
|
27
|
+
readonly entries: ReadonlyMap<string, Uint8Array>;
|
|
28
|
+
} | {
|
|
29
|
+
readonly ok: false;
|
|
30
|
+
readonly reason: ZipRejection;
|
|
31
|
+
readonly detail?: string;
|
|
32
|
+
readonly limit?: 'zip.maxTotalBytes' | 'zip.maxRatio';
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Inflate a ZIP archive with bounds + OPC name normalization. Entry name, count, archive
|
|
36
|
+
* ratio, and total-uncompressed-size limits are enforced BEFORE each entry is decompressed
|
|
37
|
+
* (via fflate's pre-inflation filter), so a zip bomb or a traversal name is rejected without
|
|
38
|
+
* ever being inflated. Keys are canonical part names.
|
|
39
|
+
*
|
|
40
|
+
* The budgets count each entry's DECLARED sizes, and the declared size is also a hard cap on
|
|
41
|
+
* what the entry may produce: fflate inflates into a buffer of exactly `originalSize` bytes
|
|
42
|
+
* and never grows it, so an entry whose stream holds more than it declares is truncated (or
|
|
43
|
+
* refused as `inflate-error`), never expanded past its budget. A stored entry is copied at
|
|
44
|
+
* its compressed size, so the larger of its two declared sizes is what counts.
|
|
45
|
+
*/
|
|
46
|
+
declare function readZip(bytes: Uint8Array, limits?: ZipLimits): ZipReadResult;
|
|
47
|
+
/** Deflate a set of canonical-part-name -> bytes into a ZIP archive. Every part name
|
|
48
|
+
* is re-validated through the OPC normalization profile before writing, so a
|
|
49
|
+
* traversal/encoded/normalized-alias name from an untrusted serialized model can
|
|
50
|
+
* never be smuggled into a ZIP entry (write-side path-traversal guard). */
|
|
51
|
+
declare function writeZip(entries: ReadonlyMap<string, Uint8Array>): Uint8Array;
|
|
25
52
|
|
|
26
53
|
/**
|
|
27
54
|
* One parsed XML node, preserving significant order, whitespace and raw lexical values.
|
|
@@ -83,108 +110,331 @@ declare function textContent(node: Extract<XmlNode, {
|
|
|
83
110
|
type: 'element';
|
|
84
111
|
}>): string;
|
|
85
112
|
|
|
86
|
-
/** The WordprocessingML main namespace — the `w:` prefix in every `word/document.xml`. */
|
|
87
|
-
declare const WML_NAMESPACE_URI = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
88
|
-
/** The reserved `xml:` namespace, which carries `xml:space`. */
|
|
89
|
-
declare const XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
|
|
90
|
-
/** The reserved `xmlns:` namespace that namespace declarations themselves live in. */
|
|
91
|
-
declare const XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
|
|
92
|
-
/** The `w14` wordml-2010 extension namespace — `w14:paraId`/`w14:textId` live here. */
|
|
93
|
-
declare const W14_NAMESPACE_URI = "http://schemas.microsoft.com/office/word/2010/wordml";
|
|
94
|
-
declare const DRAWINGML_MAIN_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/main";
|
|
95
|
-
declare const WP_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
|
|
96
|
-
declare const PIC_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/picture";
|
|
97
|
-
/** The four content-position revision wrappers, which nest and carry runs. */
|
|
98
|
-
declare function isContentRevisionKind(kind: OoxmlNode['kind']): kind is 'revisionInsert' | 'revisionDelete' | 'revisionMoveFrom' | 'revisionMoveTo';
|
|
99
|
-
/** Move-range and comment-range boundary markers, which are empty and sit between runs. */
|
|
100
|
-
declare function isRangeMarkerKind(kind: OoxmlNode['kind']): kind is 'moveFromRangeStart' | 'moveFromRangeEnd' | 'moveToRangeStart' | 'moveToRangeEnd' | 'commentRangeStart' | 'commentRangeEnd';
|
|
101
113
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
114
|
+
* Why a part or relationship name was refused.
|
|
115
|
+
*
|
|
116
|
+
* Path traversal is the reason this exists: a name with `..` or a leading `/` is refused rather
|
|
117
|
+
* than normalized, because normalizing is how a crafted package reaches outside itself.
|
|
105
118
|
*/
|
|
106
|
-
|
|
119
|
+
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';
|
|
120
|
+
/** A validated OPC name, or the typed reason it was refused. */
|
|
121
|
+
type NameResult = {
|
|
122
|
+
readonly ok: true;
|
|
123
|
+
readonly partName: string;
|
|
124
|
+
} | {
|
|
125
|
+
readonly ok: false;
|
|
126
|
+
readonly reason: NameRejection;
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Normalize a ZIP entry name or OPC part name into a canonical part name
|
|
130
|
+
* (`/word/document.xml`). Accepts leading-slash and no-leading-slash inputs;
|
|
131
|
+
* rejects traversal, dot segments, and the attack surface. Duplicate detection
|
|
132
|
+
* folds ASCII case (OPC part-name equivalence).
|
|
133
|
+
*/
|
|
134
|
+
declare function normalizePartName(raw: string): NameResult;
|
|
135
|
+
/**
|
|
136
|
+
* ASCII-only lowercase fold. OPC part-name/extension equivalence is US-ASCII
|
|
137
|
+
* case-insensitive; a locale `toLowerCase()` mis-folds e.g. Turkish `I`/`İ` and
|
|
138
|
+
* could let two "equivalent" part names evade duplicate detection.
|
|
139
|
+
*/
|
|
140
|
+
declare function asciiFold(s: string): string;
|
|
141
|
+
/** Case-folded key for OPC part-name equivalence / duplicate detection. */
|
|
142
|
+
declare function partNameKey(partName: string): string;
|
|
143
|
+
/**
|
|
144
|
+
* Detect archive entries that collide after normalization (before inflation).
|
|
145
|
+
* Returns the case-folded keys that more than one raw name maps to.
|
|
146
|
+
*/
|
|
147
|
+
declare function detectDuplicateNames(rawNames: readonly string[]): {
|
|
148
|
+
readonly duplicates: readonly string[];
|
|
149
|
+
readonly rejected: readonly {
|
|
150
|
+
raw: string;
|
|
151
|
+
reason: NameRejection;
|
|
152
|
+
}[];
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Resolve an internal relationship target against its owner part, without
|
|
156
|
+
* escaping the package root. `ownerPartName` is a canonical part name; the base
|
|
157
|
+
* is its containing folder. A leading "/" target is package-absolute. `.`/`..`
|
|
158
|
+
* segments resolve on a stack; popping above root is `traversal-escape`.
|
|
159
|
+
*/
|
|
160
|
+
declare function resolveInternalTarget(ownerPartName: string, rawTarget: string): NameResult;
|
|
161
|
+
/**
|
|
162
|
+
* Validate an external-mode relationship target. It MUST be an absolute URI, is
|
|
163
|
+
* retained verbatim by the caller, and is NEVER owner-resolved or fetched here.
|
|
164
|
+
* Unsafe schemes (javascript/vbscript/data/file) are rejected for runtime sinks;
|
|
165
|
+
* the raw lexical form is still preserved separately by the authored record.
|
|
166
|
+
*/
|
|
167
|
+
declare function validateExternalTarget(raw: string): NameResult;
|
|
107
168
|
|
|
169
|
+
/** OOXML image relationship type for embedded or linked media parts. */
|
|
170
|
+
declare const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
108
171
|
/**
|
|
109
|
-
*
|
|
172
|
+
* Whether a relationship points inside the package or out of it.
|
|
110
173
|
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
174
|
+
* The security-relevant distinction: an `External` target is retained VERBATIM and never
|
|
175
|
+
* owner-resolved or fetched, because auto-loading a file-supplied remote target is a zero-click
|
|
176
|
+
* external fetch.
|
|
114
177
|
*/
|
|
115
|
-
type
|
|
178
|
+
type TargetMode = 'Internal' | 'External';
|
|
116
179
|
/**
|
|
117
|
-
* One
|
|
118
|
-
*
|
|
119
|
-
* Preserved rather than normalized away: a document that binds `w14` at the root and a document
|
|
120
|
-
* that binds it on a paragraph are different bytes, and re-emitting the wrong one is a fidelity
|
|
121
|
-
* loss even though the semantics match.
|
|
180
|
+
* One authored relationship, with nothing materialized away: owner part, id, type, raw target
|
|
181
|
+
* lexical form, mode, and position.
|
|
122
182
|
*/
|
|
123
|
-
interface
|
|
124
|
-
readonly
|
|
125
|
-
readonly
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
readonly
|
|
129
|
-
readonly
|
|
130
|
-
readonly prefix?: string;
|
|
131
|
-
readonly value: string;
|
|
132
|
-
}
|
|
133
|
-
/** `xml:space`, which decides whether a run's leading and trailing whitespace survives. */
|
|
134
|
-
interface OoxmlXmlSpaceAttribute extends OoxmlAttributeBase {
|
|
135
|
-
readonly kind: 'xmlSpace';
|
|
136
|
-
readonly namespaceUri: typeof XML_NAMESPACE_URI;
|
|
137
|
-
readonly localName: 'space';
|
|
138
|
-
readonly prefix: 'xml';
|
|
139
|
-
readonly value: 'default' | 'preserve';
|
|
140
|
-
}
|
|
141
|
-
/** `w:val` — the attribute nearly every WordprocessingML property carries its value in. */
|
|
142
|
-
interface OoxmlWmlValAttribute extends OoxmlAttributeBase {
|
|
143
|
-
readonly kind: 'wmlVal';
|
|
144
|
-
readonly namespaceUri: typeof WML_NAMESPACE_URI;
|
|
145
|
-
readonly localName: 'val';
|
|
183
|
+
interface RelationshipRecord {
|
|
184
|
+
readonly ownerPart: string;
|
|
185
|
+
readonly id: string;
|
|
186
|
+
readonly type: string;
|
|
187
|
+
readonly rawTarget: string;
|
|
188
|
+
readonly targetMode: TargetMode;
|
|
189
|
+
readonly order: number;
|
|
146
190
|
}
|
|
191
|
+
/** Why a relationship set is invalid. Duplicate ids within one owner fail closed. */
|
|
192
|
+
type RelationshipError = {
|
|
193
|
+
readonly code: 'duplicate-id';
|
|
194
|
+
readonly ownerPart: string;
|
|
195
|
+
readonly id: string;
|
|
196
|
+
};
|
|
197
|
+
/** The validated relationship set, or the conflict that rejected it. */
|
|
198
|
+
type RelationshipSetResult = {
|
|
199
|
+
readonly ok: true;
|
|
200
|
+
readonly byOwner: ReadonlyMap<string, readonly RelationshipRecord[]>;
|
|
201
|
+
} | {
|
|
202
|
+
readonly ok: false;
|
|
203
|
+
readonly error: RelationshipError;
|
|
204
|
+
};
|
|
205
|
+
/** Group relationships by owner in authored order; reject duplicate ids per owner. */
|
|
206
|
+
declare function buildRelationshipSet(records: readonly RelationshipRecord[]): RelationshipSetResult;
|
|
147
207
|
/**
|
|
148
|
-
*
|
|
208
|
+
* A relationship resolved to a part, or the reason it could not be.
|
|
149
209
|
*
|
|
150
|
-
*
|
|
151
|
-
* exactly rather than dropped, so a save re-emits what the file said.
|
|
210
|
+
* External targets resolve to a refusal by design: they are never followed from a file.
|
|
152
211
|
*/
|
|
153
|
-
|
|
154
|
-
readonly
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
212
|
+
type ResolvedRelationship = {
|
|
213
|
+
readonly mode: 'Internal';
|
|
214
|
+
readonly target: NameResult;
|
|
215
|
+
readonly raw: string;
|
|
216
|
+
} | {
|
|
217
|
+
readonly mode: 'External';
|
|
218
|
+
readonly sinkSafe: NameResult;
|
|
219
|
+
readonly raw: string;
|
|
220
|
+
};
|
|
158
221
|
/**
|
|
159
|
-
*
|
|
222
|
+
* Resolve a relationship to a runtime projection while the raw target stays
|
|
223
|
+
* authored. Internal -> owner-relative part name; External -> sink-safe
|
|
224
|
+
* validation only (never owner-resolved, never fetched). `raw` is always the
|
|
225
|
+
* verbatim authored target.
|
|
226
|
+
*/
|
|
227
|
+
declare function resolveRelationship(rec: RelationshipRecord): ResolvedRelationship;
|
|
228
|
+
/**
|
|
229
|
+
* An image relationship resolved to package bytes, or why it was refused.
|
|
160
230
|
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
231
|
+
* External-mode image rels are refused rather than fetched — the no-zero-click-external-fetch
|
|
232
|
+
* rule applies to images exactly as it does to links.
|
|
163
233
|
*/
|
|
164
|
-
type
|
|
165
|
-
|
|
166
|
-
readonly
|
|
167
|
-
readonly
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
readonly
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
readonly
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
readonly
|
|
185
|
-
readonly
|
|
186
|
-
|
|
187
|
-
|
|
234
|
+
type ImageRelationshipResolution = {
|
|
235
|
+
readonly mode: 'internal';
|
|
236
|
+
readonly partName: string;
|
|
237
|
+
readonly raw: string;
|
|
238
|
+
} | {
|
|
239
|
+
readonly mode: 'external';
|
|
240
|
+
readonly sinkSafe: boolean;
|
|
241
|
+
readonly raw: string;
|
|
242
|
+
} | {
|
|
243
|
+
readonly mode: 'missing';
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* Resolve an image relationship id from an owner part. Internal targets resolve
|
|
247
|
+
* owner-relative; external targets are never fetched; a missing id is `missing`.
|
|
248
|
+
*/
|
|
249
|
+
declare function resolveImageRelationship(records: readonly RelationshipRecord[] | undefined, ownerPart: string, relationshipId: string): ImageRelationshipResolution;
|
|
250
|
+
|
|
251
|
+
/** One `<Default>`: a file extension mapped to a content type. */
|
|
252
|
+
interface DefaultRecord {
|
|
253
|
+
readonly extension: string;
|
|
254
|
+
readonly contentType: string;
|
|
255
|
+
readonly order: number;
|
|
256
|
+
}
|
|
257
|
+
/** One `<Override>`: a specific part name mapped to a content type. Beats any Default. */
|
|
258
|
+
interface OverrideRecord {
|
|
259
|
+
readonly partName: string;
|
|
260
|
+
readonly contentType: string;
|
|
261
|
+
readonly order: number;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* The authored `[Content_Types].xml` records, in significant order.
|
|
265
|
+
*
|
|
266
|
+
* Retained rather than collapsed into a lookup, because the file's lexical form and ordering are
|
|
267
|
+
* part of what a lossless save re-emits.
|
|
268
|
+
*/
|
|
269
|
+
interface ContentTypeRecords {
|
|
270
|
+
readonly defaults: readonly DefaultRecord[];
|
|
271
|
+
readonly overrides: readonly OverrideRecord[];
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Why content-type records could not be indexed.
|
|
275
|
+
*
|
|
276
|
+
* All fail CLOSED: conflicting Defaults on one extension, duplicate normalized Override names, or
|
|
277
|
+
* invalid MIME syntax are refused rather than resolved by picking one.
|
|
278
|
+
*/
|
|
279
|
+
type ContentTypeError = {
|
|
280
|
+
readonly code: 'invalid-mime';
|
|
281
|
+
readonly value: string;
|
|
282
|
+
} | {
|
|
283
|
+
readonly code: 'conflicting-default';
|
|
284
|
+
readonly extension: string;
|
|
285
|
+
} | {
|
|
286
|
+
readonly code: 'duplicate-override';
|
|
287
|
+
readonly partName: string;
|
|
288
|
+
} | {
|
|
289
|
+
readonly code: 'invalid-override-name';
|
|
290
|
+
readonly partName: string;
|
|
291
|
+
} | {
|
|
292
|
+
readonly code: 'too-many-records';
|
|
293
|
+
readonly limit: number;
|
|
294
|
+
};
|
|
295
|
+
/** Whether a string is syntactically a MIME type. Syntax only — no registry lookup. */
|
|
296
|
+
declare function isValidMime(value: string): boolean;
|
|
297
|
+
/** ASCII-case-insensitive extension key (leading dot removed; ASCII-only fold). */
|
|
298
|
+
declare function extensionKey(extension: string): string;
|
|
299
|
+
/** The resolved lookup: Override by case-folded part name, Default by case-insensitive extension. */
|
|
300
|
+
interface ContentTypeIndex {
|
|
301
|
+
/** ext key -> single MIME (identical duplicates collapsed). */
|
|
302
|
+
readonly defaults: ReadonlyMap<string, string>;
|
|
303
|
+
/** case-folded part name -> MIME. */
|
|
304
|
+
readonly overrides: ReadonlyMap<string, string>;
|
|
305
|
+
}
|
|
306
|
+
/** The built index, or the conflict that made it impossible. */
|
|
307
|
+
type IndexResult = {
|
|
308
|
+
readonly ok: true;
|
|
309
|
+
readonly index: ContentTypeIndex;
|
|
310
|
+
} | {
|
|
311
|
+
readonly ok: false;
|
|
312
|
+
readonly error: ContentTypeError;
|
|
313
|
+
};
|
|
314
|
+
/**
|
|
315
|
+
* Build a resolved content-type index, failing closed on conflict/duplicate/MIME
|
|
316
|
+
* errors. `maxRecords` bounds the combined record count (N/N+1 gate).
|
|
317
|
+
*/
|
|
318
|
+
declare function buildContentTypeIndex(records: ContentTypeRecords, maxRecords?: number): IndexResult;
|
|
319
|
+
/**
|
|
320
|
+
* A part's content type, or why it has none.
|
|
321
|
+
*
|
|
322
|
+
* An orphan record never determines a part's type — a Default with no matching part is preserved
|
|
323
|
+
* inertly rather than applied.
|
|
324
|
+
*/
|
|
325
|
+
type ResolveResult = {
|
|
326
|
+
readonly ok: true;
|
|
327
|
+
readonly contentType: string;
|
|
328
|
+
readonly source: 'override' | 'default';
|
|
329
|
+
} | {
|
|
330
|
+
readonly ok: false;
|
|
331
|
+
readonly reason: 'unknown';
|
|
332
|
+
};
|
|
333
|
+
/** Resolve a part's content type: Override wins over Default; else unknown. */
|
|
334
|
+
declare function resolveContentType(index: ContentTypeIndex, partName: string): ResolveResult;
|
|
335
|
+
|
|
336
|
+
/** The WordprocessingML main namespace — the `w:` prefix in every `word/document.xml`. */
|
|
337
|
+
declare const WML_NAMESPACE_URI = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
338
|
+
/** The reserved `xml:` namespace, which carries `xml:space`. */
|
|
339
|
+
declare const XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
|
|
340
|
+
/** The reserved `xmlns:` namespace that namespace declarations themselves live in. */
|
|
341
|
+
declare const XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
|
|
342
|
+
/** The `w14` wordml-2010 extension namespace — `w14:paraId`/`w14:textId` live here. */
|
|
343
|
+
declare const W14_NAMESPACE_URI = "http://schemas.microsoft.com/office/word/2010/wordml";
|
|
344
|
+
declare const DRAWINGML_MAIN_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/main";
|
|
345
|
+
declare const WP_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
|
|
346
|
+
declare const PIC_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/picture";
|
|
347
|
+
/** The four content-position revision wrappers, which nest and carry runs. */
|
|
348
|
+
declare function isContentRevisionKind(kind: OoxmlNode['kind']): kind is 'revisionInsert' | 'revisionDelete' | 'revisionMoveFrom' | 'revisionMoveTo';
|
|
349
|
+
/** Move-range and comment-range boundary markers, which are empty and sit between runs. */
|
|
350
|
+
declare function isRangeMarkerKind(kind: OoxmlNode['kind']): kind is 'moveFromRangeStart' | 'moveFromRangeEnd' | 'moveToRangeStart' | 'moveToRangeEnd' | 'commentRangeStart' | 'commentRangeEnd';
|
|
351
|
+
/**
|
|
352
|
+
* OOXML on/off toggle: on only when a same-namespace child is present and its `w:val`
|
|
353
|
+
* (same namespace as the child) does not explicitly disable. Foreign-namespace siblings
|
|
354
|
+
* with the same local name cannot turn the flag on.
|
|
355
|
+
*/
|
|
356
|
+
declare function readOnOffChild(parent: OoxmlNode, localName: string, namespaceUri?: string): boolean;
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* A node's stable identity within its part.
|
|
360
|
+
*
|
|
361
|
+
* Minted deterministically from the structural path at parse, then RETAINED through structural
|
|
362
|
+
* sharing — the same bytes always produce the same ids, and an edit elsewhere in the document
|
|
363
|
+
* does not renumber untouched nodes. Every tree op addresses nodes by these.
|
|
364
|
+
*/
|
|
365
|
+
type OoxmlNodeId = string;
|
|
366
|
+
/**
|
|
367
|
+
* One `xmlns:` declaration carried on a node.
|
|
368
|
+
*
|
|
369
|
+
* Preserved rather than normalized away: a document that binds `w14` at the root and a document
|
|
370
|
+
* that binds it on a paragraph are different bytes, and re-emitting the wrong one is a fidelity
|
|
371
|
+
* loss even though the semantics match.
|
|
372
|
+
*/
|
|
373
|
+
interface OoxmlNamespaceBinding {
|
|
374
|
+
readonly prefix: string;
|
|
375
|
+
readonly namespaceUri: string;
|
|
376
|
+
}
|
|
377
|
+
interface OoxmlAttributeBase {
|
|
378
|
+
readonly namespaceUri: string;
|
|
379
|
+
readonly localName: string;
|
|
380
|
+
readonly prefix?: string;
|
|
381
|
+
readonly value: string;
|
|
382
|
+
}
|
|
383
|
+
/** `xml:space`, which decides whether a run's leading and trailing whitespace survives. */
|
|
384
|
+
interface OoxmlXmlSpaceAttribute extends OoxmlAttributeBase {
|
|
385
|
+
readonly kind: 'xmlSpace';
|
|
386
|
+
readonly namespaceUri: typeof XML_NAMESPACE_URI;
|
|
387
|
+
readonly localName: 'space';
|
|
388
|
+
readonly prefix: 'xml';
|
|
389
|
+
readonly value: 'default' | 'preserve';
|
|
390
|
+
}
|
|
391
|
+
/** `w:val` — the attribute nearly every WordprocessingML property carries its value in. */
|
|
392
|
+
interface OoxmlWmlValAttribute extends OoxmlAttributeBase {
|
|
393
|
+
readonly kind: 'wmlVal';
|
|
394
|
+
readonly namespaceUri: typeof WML_NAMESPACE_URI;
|
|
395
|
+
readonly localName: 'val';
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Any attribute outside the typed vocabulary, carried verbatim.
|
|
399
|
+
*
|
|
400
|
+
* Where losslessness actually happens: an attribute this engine has no model for is preserved
|
|
401
|
+
* exactly rather than dropped, so a save re-emits what the file said.
|
|
402
|
+
*/
|
|
403
|
+
interface OoxmlGenericExtensionAttribute extends OoxmlAttributeBase {
|
|
404
|
+
readonly kind: 'genericExtension';
|
|
405
|
+
}
|
|
406
|
+
/** Any attribute on any node: the two typed ones, plus the verbatim catch-all. */
|
|
407
|
+
type OoxmlAttribute = OoxmlXmlSpaceAttribute | OoxmlWmlValAttribute | OoxmlGenericExtensionAttribute;
|
|
408
|
+
/**
|
|
409
|
+
* Attributes a TYPED node may carry.
|
|
410
|
+
*
|
|
411
|
+
* Excludes `w:val` on purpose: a node the engine models keeps its value in typed fields, and
|
|
412
|
+
* allowing a stray `w:val` alongside them would create two sources of truth for one property.
|
|
413
|
+
*/
|
|
414
|
+
type OoxmlKnownNodeAttribute = OoxmlXmlSpaceAttribute | OoxmlGenericExtensionAttribute;
|
|
415
|
+
interface OoxmlElementBase<Children extends readonly OoxmlNode[] = readonly OoxmlNode[], Attributes extends readonly OoxmlAttribute[] = readonly OoxmlAttribute[]> {
|
|
416
|
+
readonly id: OoxmlNodeId;
|
|
417
|
+
readonly namespaceUri: string;
|
|
418
|
+
readonly localName: string;
|
|
419
|
+
/** Authored prefix retained as non-authoritative fidelity evidence. */
|
|
420
|
+
readonly prefix?: string;
|
|
421
|
+
/** Namespace declarations authored directly on this element, in source order. */
|
|
422
|
+
readonly namespaceBindings: readonly OoxmlNamespaceBinding[];
|
|
423
|
+
readonly attributes: Attributes;
|
|
424
|
+
readonly children: Children;
|
|
425
|
+
}
|
|
426
|
+
/** `w:document` — the root of a main document part. */
|
|
427
|
+
interface OoxmlDocumentNode extends OoxmlElementBase<readonly (OoxmlBodyNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
|
|
428
|
+
readonly kind: 'document';
|
|
429
|
+
readonly namespaceUri: typeof WML_NAMESPACE_URI;
|
|
430
|
+
readonly localName: 'document';
|
|
431
|
+
}
|
|
432
|
+
/** `w:body` — the main story's block content. */
|
|
433
|
+
interface OoxmlBodyNode extends OoxmlElementBase<readonly (OoxmlParagraphNode | OoxmlTableNode | OoxmlContentControlNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
|
|
434
|
+
readonly kind: 'body';
|
|
435
|
+
readonly namespaceUri: typeof WML_NAMESPACE_URI;
|
|
436
|
+
readonly localName: 'body';
|
|
437
|
+
}
|
|
188
438
|
interface OoxmlTableNode extends OoxmlElementBase<readonly (OoxmlTablePropertiesNode | OoxmlTableGridNode | OoxmlTableRowNode | OoxmlContentControlNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
|
|
189
439
|
readonly kind: 'table';
|
|
190
440
|
readonly namespaceUri: typeof WML_NAMESPACE_URI;
|
|
@@ -846,369 +1096,70 @@ type OoxmlReadRejection = XmlRejection | 'missing-root' | 'multiple-roots' | 'in
|
|
|
846
1096
|
/** A parsed part, or a typed refusal. Never throws — the input is untrusted by definition. */
|
|
847
1097
|
type OoxmlReadResult = {
|
|
848
1098
|
readonly ok: true;
|
|
849
|
-
readonly part: OoxmlPart;
|
|
850
|
-
} | {
|
|
851
|
-
readonly ok: false;
|
|
852
|
-
readonly reason: OoxmlReadRejection;
|
|
853
|
-
};
|
|
854
|
-
/**
|
|
855
|
-
* The node-identity contract, written down as a type so it is checkable rather than merely
|
|
856
|
-
* documented.
|
|
857
|
-
*
|
|
858
|
-
* Ids are deterministic from a normalized parse, retained through structural sharing, explicit on
|
|
859
|
-
* replacement, and unique within a part. Everything that addresses nodes — ops, the caret, the
|
|
860
|
-
* paraId bimap — depends on all four holding.
|
|
861
|
-
*/
|
|
862
|
-
interface OoxmlNodeIdentityRules {
|
|
863
|
-
readonly initial: 'deterministic-structural-path-after-normalized-parse';
|
|
864
|
-
readonly unchanged: 'retain-id-through-structural-sharing';
|
|
865
|
-
readonly replacement: 'explicitly-retain-or-allocate';
|
|
866
|
-
readonly uniqueness: 'unique-within-part';
|
|
867
|
-
}
|
|
868
|
-
/**
|
|
869
|
-
* Identity policy for future immutable tree edits. This defines the boundary
|
|
870
|
-
* without implementing task 2.4 edit primitives.
|
|
871
|
-
*/
|
|
872
|
-
declare const OOXML_NODE_IDENTITY_RULES: OoxmlNodeIdentityRules;
|
|
873
|
-
/** What a tree invariant walk found wrong. Each names a rule the canonical tree must satisfy. */
|
|
874
|
-
type OoxmlInvariantIssueCode = 'invalid-id' | 'duplicate-id' | 'invalid-name' | 'invalid-namespace' | 'invalid-qname' | 'duplicate-expanded-attribute' | 'invalid-xml-value' | 'known-node-invariant';
|
|
875
|
-
/** One invariant violation, located by structural path and node id. */
|
|
876
|
-
interface OoxmlInvariantIssue {
|
|
877
|
-
readonly code: OoxmlInvariantIssueCode;
|
|
878
|
-
readonly path: string;
|
|
879
|
-
readonly nodeId?: string;
|
|
880
|
-
}
|
|
881
|
-
/** Whether a tree satisfies its invariants, listing every violation when it does not. */
|
|
882
|
-
type OoxmlInvariantResult = {
|
|
883
|
-
readonly ok: true;
|
|
884
|
-
} | {
|
|
885
|
-
readonly ok: false;
|
|
886
|
-
readonly issues: readonly OoxmlInvariantIssue[];
|
|
887
|
-
};
|
|
888
|
-
/**
|
|
889
|
-
* Read one XML part into the additive typed/generic foundation. Existing package
|
|
890
|
-
* parsing and DocumentStore models intentionally remain unchanged until their
|
|
891
|
-
* later migration tasks; this tree is not yet the repository's sole runtime authority.
|
|
892
|
-
* Structural-path IDs are deterministic across normalized reopen. Preserving an
|
|
893
|
-
* identity through moves and edits is deferred to PackageModel/DocumentStore integration.
|
|
894
|
-
*/
|
|
895
|
-
declare function readOoxmlPart(xml: string, metadata: OoxmlPartMetadata, limits?: XmlLimits): OoxmlReadResult;
|
|
896
|
-
|
|
897
|
-
type AutomationTableMutation = {
|
|
898
|
-
readonly kind: 'insertRows';
|
|
899
|
-
readonly rowId: string;
|
|
900
|
-
readonly location: 'before' | 'after';
|
|
901
|
-
readonly count: number;
|
|
902
|
-
readonly values?: readonly (readonly string[])[];
|
|
903
|
-
} | {
|
|
904
|
-
readonly kind: 'values';
|
|
905
|
-
readonly values: readonly (readonly string[])[];
|
|
906
|
-
} | {
|
|
907
|
-
readonly kind: 'addRows' | 'addColumns';
|
|
908
|
-
readonly location: 'start' | 'end';
|
|
909
|
-
readonly count: number;
|
|
910
|
-
readonly values?: readonly (readonly string[])[];
|
|
911
|
-
} | {
|
|
912
|
-
readonly kind: 'deleteRows' | 'deleteColumns';
|
|
913
|
-
readonly index: number;
|
|
914
|
-
readonly count: number;
|
|
915
|
-
} | {
|
|
916
|
-
readonly kind: 'delete';
|
|
917
|
-
} | {
|
|
918
|
-
readonly kind: 'properties';
|
|
919
|
-
readonly styleId?: string;
|
|
920
|
-
readonly headerRowCount?: number;
|
|
921
|
-
} | {
|
|
922
|
-
readonly kind: 'cell';
|
|
923
|
-
readonly cellId: string;
|
|
924
|
-
readonly value?: string;
|
|
925
|
-
readonly columnWidth?: number;
|
|
926
|
-
readonly shadingColor?: string;
|
|
927
|
-
readonly verticalAlignment?: 'Top' | 'Center' | 'Bottom';
|
|
928
|
-
};
|
|
929
|
-
|
|
930
|
-
/** Select one declared entry of a legacy Word dropdown form field. */
|
|
931
|
-
interface SetLegacyDropdownOp {
|
|
932
|
-
readonly op: 'setLegacyDropdown';
|
|
933
|
-
readonly paragraphId: string;
|
|
934
|
-
readonly fieldNodeId: string;
|
|
935
|
-
readonly selectedIndex: number;
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
interface SetFieldCodeOp {
|
|
939
|
-
readonly op: 'setFieldCode';
|
|
940
|
-
readonly paragraphId: string;
|
|
941
|
-
readonly fieldNodeId: string;
|
|
942
|
-
readonly code: string;
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
type InsertTextOp = {
|
|
946
|
-
readonly op: 'insertText';
|
|
947
|
-
readonly paragraphId: string;
|
|
948
|
-
/** Legacy text form identity for protected filling; never an inline wrapper owner. */
|
|
949
|
-
readonly textFormFieldId?: string;
|
|
950
|
-
readonly offset: number;
|
|
951
|
-
readonly text: string;
|
|
952
|
-
/**
|
|
953
|
-
* Write this as a TRACKED insertion, attributed here.
|
|
954
|
-
*
|
|
955
|
-
* On the op rather than on the store, so suggesting stays a decision the surface makes
|
|
956
|
-
* per edit and the write vocabulary stays explicit — a global "everything is tracked
|
|
957
|
-
* now" flag is exactly what `DocEdits` refuses, because it makes the meaning of an op
|
|
958
|
-
* depend on state the op does not carry.
|
|
959
|
-
*/
|
|
960
|
-
readonly revision?: RevisionAttributionInput;
|
|
961
|
-
/**
|
|
962
|
-
* When set, the text belongs INSIDE this content control, whatever sits at the offset.
|
|
963
|
-
*
|
|
964
|
-
* A boundary offset is owned by the run that starts there, which at a control's trailing
|
|
965
|
-
* edge is the run after the control — so an offset alone cannot say "append to this field",
|
|
966
|
-
* the way it cannot say which run of a field result to format (see `targetRunIds`). A
|
|
967
|
-
* caller that names the control gets the text in the control; one that does not gets the
|
|
968
|
-
* plain offset rule, which is what a keystroke beside a field means.
|
|
969
|
-
*/
|
|
970
|
-
readonly inside?: string;
|
|
971
|
-
/**
|
|
972
|
-
* Which side of a run BOUNDARY the text joins. Default `'left'` — Word's typing rule:
|
|
973
|
-
* the next character takes the formatting of the character before the caret.
|
|
974
|
-
*
|
|
975
|
-
* `'right'` is for a caller that is not typing but placing text inside the run that
|
|
976
|
-
* STARTS at the offset — the hyperlink editor rewriting a link's display text, where
|
|
977
|
-
* landing left of the boundary would put the new text outside the link. Ignored when
|
|
978
|
-
* the offset falls strictly inside a run, which has no boundary to choose.
|
|
979
|
-
*/
|
|
980
|
-
readonly bias?: 'left' | 'right';
|
|
981
|
-
};
|
|
982
|
-
type DeleteTextOp = {
|
|
983
|
-
readonly op: 'deleteText';
|
|
984
|
-
readonly paragraphId: string;
|
|
985
|
-
/** Legacy text form identity for protected filling; never an inline wrapper owner. */
|
|
986
|
-
readonly textFormFieldId?: string;
|
|
987
|
-
readonly start: number;
|
|
988
|
-
readonly end: number;
|
|
989
|
-
/** Write this as a TRACKED deletion — the characters stay, wrapped in `w:del`. */
|
|
990
|
-
readonly revision?: RevisionAttributionInput;
|
|
991
|
-
};
|
|
992
|
-
|
|
993
|
-
/** Editable legacy text input types. Other authored types remain inert. */
|
|
994
|
-
type TextFormFieldType = 'regular' | 'number' | 'date';
|
|
995
|
-
/** Options stored in the legacy field definition. Zero means unlimited length. */
|
|
996
|
-
interface TextFormFieldOptions {
|
|
997
|
-
readonly type: TextFormFieldType;
|
|
998
|
-
readonly maxLength: number;
|
|
999
|
-
readonly format: string;
|
|
1000
|
-
readonly enabled: boolean;
|
|
1001
|
-
}
|
|
1002
|
-
/** Supported format choices for legacy text input fields. @public */
|
|
1003
|
-
declare const TEXT_FORM_FORMATS: {
|
|
1004
|
-
readonly regular: readonly ['', 'Uppercase', 'Lowercase', 'First capital', 'Title case'];
|
|
1005
|
-
readonly number: readonly ['', '0', '0.00', '#,##0', '#,##0.00', '0%', '0.00%'];
|
|
1006
|
-
readonly date: readonly ['', 'M/d/yyyy', 'MM/dd/yyyy', 'd/M/yyyy', 'dd/MM/yyyy', 'yyyy-MM-dd', 'd MMMM yyyy', 'MMMM d, yyyy'];
|
|
1007
|
-
};
|
|
1008
|
-
|
|
1009
|
-
/** A legacy text input in the shared paragraph offset space. */
|
|
1010
|
-
interface TextFormFieldRange {
|
|
1011
|
-
readonly fieldNodeId: string;
|
|
1012
|
-
readonly start: number;
|
|
1013
|
-
readonly end: number;
|
|
1014
|
-
readonly enabled: boolean;
|
|
1015
|
-
readonly defaultText: string;
|
|
1016
|
-
readonly type: string;
|
|
1017
|
-
readonly maxLength: number;
|
|
1018
|
-
readonly format: string;
|
|
1019
|
-
readonly chromeIds: readonly string[];
|
|
1020
|
-
}
|
|
1021
|
-
/** Uses the field parser and offset index; never introduces another inline walk. */
|
|
1022
|
-
declare function textFormFieldsOf(paragraph: OoxmlParagraphNode): readonly TextFormFieldRange[];
|
|
1023
|
-
/** Options edit for an existing legacy text form. */
|
|
1024
|
-
interface SetTextFormFieldDefaultOp {
|
|
1025
|
-
readonly op: 'setTextFormFieldDefault';
|
|
1026
|
-
/** Regional conventions for new date input; defaults to en-US. */
|
|
1027
|
-
readonly locale?: string;
|
|
1028
|
-
readonly paragraphId: string;
|
|
1029
|
-
readonly fieldNodeId: string;
|
|
1030
|
-
readonly text: string;
|
|
1031
|
-
readonly options?: TextFormFieldOptions;
|
|
1032
|
-
}
|
|
1033
|
-
/** Validate and format the existing result when a user finishes filling a field. */
|
|
1034
|
-
interface CommitTextFormFieldOp {
|
|
1035
|
-
readonly op: 'commitTextFormField';
|
|
1036
|
-
/** Regional conventions for new date input; defaults to en-US. */
|
|
1037
|
-
readonly locale?: string;
|
|
1038
|
-
readonly paragraphId: string;
|
|
1039
|
-
readonly fieldNodeId: string;
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
/** One FORMCHECKBOX in the shared paragraph offset space. */
|
|
1043
|
-
interface LegacyCheckboxFieldRange {
|
|
1044
|
-
/** The begin `w:fldChar` node: what the op addresses. */
|
|
1045
|
-
readonly fieldNodeId: string;
|
|
1046
|
-
readonly start: number;
|
|
1047
|
-
readonly end: number;
|
|
1048
|
-
readonly checked: boolean;
|
|
1049
|
-
/** `w:enabled` under `w:ffData`; a disabled field renders but refuses the toggle. */
|
|
1050
|
-
readonly enabled: boolean;
|
|
1051
|
-
}
|
|
1052
|
-
/** Flip a FORMCHECKBOX's state; the only write into `w:ffData` a checkbox permits. */
|
|
1053
|
-
interface SetLegacyCheckboxOp {
|
|
1054
|
-
readonly op: 'setLegacyCheckbox';
|
|
1055
|
-
readonly paragraphId: string;
|
|
1056
|
-
readonly fieldNodeId: string;
|
|
1057
|
-
readonly checked: boolean;
|
|
1058
|
-
}
|
|
1059
|
-
/** Every FORMCHECKBOX in a paragraph, in document order; uses the shared field parser. */
|
|
1060
|
-
declare function legacyCheckboxFieldsOf(paragraph: OoxmlParagraphNode): readonly LegacyCheckboxFieldRange[];
|
|
1061
|
-
|
|
1062
|
-
/** Replace a building block gallery control's content with one block's body. */
|
|
1063
|
-
interface InsertBuildingBlockOp {
|
|
1064
|
-
readonly op: 'insertBuildingBlock';
|
|
1065
|
-
readonly controlId: string;
|
|
1066
|
-
/** `w:docPartPr/w:name` of the picked block, for the journal and the host. */
|
|
1067
|
-
readonly name: string;
|
|
1068
|
-
/**
|
|
1069
|
-
* Self-contained `w:docPartBody` children, cloned with fresh ids at apply.
|
|
1070
|
-
* Resource, style, field, bookmark, note and revision references return `unsupported`.
|
|
1071
|
-
*/
|
|
1072
|
-
readonly blocks: readonly OoxmlNode[];
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
/**
|
|
1076
|
-
* Why a part or relationship name was refused.
|
|
1077
|
-
*
|
|
1078
|
-
* Path traversal is the reason this exists: a name with `..` or a leading `/` is refused rather
|
|
1079
|
-
* than normalized, because normalizing is how a crafted package reaches outside itself.
|
|
1080
|
-
*/
|
|
1081
|
-
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';
|
|
1082
|
-
/** A validated OPC name, or the typed reason it was refused. */
|
|
1083
|
-
type NameResult = {
|
|
1084
|
-
readonly ok: true;
|
|
1085
|
-
readonly partName: string;
|
|
1086
|
-
} | {
|
|
1087
|
-
readonly ok: false;
|
|
1088
|
-
readonly reason: NameRejection;
|
|
1089
|
-
};
|
|
1090
|
-
/**
|
|
1091
|
-
* Normalize a ZIP entry name or OPC part name into a canonical part name
|
|
1092
|
-
* (`/word/document.xml`). Accepts leading-slash and no-leading-slash inputs;
|
|
1093
|
-
* rejects traversal, dot segments, and the attack surface. Duplicate detection
|
|
1094
|
-
* folds ASCII case (OPC part-name equivalence).
|
|
1095
|
-
*/
|
|
1096
|
-
declare function normalizePartName(raw: string): NameResult;
|
|
1097
|
-
/**
|
|
1098
|
-
* ASCII-only lowercase fold. OPC part-name/extension equivalence is US-ASCII
|
|
1099
|
-
* case-insensitive; a locale `toLowerCase()` mis-folds e.g. Turkish `I`/`İ` and
|
|
1100
|
-
* could let two "equivalent" part names evade duplicate detection.
|
|
1101
|
-
*/
|
|
1102
|
-
declare function asciiFold(s: string): string;
|
|
1103
|
-
/** Case-folded key for OPC part-name equivalence / duplicate detection. */
|
|
1104
|
-
declare function partNameKey(partName: string): string;
|
|
1105
|
-
/**
|
|
1106
|
-
* Detect archive entries that collide after normalization (before inflation).
|
|
1107
|
-
* Returns the case-folded keys that more than one raw name maps to.
|
|
1108
|
-
*/
|
|
1109
|
-
declare function detectDuplicateNames(rawNames: readonly string[]): {
|
|
1110
|
-
readonly duplicates: readonly string[];
|
|
1111
|
-
readonly rejected: readonly {
|
|
1112
|
-
raw: string;
|
|
1113
|
-
reason: NameRejection;
|
|
1114
|
-
}[];
|
|
1115
|
-
};
|
|
1116
|
-
/**
|
|
1117
|
-
* Resolve an internal relationship target against its owner part, without
|
|
1118
|
-
* escaping the package root. `ownerPartName` is a canonical part name; the base
|
|
1119
|
-
* is its containing folder. A leading "/" target is package-absolute. `.`/`..`
|
|
1120
|
-
* segments resolve on a stack; popping above root is `traversal-escape`.
|
|
1121
|
-
*/
|
|
1122
|
-
declare function resolveInternalTarget(ownerPartName: string, rawTarget: string): NameResult;
|
|
1123
|
-
/**
|
|
1124
|
-
* Validate an external-mode relationship target. It MUST be an absolute URI, is
|
|
1125
|
-
* retained verbatim by the caller, and is NEVER owner-resolved or fetched here.
|
|
1126
|
-
* Unsafe schemes (javascript/vbscript/data/file) are rejected for runtime sinks;
|
|
1127
|
-
* the raw lexical form is still preserved separately by the authored record.
|
|
1128
|
-
*/
|
|
1129
|
-
declare function validateExternalTarget(raw: string): NameResult;
|
|
1130
|
-
|
|
1131
|
-
/** OOXML image relationship type for embedded or linked media parts. */
|
|
1132
|
-
declare const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
1133
|
-
/**
|
|
1134
|
-
* Whether a relationship points inside the package or out of it.
|
|
1135
|
-
*
|
|
1136
|
-
* The security-relevant distinction: an `External` target is retained VERBATIM and never
|
|
1137
|
-
* owner-resolved or fetched, because auto-loading a file-supplied remote target is a zero-click
|
|
1138
|
-
* external fetch.
|
|
1139
|
-
*/
|
|
1140
|
-
type TargetMode = 'Internal' | 'External';
|
|
1141
|
-
/**
|
|
1142
|
-
* One authored relationship, with nothing materialized away: owner part, id, type, raw target
|
|
1143
|
-
* lexical form, mode, and position.
|
|
1144
|
-
*/
|
|
1145
|
-
interface RelationshipRecord {
|
|
1146
|
-
readonly ownerPart: string;
|
|
1147
|
-
readonly id: string;
|
|
1148
|
-
readonly type: string;
|
|
1149
|
-
readonly rawTarget: string;
|
|
1150
|
-
readonly targetMode: TargetMode;
|
|
1151
|
-
readonly order: number;
|
|
1152
|
-
}
|
|
1153
|
-
/** Why a relationship set is invalid. Duplicate ids within one owner fail closed. */
|
|
1154
|
-
type RelationshipError = {
|
|
1155
|
-
readonly code: 'duplicate-id';
|
|
1156
|
-
readonly ownerPart: string;
|
|
1157
|
-
readonly id: string;
|
|
1158
|
-
};
|
|
1159
|
-
/** The validated relationship set, or the conflict that rejected it. */
|
|
1160
|
-
type RelationshipSetResult = {
|
|
1161
|
-
readonly ok: true;
|
|
1162
|
-
readonly byOwner: ReadonlyMap<string, readonly RelationshipRecord[]>;
|
|
1163
|
-
} | {
|
|
1164
|
-
readonly ok: false;
|
|
1165
|
-
readonly error: RelationshipError;
|
|
1166
|
-
};
|
|
1167
|
-
/** Group relationships by owner in authored order; reject duplicate ids per owner. */
|
|
1168
|
-
declare function buildRelationshipSet(records: readonly RelationshipRecord[]): RelationshipSetResult;
|
|
1169
|
-
/**
|
|
1170
|
-
* A relationship resolved to a part, or the reason it could not be.
|
|
1171
|
-
*
|
|
1172
|
-
* External targets resolve to a refusal by design: they are never followed from a file.
|
|
1173
|
-
*/
|
|
1174
|
-
type ResolvedRelationship = {
|
|
1175
|
-
readonly mode: 'Internal';
|
|
1176
|
-
readonly target: NameResult;
|
|
1177
|
-
readonly raw: string;
|
|
1099
|
+
readonly part: OoxmlPart;
|
|
1178
1100
|
} | {
|
|
1179
|
-
readonly
|
|
1180
|
-
readonly
|
|
1181
|
-
readonly raw: string;
|
|
1101
|
+
readonly ok: false;
|
|
1102
|
+
readonly reason: OoxmlReadRejection;
|
|
1182
1103
|
};
|
|
1183
1104
|
/**
|
|
1184
|
-
*
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1187
|
-
*
|
|
1105
|
+
* The node-identity contract, written down as a type so it is checkable rather than merely
|
|
1106
|
+
* documented.
|
|
1107
|
+
*
|
|
1108
|
+
* Ids are deterministic from a normalized parse, retained through structural sharing, explicit on
|
|
1109
|
+
* replacement, and unique within a part. Everything that addresses nodes — ops, the caret, the
|
|
1110
|
+
* paraId bimap — depends on all four holding.
|
|
1188
1111
|
*/
|
|
1189
|
-
|
|
1112
|
+
interface OoxmlNodeIdentityRules {
|
|
1113
|
+
readonly initial: 'deterministic-structural-path-after-normalized-parse';
|
|
1114
|
+
readonly unchanged: 'retain-id-through-structural-sharing';
|
|
1115
|
+
readonly replacement: 'explicitly-retain-or-allocate';
|
|
1116
|
+
readonly uniqueness: 'unique-within-part';
|
|
1117
|
+
}
|
|
1190
1118
|
/**
|
|
1191
|
-
*
|
|
1192
|
-
*
|
|
1193
|
-
* External-mode image rels are refused rather than fetched — the no-zero-click-external-fetch
|
|
1194
|
-
* rule applies to images exactly as it does to links.
|
|
1119
|
+
* Identity policy for future immutable tree edits. This defines the boundary
|
|
1120
|
+
* without implementing task 2.4 edit primitives.
|
|
1195
1121
|
*/
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
readonly
|
|
1202
|
-
readonly
|
|
1203
|
-
readonly
|
|
1122
|
+
declare const OOXML_NODE_IDENTITY_RULES: OoxmlNodeIdentityRules;
|
|
1123
|
+
/** What a tree invariant walk found wrong. Each names a rule the canonical tree must satisfy. */
|
|
1124
|
+
type OoxmlInvariantIssueCode = 'invalid-id' | 'duplicate-id' | 'invalid-name' | 'invalid-namespace' | 'invalid-qname' | 'duplicate-expanded-attribute' | 'invalid-xml-value' | 'known-node-invariant';
|
|
1125
|
+
/** One invariant violation, located by structural path and node id. */
|
|
1126
|
+
interface OoxmlInvariantIssue {
|
|
1127
|
+
readonly code: OoxmlInvariantIssueCode;
|
|
1128
|
+
readonly path: string;
|
|
1129
|
+
readonly nodeId?: string;
|
|
1130
|
+
}
|
|
1131
|
+
/** Whether a tree satisfies its invariants, listing every violation when it does not. */
|
|
1132
|
+
type OoxmlInvariantResult = {
|
|
1133
|
+
readonly ok: true;
|
|
1204
1134
|
} | {
|
|
1205
|
-
readonly
|
|
1135
|
+
readonly ok: false;
|
|
1136
|
+
readonly issues: readonly OoxmlInvariantIssue[];
|
|
1206
1137
|
};
|
|
1207
1138
|
/**
|
|
1208
|
-
*
|
|
1209
|
-
*
|
|
1139
|
+
* Read one XML part into the additive typed/generic foundation. Existing package
|
|
1140
|
+
* parsing and DocumentStore models intentionally remain unchanged until their
|
|
1141
|
+
* later migration tasks; this tree is not yet the repository's sole runtime authority.
|
|
1142
|
+
* Structural-path IDs are deterministic across normalized reopen. Preserving an
|
|
1143
|
+
* identity through moves and edits is deferred to PackageModel/DocumentStore integration.
|
|
1210
1144
|
*/
|
|
1211
|
-
declare function
|
|
1145
|
+
declare function readOoxmlPart(xml: string, metadata: OoxmlPartMetadata, limits?: XmlLimits): OoxmlReadResult;
|
|
1146
|
+
|
|
1147
|
+
/** Plain text fitted to a floating shape box, painted with one fill and an optional outline. */
|
|
1148
|
+
interface LegacyTextArtProjection {
|
|
1149
|
+
readonly text: string;
|
|
1150
|
+
readonly fontFamily: string;
|
|
1151
|
+
readonly bold: boolean;
|
|
1152
|
+
readonly italic: boolean;
|
|
1153
|
+
/** `RRGGBB`, or null when the shape is not filled. */
|
|
1154
|
+
readonly fillHex: string | null;
|
|
1155
|
+
readonly fillAlpha: number;
|
|
1156
|
+
/** `RRGGBB`, or null when the shape is not stroked. */
|
|
1157
|
+
readonly strokeHex: string | null;
|
|
1158
|
+
readonly strokeAlpha: number;
|
|
1159
|
+
readonly strokeWidthPt: number;
|
|
1160
|
+
/** Clockwise rotation about the box centre, in [0, 360). */
|
|
1161
|
+
readonly rotationDegrees: number;
|
|
1162
|
+
}
|
|
1212
1163
|
|
|
1213
1164
|
type ShapeSchemeColorResolver = (scheme: string) => string | null;
|
|
1214
1165
|
type ShapeStyleMatrixResolver = (kind: 'fill' | 'line', index: number) => OoxmlElement | null;
|
|
@@ -1267,6 +1218,9 @@ interface VectorShapeComponent {
|
|
|
1267
1218
|
readonly strokeHex: string | null;
|
|
1268
1219
|
readonly strokeAlpha: number;
|
|
1269
1220
|
readonly strokeWidthEmu: number;
|
|
1221
|
+
/** Authored line ends and joins, inherited from the selected theme line when absent. */
|
|
1222
|
+
readonly strokeCap?: 'butt' | 'round' | 'square';
|
|
1223
|
+
readonly strokeJoin?: 'round' | 'bevel';
|
|
1270
1224
|
/**
|
|
1271
1225
|
* The outline sits inside the closed geometry (`a:ln algn="in"`): painters draw it at twice
|
|
1272
1226
|
* its width clipped to the path, so the authored width stays inside the shape and adds no
|
|
@@ -1477,139 +1431,401 @@ interface GroupPictureProjection {
|
|
|
1477
1431
|
}
|
|
1478
1432
|
|
|
1479
1433
|
/**
|
|
1480
|
-
*
|
|
1434
|
+
* Whether a drawing sits in the text flow or is positioned against a frame.
|
|
1481
1435
|
*
|
|
1482
|
-
*
|
|
1483
|
-
* an
|
|
1436
|
+
* The distinction that decides everything downstream: an inline drawing occupies a character
|
|
1437
|
+
* position, while an anchored one has offsets relative to a page, margin or column.
|
|
1484
1438
|
*/
|
|
1485
|
-
type
|
|
1486
|
-
/**
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1439
|
+
type DrawingKind = 'inline' | 'anchored';
|
|
1440
|
+
/** Nine Word wrap menu targets (inline plus eight floating modes). @public */
|
|
1441
|
+
type ImageWrapTarget = 'inline' | 'square' | 'squareLeft' | 'squareRight' | 'tight' | 'through' | 'topAndBottom' | 'behind' | 'inFront';
|
|
1442
|
+
/** Every text-wrap mode a drawing may be set to, including `inline`. */
|
|
1443
|
+
declare const IMAGE_WRAP_TARGETS: readonly ImageWrapTarget[];
|
|
1444
|
+
type DrawingWrapElement = 'none' | 'square' | 'tight' | 'through' | 'topAndBottom';
|
|
1445
|
+
type DrawingHorizontalReferenceFrame = 'character' | 'column' | 'insideMargin' | 'leftMargin' | 'margin' | 'outsideMargin' | 'page' | 'rightMargin';
|
|
1446
|
+
type DrawingVerticalReferenceFrame = 'bottomMargin' | 'insideMargin' | 'line' | 'margin' | 'outsideMargin' | 'page' | 'paragraph' | 'topMargin';
|
|
1447
|
+
/** `a:srcRect` — how much of each edge of the source image is cropped away, as fractions. */
|
|
1448
|
+
interface SourceCrop {
|
|
1449
|
+
readonly left: number;
|
|
1450
|
+
readonly top: number;
|
|
1451
|
+
readonly right: number;
|
|
1452
|
+
readonly bottom: number;
|
|
1453
|
+
}
|
|
1454
|
+
interface DrawingTransform {
|
|
1455
|
+
readonly rotationDegrees: number;
|
|
1456
|
+
readonly flipHorizontal: boolean;
|
|
1457
|
+
readonly flipVertical: boolean;
|
|
1458
|
+
/** Source `a:off` in EMU; defaults to origin when absent. */
|
|
1459
|
+
readonly offsetEmu: Readonly<{
|
|
1460
|
+
x: number;
|
|
1461
|
+
y: number;
|
|
1462
|
+
}>;
|
|
1463
|
+
/** Source `a:ext` in EMU; zero falls back to `wp:extent` at geometry time. */
|
|
1464
|
+
readonly extentEmu: Readonly<{
|
|
1465
|
+
cx: number;
|
|
1466
|
+
cy: number;
|
|
1467
|
+
}>;
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* What a drawing refuses: selection, movement, resizing, aspect change.
|
|
1471
|
+
*
|
|
1472
|
+
* Read and honoured rather than advisory — chrome that offered a handle the store will refuse
|
|
1473
|
+
* would promise an edit that cannot happen.
|
|
1474
|
+
*/
|
|
1475
|
+
interface DrawingLocks {
|
|
1476
|
+
readonly select: boolean;
|
|
1477
|
+
readonly move: boolean;
|
|
1478
|
+
readonly resize: boolean;
|
|
1479
|
+
readonly changeAspect: boolean;
|
|
1480
|
+
}
|
|
1481
|
+
interface DrawingLocksInput {
|
|
1482
|
+
readonly select?: boolean;
|
|
1483
|
+
readonly move?: boolean;
|
|
1484
|
+
readonly resize?: boolean;
|
|
1485
|
+
readonly changeAspect?: boolean;
|
|
1486
|
+
}
|
|
1487
|
+
/**
|
|
1488
|
+
* An anchored drawing's position: offsets, and the frames they are relative to.
|
|
1489
|
+
*
|
|
1490
|
+
* The relative-to bases matter as much as the offsets. Writing an offset without preserving its
|
|
1491
|
+
* base re-anchors the drawing against a different reference and moves it somewhere nobody asked.
|
|
1492
|
+
*/
|
|
1493
|
+
interface DrawingPositionInput {
|
|
1491
1494
|
/**
|
|
1492
|
-
*
|
|
1493
|
-
*
|
|
1494
|
-
* never refused for compressing well.
|
|
1495
|
+
* `'simple'` when `@simplePos="1"`: `horizontalEmu` / `verticalEmu` are authoritative
|
|
1496
|
+
* `wp:simplePos` x/y. `'frame'` (default) uses positionH/V relative frames.
|
|
1495
1497
|
*/
|
|
1496
|
-
readonly
|
|
1498
|
+
readonly mode?: 'frame' | 'simple';
|
|
1499
|
+
readonly horizontalEmu?: number;
|
|
1500
|
+
readonly verticalEmu?: number;
|
|
1501
|
+
readonly relativeToH?: DrawingHorizontalReferenceFrame;
|
|
1502
|
+
readonly relativeToV?: DrawingVerticalReferenceFrame;
|
|
1503
|
+
}
|
|
1504
|
+
interface DrawingProjection {
|
|
1505
|
+
readonly drawingNodeId: string;
|
|
1506
|
+
readonly ownerPartName: string;
|
|
1507
|
+
readonly kind: DrawingKind;
|
|
1508
|
+
readonly relationshipId: string | null;
|
|
1509
|
+
readonly docPrId: number | null;
|
|
1510
|
+
readonly name: string;
|
|
1511
|
+
readonly title: string;
|
|
1512
|
+
readonly description: string;
|
|
1513
|
+
readonly hyperlinkHref: string | null;
|
|
1514
|
+
readonly hidden: boolean;
|
|
1515
|
+
readonly extentEmu: Readonly<{
|
|
1516
|
+
cx: number;
|
|
1517
|
+
cy: number;
|
|
1518
|
+
}>;
|
|
1519
|
+
readonly effectExtentEmu: Readonly<{
|
|
1520
|
+
top: number;
|
|
1521
|
+
right: number;
|
|
1522
|
+
bottom: number;
|
|
1523
|
+
left: number;
|
|
1524
|
+
}>;
|
|
1525
|
+
readonly inlineDistancesEmu: Readonly<{
|
|
1526
|
+
top: number;
|
|
1527
|
+
right: number;
|
|
1528
|
+
bottom: number;
|
|
1529
|
+
left: number;
|
|
1530
|
+
}>;
|
|
1531
|
+
readonly wrap: ImageWrapTarget;
|
|
1532
|
+
readonly wrapGeometry: DrawingWrapProjection | null;
|
|
1533
|
+
readonly position: DrawingPositionProjection | null;
|
|
1534
|
+
readonly anchor: Readonly<{
|
|
1535
|
+
simplePos: boolean;
|
|
1536
|
+
relativeHeight: number;
|
|
1537
|
+
behindDocument: boolean;
|
|
1538
|
+
layoutInCell: boolean;
|
|
1539
|
+
allowOverlap: boolean;
|
|
1540
|
+
}> | null;
|
|
1541
|
+
readonly picture: PictureProjection | null;
|
|
1542
|
+
readonly vectorShape: VectorShapeProjection | null;
|
|
1543
|
+
/** The picture member of a `wpg:wgp` group; `picture` stays null for a group. */
|
|
1544
|
+
readonly groupPicture: GroupPictureProjection | null;
|
|
1545
|
+
readonly textboxStory: TextboxStoryProjection | null;
|
|
1546
|
+
/** Text box members of a `wpg:wgp` group, laid out read-only; absent when none has text. */
|
|
1547
|
+
readonly groupTextboxes?: readonly GroupTextboxProjection[];
|
|
1548
|
+
/** Read-only preview of the supported native VML subset; the canonical XML is untouched. */
|
|
1549
|
+
readonly legacyGraphic?: LegacyGraphicProjection;
|
|
1550
|
+
/** Floating VML text art (a text watermark), fitted to the box by layout. */
|
|
1551
|
+
readonly textArt?: LegacyTextArtProjection;
|
|
1552
|
+
readonly locks: DrawingLocks;
|
|
1553
|
+
readonly effects: DrawingImageEffects;
|
|
1554
|
+
readonly compatibilityBranchNodeId: string | null;
|
|
1555
|
+
readonly diagnostics: readonly DrawingDiagnostic[];
|
|
1556
|
+
/** Layout-only wrap area of an MC payload that cannot paint (`wrapFootprintProjection`). */
|
|
1557
|
+
readonly footprintOnly?: true;
|
|
1558
|
+
}
|
|
1559
|
+
interface DrawingAccessibility {
|
|
1560
|
+
/**
|
|
1561
|
+
* The record takes part in layout only, for example the wrap area of a payload that cannot
|
|
1562
|
+
* paint. Outputs must not paint, hit-test, select, link, or export it.
|
|
1563
|
+
*/
|
|
1564
|
+
readonly hidden: boolean;
|
|
1565
|
+
readonly decorative: boolean;
|
|
1566
|
+
readonly label: string | null;
|
|
1567
|
+
}
|
|
1568
|
+
interface DrawingPositionProjection {
|
|
1569
|
+
readonly simplePosition: Readonly<{
|
|
1570
|
+
xEmu: number;
|
|
1571
|
+
yEmu: number;
|
|
1572
|
+
}>;
|
|
1573
|
+
readonly horizontal: Readonly<{
|
|
1574
|
+
relativeFrom: DrawingHorizontalReferenceFrame;
|
|
1575
|
+
align: string | null;
|
|
1576
|
+
offsetEmu: number | null;
|
|
1577
|
+
}>;
|
|
1578
|
+
readonly vertical: Readonly<{
|
|
1579
|
+
relativeFrom: DrawingVerticalReferenceFrame;
|
|
1580
|
+
align: string | null;
|
|
1581
|
+
offsetEmu: number | null;
|
|
1582
|
+
}>;
|
|
1583
|
+
}
|
|
1584
|
+
interface DrawingWrapProjection {
|
|
1585
|
+
readonly element: DrawingWrapElement;
|
|
1586
|
+
readonly textSide: 'bothSides' | 'left' | 'right' | 'largest';
|
|
1587
|
+
readonly distancesEmu: Readonly<{
|
|
1588
|
+
top: number;
|
|
1589
|
+
right: number;
|
|
1590
|
+
bottom: number;
|
|
1591
|
+
left: number;
|
|
1592
|
+
}>;
|
|
1593
|
+
readonly polygon: readonly Readonly<{
|
|
1594
|
+
x: number;
|
|
1595
|
+
y: number;
|
|
1596
|
+
}>[];
|
|
1597
|
+
}
|
|
1598
|
+
interface PictureProjection {
|
|
1599
|
+
readonly embeddedRelationshipId: string | null;
|
|
1600
|
+
readonly linkedRelationshipId: string | null;
|
|
1601
|
+
readonly crop: SourceCrop;
|
|
1602
|
+
readonly fillMode: 'stretch' | 'tile';
|
|
1603
|
+
readonly transform: DrawingTransform;
|
|
1604
|
+
readonly presetGeometry: string | null;
|
|
1497
1605
|
}
|
|
1498
|
-
/** The archive caps in force when a host configures none. Conservative and finite. */
|
|
1499
|
-
declare const DEFAULT_ZIP_LIMITS: ZipLimits;
|
|
1500
|
-
/** The read entries, or the typed refusal. Never throws — the bytes are untrusted. */
|
|
1501
|
-
type ZipReadResult = {
|
|
1502
|
-
readonly ok: true;
|
|
1503
|
-
readonly entries: ReadonlyMap<string, Uint8Array>;
|
|
1504
|
-
} | {
|
|
1505
|
-
readonly ok: false;
|
|
1506
|
-
readonly reason: ZipRejection;
|
|
1507
|
-
readonly detail?: string;
|
|
1508
|
-
readonly limit?: 'zip.maxTotalBytes' | 'zip.maxRatio';
|
|
1509
|
-
};
|
|
1510
1606
|
/**
|
|
1511
|
-
*
|
|
1512
|
-
* ratio, and total-uncompressed-size limits are enforced BEFORE each entry is decompressed
|
|
1513
|
-
* (via fflate's pre-inflation filter), so a zip bomb or a traversal name is rejected without
|
|
1514
|
-
* ever being inflated. Keys are canonical part names.
|
|
1607
|
+
* Project one `w:drawing` into the resolved shape layout and chrome read.
|
|
1515
1608
|
*
|
|
1516
|
-
*
|
|
1517
|
-
*
|
|
1518
|
-
*
|
|
1519
|
-
* refused as `inflate-error`), never expanded past its budget. A stored entry is copied at
|
|
1520
|
-
* its compressed size, so the larger of its two declared sizes is what counts.
|
|
1609
|
+
* Bounded throughout: extents, crops and nesting all come from a file. Returns a projection that
|
|
1610
|
+
* reports `hidden` and its locks rather than throwing, so an unusable drawing degrades to
|
|
1611
|
+
* something the surface can skip.
|
|
1521
1612
|
*/
|
|
1522
|
-
declare function
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1613
|
+
declare function projectDrawing(drawing: OoxmlDrawingNode, context: Readonly<{
|
|
1614
|
+
ownerPartName: string;
|
|
1615
|
+
supportedMcRequires: ReadonlySet<string>;
|
|
1616
|
+
limits: DrawingProjectionLimits;
|
|
1617
|
+
namespaceScope?: ReadonlyMap<string, string>;
|
|
1618
|
+
resolveRelationship?: RelationshipTargetResolver;
|
|
1619
|
+
resolveSchemeColor?: ShapeSchemeColorResolver;
|
|
1620
|
+
resolveStyleMatrixReference?: ShapeStyleMatrixResolver;
|
|
1621
|
+
}>): DrawingProjection | null;
|
|
1528
1622
|
|
|
1529
|
-
/**
|
|
1530
|
-
interface
|
|
1531
|
-
readonly
|
|
1532
|
-
readonly
|
|
1533
|
-
readonly
|
|
1534
|
-
|
|
1535
|
-
/** One `<Override>`: a specific part name mapped to a content type. Beats any Default. */
|
|
1536
|
-
interface OverrideRecord {
|
|
1537
|
-
readonly partName: string;
|
|
1538
|
-
readonly contentType: string;
|
|
1539
|
-
readonly order: number;
|
|
1623
|
+
/** Opaque handle — bytes are reachable only through {@link mintValidatedImageBytes}. */
|
|
1624
|
+
interface ValidatedImageBytesHandle {
|
|
1625
|
+
readonly registryId: number;
|
|
1626
|
+
readonly resourceKey: string;
|
|
1627
|
+
readonly contentId: string;
|
|
1628
|
+
readonly generation: number;
|
|
1540
1629
|
}
|
|
1630
|
+
|
|
1541
1631
|
/**
|
|
1542
|
-
* The
|
|
1632
|
+
* The engine's trust-boundary caps: recursion depth, element counts, and the rest.
|
|
1633
|
+
*
|
|
1634
|
+
* A caller may LOWER any of these but never raise or disable one — an override of `Infinity`,
|
|
1635
|
+
* zero, a negative or `NaN` clamps into `(0, ceiling]` rather than turning the limit off. These
|
|
1636
|
+
* are security ceilings, not performance budgets.
|
|
1637
|
+
*/
|
|
1638
|
+
interface ResourceLimits {
|
|
1639
|
+
/** Max nested-structure recursion (tables/shapes/SDT/groups). */
|
|
1640
|
+
readonly maxRecursionDepth: number;
|
|
1641
|
+
/** Max total parsed element count. */
|
|
1642
|
+
readonly maxElementCount: number;
|
|
1643
|
+
/** Max package part count. */
|
|
1644
|
+
readonly maxPartCount: number;
|
|
1645
|
+
/** Max total decompressed bytes (zip-bomb guard). */
|
|
1646
|
+
readonly maxDecompressedBytes: number;
|
|
1647
|
+
/** Max total compressed input bytes. */
|
|
1648
|
+
readonly maxCompressedBytes: number;
|
|
1649
|
+
/** Max decompressed:compressed ratio per entry. */
|
|
1650
|
+
readonly maxCompressionRatio: number;
|
|
1651
|
+
/** In-memory chunk budget for streaming/spooling. */
|
|
1652
|
+
readonly maxChunkBytes: number;
|
|
1653
|
+
/** Max pagination passes before non-convergence is declared. */
|
|
1654
|
+
readonly maxPaginationPasses: number;
|
|
1655
|
+
/** Max queued items in any bounded work queue. */
|
|
1656
|
+
readonly maxQueueDepth: number;
|
|
1657
|
+
}
|
|
1658
|
+
/** Non-disableable hard ceilings: no resolved limit may exceed these. */
|
|
1659
|
+
declare const HARD_CEILINGS: ResourceLimits;
|
|
1660
|
+
/** Finite defaults, all <= their hard ceiling. */
|
|
1661
|
+
declare const DEFAULT_LIMITS: ResourceLimits;
|
|
1662
|
+
/**
|
|
1663
|
+
* Resolve caller overrides into a frozen, always-finite limit set. Each value is
|
|
1664
|
+
* `min(override>0 ? override : default, ceiling)`. Infinity/0/negative/NaN can
|
|
1665
|
+
* never disable a limit — the hard ceiling always wins.
|
|
1666
|
+
*/
|
|
1667
|
+
declare function resolveLimits(overrides?: Partial<ResourceLimits>): ResourceLimits;
|
|
1668
|
+
/** Bounded image decode limits (typed-drawings-and-images task 4). */
|
|
1669
|
+
/** Trust-boundary caps specific to image decoding and embedding. */
|
|
1670
|
+
interface ImageResourceLimits {
|
|
1671
|
+
readonly maxEncodedBytes: number;
|
|
1672
|
+
readonly maxDecodedBytes: number;
|
|
1673
|
+
readonly maxPixels: number;
|
|
1674
|
+
readonly maxDimension: number;
|
|
1675
|
+
readonly maxPolygonPoints: number;
|
|
1676
|
+
readonly maxExternalRedirects: number;
|
|
1677
|
+
}
|
|
1678
|
+
/** Image caps nothing can raise past. A caller's override clamps into these. */
|
|
1679
|
+
declare const IMAGE_RESOURCE_HARD_CEILINGS: ImageResourceLimits;
|
|
1680
|
+
/** The image caps in force when a host configures none. Conservative and finite. */
|
|
1681
|
+
declare const DEFAULT_IMAGE_RESOURCE_LIMITS: ImageResourceLimits;
|
|
1682
|
+
/** Resolve caller overrides into frozen image limits; hard ceilings cannot be raised. */
|
|
1683
|
+
declare function resolveImageResourceLimits(overrides?: Partial<ImageResourceLimits>): ImageResourceLimits;
|
|
1684
|
+
|
|
1685
|
+
/**
|
|
1686
|
+
* Raster media the decode port measures and any authoring path may write.
|
|
1543
1687
|
*
|
|
1544
|
-
*
|
|
1545
|
-
*
|
|
1688
|
+
* BMP and WebP are here for the same reason the other three are: an `<img>` decodes them
|
|
1689
|
+
* natively, so they need a signature and a structural header and nothing else. BMP is what
|
|
1690
|
+
* older documents carry; WebP is what current Word writes.
|
|
1546
1691
|
*/
|
|
1547
|
-
|
|
1548
|
-
readonly defaults: readonly DefaultRecord[];
|
|
1549
|
-
readonly overrides: readonly OverrideRecord[];
|
|
1550
|
-
}
|
|
1692
|
+
type SupportedImageMime = 'image/png' | 'image/jpeg' | 'image/gif' | 'image/bmp' | 'image/webp';
|
|
1551
1693
|
/**
|
|
1552
|
-
*
|
|
1694
|
+
* Vector media painted straight from validated bytes. An `<img>` renders SVG in the
|
|
1695
|
+
* browser's secure static mode — no script, no external subresource loads — so there is
|
|
1696
|
+
* no decode step and no raster buffer sized by a file-supplied number.
|
|
1697
|
+
*/
|
|
1698
|
+
type VectorImageMime = 'image/svg+xml';
|
|
1699
|
+
/** Every mime the painter can hand to an `<img>`. */
|
|
1700
|
+
type RenderableImageMime = SupportedImageMime | VectorImageMime;
|
|
1701
|
+
/**
|
|
1702
|
+
* Media kept in the package byte-for-byte that the painter cannot hand to an `<img>`.
|
|
1703
|
+
* A decode port may rasterize it; without one it paints as a labelled placeholder.
|
|
1704
|
+
*/
|
|
1705
|
+
type PreservedImageMime = 'image/tiff' | 'image/x-emf' | 'image/x-wmf';
|
|
1706
|
+
/**
|
|
1707
|
+
* What is known about one embedded image: validated, refused, or still decoding.
|
|
1553
1708
|
*
|
|
1554
|
-
*
|
|
1555
|
-
*
|
|
1709
|
+
* Content type is a CLAIM. Signature sniffing, structural header validation and the decode port
|
|
1710
|
+
* are authoritative, and bytes that fail them never enter public state.
|
|
1556
1711
|
*/
|
|
1557
|
-
type
|
|
1558
|
-
readonly
|
|
1559
|
-
readonly value: string;
|
|
1560
|
-
} | {
|
|
1561
|
-
readonly code: 'conflicting-default';
|
|
1562
|
-
readonly extension: string;
|
|
1563
|
-
} | {
|
|
1564
|
-
readonly code: 'duplicate-override';
|
|
1712
|
+
type ImageResourceState = {
|
|
1713
|
+
readonly kind: 'ready';
|
|
1565
1714
|
readonly partName: string;
|
|
1715
|
+
readonly contentId: string;
|
|
1716
|
+
readonly resourceKey: string;
|
|
1717
|
+
readonly validatedHandle: ValidatedImageBytesHandle;
|
|
1718
|
+
readonly mime: RenderableImageMime;
|
|
1719
|
+
readonly pixelWidth: number;
|
|
1720
|
+
readonly pixelHeight: number;
|
|
1721
|
+
readonly dpiX: number;
|
|
1722
|
+
readonly dpiY: number;
|
|
1566
1723
|
} | {
|
|
1567
|
-
readonly
|
|
1568
|
-
readonly partName: string;
|
|
1724
|
+
readonly kind: 'unrenderable';
|
|
1725
|
+
readonly partName: string | null;
|
|
1726
|
+
readonly mime: RenderableImageMime | PreservedImageMime | 'unknown';
|
|
1727
|
+
readonly reason: 'unsupported-format' | 'non-picture-graphic' | 'signature-mismatch' | 'decode-failed' | 'resource-limit';
|
|
1569
1728
|
} | {
|
|
1570
|
-
readonly
|
|
1571
|
-
readonly
|
|
1572
|
-
|
|
1573
|
-
/** Whether a string is syntactically a MIME type. Syntax only — no registry lookup. */
|
|
1574
|
-
declare function isValidMime(value: string): boolean;
|
|
1575
|
-
/** ASCII-case-insensitive extension key (leading dot removed; ASCII-only fold). */
|
|
1576
|
-
declare function extensionKey(extension: string): string;
|
|
1577
|
-
/** The resolved lookup: Override by case-folded part name, Default by case-insensitive extension. */
|
|
1578
|
-
interface ContentTypeIndex {
|
|
1579
|
-
/** ext key -> single MIME (identical duplicates collapsed). */
|
|
1580
|
-
readonly defaults: ReadonlyMap<string, string>;
|
|
1581
|
-
/** case-folded part name -> MIME. */
|
|
1582
|
-
readonly overrides: ReadonlyMap<string, string>;
|
|
1583
|
-
}
|
|
1584
|
-
/** The built index, or the conflict that made it impossible. */
|
|
1585
|
-
type IndexResult = {
|
|
1586
|
-
readonly ok: true;
|
|
1587
|
-
readonly index: ContentTypeIndex;
|
|
1729
|
+
readonly kind: 'external';
|
|
1730
|
+
readonly relationshipId: string;
|
|
1731
|
+
readonly sinkSafe: boolean;
|
|
1588
1732
|
} | {
|
|
1589
|
-
readonly
|
|
1590
|
-
readonly
|
|
1733
|
+
readonly kind: 'missing';
|
|
1734
|
+
readonly relationshipId: string;
|
|
1735
|
+
} | {
|
|
1736
|
+
readonly kind: 'pending';
|
|
1737
|
+
readonly resourceKey: string;
|
|
1591
1738
|
};
|
|
1592
1739
|
/**
|
|
1593
|
-
*
|
|
1594
|
-
* errors. `maxRecords` bounds the combined record count (N/N+1 gate).
|
|
1595
|
-
*/
|
|
1596
|
-
declare function buildContentTypeIndex(records: ContentTypeRecords, maxRecords?: number): IndexResult;
|
|
1597
|
-
/**
|
|
1598
|
-
* A part's content type, or why it has none.
|
|
1740
|
+
* The injected image decoder.
|
|
1599
1741
|
*
|
|
1600
|
-
*
|
|
1601
|
-
*
|
|
1742
|
+
* A port rather than a direct `Image`/`createImageBitmap` call, so a worker or server runtime
|
|
1743
|
+
* supplies its own and the engine never reaches for a browser global.
|
|
1602
1744
|
*/
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1745
|
+
interface ImageDecodePort {
|
|
1746
|
+
decode(bytes: Uint8Array, mime: SupportedImageMime, limits: ImageResourceLimits,
|
|
1747
|
+
/** Aborted when the owning lookup/session is disposed. */
|
|
1748
|
+
signal?: AbortSignal): Promise<Readonly<{
|
|
1749
|
+
pixelWidth: number;
|
|
1750
|
+
pixelHeight: number;
|
|
1751
|
+
dpiX: number;
|
|
1752
|
+
dpiY: number;
|
|
1753
|
+
}>>;
|
|
1754
|
+
/**
|
|
1755
|
+
* Optional conversion of media an `<img>` cannot render (EMF/WMF metafiles, TIFF) into a
|
|
1756
|
+
* renderable raster. The returned bytes are untrusted and re-enter the full raster
|
|
1757
|
+
* validation path (sniff, header, pixel caps, decode) before they can become a ready
|
|
1758
|
+
* resource. A null return declines the format and keeps the labelled placeholder; so does
|
|
1759
|
+
* a throw, as `decode-failed`.
|
|
1760
|
+
*/
|
|
1761
|
+
convertPreserved?(bytes: Uint8Array, mime: PreservedImageMime, limits: ImageResourceLimits,
|
|
1762
|
+
/** Aborted when the owning lookup/session is disposed. */
|
|
1763
|
+
signal?: AbortSignal): Promise<Readonly<{
|
|
1764
|
+
bytes: Uint8Array;
|
|
1765
|
+
mime: SupportedImageMime;
|
|
1766
|
+
}> | null>;
|
|
1767
|
+
}
|
|
1768
|
+
/** Resolves a relationship id to a validated image resource, or reports why it could not. */
|
|
1769
|
+
interface ImageResourceLookup {
|
|
1770
|
+
readonly resolveEmbedded: (ownerPartName: string, relationshipId: string) => Promise<ImageResourceState>;
|
|
1771
|
+
readonly resolveLinked: (ownerPartName: string, relationshipId: string) => ImageResourceState;
|
|
1772
|
+
readonly resolveForProjection: (projection: DrawingProjection) => Promise<ImageResourceState>;
|
|
1773
|
+
readonly liveReferenceCount: (partName: string) => number;
|
|
1774
|
+
readonly dispose: () => void;
|
|
1775
|
+
}
|
|
1776
|
+
/** Maximum prefix inspected for SVG root detection (exported for bounded-scan tests). */
|
|
1777
|
+
declare const MAX_SVG_SNIFF_BYTES = 512;
|
|
1778
|
+
/** A raster header that passed structural validation: its real MIME type and pixel extent. */
|
|
1779
|
+
interface ValidatedRasterHeader {
|
|
1780
|
+
readonly pixelWidth: number;
|
|
1781
|
+
readonly pixelHeight: number;
|
|
1782
|
+
/** Horizontal physical density when bounded header metadata supplies it. */
|
|
1783
|
+
readonly dpiX?: number;
|
|
1784
|
+
/** Vertical physical density when bounded header metadata supplies it. */
|
|
1785
|
+
readonly dpiY?: number;
|
|
1786
|
+
}
|
|
1787
|
+
/** Bounded scan for an `<svg` document root (optional `<?xml` prolog only). */
|
|
1788
|
+
declare function hasBoundedSvgRoot(bytes: Uint8Array): boolean;
|
|
1789
|
+
/** Signature sniffing — authoritative over declared content type. */
|
|
1790
|
+
declare function sniffImageMime(bytes: Uint8Array): RenderableImageMime | PreservedImageMime | 'unknown';
|
|
1791
|
+
/** Structural PNG IHDR validation before decode. */
|
|
1792
|
+
declare function validatePngHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
|
|
1793
|
+
/** Structural GIF logical screen descriptor validation before decode. */
|
|
1794
|
+
declare function validateGifHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
|
|
1795
|
+
/** Bounded JPEG marker scan through the first supported SOF marker. */
|
|
1796
|
+
declare function validateJpegHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
|
|
1797
|
+
/**
|
|
1798
|
+
* Intrinsic size of an SVG, resolved the way a browser sizes one: absolute `width`/`height`
|
|
1799
|
+
* first, then `viewBox` for the missing axis or ratio, then the CSS 300x150 default.
|
|
1800
|
+
*
|
|
1801
|
+
* This is metadata for insert and reset-to-natural-size only. Layout uses the authored
|
|
1802
|
+
* `wp:extent` and the browser rasterizes into that box, so nothing here sizes an allocation
|
|
1803
|
+
* and an out-of-range value is clamped rather than refused.
|
|
1804
|
+
*/
|
|
1805
|
+
declare function resolveSvgIntrinsicSize(bytes: Uint8Array, limits: ImageResourceLimits): ValidatedRasterHeader | null;
|
|
1806
|
+
/**
|
|
1807
|
+
* Validate a raster image's header structurally and report its real MIME type and extent.
|
|
1808
|
+
*
|
|
1809
|
+
* Content type is a CLAIM; this is what makes it a fact. A file declaring `image/png` over JPEG
|
|
1810
|
+
* bytes is caught here rather than at decode.
|
|
1811
|
+
*/
|
|
1812
|
+
declare function validateRasterHeader(bytes: Uint8Array, mime: SupportedImageMime): ValidatedRasterHeader | null;
|
|
1813
|
+
/** Package-wide live drawing references to a media part name. */
|
|
1814
|
+
declare function liveDrawingReferenceCount(pkg: OoxmlPackage, partName: string): number;
|
|
1815
|
+
/** How the image cache decodes, and what it will spend doing so. */
|
|
1816
|
+
interface CreateImageResourceCacheOptions {
|
|
1817
|
+
readonly limits?: Partial<ImageResourceLimits>;
|
|
1818
|
+
readonly decodePort: ImageDecodePort;
|
|
1819
|
+
}
|
|
1820
|
+
/**
|
|
1821
|
+
* Derived cache for one immutable package snapshot. Registry identity is
|
|
1822
|
+
* `(package snapshot, decodePort object, normalized limits)` — the first caller
|
|
1823
|
+
* never imposes its decoder or limits on later callers with different options.
|
|
1824
|
+
*/
|
|
1825
|
+
declare function imageResourceLookupFor(pkg: OoxmlPackage, options: CreateImageResourceCacheOptions): ImageResourceLookup;
|
|
1826
|
+
/** @deprecated Prefer {@link imageResourceLookupFor} — registry binds cache to package identity. */
|
|
1827
|
+
/** Build the per-document image cache. Validated bytes only; refusals are remembered too. */
|
|
1828
|
+
declare function createImageResourceCache(initialPkg: OoxmlPackage, options: CreateImageResourceCacheOptions): ImageResourceLookup;
|
|
1613
1829
|
|
|
1614
1830
|
/** Caps applied while loading a package: zip, XML, part count and relationship count. */
|
|
1615
1831
|
interface OoxmlPackageLimits {
|
|
@@ -1699,193 +1915,300 @@ declare function writeOoxmlPackage(pkg: OoxmlPackage): Uint8Array;
|
|
|
1699
1915
|
/** Replace one part's tree, returning a new package. Pure, like the tree edits themselves. */
|
|
1700
1916
|
declare function withPart(pkg: OoxmlPackage, part: OoxmlPart): OoxmlPackage;
|
|
1701
1917
|
|
|
1918
|
+
/** A text watermark as the package stores it. */
|
|
1919
|
+
interface PackageTextWatermark {
|
|
1920
|
+
readonly kind: 'text';
|
|
1921
|
+
readonly text: string;
|
|
1922
|
+
readonly fontFamily: string;
|
|
1923
|
+
/** Null for Auto size, which fits the text to the shape box. */
|
|
1924
|
+
readonly fontSizePt: number | null;
|
|
1925
|
+
readonly bold: boolean;
|
|
1926
|
+
readonly italic: boolean;
|
|
1927
|
+
/** `RRGGBB`. */
|
|
1928
|
+
readonly colorHex: string;
|
|
1929
|
+
/** Fill opacity in [0, 1]; the dialog's Transparency is `1 - opacity`. */
|
|
1930
|
+
readonly opacity: number;
|
|
1931
|
+
readonly diagonal: boolean;
|
|
1932
|
+
readonly widthPt: number;
|
|
1933
|
+
readonly heightPt: number;
|
|
1934
|
+
}
|
|
1935
|
+
/** A picture watermark as the package stores it. */
|
|
1936
|
+
interface PackagePictureWatermark {
|
|
1937
|
+
readonly kind: 'picture';
|
|
1938
|
+
readonly washout: boolean;
|
|
1939
|
+
readonly widthPt: number;
|
|
1940
|
+
readonly heightPt: number;
|
|
1941
|
+
}
|
|
1942
|
+
/** One section's shape size, in points. */
|
|
1943
|
+
interface PackageWatermarkSize {
|
|
1944
|
+
readonly widthPt: number;
|
|
1945
|
+
readonly heightPt: number;
|
|
1946
|
+
}
|
|
1702
1947
|
/**
|
|
1703
|
-
*
|
|
1948
|
+
* A write may size the shape per section, indexed like the body's sections: a header part
|
|
1949
|
+
* takes the size of the first section that shows it, so a landscape section's watermark
|
|
1950
|
+
* fits its own text area. A missing or unusable entry falls back to `widthPt`/`heightPt`.
|
|
1951
|
+
*/
|
|
1952
|
+
interface PackageWatermarkSectionSizes {
|
|
1953
|
+
readonly sectionSizes?: readonly (PackageWatermarkSize | null)[];
|
|
1954
|
+
}
|
|
1955
|
+
/** A picture watermark write carries the image bytes. */
|
|
1956
|
+
type PackageWatermarkWrite = (PackageTextWatermark & PackageWatermarkSectionSizes) | (PackagePictureWatermark & PackageWatermarkSectionSizes & {
|
|
1957
|
+
readonly image: {
|
|
1958
|
+
readonly bytes: Uint8Array;
|
|
1959
|
+
readonly mime: SupportedImageMime;
|
|
1960
|
+
};
|
|
1961
|
+
});
|
|
1962
|
+
|
|
1963
|
+
/**
|
|
1964
|
+
* How a tracked change is addressed: `@w:id`, `@w:author` and `@w:date` together, within a
|
|
1965
|
+
* part.
|
|
1704
1966
|
*
|
|
1705
|
-
*
|
|
1706
|
-
*
|
|
1967
|
+
* All of them, always. `@w:id` is unique only within a part, so an id alone names two
|
|
1968
|
+
* revisions in any package with a header or a comments part — and it is not author-scoped
|
|
1969
|
+
* either, so `(part, id)` would merge two authors' distinct revisions. One logical revision is
|
|
1970
|
+
* also deliberately many elements sharing an id, as a tracked row insertion is, which no
|
|
1971
|
+
* uniqueness rule could express.
|
|
1707
1972
|
*/
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
/**
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
readonly
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1973
|
+
interface RevisionAddress {
|
|
1974
|
+
readonly id: string;
|
|
1975
|
+
readonly author: string;
|
|
1976
|
+
/** Absent when the file wrote no `@w:date`; part of the identity either way. */
|
|
1977
|
+
readonly date?: string;
|
|
1978
|
+
}
|
|
1979
|
+
/** The author and timestamp a tracked edit is recorded under. */
|
|
1980
|
+
interface RevisionAttributionInput {
|
|
1981
|
+
readonly author: string;
|
|
1982
|
+
/** ISO-8601. Omitted writes no `@w:date`. */
|
|
1983
|
+
readonly date?: string;
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
type AutomationTableMutation = {
|
|
1987
|
+
readonly kind: 'insertRows';
|
|
1988
|
+
readonly rowId: string;
|
|
1989
|
+
readonly location: 'before' | 'after';
|
|
1990
|
+
readonly count: number;
|
|
1991
|
+
readonly values?: readonly (readonly string[])[];
|
|
1992
|
+
} | {
|
|
1993
|
+
readonly kind: 'values';
|
|
1994
|
+
readonly values: readonly (readonly string[])[];
|
|
1995
|
+
} | {
|
|
1996
|
+
readonly kind: 'addRows' | 'addColumns';
|
|
1997
|
+
readonly location: 'start' | 'end';
|
|
1998
|
+
readonly count: number;
|
|
1999
|
+
readonly values?: readonly (readonly string[])[];
|
|
2000
|
+
} | {
|
|
2001
|
+
readonly kind: 'deleteRows' | 'deleteColumns';
|
|
2002
|
+
readonly index: number;
|
|
2003
|
+
readonly count: number;
|
|
2004
|
+
} | {
|
|
2005
|
+
readonly kind: 'delete';
|
|
2006
|
+
} | {
|
|
2007
|
+
readonly kind: 'properties';
|
|
2008
|
+
readonly styleId?: string;
|
|
2009
|
+
readonly headerRowCount?: number;
|
|
2010
|
+
} | {
|
|
2011
|
+
readonly kind: 'cell';
|
|
2012
|
+
readonly cellId: string;
|
|
2013
|
+
readonly value?: string;
|
|
2014
|
+
readonly columnWidth?: number;
|
|
2015
|
+
readonly shadingColor?: string;
|
|
2016
|
+
readonly verticalAlignment?: 'Top' | 'Center' | 'Bottom';
|
|
2017
|
+
};
|
|
2018
|
+
|
|
2019
|
+
/** Select one declared entry of a legacy Word dropdown form field. */
|
|
2020
|
+
interface SetLegacyDropdownOp {
|
|
2021
|
+
readonly op: 'setLegacyDropdown';
|
|
2022
|
+
readonly paragraphId: string;
|
|
2023
|
+
readonly fieldNodeId: string;
|
|
2024
|
+
readonly selectedIndex: number;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
interface SetFieldCodeOp {
|
|
2028
|
+
readonly op: 'setFieldCode';
|
|
2029
|
+
readonly paragraphId: string;
|
|
2030
|
+
readonly fieldNodeId: string;
|
|
2031
|
+
readonly code: string;
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
type InsertTextOp = {
|
|
2035
|
+
readonly op: 'insertText';
|
|
2036
|
+
readonly paragraphId: string;
|
|
2037
|
+
/** Legacy text form identity for protected filling; never an inline wrapper owner. */
|
|
2038
|
+
readonly textFormFieldId?: string;
|
|
2039
|
+
readonly offset: number;
|
|
2040
|
+
readonly text: string;
|
|
2041
|
+
/**
|
|
2042
|
+
* Write this as a TRACKED insertion, attributed here.
|
|
2043
|
+
*
|
|
2044
|
+
* On the op rather than on the store, so suggesting stays a decision the surface makes
|
|
2045
|
+
* per edit and the write vocabulary stays explicit — a global "everything is tracked
|
|
2046
|
+
* now" flag is exactly what `DocEdits` refuses, because it makes the meaning of an op
|
|
2047
|
+
* depend on state the op does not carry.
|
|
2048
|
+
*/
|
|
2049
|
+
readonly revision?: RevisionAttributionInput;
|
|
2050
|
+
/**
|
|
2051
|
+
* When set, the text belongs INSIDE this content control, whatever sits at the offset.
|
|
2052
|
+
*
|
|
2053
|
+
* A boundary offset is owned by the run that starts there, which at a control's trailing
|
|
2054
|
+
* edge is the run after the control — so an offset alone cannot say "append to this field",
|
|
2055
|
+
* the way it cannot say which run of a field result to format (see `targetRunIds`). A
|
|
2056
|
+
* caller that names the control gets the text in the control; one that does not gets the
|
|
2057
|
+
* plain offset rule, which is what a keystroke beside a field means.
|
|
2058
|
+
*/
|
|
2059
|
+
readonly inside?: string;
|
|
2060
|
+
/**
|
|
2061
|
+
* Which side of a run BOUNDARY the text joins. Default `'left'` — Word's typing rule:
|
|
2062
|
+
* the next character takes the formatting of the character before the caret.
|
|
2063
|
+
*
|
|
2064
|
+
* `'right'` is for a caller that is not typing but placing text inside the run that
|
|
2065
|
+
* STARTS at the offset — the hyperlink editor rewriting a link's display text, where
|
|
2066
|
+
* landing left of the boundary would put the new text outside the link. Ignored when
|
|
2067
|
+
* the offset falls strictly inside a run, which has no boundary to choose.
|
|
2068
|
+
*/
|
|
2069
|
+
readonly bias?: 'left' | 'right';
|
|
2070
|
+
};
|
|
2071
|
+
type DeleteTextOp = {
|
|
2072
|
+
readonly op: 'deleteText';
|
|
2073
|
+
readonly paragraphId: string;
|
|
2074
|
+
/** Legacy text form identity for protected filling; never an inline wrapper owner. */
|
|
2075
|
+
readonly textFormFieldId?: string;
|
|
2076
|
+
readonly start: number;
|
|
2077
|
+
readonly end: number;
|
|
2078
|
+
/** Write this as a TRACKED deletion — the characters stay, wrapped in `w:del`. */
|
|
2079
|
+
readonly revision?: RevisionAttributionInput;
|
|
2080
|
+
};
|
|
2081
|
+
|
|
2082
|
+
/** Editable legacy text input types. Other authored types remain inert. */
|
|
2083
|
+
type TextFormFieldType = 'regular' | 'number' | 'date';
|
|
2084
|
+
/** Options stored in the legacy field definition. Zero means unlimited length. */
|
|
2085
|
+
interface TextFormFieldOptions {
|
|
2086
|
+
readonly type: TextFormFieldType;
|
|
2087
|
+
readonly maxLength: number;
|
|
2088
|
+
readonly format: string;
|
|
2089
|
+
readonly enabled: boolean;
|
|
1722
2090
|
}
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
readonly
|
|
1726
|
-
readonly
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
readonly
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
2091
|
+
/** Supported format choices for legacy text input fields. @public */
|
|
2092
|
+
declare const TEXT_FORM_FORMATS: {
|
|
2093
|
+
readonly regular: readonly ['', 'Uppercase', 'Lowercase', 'First capital', 'Title case'];
|
|
2094
|
+
readonly number: readonly ['', '0', '0.00', '#,##0', '#,##0.00', '0%', '0.00%'];
|
|
2095
|
+
readonly date: readonly ['', 'M/d/yyyy', 'MM/dd/yyyy', 'd/M/yyyy', 'dd/MM/yyyy', 'yyyy-MM-dd', 'd MMMM yyyy', 'MMMM d, yyyy'];
|
|
2096
|
+
};
|
|
2097
|
+
|
|
2098
|
+
/** A legacy text input in the shared paragraph offset space. */
|
|
2099
|
+
interface TextFormFieldRange {
|
|
2100
|
+
readonly fieldNodeId: string;
|
|
2101
|
+
readonly start: number;
|
|
2102
|
+
readonly end: number;
|
|
2103
|
+
readonly enabled: boolean;
|
|
2104
|
+
readonly defaultText: string;
|
|
2105
|
+
readonly type: string;
|
|
2106
|
+
readonly maxLength: number;
|
|
2107
|
+
readonly format: string;
|
|
2108
|
+
readonly chromeIds: readonly string[];
|
|
1737
2109
|
}
|
|
1738
|
-
/**
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
*/
|
|
1744
|
-
|
|
1745
|
-
readonly
|
|
1746
|
-
readonly
|
|
1747
|
-
readonly
|
|
1748
|
-
readonly
|
|
2110
|
+
/** Uses the field parser and offset index; never introduces another inline walk. */
|
|
2111
|
+
declare function textFormFieldsOf(paragraph: OoxmlParagraphNode): readonly TextFormFieldRange[];
|
|
2112
|
+
/** Options edit for an existing legacy text form. */
|
|
2113
|
+
interface SetTextFormFieldDefaultOp {
|
|
2114
|
+
readonly op: 'setTextFormFieldDefault';
|
|
2115
|
+
/** Regional conventions for new date input; defaults to en-US. */
|
|
2116
|
+
readonly locale?: string;
|
|
2117
|
+
readonly paragraphId: string;
|
|
2118
|
+
readonly fieldNodeId: string;
|
|
2119
|
+
readonly text: string;
|
|
2120
|
+
readonly options?: TextFormFieldOptions;
|
|
1749
2121
|
}
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
readonly
|
|
1753
|
-
|
|
1754
|
-
readonly
|
|
2122
|
+
/** Validate and format the existing result when a user finishes filling a field. */
|
|
2123
|
+
interface CommitTextFormFieldOp {
|
|
2124
|
+
readonly op: 'commitTextFormField';
|
|
2125
|
+
/** Regional conventions for new date input; defaults to en-US. */
|
|
2126
|
+
readonly locale?: string;
|
|
2127
|
+
readonly paragraphId: string;
|
|
2128
|
+
readonly fieldNodeId: string;
|
|
1755
2129
|
}
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
*/
|
|
1767
|
-
readonly mode?: 'frame' | 'simple';
|
|
1768
|
-
readonly horizontalEmu?: number;
|
|
1769
|
-
readonly verticalEmu?: number;
|
|
1770
|
-
readonly relativeToH?: DrawingHorizontalReferenceFrame;
|
|
1771
|
-
readonly relativeToV?: DrawingVerticalReferenceFrame;
|
|
2130
|
+
|
|
2131
|
+
/** One FORMCHECKBOX in the shared paragraph offset space. */
|
|
2132
|
+
interface LegacyCheckboxFieldRange {
|
|
2133
|
+
/** The begin `w:fldChar` node: what the op addresses. */
|
|
2134
|
+
readonly fieldNodeId: string;
|
|
2135
|
+
readonly start: number;
|
|
2136
|
+
readonly end: number;
|
|
2137
|
+
readonly checked: boolean;
|
|
2138
|
+
/** `w:enabled` under `w:ffData`; a disabled field renders but refuses the toggle. */
|
|
2139
|
+
readonly enabled: boolean;
|
|
1772
2140
|
}
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
readonly
|
|
1776
|
-
readonly
|
|
1777
|
-
readonly
|
|
1778
|
-
readonly
|
|
1779
|
-
readonly name: string;
|
|
1780
|
-
readonly title: string;
|
|
1781
|
-
readonly description: string;
|
|
1782
|
-
readonly hyperlinkHref: string | null;
|
|
1783
|
-
readonly hidden: boolean;
|
|
1784
|
-
readonly extentEmu: Readonly<{
|
|
1785
|
-
cx: number;
|
|
1786
|
-
cy: number;
|
|
1787
|
-
}>;
|
|
1788
|
-
readonly effectExtentEmu: Readonly<{
|
|
1789
|
-
top: number;
|
|
1790
|
-
right: number;
|
|
1791
|
-
bottom: number;
|
|
1792
|
-
left: number;
|
|
1793
|
-
}>;
|
|
1794
|
-
readonly inlineDistancesEmu: Readonly<{
|
|
1795
|
-
top: number;
|
|
1796
|
-
right: number;
|
|
1797
|
-
bottom: number;
|
|
1798
|
-
left: number;
|
|
1799
|
-
}>;
|
|
1800
|
-
readonly wrap: ImageWrapTarget;
|
|
1801
|
-
readonly wrapGeometry: DrawingWrapProjection | null;
|
|
1802
|
-
readonly position: DrawingPositionProjection | null;
|
|
1803
|
-
readonly anchor: Readonly<{
|
|
1804
|
-
simplePos: boolean;
|
|
1805
|
-
relativeHeight: number;
|
|
1806
|
-
behindDocument: boolean;
|
|
1807
|
-
layoutInCell: boolean;
|
|
1808
|
-
allowOverlap: boolean;
|
|
1809
|
-
}> | null;
|
|
1810
|
-
readonly picture: PictureProjection | null;
|
|
1811
|
-
readonly vectorShape: VectorShapeProjection | null;
|
|
1812
|
-
/** The picture member of a `wpg:wgp` group; `picture` stays null for a group. */
|
|
1813
|
-
readonly groupPicture: GroupPictureProjection | null;
|
|
1814
|
-
readonly textboxStory: TextboxStoryProjection | null;
|
|
1815
|
-
/** Text box members of a `wpg:wgp` group, laid out read-only; absent when none has text. */
|
|
1816
|
-
readonly groupTextboxes?: readonly GroupTextboxProjection[];
|
|
1817
|
-
/** Read-only preview of the supported native VML subset; the canonical XML is untouched. */
|
|
1818
|
-
readonly legacyGraphic?: LegacyGraphicProjection;
|
|
1819
|
-
readonly locks: DrawingLocks;
|
|
1820
|
-
readonly effects: DrawingImageEffects;
|
|
1821
|
-
readonly compatibilityBranchNodeId: string | null;
|
|
1822
|
-
readonly diagnostics: readonly DrawingDiagnostic[];
|
|
1823
|
-
/** Layout-only wrap area of an MC payload that cannot paint (`wrapFootprintProjection`). */
|
|
1824
|
-
readonly footprintOnly?: true;
|
|
2141
|
+
/** Flip a FORMCHECKBOX's state; the only write into `w:ffData` a checkbox permits. */
|
|
2142
|
+
interface SetLegacyCheckboxOp {
|
|
2143
|
+
readonly op: 'setLegacyCheckbox';
|
|
2144
|
+
readonly paragraphId: string;
|
|
2145
|
+
readonly fieldNodeId: string;
|
|
2146
|
+
readonly checked: boolean;
|
|
1825
2147
|
}
|
|
1826
|
-
|
|
2148
|
+
/** Every FORMCHECKBOX in a paragraph, in document order; uses the shared field parser. */
|
|
2149
|
+
declare function legacyCheckboxFieldsOf(paragraph: OoxmlParagraphNode): readonly LegacyCheckboxFieldRange[];
|
|
2150
|
+
|
|
2151
|
+
/** Replace a building block gallery control's content with one block's body. */
|
|
2152
|
+
interface InsertBuildingBlockOp {
|
|
2153
|
+
readonly op: 'insertBuildingBlock';
|
|
2154
|
+
readonly controlId: string;
|
|
2155
|
+
/** `w:docPartPr/w:name` of the picked block, for the journal and the host. */
|
|
2156
|
+
readonly name: string;
|
|
1827
2157
|
/**
|
|
1828
|
-
*
|
|
1829
|
-
*
|
|
2158
|
+
* Self-contained `w:docPartBody` children, cloned with fresh ids at apply.
|
|
2159
|
+
* Resource, style, field, bookmark, note and revision references return `unsupported`.
|
|
1830
2160
|
*/
|
|
1831
|
-
readonly
|
|
1832
|
-
readonly decorative: boolean;
|
|
1833
|
-
readonly label: string | null;
|
|
1834
|
-
}
|
|
1835
|
-
interface DrawingPositionProjection {
|
|
1836
|
-
readonly simplePosition: Readonly<{
|
|
1837
|
-
xEmu: number;
|
|
1838
|
-
yEmu: number;
|
|
1839
|
-
}>;
|
|
1840
|
-
readonly horizontal: Readonly<{
|
|
1841
|
-
relativeFrom: DrawingHorizontalReferenceFrame;
|
|
1842
|
-
align: string | null;
|
|
1843
|
-
offsetEmu: number | null;
|
|
1844
|
-
}>;
|
|
1845
|
-
readonly vertical: Readonly<{
|
|
1846
|
-
relativeFrom: DrawingVerticalReferenceFrame;
|
|
1847
|
-
align: string | null;
|
|
1848
|
-
offsetEmu: number | null;
|
|
1849
|
-
}>;
|
|
2161
|
+
readonly blocks: readonly OoxmlNode[];
|
|
1850
2162
|
}
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
readonly
|
|
1855
|
-
|
|
1856
|
-
right: number;
|
|
1857
|
-
bottom: number;
|
|
1858
|
-
left: number;
|
|
1859
|
-
}>;
|
|
1860
|
-
readonly polygon: readonly Readonly<{
|
|
1861
|
-
x: number;
|
|
1862
|
-
y: number;
|
|
1863
|
-
}>[];
|
|
2163
|
+
|
|
2164
|
+
/** A text position in the op's part. */
|
|
2165
|
+
interface BookmarkOpPosition {
|
|
2166
|
+
readonly paragraphId: string;
|
|
2167
|
+
readonly offset: number;
|
|
1864
2168
|
}
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
2169
|
+
/**
|
|
2170
|
+
* Add a bookmark around `start`..`end`, or at one point when the two are equal.
|
|
2171
|
+
*
|
|
2172
|
+
* The name must pass `bookmarkNameProblem`. A bookmark the part already declares under the
|
|
2173
|
+
* same name, compared without case, is removed in the same op.
|
|
2174
|
+
*/
|
|
2175
|
+
interface InsertBookmarkOp {
|
|
2176
|
+
readonly op: 'insertBookmark';
|
|
2177
|
+
readonly name: string;
|
|
2178
|
+
readonly start: BookmarkOpPosition;
|
|
2179
|
+
readonly end: BookmarkOpPosition;
|
|
1872
2180
|
}
|
|
1873
2181
|
/**
|
|
1874
|
-
*
|
|
2182
|
+
* Remove every marker pair that declares this name, compared without case. The name is the
|
|
2183
|
+
* one the file declares, so it is not held to the authoring rules.
|
|
1875
2184
|
*
|
|
1876
|
-
*
|
|
1877
|
-
*
|
|
1878
|
-
*
|
|
2185
|
+
* With `keepFirst`, remove only the copies: the pair `listBookmarks` answers for the name
|
|
2186
|
+
* stays where it is. Refused when the part holds no copy. Two collaborators who both remove
|
|
2187
|
+
* the copies remove the same nodes, so their edits converge on one bookmark.
|
|
1879
2188
|
*/
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
}
|
|
2189
|
+
interface DeleteBookmarkOp {
|
|
2190
|
+
readonly op: 'deleteBookmark';
|
|
2191
|
+
readonly name: string;
|
|
2192
|
+
readonly keepFirst?: boolean;
|
|
2193
|
+
/** @internal Limit a text deletion to one enclosed pair; explicit name deletion omits this. */
|
|
2194
|
+
readonly pair?: {
|
|
2195
|
+
readonly startNodeId: string;
|
|
2196
|
+
readonly endNodeId: string;
|
|
2197
|
+
};
|
|
2198
|
+
}
|
|
2199
|
+
/**
|
|
2200
|
+
* The package with every bookmark of this name removed from one part, for moving a name out
|
|
2201
|
+
* of another story inside the same transaction. The package is unchanged when that part does
|
|
2202
|
+
* not declare the name. Protected markers refuse the whole package transaction.
|
|
2203
|
+
*/
|
|
2204
|
+
declare function withoutBookmarkInPart(pkg: OoxmlPackage, partName: string, name: string): OoxmlPackage;
|
|
2205
|
+
/**
|
|
2206
|
+
* The `deleteBookmark` ops for the bookmarks an untracked deletion of `from`..`to` encloses,
|
|
2207
|
+
* for a deletion that crosses paragraphs. `order` lists the part's paragraph ids in document
|
|
2208
|
+
* order. A range bookmark goes when the deletion covers it edge to edge; a point bookmark goes
|
|
2209
|
+
* when it is strictly inside. Applied before the text ops, so they find nothing left to drop.
|
|
2210
|
+
*/
|
|
2211
|
+
declare function enclosedBookmarkDeletions(part: OoxmlPart, from: BookmarkOpPosition, to: BookmarkOpPosition, order: readonly string[]): readonly DeleteBookmarkOp[];
|
|
1889
2212
|
|
|
1890
2213
|
/** The `w15` namespace: `commentsExtended.xml` — thread parent and resolved state. */
|
|
1891
2214
|
declare const W15_NAMESPACE_URI = "http://schemas.microsoft.com/office/word/2012/wordml";
|
|
@@ -2864,8 +3187,9 @@ interface RunFormatting {
|
|
|
2864
3187
|
/**
|
|
2865
3188
|
* Line spacing at the selection, in the unit its rule implies — LINES for `multiple`,
|
|
2866
3189
|
* points for `exact` and `atLeast`. The same vocabulary `setLineSpacing` takes, so a
|
|
2867
|
-
* control can show what it reads and send back what it shows.
|
|
2868
|
-
*
|
|
3190
|
+
* control can show what it reads and send back what it shows. The effective value: a
|
|
3191
|
+
* paragraph whose cascade states none reads as single spacing (`multiple`, 1). Absent
|
|
3192
|
+
* when the selection's paragraphs disagree.
|
|
2869
3193
|
*/
|
|
2870
3194
|
readonly lineSpacing?: {
|
|
2871
3195
|
readonly rule: 'multiple' | 'exact' | 'atLeast';
|
|
@@ -3174,10 +3498,72 @@ interface Theme {
|
|
|
3174
3498
|
}
|
|
3175
3499
|
/** Theme colour slots (`accent1`, `dk1`, `lt2`, …) to hex. */
|
|
3176
3500
|
type ThemeColorScheme = Readonly<Record<string, string>>;
|
|
3177
|
-
/**
|
|
3501
|
+
/**
|
|
3502
|
+
* A document watermark: text or a picture drawn behind the text of every page.
|
|
3503
|
+
*
|
|
3504
|
+
* Set `text` for a text watermark or `imageData` for a picture watermark, never both. Omitted
|
|
3505
|
+
* options take the defaults in each field's description. The watermark goes into every header
|
|
3506
|
+
* the document shows; a section with no header gets one.
|
|
3507
|
+
*
|
|
3508
|
+
* Text options apply only with `text`; `scale` and `washout` apply only with `imageData`.
|
|
3509
|
+
* `setWatermark` refuses a mixed or out-of-range value with `invalidArgs` and a reason naming
|
|
3510
|
+
* the field, and writes nothing.
|
|
3511
|
+
*
|
|
3512
|
+
* @example
|
|
3513
|
+
* ```ts
|
|
3514
|
+
* // A red, horizontal text watermark at 72pt.
|
|
3515
|
+
* editor.exec({
|
|
3516
|
+
* type: 'setWatermark',
|
|
3517
|
+
* watermark: { text: 'CONFIDENTIAL', color: 'C00000', fontSizePt: 72, layout: 'horizontal' },
|
|
3518
|
+
* });
|
|
3519
|
+
* // A washed-out picture watermark at its natural size.
|
|
3520
|
+
* editor.exec({ type: 'setWatermark', watermark: { imageData: pngBytes, scale: 1 } });
|
|
3521
|
+
* ```
|
|
3522
|
+
*/
|
|
3178
3523
|
interface Watermark {
|
|
3524
|
+
/** The text of a text watermark, up to 256 characters on one line. */
|
|
3179
3525
|
readonly text?: string;
|
|
3526
|
+
/** The PNG, JPEG, GIF, BMP or WebP bytes of a picture watermark. */
|
|
3180
3527
|
readonly imageData?: Uint8Array;
|
|
3528
|
+
/** Text: the font family. Defaults to `Calibri`. */
|
|
3529
|
+
readonly fontFamily?: string;
|
|
3530
|
+
/** Text: the size in points, from 1 to 1000. Omitted or null is Auto, which fills the page. */
|
|
3531
|
+
readonly fontSizePt?: number | null;
|
|
3532
|
+
/** Text: bold. Defaults to false. */
|
|
3533
|
+
readonly bold?: boolean;
|
|
3534
|
+
/** Text: italic. Defaults to false. */
|
|
3535
|
+
readonly italic?: boolean;
|
|
3536
|
+
/** Text: the colour as `RRGGBB`. Defaults to `C0C0C0` (silver). */
|
|
3537
|
+
readonly color?: string;
|
|
3538
|
+
/** Text: transparency from 0 (opaque) to 1. Defaults to 0.5. */
|
|
3539
|
+
readonly transparency?: number;
|
|
3540
|
+
/** Text: the orientation. Defaults to `diagonal`. */
|
|
3541
|
+
readonly layout?: WatermarkLayout;
|
|
3542
|
+
/** Picture: a factor of the picture's natural size. Omitted or null is Auto, which fits the page. */
|
|
3543
|
+
readonly scale?: number | null;
|
|
3544
|
+
/** Picture: lighten the picture so text over it stays readable. Defaults to true. */
|
|
3545
|
+
readonly washout?: boolean;
|
|
3546
|
+
}
|
|
3547
|
+
/** How a text watermark crosses the page. */
|
|
3548
|
+
type WatermarkLayout = 'diagonal' | 'horizontal';
|
|
3549
|
+
/**
|
|
3550
|
+
* The watermark a document shows, as `Editor.getWatermark()` reads it.
|
|
3551
|
+
*
|
|
3552
|
+
* The text fields are present for a text watermark, `washout` for a picture watermark.
|
|
3553
|
+
*/
|
|
3554
|
+
interface WatermarkState {
|
|
3555
|
+
readonly kind: 'text' | 'image';
|
|
3556
|
+
readonly text?: string;
|
|
3557
|
+
readonly fontFamily?: string;
|
|
3558
|
+
/** Null for Auto size. */
|
|
3559
|
+
readonly fontSizePt?: number | null;
|
|
3560
|
+
readonly bold?: boolean;
|
|
3561
|
+
readonly italic?: boolean;
|
|
3562
|
+
/** `RRGGBB`. */
|
|
3563
|
+
readonly color?: string;
|
|
3564
|
+
readonly transparency?: number;
|
|
3565
|
+
readonly layout?: WatermarkLayout;
|
|
3566
|
+
readonly washout?: boolean;
|
|
3181
3567
|
}
|
|
3182
3568
|
/** A size in EMUs, the unit DrawingML stores extents in. 914400 EMU = 1 inch. */
|
|
3183
3569
|
interface Extent {
|
|
@@ -3907,6 +4293,10 @@ type TreeDocOp = SetFieldCodeOp | {
|
|
|
3907
4293
|
*/
|
|
3908
4294
|
readonly op: 'setDocumentProtection';
|
|
3909
4295
|
readonly enforce: boolean;
|
|
4296
|
+
} | {
|
|
4297
|
+
/** Replace the watermark in every header a section shows; null removes it. Package-level. */
|
|
4298
|
+
readonly op: 'setWatermark';
|
|
4299
|
+
readonly watermark: PackageWatermarkWrite | null;
|
|
3910
4300
|
} | {
|
|
3911
4301
|
/**
|
|
3912
4302
|
* Insert a footnote or endnote: body reference + notes-part body (+ create the
|
|
@@ -4110,7 +4500,7 @@ type TreeDocOp = SetFieldCodeOp | {
|
|
|
4110
4500
|
readonly paragraphId: string;
|
|
4111
4501
|
readonly pageNumberText: string;
|
|
4112
4502
|
}[];
|
|
4113
|
-
} | SetTextFormFieldDefaultOp | CommitTextFormFieldOp | SetLegacyCheckboxOp | SetLegacyDropdownOp | InsertBuildingBlockOp | {
|
|
4503
|
+
} | SetTextFormFieldDefaultOp | CommitTextFormFieldOp | SetLegacyCheckboxOp | SetLegacyDropdownOp | InsertBuildingBlockOp | InsertBookmarkOp | DeleteBookmarkOp | {
|
|
4114
4504
|
/**
|
|
4115
4505
|
* Rewrite recognized fields' cached RESULT runs in place — between the `separate` and
|
|
4116
4506
|
* `end` fldChars, or a `w:fldSimple`'s content. The instruction is never modified; a
|
|
@@ -4210,6 +4600,11 @@ type TreeOpRejection = 'unknown-op' | 'unknown-paragraph' | 'not-a-paragraph' |
|
|
|
4210
4600
|
* pointing at a part nobody created, or a part with no declared content type.
|
|
4211
4601
|
*/
|
|
4212
4602
|
| 'package-invariant'
|
|
4603
|
+
/**
|
|
4604
|
+
* A package edit refused the package it was given, for example because an id or part name it
|
|
4605
|
+
* expected to allocate is taken or a definition it addresses changed. Nothing was applied.
|
|
4606
|
+
*/
|
|
4607
|
+
| 'package-changed'
|
|
4213
4608
|
/** No revision in this part carries the addressed `(id, author, date)` triple. */
|
|
4214
4609
|
| 'unknown-revision'
|
|
4215
4610
|
/**
|
|
@@ -4217,7 +4612,13 @@ type TreeOpRejection = 'unknown-op' | 'unknown-paragraph' | 'not-a-paragraph' |
|
|
|
4217
4612
|
* implemented. Refusing is deliberate: removing the markup alone would report the decision
|
|
4218
4613
|
* applied while leaving the row, cell, or section it describes untouched.
|
|
4219
4614
|
*/
|
|
4220
|
-
| 'unsupported-revision'
|
|
4615
|
+
| 'unsupported-revision'
|
|
4616
|
+
/**
|
|
4617
|
+
* A tracked insertion would land inside a link, content control, or other container within
|
|
4618
|
+
* another author's pending insertion. The container cannot split, and nested words would
|
|
4619
|
+
* become part of that author's proposal.
|
|
4620
|
+
*/
|
|
4621
|
+
| 'unsupported-revision:foreign-insertion' | 'tree-invariant'
|
|
4221
4622
|
/** No content control in this part carries the addressed node id. */
|
|
4222
4623
|
| 'unknown-content-control'
|
|
4223
4624
|
/** The addressed node exists and is not a `w:sdt`. */
|
|
@@ -4286,5 +4687,5 @@ type TreeOpResult = {
|
|
|
4286
4687
|
readonly detail?: string;
|
|
4287
4688
|
};
|
|
4288
4689
|
|
|
4289
|
-
export {
|
|
4290
|
-
export type { DrawingVerticalReferenceFrame as $, ParagraphTabStop as A, Block as B, CommentRecord as C, DocxDocument as D, ExecResult as E, RevisionType as F, Section as G, HeaderFooterSet as H, InsertableContentControlType as I, SectionProperties as J, StyleDefinition as K, Theme as L, ThemeColorScheme as M, OoxmlNode as N, OoxmlPart as O, Paragraph as P, OoxmlPackage as Q, ReviewModelInput as R, StyleDefinitions as S, Table as T, OoxmlNodeId as U, OoxmlGenericElementNode as V, DocxDocumentJSON as W, DrawingHorizontalReferenceFrame as X, DrawingKind as Y, DrawingLocks as Z, DrawingPositionInput as _, ReviewItem as a,
|
|
4690
|
+
export { validateRasterHeader as a$, DEFAULT_IMAGE_RESOURCE_LIMITS as aV, IMAGE_WRAP_TARGETS as aW, TEXT_FORM_FORMATS as aX, resolveImageResourceLimits as aY, resolveSvgIntrinsicSize as aZ, sniffImageMime as a_, DEFAULT_LIMITS as bF, DEFAULT_OOXML_PACKAGE_LIMITS as bG, DEFAULT_ZIP_LIMITS as bH, HARD_CEILINGS as bL, HYPERLINK_RELATIONSHIP_TYPE as bM, IMAGE_RELATIONSHIP_TYPE as bP, IMAGE_RESOURCE_HARD_CEILINGS as bQ, MAX_CONTENT_CONTROLS_PER_PART as bY, MAX_CONTENT_CONTROL_NESTING as bZ, MAX_SVG_SNIFF_BYTES as b_, ACCEPTED_PARAGRAPH_PROPERTIES as bj, ACCEPTED_RUN_PROPERTIES as bk, CONTENT_CONTROL_ID_MAX as bm, CONTENT_CONTROL_PROPERTY_ORDER as bn, OFFICE_RELATIONSHIP_NAMESPACE_URI as c1, OOXML_NODE_IDENTITY_RULES as c2, TABLE_BORDER_STYLES as cO, W15_NAMESPACE_URI as cV, WML_NAMESPACE_URI as cW, XMLNS_NAMESPACE_URI as cX, XML_NAMESPACE_URI as cY, reviewItemKey as d$, allocateContentControlId as d4, asciiFold as d5, buildContentTypeIndex as d6, buildRelationshipSet as d7, childElements as d8, commentAnchorsOfStory as d9, isContentControlWrapper as dA, isContentRevisionKind as dB, isHyperlinkNode as dC, isRangeMarkerKind as dD, isValidMime as dE, legacyCheckboxFieldsOf as dF, liveDrawingReferenceCount as dG, lockForbidsEdit as dH, lockForbidsRemoval as dI, normalizePartName as dJ, orderedContentControlProperties as dK, parseContentControlId as dL, partNameKey as dM, planRevisionAuthorChange as dN, planRevisionBatch as dO, projectDrawing as dP, readOnOffChild as dQ, readOoxmlPackage as dR, readOoxmlPart as dS, readXml as dT, readZip as dU, resolveContentControlLock as dV, resolveContentType as dW, resolveImageRelationship as dX, resolveInternalTarget as dY, resolveLimits as dZ, resolveRelationship as d_, commentsOfPart as da, contentControlContentChildren as db, contentControlContentNodeOf as dc, contentControlEndPropertiesNodeOf as dd, contentControlLevelOf as de, contentControlPropertiesNodeOf as df, contentControlPropertiesOf as dg, contentControlTextOf as dh, contentControlsIn as di, createImageResourceCache as dj, detectDuplicateNames as dk, enclosedBookmarkDeletions as dl, extensionKey as dm, findContentControl as dn, findElement as dp, firstReviewRange as dq, flattenContentControls as dr, hasAnyComment as ds, hasBoundedSvgRoot as dt, hyperlinkAnchorOf as du, hyperlinkRelationshipIdOf as dv, hyperlinkTargetOf as dw, imageResourceLookupFor as dx, isContentControlContentNode as dy, isContentControlNode as dz, reviewItemRanges as e0, textContent as e1, textFormFieldsOf as e2, threadStateOfPart as e3, validateExternalTarget as e4, validateGifHeader as e5, validateJpegHeader as e6, validatePngHeader as e7, withPart as e8, withoutBookmarkInPart as e9, writeOoxmlPackage as ea, writeZip as eb, activeReviewItem as ed, reviewItemPositionRank as ee, reviewItemsAt as ef, reviewThreadRootOf as eg };
|
|
4691
|
+
export type { DrawingVerticalReferenceFrame as $, ParagraphTabStop as A, Block as B, CommentRecord as C, DocxDocument as D, ExecResult as E, RevisionType as F, Section as G, HeaderFooterSet as H, InsertableContentControlType as I, SectionProperties as J, StyleDefinition as K, Theme as L, ThemeColorScheme as M, OoxmlNode as N, OoxmlPart as O, Paragraph as P, OoxmlPackage as Q, ReviewModelInput as R, StyleDefinitions as S, Table as T, OoxmlNodeId as U, OoxmlGenericElementNode as V, DocxDocumentJSON as W, DrawingHorizontalReferenceFrame as X, DrawingKind as Y, DrawingLocks as Z, DrawingPositionInput as _, ReviewItem as a, FontDefinition as a0, ImageResourceState as a1, ImageWrapTarget as a2, NumberingRef as a3, PageMargins as a4, ParagraphDisagreements as a5, ParagraphFormatCommand as a6, Point as a7, PreservedImageMime as a8, Rect as a9, RevisionBatchSkipReason as aA, RevisionSiteRefusal as aB, TreeOpRejection as aC, ImageResourceLimits as aD, ImageDecodePort as aE, AutomationTableMutation as aF, RevisionAttributionInput as aG, PackageWatermarkWrite as aH, OoxmlInvariantIssue as aI, DrawingTreeDocOp as aJ, ImpactClass as aK, OoxmlParagraphNode as aL, OoxmlNoteNode as aM, OoxmlContinuationSeparatorNode as aN, OoxmlEndnotesNode as aO, OoxmlFootnotesNode as aP, OoxmlNoteRefNode as aQ, OoxmlNoteReferenceNode as aR, OoxmlSeparatorNode as aS, SourceCrop as aT, TreeDocColorValue as aU, RenderableImageMime as aa, RevisionAuthorResult as ab, RevisionBatchResult as ac, Run as ad, SelectionPin as ae, SupportedImageMime as af, TableCell as ag, TableRow as ah, Unsubscribe as ai, ValidatedImageBytesHandle as aj, VectorImageMime as ak, Watermark as al, WatermarkLayout as am, WatermarkState as an, TreeDocOp as ao, OoxmlElement as ap, OoxmlContentControlNode as aq, OoxmlContentControlContentNode as ar, OoxmlPackageRejection as as, OoxmlProperty as at, OoxmlPackageResult as au, OoxmlPackageLimits as av, RevisionAuthorEntry as aw, RevisionAuthorSkipReason as ax, RevisionBatchEntry as ay, RevisionBatchSkipDetail as az, ReviewRevisionItem as b, NameRejection as b$, TextFormFieldRange as b0, TextFormFieldOptions as b1, DrawingTransform as b2, TableBorderStyle as b3, DrawingAccessibility as b4, DrawingImageEffects as b5, VectorShapeProjection as b6, DrawingProjection as b7, OoxmlDrawingNode as b8, OoxmlInvariantResult as b9, ContentControlProperties as bA, ContentTypeError as bB, ContentTypeIndex as bC, ContentTypeRecords as bD, CreateImageResourceCacheOptions as bE, DefaultRecord as bI, DeleteBookmarkOp as bJ, DeleteTextOp as bK, HyperlinkKind as bN, HyperlinkTarget as bO, ImageRelationshipResolution as bR, ImageResourceLookup as bS, IndexResult as bT, InsertBookmarkOp as bU, InsertBuildingBlockOp as bV, InsertTextOp as bW, LegacyCheckboxFieldRange as bX, OoxmlFldCharNode as ba, OoxmlFldSimpleNode as bb, OoxmlInstrTextNode as bc, TreeOpResult as bd, RelationshipRecord as be, OoxmlHardBreakNode as bf, OoxmlAttribute as bg, ResourceLimits as bh, CommentThreadState as bi, BookmarkOpPosition as bl, CommentAnchor as bo, CommentPosition as bp, CommitTextFormFieldOp as bq, ContentControlCheckbox as br, ContentControlCheckboxState as bs, ContentControlDataBinding as bt, ContentControlDateFormat as bu, ContentControlEntry as bv, ContentControlKind as bw, ContentControlLevel as bx, ContentControlListItem as by, ContentControlLock as bz, ReviewCommentItem as c, XmlRejection as c$, NameResult as c0, OoxmlBodyNode as c3, OoxmlBookmarkEndNode as c4, OoxmlBookmarkStartNode as c5, OoxmlContentControlCalendarNode as c6, OoxmlContentControlCheckboxNode as c7, OoxmlContentControlCheckedNode as c8, OoxmlContentControlCheckedStateNode as c9, OoxmlTabNode as cA, OoxmlTextElementNode as cB, OoxmlTextNode as cC, OoxmlWmlValAttribute as cD, OoxmlXmlSpaceAttribute as cE, OverrideRecord as cF, RelationshipError as cG, RelationshipSetResult as cH, RelationshipTargetResolver as cI, ResolveResult as cJ, ResolvedRelationship as cK, SetLegacyCheckboxOp as cL, SetLegacyDropdownOp as cM, SetTextFormFieldDefaultOp as cN, TabStopWrite as cP, TargetMode as cQ, TextFormFieldType as cR, TreeDocOpKind as cS, TreeOpEffect as cT, ValidatedRasterHeader as cU, XmlLimits as cZ, XmlNode as c_, OoxmlContentControlComboBoxNode as ca, OoxmlContentControlDataBindingNode as cb, OoxmlContentControlDateFormatNode as cc, OoxmlContentControlDateNode as cd, OoxmlContentControlDropDownListNode as ce, OoxmlContentControlEndPropertiesNode as cf, OoxmlContentControlLidNode as cg, OoxmlContentControlListItemNode as ch, OoxmlContentControlPropertiesNode as ci, OoxmlContentControlStoreMappedDataAsNode as cj, OoxmlContentControlTextNode as ck, OoxmlContentControlUncheckedStateNode as cl, OoxmlDocumentNode as cm, OoxmlExternalTarget as cn, OoxmlGenericExtensionAttribute as co, OoxmlHyperlinkNode as cp, OoxmlInvariantIssueCode as cq, OoxmlKnownNodeAttribute as cr, OoxmlNamespaceBinding as cs, OoxmlNodeIdentityRules as ct, OoxmlParagraphPropertiesNode as cu, OoxmlPartMetadata as cv, OoxmlReadRejection as cw, OoxmlReadResult as cx, OoxmlRunNode as cy, OoxmlRunPropertiesNode as cz, ReviewCustomItem as d, XmlResult as d0, ZipLimits as d1, ZipReadResult as d2, ZipRejection as d3, ReviewPosition as e, VectorShapeComponent as ec, ReviewRange as f, ReviewRevisionKind as g, RevisionAddress as h, ContentControlType as i, DocTarget as j, RunFormatting as k, Extent as l, ContainerRef as m, ContentControlFilter as n, DocRange as o, Revision as p, DocComment as q, ColorValue as r, ContentControl as s, DocAnchor as t, DocAnchorRange as u, DocLocation as v, DocumentBody as w, ExecErrorCode as x, IndentFormatting as y, ParagraphFlags as z };
|