@docx-editor.dev/core 2.19.1 → 2.20.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 +10 -9
- package/dist/automation.js +1 -1
- package/dist/binding.cjs +1 -1
- package/dist/binding.d.ts +8 -9
- package/dist/binding.js +1 -1
- package/dist/chunk-2H4ABRMB.cjs +20 -0
- package/dist/{chunk-NIVIC7PA.cjs → chunk-2HQXLL5L.cjs} +1 -1
- package/dist/chunk-3EZO3O6I.js +4 -0
- package/dist/{chunk-GWW5FOLJ.cjs → chunk-44SIVFJT.cjs} +5 -5
- package/dist/chunk-6UCDHGXI.js +1 -0
- package/dist/chunk-7VMVDRRU.js +2 -0
- package/dist/{chunk-2QU7QTM7.js → chunk-CAIWEQLC.js} +1 -1
- package/dist/{chunk-3JKOZBQ3.cjs → chunk-CEXC2VHI.cjs} +1 -1
- package/dist/chunk-CF3JR35B.js +11 -0
- package/dist/chunk-D2V4YBWJ.cjs +2 -0
- package/dist/chunk-DGSJZMAE.cjs +11 -0
- package/dist/chunk-EHBPYFRE.js +20 -0
- package/dist/chunk-GSEUM6AI.cjs +1 -0
- package/dist/chunk-H6WDEAOJ.js +18 -0
- package/dist/chunk-I6LSEDUL.cjs +18 -0
- package/dist/{chunk-3SU7UWCR.js → chunk-IW35GWJN.js} +1 -1
- package/dist/{chunk-BJQDNKEX.js → chunk-JRBGCIR2.js} +4 -4
- package/dist/chunk-K5HIOS6J.cjs +3 -0
- package/dist/chunk-KLQXP27K.js +3 -0
- package/dist/{chunk-RDKPMNN6.cjs → chunk-MZFFU66H.cjs} +1 -1
- package/dist/{chunk-TSDGKNV7.js → chunk-MZPNLIP3.js} +1 -1
- package/dist/{chunk-JWHXOJEU.cjs → chunk-OA6LFCTG.cjs} +2 -2
- package/dist/{chunk-BUNY5MRX.js → chunk-OHVJYJOA.js} +1 -1
- package/dist/{chunk-UOE4WKL7.js → chunk-P4TGGDK3.js} +1 -1
- package/dist/{chunk-7VO6BLKV.cjs → chunk-PIBYJZIH.cjs} +1 -1
- package/dist/{chunk-76F73CY6.cjs → chunk-WTILOUPG.cjs} +1 -1
- package/dist/collaboration/replication.cjs +1 -1
- package/dist/collaboration/replication.d.ts +3 -3
- package/dist/collaboration/replication.js +1 -1
- package/dist/collaboration.d.ts +3 -3
- package/dist/contracts/document.d.ts +2 -2
- package/dist/contracts/editor.d.ts +8 -9
- package/dist/contracts/modules.d.ts +5 -7
- package/dist/contracts/types.d.ts +1 -562
- package/dist/{custom-node-writes-BqIv94ei.d.ts → custom-node-writes-piokwVR5.d.ts} +2 -2
- package/dist/{document-protection-BL5zp8cU.d.ts → document-protection-C6RvCHx-.d.ts} +1 -1
- package/dist/{editor-WXbTSXx1.d.ts → editor-BgtcHulQ.d.ts} +19 -14
- package/dist/editor.cjs +1 -1
- package/dist/editor.css +1 -1
- package/dist/editor.d.ts +25 -27
- package/dist/editor.js +1 -1
- package/dist/export.cjs +2 -2
- package/dist/export.d.ts +12 -13
- package/dist/export.js +1 -1
- package/dist/{font-resolver-BSrKnTeR.d.ts → font-resolver-Bv2Z25-J.d.ts} +1 -1
- package/dist/{headless-document-view-C4ttQJ5H.d.ts → headless-document-view-DHKMN_3Y.d.ts} +2 -2
- package/dist/image-resources-C51LuAAu.d.ts +210 -0
- package/dist/{index-C3As-Xxp.d.ts → index-3lr8xXF8.d.ts} +14 -15
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +17 -18
- package/dist/index.js +1 -1
- package/dist/{layout-shaping-Dqu3JW3p.d.ts → layout-shaping-CKBUSaS7.d.ts} +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.d.ts +48 -19
- package/dist/layout.js +1 -1
- package/dist/{tree-package-fragment-1pdDnhZ_.d.ts → note-lifecycle-D4AOFCAt.d.ts} +142 -141
- package/dist/{note-properties-RjYgbmXe.d.ts → note-properties-CcXUgqr8.d.ts} +2 -2
- package/dist/{omml-equation-hcP9AUFX.d.ts → omml-equation-C5P6Ym3v.d.ts} +1 -1
- package/dist/output.cjs +1 -1
- package/dist/output.d.ts +7 -7
- package/dist/output.js +1 -1
- package/dist/{protocol-OdRd17KZ.d.ts → protocol-CsawNZkt.d.ts} +14 -4
- package/dist/{review-paragraph-order--jLHXIcd.d.ts → review-paragraph-order-BCIqjopY.d.ts} +2 -3
- package/dist/{revision-projection-BIHO_qvw.d.ts → revision-projection-BcRnC4Yj.d.ts} +1 -1
- package/dist/{semantic-cell-selection-lCYAVCCF.d.ts → semantic-cell-selection-R9wrenwR.d.ts} +4 -4
- package/dist/{semantic-interaction-0vQXcMZk.d.ts → semantic-interaction-B7beVwH7.d.ts} +1 -1
- package/dist/{semantic-paint-BSan4pBk.d.ts → semantic-paint-CLvHwf8y.d.ts} +2 -2
- package/dist/{semantic-records-ZcYuB4-H.d.ts → semantic-records-CbXwnS80.d.ts} +5 -4
- package/dist/store.cjs +1 -1
- package/dist/store.d.ts +13 -14
- package/dist/store.js +1 -1
- package/dist/{tree-session-contract-Cgn6fQ-M.d.ts → tree-session-contract-DTQxw2zL.d.ts} +5 -5
- package/dist/{tree-op-types-DbdM7fJV.d.ts → types-barrel-CEOy-Jv0.d.ts} +961 -210
- package/package.json +2 -2
- package/dist/chunk-5BI4SIHO.cjs +0 -1
- package/dist/chunk-6ESSCMXL.js +0 -2
- package/dist/chunk-6W4DIR4X.cjs +0 -2
- package/dist/chunk-AKQRKR2H.js +0 -1
- package/dist/chunk-FBWBSHC4.cjs +0 -11
- package/dist/chunk-IA7WTZHI.js +0 -11
- package/dist/chunk-IXGUCLER.js +0 -20
- package/dist/chunk-NDPLQG4Y.cjs +0 -18
- package/dist/chunk-NLGUL6QL.js +0 -3
- package/dist/chunk-OWUSDS3L.cjs +0 -20
- package/dist/chunk-TUCDPXBD.js +0 -18
- package/dist/chunk-VSCPFHTD.cjs +0 -3
- package/dist/chunk-ZUGTEKLM.js +0 -4
- package/dist/review-items-CJz-kAW8.d.ts +0 -370
|
@@ -1,59 +1,3 @@
|
|
|
1
|
-
import { ParagraphTabStop } from './contracts/types.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The engine's trust-boundary caps: recursion depth, element counts, and the rest.
|
|
5
|
-
*
|
|
6
|
-
* A caller may LOWER any of these but never raise or disable one — an override of `Infinity`,
|
|
7
|
-
* zero, a negative or `NaN` clamps into `(0, ceiling]` rather than turning the limit off. These
|
|
8
|
-
* are security ceilings, not performance budgets.
|
|
9
|
-
*/
|
|
10
|
-
interface ResourceLimits {
|
|
11
|
-
/** Max nested-structure recursion (tables/shapes/SDT/groups). */
|
|
12
|
-
readonly maxRecursionDepth: number;
|
|
13
|
-
/** Max total parsed element count. */
|
|
14
|
-
readonly maxElementCount: number;
|
|
15
|
-
/** Max package part count. */
|
|
16
|
-
readonly maxPartCount: number;
|
|
17
|
-
/** Max total decompressed bytes (zip-bomb guard). */
|
|
18
|
-
readonly maxDecompressedBytes: number;
|
|
19
|
-
/** Max total compressed input bytes. */
|
|
20
|
-
readonly maxCompressedBytes: number;
|
|
21
|
-
/** Max decompressed:compressed ratio per entry. */
|
|
22
|
-
readonly maxCompressionRatio: number;
|
|
23
|
-
/** In-memory chunk budget for streaming/spooling. */
|
|
24
|
-
readonly maxChunkBytes: number;
|
|
25
|
-
/** Max pagination passes before non-convergence is declared. */
|
|
26
|
-
readonly maxPaginationPasses: number;
|
|
27
|
-
/** Max queued items in any bounded work queue. */
|
|
28
|
-
readonly maxQueueDepth: number;
|
|
29
|
-
}
|
|
30
|
-
/** Non-disableable hard ceilings: no resolved limit may exceed these. */
|
|
31
|
-
declare const HARD_CEILINGS: ResourceLimits;
|
|
32
|
-
/** Finite defaults, all <= their hard ceiling. */
|
|
33
|
-
declare const DEFAULT_LIMITS: ResourceLimits;
|
|
34
|
-
/**
|
|
35
|
-
* Resolve caller overrides into a frozen, always-finite limit set. Each value is
|
|
36
|
-
* `min(override>0 ? override : default, ceiling)`. Infinity/0/negative/NaN can
|
|
37
|
-
* never disable a limit — the hard ceiling always wins.
|
|
38
|
-
*/
|
|
39
|
-
declare function resolveLimits(overrides?: Partial<ResourceLimits>): ResourceLimits;
|
|
40
|
-
/** Bounded image decode limits (typed-drawings-and-images task 4). */
|
|
41
|
-
/** Trust-boundary caps specific to image decoding and embedding. */
|
|
42
|
-
interface ImageResourceLimits {
|
|
43
|
-
readonly maxEncodedBytes: number;
|
|
44
|
-
readonly maxDecodedBytes: number;
|
|
45
|
-
readonly maxPixels: number;
|
|
46
|
-
readonly maxDimension: number;
|
|
47
|
-
readonly maxPolygonPoints: number;
|
|
48
|
-
readonly maxExternalRedirects: number;
|
|
49
|
-
}
|
|
50
|
-
/** Image caps nothing can raise past. A caller's override clamps into these. */
|
|
51
|
-
declare const IMAGE_RESOURCE_HARD_CEILINGS: ImageResourceLimits;
|
|
52
|
-
/** The image caps in force when a host configures none. Conservative and finite. */
|
|
53
|
-
declare const DEFAULT_IMAGE_RESOURCE_LIMITS: ImageResourceLimits;
|
|
54
|
-
/** Resolve caller overrides into frozen image limits; hard ceilings cannot be raised. */
|
|
55
|
-
declare function resolveImageResourceLimits(overrides?: Partial<ImageResourceLimits>): ImageResourceLimits;
|
|
56
|
-
|
|
57
1
|
/**
|
|
58
2
|
* Why a part or relationship name was refused.
|
|
59
3
|
*
|
|
@@ -1573,159 +1517,6 @@ declare function projectDrawing(drawing: OoxmlDrawingNode, context: Readonly<{
|
|
|
1573
1517
|
resolveStyleMatrixReference?: ShapeStyleMatrixResolver;
|
|
1574
1518
|
}>): DrawingProjection | null;
|
|
1575
1519
|
|
|
1576
|
-
/** Opaque handle — bytes are reachable only through {@link mintValidatedImageBytes}. */
|
|
1577
|
-
interface ValidatedImageBytesHandle {
|
|
1578
|
-
readonly registryId: number;
|
|
1579
|
-
readonly resourceKey: string;
|
|
1580
|
-
readonly contentId: string;
|
|
1581
|
-
readonly generation: number;
|
|
1582
|
-
}
|
|
1583
|
-
|
|
1584
|
-
/**
|
|
1585
|
-
* Raster media the decode port measures and any authoring path may write.
|
|
1586
|
-
*
|
|
1587
|
-
* BMP and WebP are here for the same reason the other three are: an `<img>` decodes them
|
|
1588
|
-
* natively, so they need a signature and a structural header and nothing else. BMP is what
|
|
1589
|
-
* older documents carry; WebP is what current Word writes.
|
|
1590
|
-
*/
|
|
1591
|
-
type SupportedImageMime = 'image/png' | 'image/jpeg' | 'image/gif' | 'image/bmp' | 'image/webp';
|
|
1592
|
-
/**
|
|
1593
|
-
* Vector media painted straight from validated bytes. An `<img>` renders SVG in the
|
|
1594
|
-
* browser's secure static mode — no script, no external subresource loads — so there is
|
|
1595
|
-
* no decode step and no raster buffer sized by a file-supplied number.
|
|
1596
|
-
*/
|
|
1597
|
-
type VectorImageMime = 'image/svg+xml';
|
|
1598
|
-
/** Every mime the painter can hand to an `<img>`. */
|
|
1599
|
-
type RenderableImageMime = SupportedImageMime | VectorImageMime;
|
|
1600
|
-
/**
|
|
1601
|
-
* Media kept in the package byte-for-byte that the painter cannot hand to an `<img>`.
|
|
1602
|
-
* A decode port may rasterize it; without one it paints as a labelled placeholder.
|
|
1603
|
-
*/
|
|
1604
|
-
type PreservedImageMime = 'image/tiff' | 'image/x-emf' | 'image/x-wmf';
|
|
1605
|
-
/**
|
|
1606
|
-
* What is known about one embedded image: validated, refused, or still decoding.
|
|
1607
|
-
*
|
|
1608
|
-
* Content type is a CLAIM. Signature sniffing, structural header validation and the decode port
|
|
1609
|
-
* are authoritative, and bytes that fail them never enter public state.
|
|
1610
|
-
*/
|
|
1611
|
-
type ImageResourceState = {
|
|
1612
|
-
readonly kind: 'ready';
|
|
1613
|
-
readonly partName: string;
|
|
1614
|
-
readonly contentId: string;
|
|
1615
|
-
readonly resourceKey: string;
|
|
1616
|
-
readonly validatedHandle: ValidatedImageBytesHandle;
|
|
1617
|
-
readonly mime: RenderableImageMime;
|
|
1618
|
-
readonly pixelWidth: number;
|
|
1619
|
-
readonly pixelHeight: number;
|
|
1620
|
-
readonly dpiX: number;
|
|
1621
|
-
readonly dpiY: number;
|
|
1622
|
-
} | {
|
|
1623
|
-
readonly kind: 'unrenderable';
|
|
1624
|
-
readonly partName: string | null;
|
|
1625
|
-
readonly mime: RenderableImageMime | PreservedImageMime | 'unknown';
|
|
1626
|
-
readonly reason: 'unsupported-format' | 'non-picture-graphic' | 'signature-mismatch' | 'decode-failed' | 'resource-limit';
|
|
1627
|
-
} | {
|
|
1628
|
-
readonly kind: 'external';
|
|
1629
|
-
readonly relationshipId: string;
|
|
1630
|
-
readonly sinkSafe: boolean;
|
|
1631
|
-
} | {
|
|
1632
|
-
readonly kind: 'missing';
|
|
1633
|
-
readonly relationshipId: string;
|
|
1634
|
-
} | {
|
|
1635
|
-
readonly kind: 'pending';
|
|
1636
|
-
readonly resourceKey: string;
|
|
1637
|
-
};
|
|
1638
|
-
/**
|
|
1639
|
-
* The injected image decoder.
|
|
1640
|
-
*
|
|
1641
|
-
* A port rather than a direct `Image`/`createImageBitmap` call, so a worker or server runtime
|
|
1642
|
-
* supplies its own and the engine never reaches for a browser global.
|
|
1643
|
-
*/
|
|
1644
|
-
interface ImageDecodePort {
|
|
1645
|
-
decode(bytes: Uint8Array, mime: SupportedImageMime, limits: ImageResourceLimits,
|
|
1646
|
-
/** Aborted when the owning lookup/session is disposed. */
|
|
1647
|
-
signal?: AbortSignal): Promise<Readonly<{
|
|
1648
|
-
pixelWidth: number;
|
|
1649
|
-
pixelHeight: number;
|
|
1650
|
-
dpiX: number;
|
|
1651
|
-
dpiY: number;
|
|
1652
|
-
}>>;
|
|
1653
|
-
/**
|
|
1654
|
-
* Optional conversion of media an `<img>` cannot render (EMF/WMF metafiles, TIFF) into a
|
|
1655
|
-
* renderable raster. The returned bytes are untrusted and re-enter the full raster
|
|
1656
|
-
* validation path (sniff, header, pixel caps, decode) before they can become a ready
|
|
1657
|
-
* resource. A null return declines the format and keeps the labelled placeholder; so does
|
|
1658
|
-
* a throw, as `decode-failed`.
|
|
1659
|
-
*/
|
|
1660
|
-
convertPreserved?(bytes: Uint8Array, mime: PreservedImageMime, limits: ImageResourceLimits,
|
|
1661
|
-
/** Aborted when the owning lookup/session is disposed. */
|
|
1662
|
-
signal?: AbortSignal): Promise<Readonly<{
|
|
1663
|
-
bytes: Uint8Array;
|
|
1664
|
-
mime: SupportedImageMime;
|
|
1665
|
-
}> | null>;
|
|
1666
|
-
}
|
|
1667
|
-
/** Resolves a relationship id to a validated image resource, or reports why it could not. */
|
|
1668
|
-
interface ImageResourceLookup {
|
|
1669
|
-
readonly resolveEmbedded: (ownerPartName: string, relationshipId: string) => Promise<ImageResourceState>;
|
|
1670
|
-
readonly resolveLinked: (ownerPartName: string, relationshipId: string) => ImageResourceState;
|
|
1671
|
-
readonly resolveForProjection: (projection: DrawingProjection) => Promise<ImageResourceState>;
|
|
1672
|
-
readonly liveReferenceCount: (partName: string) => number;
|
|
1673
|
-
readonly dispose: () => void;
|
|
1674
|
-
}
|
|
1675
|
-
/** Maximum prefix inspected for SVG root detection (exported for bounded-scan tests). */
|
|
1676
|
-
declare const MAX_SVG_SNIFF_BYTES = 512;
|
|
1677
|
-
/** A raster header that passed structural validation: its real MIME type and pixel extent. */
|
|
1678
|
-
interface ValidatedRasterHeader {
|
|
1679
|
-
readonly pixelWidth: number;
|
|
1680
|
-
readonly pixelHeight: number;
|
|
1681
|
-
/** Horizontal physical density when bounded header metadata supplies it. */
|
|
1682
|
-
readonly dpiX?: number;
|
|
1683
|
-
/** Vertical physical density when bounded header metadata supplies it. */
|
|
1684
|
-
readonly dpiY?: number;
|
|
1685
|
-
}
|
|
1686
|
-
/** Bounded scan for an `<svg` document root (optional `<?xml` prolog only). */
|
|
1687
|
-
declare function hasBoundedSvgRoot(bytes: Uint8Array): boolean;
|
|
1688
|
-
/** Signature sniffing — authoritative over declared content type. */
|
|
1689
|
-
declare function sniffImageMime(bytes: Uint8Array): RenderableImageMime | PreservedImageMime | 'unknown';
|
|
1690
|
-
/** Structural PNG IHDR validation before decode. */
|
|
1691
|
-
declare function validatePngHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
|
|
1692
|
-
/** Structural GIF logical screen descriptor validation before decode. */
|
|
1693
|
-
declare function validateGifHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
|
|
1694
|
-
/** Bounded JPEG marker scan through the first supported SOF marker. */
|
|
1695
|
-
declare function validateJpegHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
|
|
1696
|
-
/**
|
|
1697
|
-
* Intrinsic size of an SVG, resolved the way a browser sizes one: absolute `width`/`height`
|
|
1698
|
-
* first, then `viewBox` for the missing axis or ratio, then the CSS 300x150 default.
|
|
1699
|
-
*
|
|
1700
|
-
* This is metadata for insert and reset-to-natural-size only. Layout uses the authored
|
|
1701
|
-
* `wp:extent` and the browser rasterizes into that box, so nothing here sizes an allocation
|
|
1702
|
-
* and an out-of-range value is clamped rather than refused.
|
|
1703
|
-
*/
|
|
1704
|
-
declare function resolveSvgIntrinsicSize(bytes: Uint8Array, limits: ImageResourceLimits): ValidatedRasterHeader | null;
|
|
1705
|
-
/**
|
|
1706
|
-
* Validate a raster image's header structurally and report its real MIME type and extent.
|
|
1707
|
-
*
|
|
1708
|
-
* Content type is a CLAIM; this is what makes it a fact. A file declaring `image/png` over JPEG
|
|
1709
|
-
* bytes is caught here rather than at decode.
|
|
1710
|
-
*/
|
|
1711
|
-
declare function validateRasterHeader(bytes: Uint8Array, mime: SupportedImageMime): ValidatedRasterHeader | null;
|
|
1712
|
-
/** Package-wide live drawing references to a media part name. */
|
|
1713
|
-
declare function liveDrawingReferenceCount(pkg: OoxmlPackage, partName: string): number;
|
|
1714
|
-
/** How the image cache decodes, and what it will spend doing so. */
|
|
1715
|
-
interface CreateImageResourceCacheOptions {
|
|
1716
|
-
readonly limits?: Partial<ImageResourceLimits>;
|
|
1717
|
-
readonly decodePort: ImageDecodePort;
|
|
1718
|
-
}
|
|
1719
|
-
/**
|
|
1720
|
-
* Derived cache for one immutable package snapshot. Registry identity is
|
|
1721
|
-
* `(package snapshot, decodePort object, normalized limits)` — the first caller
|
|
1722
|
-
* never imposes its decoder or limits on later callers with different options.
|
|
1723
|
-
*/
|
|
1724
|
-
declare function imageResourceLookupFor(pkg: OoxmlPackage, options: CreateImageResourceCacheOptions): ImageResourceLookup;
|
|
1725
|
-
/** @deprecated Prefer {@link imageResourceLookupFor} — registry binds cache to package identity. */
|
|
1726
|
-
/** Build the per-document image cache. Validated bytes only; refusals are remembered too. */
|
|
1727
|
-
declare function createImageResourceCache(initialPkg: OoxmlPackage, options: CreateImageResourceCacheOptions): ImageResourceLookup;
|
|
1728
|
-
|
|
1729
1520
|
/** Caps applied while loading a package: zip, XML, part count and relationship count. */
|
|
1730
1521
|
interface OoxmlPackageLimits {
|
|
1731
1522
|
readonly zip?: ZipLimits;
|
|
@@ -1931,6 +1722,962 @@ interface CommitTextFormFieldOp {
|
|
|
1931
1722
|
readonly fieldNodeId: string;
|
|
1932
1723
|
}
|
|
1933
1724
|
|
|
1725
|
+
/** The `w15` namespace: `commentsExtended.xml` — thread parent and resolved state. */
|
|
1726
|
+
declare const W15_NAMESPACE_URI = "http://schemas.microsoft.com/office/word/2012/wordml";
|
|
1727
|
+
/** A position in one story: a paragraph node id plus a UTF-16 offset inside it. */
|
|
1728
|
+
interface CommentPosition {
|
|
1729
|
+
readonly paragraphId: string;
|
|
1730
|
+
readonly offset: number;
|
|
1731
|
+
}
|
|
1732
|
+
/**
|
|
1733
|
+
* Where a comment is anchored, as a range.
|
|
1734
|
+
*
|
|
1735
|
+
* `orphaned` records that the file did not give this comment a usable range — a reference with
|
|
1736
|
+
* no range markers, or a start with no end. The comment is still listed, marked orphaned,
|
|
1737
|
+
* rather than dropped: a reviewer's remark disappearing silently is worse than one that says
|
|
1738
|
+
* it lost its text.
|
|
1739
|
+
*/
|
|
1740
|
+
interface CommentAnchor {
|
|
1741
|
+
readonly commentId: string;
|
|
1742
|
+
/** Canonical name of the part the range lives in, so a header comment is attributable. */
|
|
1743
|
+
readonly partName: string;
|
|
1744
|
+
readonly start: CommentPosition;
|
|
1745
|
+
readonly end: CommentPosition;
|
|
1746
|
+
readonly orphaned: boolean;
|
|
1747
|
+
}
|
|
1748
|
+
/** One comment as authored in `word/comments.xml`. */
|
|
1749
|
+
interface CommentRecord {
|
|
1750
|
+
readonly id: string;
|
|
1751
|
+
readonly author: string;
|
|
1752
|
+
readonly initials?: string;
|
|
1753
|
+
readonly date?: string;
|
|
1754
|
+
/** Body paragraphs, as tree nodes, so the surface renders measured text rather than a string. */
|
|
1755
|
+
readonly blocks: readonly OoxmlElement[];
|
|
1756
|
+
/** `w14:paraId` of the last body paragraph — the key thread state is stored under. */
|
|
1757
|
+
readonly paraId?: string;
|
|
1758
|
+
/** `@w16cid:parentId` — the `w:id` of the comment this replies to, when the file names it. */
|
|
1759
|
+
readonly parentCommentId?: string;
|
|
1760
|
+
}
|
|
1761
|
+
/** Thread state for one comment, read from `commentsExtended.xml`. */
|
|
1762
|
+
interface CommentThreadState {
|
|
1763
|
+
/** `@w15:paraIdParent` — the comment this one replies to, absent for a top-level comment. */
|
|
1764
|
+
readonly parentParaId?: string;
|
|
1765
|
+
readonly done: boolean;
|
|
1766
|
+
}
|
|
1767
|
+
/**
|
|
1768
|
+
* Every comment anchor in one story, in document order.
|
|
1769
|
+
*
|
|
1770
|
+
* Overlapping and nested ranges are supported because each anchor is resolved independently —
|
|
1771
|
+
* Word produces both, and a model that assumed ranges nest cleanly would mis-anchor them.
|
|
1772
|
+
*
|
|
1773
|
+
* A start with no matching end anchors to the end of its own paragraph and is reported orphaned
|
|
1774
|
+
* rather than guessed at: extending it to the next end marker would attach a reviewer's remark
|
|
1775
|
+
* to text they never saw.
|
|
1776
|
+
*/
|
|
1777
|
+
declare function commentAnchorsOfStory(part: OoxmlPart): CommentAnchor[];
|
|
1778
|
+
/**
|
|
1779
|
+
* The comments in `word/comments.xml`, in authored order.
|
|
1780
|
+
*
|
|
1781
|
+
* Every value here comes from a file an attacker fully controls, so nothing is interpreted:
|
|
1782
|
+
* author, initials and date are carried verbatim for a surface that will set them as TEXT.
|
|
1783
|
+
*/
|
|
1784
|
+
declare function commentsOfPart(part: OoxmlPart): CommentRecord[];
|
|
1785
|
+
/**
|
|
1786
|
+
* Thread state by `w14:paraId`, from `commentsExtended.xml`.
|
|
1787
|
+
*
|
|
1788
|
+
* The part being PRESENT is not evidence of threading. `issue-68-large-comments-suggestions.docx`
|
|
1789
|
+
* ships it with 212 entries carrying `@w15:done` and not one `@w15:paraIdParent`, so it records
|
|
1790
|
+
* resolved state for a flat list. Absent parent means top-level, and that is a fact about the
|
|
1791
|
+
* file rather than a default this code chose.
|
|
1792
|
+
*/
|
|
1793
|
+
declare function threadStateOfPart(part: OoxmlPart): Map<string, CommentThreadState>;
|
|
1794
|
+
/**
|
|
1795
|
+
* Whether the package holds any `w:comment` record — the cheap gate before a reap.
|
|
1796
|
+
*
|
|
1797
|
+
* Overflow cannot prove the package is comment-free, so it returns true and the reap still
|
|
1798
|
+
* runs rather than skipping cleanup.
|
|
1799
|
+
*/
|
|
1800
|
+
declare function hasAnyComment(pkg: OoxmlPackage): boolean;
|
|
1801
|
+
|
|
1802
|
+
/** A position in the model offset space of one story. */
|
|
1803
|
+
interface ReviewPosition {
|
|
1804
|
+
readonly paragraphId: string;
|
|
1805
|
+
readonly offset: number;
|
|
1806
|
+
}
|
|
1807
|
+
/** Where an item is anchored: a range in one story. */
|
|
1808
|
+
interface ReviewRange {
|
|
1809
|
+
readonly partName: string;
|
|
1810
|
+
readonly start: ReviewPosition;
|
|
1811
|
+
readonly end: ReviewPosition;
|
|
1812
|
+
}
|
|
1813
|
+
/**
|
|
1814
|
+
* What kind of decision a revision card represents.
|
|
1815
|
+
*
|
|
1816
|
+
* Wider than the four content wrappers, because a reviewer has to be shown every pending
|
|
1817
|
+
* decision, including the ones that decorate no characters. A card the surface cannot show is
|
|
1818
|
+
* a change the reviewer never learns about — and `acceptAllRevisions` refuses if ANY revision
|
|
1819
|
+
* in the document is one the engine cannot resolve, so an invisible one makes Accept All fail
|
|
1820
|
+
* for a reason nothing on screen explains.
|
|
1821
|
+
*/
|
|
1822
|
+
type ReviewRevisionKind = 'insert' | 'delete'
|
|
1823
|
+
/**
|
|
1824
|
+
* A deletion and an insertion that are one edit: text typed over a selection.
|
|
1825
|
+
*
|
|
1826
|
+
* Word shows these as a single `Replaced "x" with "y"` card, and resolving one half
|
|
1827
|
+
* without the other is never what the reviewer meant — accepting the deletion alone
|
|
1828
|
+
* leaves the replacement text unproposed, rejecting it alone leaves both.
|
|
1829
|
+
*/
|
|
1830
|
+
| 'replace' | 'moveFrom' | 'moveTo'
|
|
1831
|
+
/** `w:rPrChange` / `w:pPrChange` — the words are unchanged, their formatting is not. */
|
|
1832
|
+
| 'format'
|
|
1833
|
+
/** `w:pPr/w:rPr/w:ins|w:del` — a paragraph split or merge. */
|
|
1834
|
+
| 'paragraphMark'
|
|
1835
|
+
/** A row, cell, section or grid revision. Supported row revisions are resolvable. */
|
|
1836
|
+
| 'structural';
|
|
1837
|
+
/**
|
|
1838
|
+
* One tracked change as a review card.
|
|
1839
|
+
*
|
|
1840
|
+
* Keyed per DECISION rather than per site: a revision spanning three ranges is one card, because
|
|
1841
|
+
* accepting it accepts all three.
|
|
1842
|
+
*/
|
|
1843
|
+
interface ReviewRevisionItem {
|
|
1844
|
+
readonly kind: 'revision';
|
|
1845
|
+
/** Stable across renders and unique per DECISION, not per site. */
|
|
1846
|
+
readonly id: string;
|
|
1847
|
+
/** The payload `acceptRevision` / `rejectRevision` take. */
|
|
1848
|
+
readonly address: RevisionAddress;
|
|
1849
|
+
/**
|
|
1850
|
+
* EVERY address this decision covers, `address` first.
|
|
1851
|
+
*
|
|
1852
|
+
* More than one only for a replacement, whose halves a foreign editor may have written
|
|
1853
|
+
* as two independent revisions. Accept and reject walk all of them in one transaction:
|
|
1854
|
+
* resolving one half and leaving the other is a state no reviewer asked for.
|
|
1855
|
+
*/
|
|
1856
|
+
readonly addresses: readonly RevisionAddress[];
|
|
1857
|
+
/** The words a replacement removes. Empty for every other kind. */
|
|
1858
|
+
readonly replacedText: string;
|
|
1859
|
+
readonly revisionKind: ReviewRevisionKind;
|
|
1860
|
+
/** OOXML property-change element, used to resolve independently numbered formatting kinds. */
|
|
1861
|
+
readonly formattingKind?: string;
|
|
1862
|
+
/** Changed direct formatting values, ready for localized review summaries. */
|
|
1863
|
+
readonly formattingChanges?: readonly {
|
|
1864
|
+
readonly property: 'bold' | 'italic' | 'underline' | 'strike' | 'fontFamily' | 'fontSize' | 'color' | 'alignment' | 'leftIndent' | 'rightIndent' | 'firstLineIndent' | 'hangingIndent' | 'spaceBefore' | 'spaceAfter';
|
|
1865
|
+
/** New direct value; null means inherit. Sizes and distances are in points. */
|
|
1866
|
+
readonly value: string | null;
|
|
1867
|
+
}[];
|
|
1868
|
+
/** Newly applied proofing language codes in a tracked formatting change. */
|
|
1869
|
+
readonly formattingLanguages?: readonly string[];
|
|
1870
|
+
/**
|
|
1871
|
+
* WHICH decision a `paragraphMark` records, absent for every other kind.
|
|
1872
|
+
*
|
|
1873
|
+
* `EG_ParaRPrTrackChanges` is `ins? del? moveFrom? moveTo?`, and the four say opposite
|
|
1874
|
+
* things about one break. Without this a card called a deleted break an inserted one, which
|
|
1875
|
+
* is the reverse of what Accept on that card does.
|
|
1876
|
+
*/
|
|
1877
|
+
readonly markDirection?: 'insert' | 'delete' | 'moveFrom' | 'moveTo';
|
|
1878
|
+
readonly author: string;
|
|
1879
|
+
readonly date?: string;
|
|
1880
|
+
/** Text the revision covers, for the card summary. Empty for changes with no characters. */
|
|
1881
|
+
readonly text: string;
|
|
1882
|
+
/** Every site this decision touches, in document order. */
|
|
1883
|
+
readonly ranges: readonly ReviewRange[];
|
|
1884
|
+
/**
|
|
1885
|
+
* How deeply this change is NESTED inside other changes, 0 for an unenclosed one.
|
|
1886
|
+
*
|
|
1887
|
+
* `w:ins` wrapping `w:del` is content one reviewer added and another struck. Both stay
|
|
1888
|
+
* pending, so both are cards, over one identical range — and a range then cannot say which
|
|
1889
|
+
* change a caret is in. Word treats the innermost as the operative one, so it wins the caret
|
|
1890
|
+
* and the change enclosing it stays listed and reachable.
|
|
1891
|
+
*/
|
|
1892
|
+
readonly nesting: number;
|
|
1893
|
+
/**
|
|
1894
|
+
* How many leading `ranges` are the STRUCK half of a replacement.
|
|
1895
|
+
*
|
|
1896
|
+
* A replacement's card is one decision but its ranges are two colours — red over what is
|
|
1897
|
+
* going, green over what takes its place. ABSENT when the halves do not split at a single
|
|
1898
|
+
* point, which is what a file recording both under one revision id can produce; a surface
|
|
1899
|
+
* then has no basis for two colours and should paint one neutral band rather than guess.
|
|
1900
|
+
*/
|
|
1901
|
+
readonly replacedRangeCount?: number;
|
|
1902
|
+
/**
|
|
1903
|
+
* True when the engine cannot resolve this kind, so accept and reject must not be offered.
|
|
1904
|
+
*
|
|
1905
|
+
* Derived by the DERIVATION rather than from a caller-supplied predicate: the refusal list
|
|
1906
|
+
* is internal, and a surface asked to compute it would have to guess. A card that offers a
|
|
1907
|
+
* button the engine will refuse is worse than one that explains why it cannot.
|
|
1908
|
+
*/
|
|
1909
|
+
readonly readOnly: boolean;
|
|
1910
|
+
/** The other half of a move, or the other side of a delete/insert replacement. */
|
|
1911
|
+
readonly pairedWith?: string;
|
|
1912
|
+
/**
|
|
1913
|
+
* Comments answering this change, in document order.
|
|
1914
|
+
*
|
|
1915
|
+
* A reply to a tracked change IS a comment: `w:ins` and `w:del` carry no body, so the text
|
|
1916
|
+
* is written as a comment over the revision's own range and the range is what links them.
|
|
1917
|
+
*/
|
|
1918
|
+
readonly replyIds: readonly string[];
|
|
1919
|
+
}
|
|
1920
|
+
/**
|
|
1921
|
+
* One comment as a review card. A reply carries `parentId`; OOXML gives replies no separate
|
|
1922
|
+
* element, so threads are reconstructed from that link.
|
|
1923
|
+
*/
|
|
1924
|
+
interface ReviewCommentItem {
|
|
1925
|
+
readonly kind: 'comment';
|
|
1926
|
+
readonly id: string;
|
|
1927
|
+
readonly comment: CommentRecord;
|
|
1928
|
+
readonly range: ReviewRange | null;
|
|
1929
|
+
readonly resolved: boolean;
|
|
1930
|
+
/** The comment this replies to, absent for a top-level comment. */
|
|
1931
|
+
readonly parentId?: string;
|
|
1932
|
+
/** The REVISION this comment answers, when it covers exactly that change's characters. */
|
|
1933
|
+
readonly parentRevisionId?: string;
|
|
1934
|
+
/** Replies to this comment, in document order. Empty for a reply or a childless comment. */
|
|
1935
|
+
readonly replyIds: readonly string[];
|
|
1936
|
+
/** True when the file gave this comment no usable range. */
|
|
1937
|
+
readonly orphaned: boolean;
|
|
1938
|
+
}
|
|
1939
|
+
/**
|
|
1940
|
+
* A card contributed by a recognized custom node (`defineCustomNode` with a `reviewCard`
|
|
1941
|
+
* hook), anchored at the node's range.
|
|
1942
|
+
*
|
|
1943
|
+
* Informational, never resolvable: there is nothing to accept or reject, so the engine
|
|
1944
|
+
* refuses those verbs on it. `title` and `detail` are HOST-authored (the definition's hook
|
|
1945
|
+
* produced them), but `attrs` and `text` originate in a file an attacker controls — a
|
|
1946
|
+
* surface renders every one of these as text, never markup.
|
|
1947
|
+
*/
|
|
1948
|
+
interface ReviewCustomItem {
|
|
1949
|
+
readonly kind: 'custom';
|
|
1950
|
+
/** The SDT node's stable id in the canonical tree. */
|
|
1951
|
+
readonly id: string;
|
|
1952
|
+
/** The definition's `name`. */
|
|
1953
|
+
readonly name: string;
|
|
1954
|
+
/** The raw `w:tag` the node was recognized from. Untrusted input. */
|
|
1955
|
+
readonly tag: string;
|
|
1956
|
+
/** Attrs decoded from the tag, after the definition's recognition hook. Untrusted input. */
|
|
1957
|
+
readonly attrs: Readonly<Record<string, string>>;
|
|
1958
|
+
/** The SDT's literal content text. Untrusted input. */
|
|
1959
|
+
readonly text: string;
|
|
1960
|
+
/**
|
|
1961
|
+
* The payload the node's control binds to, after the definition validated it.
|
|
1962
|
+
*
|
|
1963
|
+
* Undefined when the node carries none or the payload did not match — see the pro package's
|
|
1964
|
+
* `RecognizedCustomNode.data`, which this is carried from.
|
|
1965
|
+
*/
|
|
1966
|
+
readonly data?: unknown;
|
|
1967
|
+
/**
|
|
1968
|
+
* Whether this node asked for a sidebar card.
|
|
1969
|
+
*
|
|
1970
|
+
* False for a definition with no `reviewCard`: the item exists so the chip's own surfaces can
|
|
1971
|
+
* read `attrs`, `text` and `data` off it, and the rail leaves it out. A surface listing cards
|
|
1972
|
+
* filters on this rather than on an empty `title`.
|
|
1973
|
+
*/
|
|
1974
|
+
readonly carded: boolean;
|
|
1975
|
+
/** Card title, from the definition's `reviewCard` hook. Empty when `carded` is false. */
|
|
1976
|
+
readonly title: string;
|
|
1977
|
+
/** Card body, from the definition's `reviewCard` hook. */
|
|
1978
|
+
readonly detail?: string;
|
|
1979
|
+
/**
|
|
1980
|
+
* Glyph for this node in the collapsed rail, as an SVG path in a `0 -960 960 960` viewBox.
|
|
1981
|
+
*
|
|
1982
|
+
* A PATH rather than a rendered node because this item crosses core, which is DOM-free and
|
|
1983
|
+
* React-free — the same reason `title` and `detail` are strings. A host that wants arbitrary
|
|
1984
|
+
* markup overrides the `Markers` part's `icon` instead, which lives in the adapter where JSX
|
|
1985
|
+
* belongs. Absent falls back to the generic custom-node glyph.
|
|
1986
|
+
*
|
|
1987
|
+
* HOST-AUTHORED, never file data: it is interpolated into an SVG `d` attribute, and a path
|
|
1988
|
+
* taken from a document would be attacker-controlled markup.
|
|
1989
|
+
*/
|
|
1990
|
+
readonly icon?: string;
|
|
1991
|
+
readonly range: ReviewRange | null;
|
|
1992
|
+
}
|
|
1993
|
+
/**
|
|
1994
|
+
* One pending decision in the review queue: a tracked change, a comment thread, or a pro
|
|
1995
|
+
* custom-node card. Discriminate on `kind`.
|
|
1996
|
+
*
|
|
1997
|
+
* The store's own derivation (`collectReviewItems`) only ever produces the first two; the
|
|
1998
|
+
* `kind: 'custom'` card is contributed by the pro review module, which recognizes the node.
|
|
1999
|
+
*/
|
|
2000
|
+
type ReviewItem = ReviewRevisionItem | ReviewCommentItem | ReviewCustomItem;
|
|
2001
|
+
/** What the review queue derivation reads: one story part plus its comment parts. */
|
|
2002
|
+
interface ReviewModelInput {
|
|
2003
|
+
/** The story the ranges live in — the main document, a header, a note. */
|
|
2004
|
+
readonly storyPart: OoxmlPart;
|
|
2005
|
+
/**
|
|
2006
|
+
* Header/footer story parts, in section order. Their revisions and comment anchors join
|
|
2007
|
+
* the queue: a tracked change in a header is a pending decision like any other, and a
|
|
2008
|
+
* queue that only walked the body silently hid it from the rail AND from Accept All.
|
|
2009
|
+
*/
|
|
2010
|
+
readonly furnitureParts?: readonly OoxmlPart[] | undefined;
|
|
2011
|
+
/** `word/comments.xml`, absent when the package has none. */
|
|
2012
|
+
readonly commentsPart?: OoxmlPart | undefined;
|
|
2013
|
+
/** `word/commentsExtended.xml`, absent when the package has none. */
|
|
2014
|
+
readonly commentsExtendedPart?: OoxmlPart | undefined;
|
|
2015
|
+
/**
|
|
2016
|
+
* Custom node definitions from the module registry, forwarded OPAQUELY.
|
|
2017
|
+
*
|
|
2018
|
+
* Core carries them the way the registry does — as unknowns — so the definition shape
|
|
2019
|
+
* stays a capability-package concern. The pro derivation narrows them and contributes
|
|
2020
|
+
* `kind: 'custom'` cards for definitions that opted in.
|
|
2021
|
+
*/
|
|
2022
|
+
readonly customNodes?: readonly unknown[] | undefined;
|
|
2023
|
+
/**
|
|
2024
|
+
* Where a capability package reports a node it could not read. Supplied per editor, so a page
|
|
2025
|
+
* with two of them keeps their diagnostics apart.
|
|
2026
|
+
*/
|
|
2027
|
+
readonly reportCustomNodeDiagnostic?: ((diagnostic: unknown) => void) | undefined;
|
|
2028
|
+
/**
|
|
2029
|
+
* The payload each of the story's controls binds to, keyed by the control's node id.
|
|
2030
|
+
*
|
|
2031
|
+
* Resolved by the ENGINE and handed over, because a payload lives in a customXml data part
|
|
2032
|
+
* and a derivation that only receives story parts has no way to reach one. Untrusted file
|
|
2033
|
+
* input on both members; a capability package validates it against whatever shape it
|
|
2034
|
+
* declared before handing it to a host.
|
|
2035
|
+
*/
|
|
2036
|
+
readonly customNodePayloads?: ReadonlyMap<string, {
|
|
2037
|
+
readonly nodeId: string;
|
|
2038
|
+
readonly label: string;
|
|
2039
|
+
readonly data: string;
|
|
2040
|
+
}> | undefined;
|
|
2041
|
+
}
|
|
2042
|
+
/** The stable key a surface uses for the active item and for a React list. */
|
|
2043
|
+
declare function reviewItemKey(item: ReviewItem): string;
|
|
2044
|
+
/** Every range a decision touches. One card can cover several, in different paragraphs. */
|
|
2045
|
+
declare function reviewItemRanges(item: ReviewItem): readonly ReviewRange[];
|
|
2046
|
+
/** The first range of an item, in authored order, or null when it has none. */
|
|
2047
|
+
declare function firstReviewRange(item: ReviewItem): ReviewRange | null;
|
|
2048
|
+
/**
|
|
2049
|
+
* A single comparable number for document order.
|
|
2050
|
+
*
|
|
2051
|
+
* Paragraph index dominates offset, so a revision spanning paragraphs still sorts by where it
|
|
2052
|
+
* STARTS. An item with no resolvable range sorts last rather than to position zero, which is
|
|
2053
|
+
* where an orphan used to land — tearing an orphaned reply out of its own thread.
|
|
2054
|
+
*/
|
|
2055
|
+
declare function reviewItemPositionRank(item: ReviewItem, order: ReadonlyMap<string, number>): number;
|
|
2056
|
+
/**
|
|
2057
|
+
* Every item covering a position, innermost first.
|
|
2058
|
+
*
|
|
2059
|
+
* Returning the whole stack rather than one winner is what lets a surface offer cycling, a
|
|
2060
|
+
* stacked card, or a "1 of 3" affordance. A comment wrapping a revision used to be unreachable
|
|
2061
|
+
* because only the tightest range was ever returned.
|
|
2062
|
+
*/
|
|
2063
|
+
declare function reviewItemsAt(items: readonly ReviewItem[], position: ReviewPosition, order: ReadonlyMap<string, number>): ReviewItem[];
|
|
2064
|
+
/**
|
|
2065
|
+
* The item the caret is in, or null.
|
|
2066
|
+
*
|
|
2067
|
+
* A resolved comment never activates: a settled thread must not reopen itself as the reviewer
|
|
2068
|
+
* types near it.
|
|
2069
|
+
*
|
|
2070
|
+
* A REPLY resolves to the thread it belongs to. A reply is anchored over its parent's range,
|
|
2071
|
+
* so both cover the caret — and the reply, being newer, wins the innermost test. It is not a
|
|
2072
|
+
* card of its own (it renders inside its parent's), so the thread would have gone active with
|
|
2073
|
+
* nothing on screen showing it: the reply box vanished from a comment the moment somebody
|
|
2074
|
+
* replied to it.
|
|
2075
|
+
*/
|
|
2076
|
+
declare function activeReviewItem(items: readonly ReviewItem[], position: ReviewPosition, order: ReadonlyMap<string, number>): ReviewItem | null;
|
|
2077
|
+
/**
|
|
2078
|
+
* Walk a reply up to the card that heads its thread. Guarded against a cyclic file.
|
|
2079
|
+
*
|
|
2080
|
+
* The head is not always a comment. A reply to a tracked change renders inside the REVISION's
|
|
2081
|
+
* card, so resolving it to itself opened an item nothing on screen was drawing — the reply box
|
|
2082
|
+
* vanished the moment somebody answered a change.
|
|
2083
|
+
*
|
|
2084
|
+
* EXPORTED because the paginated surface answers "which card is open" itself, against its own
|
|
2085
|
+
* dismissed-key state, rather than through {@link activeReviewItem}. Two copies of the
|
|
2086
|
+
* innermost-wins rule was survivable while a reply could only be a comment — the parent came
|
|
2087
|
+
* first in `comments.xml` order and won the tie by accident. It stopped being survivable the
|
|
2088
|
+
* moment a reply could answer a revision, which outranks it outright.
|
|
2089
|
+
*/
|
|
2090
|
+
declare function reviewThreadRootOf(items: readonly ReviewItem[], comment: ReviewCommentItem): ReviewItem;
|
|
2091
|
+
|
|
2092
|
+
/** A canonical review decision. Keys are valid only in the open document. @public */
|
|
2093
|
+
interface RevisionBatchEntry {
|
|
2094
|
+
readonly key: string;
|
|
2095
|
+
readonly author: string;
|
|
2096
|
+
readonly partName: string;
|
|
2097
|
+
readonly revisionKind: ReviewRevisionItem['revisionKind'];
|
|
2098
|
+
}
|
|
2099
|
+
/** Why a requested decision remains pending. @public */
|
|
2100
|
+
type RevisionBatchSkipReason = 'unsupported-revision' | 'incomplete-group' | 'unknown-revision';
|
|
2101
|
+
/** Outcome of one selected-set decision. Counts refer to review decisions, not XML markers. @public */
|
|
2102
|
+
interface RevisionBatchResult {
|
|
2103
|
+
readonly resolved: readonly RevisionBatchEntry[];
|
|
2104
|
+
readonly skipped: readonly {
|
|
2105
|
+
readonly key: string;
|
|
2106
|
+
readonly reason: RevisionBatchSkipReason;
|
|
2107
|
+
readonly revision?: RevisionBatchEntry;
|
|
2108
|
+
}[];
|
|
2109
|
+
/** All pending decisions in the addressed scope, including excluded and unsupported changes. */
|
|
2110
|
+
readonly remaining: number;
|
|
2111
|
+
}
|
|
2112
|
+
/** @internal Pure preflight; callers commit its operations through their normal write guards. */
|
|
2113
|
+
declare function planRevisionBatch(part: OoxmlPart, action: 'accept' | 'reject', keys?: readonly string[], scopeRoot?: OoxmlNode): {
|
|
2114
|
+
ops: readonly TreeDocOp[];
|
|
2115
|
+
result: RevisionBatchResult;
|
|
2116
|
+
};
|
|
2117
|
+
|
|
2118
|
+
/**
|
|
2119
|
+
* Shared types for the `@docx-editor.dev/core` contract. Type-only, zero runtime.
|
|
2120
|
+
*
|
|
2121
|
+
* `@docx-editor.dev/core/contracts/types` re-exports this module verbatim, through
|
|
2122
|
+
* `types-barrel.ts`. There is no `@docx-editor.dev/core/types` subpath.
|
|
2123
|
+
*/
|
|
2124
|
+
/** Which paragraph-level reads the selection disagrees about. @public */
|
|
2125
|
+
interface ParagraphDisagreements {
|
|
2126
|
+
readonly alignment: boolean;
|
|
2127
|
+
readonly spaceBeforePt: boolean;
|
|
2128
|
+
readonly spaceAfterPt: boolean;
|
|
2129
|
+
readonly lineSpacing: boolean;
|
|
2130
|
+
readonly tabStops: boolean;
|
|
2131
|
+
}
|
|
2132
|
+
/**
|
|
2133
|
+
* The five paragraph flags a Paragraph dialog shows as checkboxes.
|
|
2134
|
+
*
|
|
2135
|
+
* `contextualSpacing` is Word's "Don't add space between paragraphs of the same style";
|
|
2136
|
+
* the rest are its Pagination block. `null` means the selection disagrees.
|
|
2137
|
+
*
|
|
2138
|
+
* @public
|
|
2139
|
+
*/
|
|
2140
|
+
interface ParagraphFlags {
|
|
2141
|
+
readonly contextualSpacing: boolean | null;
|
|
2142
|
+
readonly keepNext: boolean | null;
|
|
2143
|
+
readonly keepLines: boolean | null;
|
|
2144
|
+
readonly widowControl: boolean | null;
|
|
2145
|
+
readonly pageBreakBefore: boolean | null;
|
|
2146
|
+
}
|
|
2147
|
+
/**
|
|
2148
|
+
* Every field of the Paragraph dialog, as `setParagraphFormat` takes it.
|
|
2149
|
+
*
|
|
2150
|
+
* An omitted field is left as authored. `null` REMOVES a setting so the style supplies it
|
|
2151
|
+
* again — not the same as a zero, which blocks the cascade.
|
|
2152
|
+
*
|
|
2153
|
+
* @public
|
|
2154
|
+
*/
|
|
2155
|
+
interface ParagraphFormatCommand {
|
|
2156
|
+
alignment?: 'left' | 'center' | 'right' | 'justify';
|
|
2157
|
+
spaceBeforePt?: number | null;
|
|
2158
|
+
spaceAfterPt?: number | null;
|
|
2159
|
+
lineSpacing?: {
|
|
2160
|
+
rule: 'multiple' | 'exact' | 'atLeast';
|
|
2161
|
+
value: number;
|
|
2162
|
+
} | null;
|
|
2163
|
+
indentLeftTwips?: number | null;
|
|
2164
|
+
indentRightTwips?: number | null;
|
|
2165
|
+
/** ONE signed first-line offset: negative is a hanging indent. */
|
|
2166
|
+
indentFirstLineTwips?: number | null;
|
|
2167
|
+
contextualSpacing?: boolean;
|
|
2168
|
+
keepNext?: boolean;
|
|
2169
|
+
keepLines?: boolean;
|
|
2170
|
+
widowControl?: boolean;
|
|
2171
|
+
pageBreakBefore?: boolean;
|
|
2172
|
+
/**
|
|
2173
|
+
* Replace the paragraph's custom tab stops. An empty list CLEARS them, which is what
|
|
2174
|
+
* "Clear All" does; omit the field to leave them as authored.
|
|
2175
|
+
*/
|
|
2176
|
+
tabStops?: readonly ParagraphTabStop[];
|
|
2177
|
+
}
|
|
2178
|
+
/** One custom tab stop, as a command states it. @public */
|
|
2179
|
+
interface ParagraphTabStop {
|
|
2180
|
+
readonly positionTwips: number;
|
|
2181
|
+
readonly alignment: 'left' | 'center' | 'right' | 'decimal' | 'bar';
|
|
2182
|
+
readonly leader?: 'none' | 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot';
|
|
2183
|
+
}
|
|
2184
|
+
/** Ownership token for one retained selection highlight. @public */
|
|
2185
|
+
type SelectionPin = symbol;
|
|
2186
|
+
/**
|
|
2187
|
+
* The LLM- and JSON-facing address for a piece of a document.
|
|
2188
|
+
*
|
|
2189
|
+
* `paraId` is the 8-hex `w14:paraId`, matched case-insensitively. `search` is a
|
|
2190
|
+
* phrase that must match EXACTLY ONCE inside that paragraph; ambiguous or
|
|
2191
|
+
* missing matches fail with `'ambiguous'` / `'notFound'` rather than falling
|
|
2192
|
+
* back to first-match.
|
|
2193
|
+
*
|
|
2194
|
+
* Offset-based addressing was tried and abandoned: an agent cannot compute a
|
|
2195
|
+
* character offset it has not seen, and offsets do not survive concurrent
|
|
2196
|
+
* edits. Do not reintroduce `{ blockId, offset }`.
|
|
2197
|
+
*/
|
|
2198
|
+
interface DocAnchor {
|
|
2199
|
+
paraId: string;
|
|
2200
|
+
search?: string;
|
|
2201
|
+
/** Opt-in disambiguation. Omit to require uniqueness. */
|
|
2202
|
+
occurrence?: number;
|
|
2203
|
+
}
|
|
2204
|
+
/** Structural addressing for content the paraId map cannot reach. */
|
|
2205
|
+
interface DocLocation {
|
|
2206
|
+
container: ContainerRef;
|
|
2207
|
+
/** Block indices, descending into tables and content controls. */
|
|
2208
|
+
path: number[];
|
|
2209
|
+
offset?: number;
|
|
2210
|
+
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Which STORY a location belongs to.
|
|
2213
|
+
*
|
|
2214
|
+
* The body is one container; every header, footer and note is another. A path alone is
|
|
2215
|
+
* ambiguous without it, because block index 0 exists in every story a document has.
|
|
2216
|
+
*/
|
|
2217
|
+
type ContainerRef = {
|
|
2218
|
+
part: 'body';
|
|
2219
|
+
} | {
|
|
2220
|
+
part: 'header' | 'footer';
|
|
2221
|
+
rId: string;
|
|
2222
|
+
} | {
|
|
2223
|
+
part: 'footnote' | 'endnote';
|
|
2224
|
+
noteId: number;
|
|
2225
|
+
};
|
|
2226
|
+
/**
|
|
2227
|
+
* Anything an operation can be pointed at: a paragraph-relative {@link DocAnchor}, a structural
|
|
2228
|
+
* {@link DocLocation}, or a {@link DocRange} spanning two of them.
|
|
2229
|
+
*/
|
|
2230
|
+
type DocTarget = DocAnchor | DocLocation | DocRange;
|
|
2231
|
+
/** A span between two positions. The endpoints may be addressed either way, independently. */
|
|
2232
|
+
interface DocRange {
|
|
2233
|
+
from: DocAnchor | DocLocation;
|
|
2234
|
+
to: DocAnchor | DocLocation;
|
|
2235
|
+
}
|
|
2236
|
+
/**
|
|
2237
|
+
* Every write returns this rather than `boolean`.
|
|
2238
|
+
*
|
|
2239
|
+
* A bare boolean cannot distinguish "no-op" from "target not found" from
|
|
2240
|
+
* "content control is locked", and the editor layer already throws eight
|
|
2241
|
+
* distinct ContentControl error classes that a boolean would flatten.
|
|
2242
|
+
*/
|
|
2243
|
+
type ExecResult = {
|
|
2244
|
+
ok: true;
|
|
2245
|
+
changed: boolean;
|
|
2246
|
+
revisions?: RevisionBatchResult;
|
|
2247
|
+
} | {
|
|
2248
|
+
ok: false;
|
|
2249
|
+
code: ExecErrorCode;
|
|
2250
|
+
reason: string;
|
|
2251
|
+
target?: DocTarget;
|
|
2252
|
+
revisions?: RevisionBatchResult;
|
|
2253
|
+
};
|
|
2254
|
+
/**
|
|
2255
|
+
* Why a write was refused, as a value to branch on.
|
|
2256
|
+
*
|
|
2257
|
+
* Deliberately finer-grained than a boolean: "no-op", "target not found" and "content control is
|
|
2258
|
+
* locked" are different outcomes, and a caller retrying the first should not retry the third.
|
|
2259
|
+
*/
|
|
2260
|
+
type ExecErrorCode = 'notFound' | 'ambiguous' | 'locked' | 'bound' | 'typeMismatch' | 'kindMismatch' | 'outOfBounds' | 'unsupported' | 'invalidArgs';
|
|
2261
|
+
/**
|
|
2262
|
+
* A parsed .docx.
|
|
2263
|
+
*
|
|
2264
|
+
* NOT JSON-round-trippable: it holds `Map`s and `Date`s, plus an internal
|
|
2265
|
+
* side-table of verbatim XML used for lossless round-tripping. Use `toJSON` /
|
|
2266
|
+
* `fromJSON` before sending it over JSON-RPC or handing it to a model.
|
|
2267
|
+
*/
|
|
2268
|
+
interface DocxDocument {
|
|
2269
|
+
readonly body: DocumentBody;
|
|
2270
|
+
readonly styles: StyleDefinitions;
|
|
2271
|
+
readonly theme?: Theme;
|
|
2272
|
+
readonly comments: readonly DocComment[];
|
|
2273
|
+
readonly revisions: readonly Revision[];
|
|
2274
|
+
}
|
|
2275
|
+
/** The main story: its blocks in reading order, plus the sections derived from them. */
|
|
2276
|
+
interface DocumentBody {
|
|
2277
|
+
readonly content: readonly Block[];
|
|
2278
|
+
/**
|
|
2279
|
+
* Derived, not stored: recomputed on read from section-break markers and
|
|
2280
|
+
* section inheritance. Never treat it as a spreadable field.
|
|
2281
|
+
*/
|
|
2282
|
+
readonly sections: readonly Section[];
|
|
2283
|
+
}
|
|
2284
|
+
/** The JSON-safe projection of a document. */
|
|
2285
|
+
interface DocxDocumentJSON {
|
|
2286
|
+
readonly [key: string]: unknown;
|
|
2287
|
+
}
|
|
2288
|
+
/** One section: the page it lays out on, and the header/footer stories it declares. */
|
|
2289
|
+
interface Section {
|
|
2290
|
+
readonly properties: SectionProperties;
|
|
2291
|
+
readonly headers: HeaderFooterSet;
|
|
2292
|
+
readonly footers: HeaderFooterSet;
|
|
2293
|
+
}
|
|
2294
|
+
/**
|
|
2295
|
+
* A section's three header (or footer) variants, each a relationship id.
|
|
2296
|
+
*
|
|
2297
|
+
* All optional: a variant a section does not declare inherits the previous section's, and one
|
|
2298
|
+
* absent everywhere means the document simply has none.
|
|
2299
|
+
*/
|
|
2300
|
+
interface HeaderFooterSet {
|
|
2301
|
+
readonly default?: string;
|
|
2302
|
+
readonly first?: string;
|
|
2303
|
+
readonly even?: string;
|
|
2304
|
+
}
|
|
2305
|
+
/** Anything that can sit at block level in a story. Discriminate on `kind`. */
|
|
2306
|
+
type Block = Paragraph | Table | ContentControl;
|
|
2307
|
+
/** One paragraph: its runs, the style it names, and its list membership. */
|
|
2308
|
+
interface Paragraph {
|
|
2309
|
+
readonly kind: 'paragraph';
|
|
2310
|
+
/** `w14:paraId`. The stable handle `DocAnchor` addresses. */
|
|
2311
|
+
readonly paraId?: string;
|
|
2312
|
+
readonly runs: readonly Run[];
|
|
2313
|
+
readonly styleId?: string;
|
|
2314
|
+
readonly numbering?: NumberingRef;
|
|
2315
|
+
}
|
|
2316
|
+
/** A stretch of text sharing one set of character properties. */
|
|
2317
|
+
interface Run {
|
|
2318
|
+
readonly text: string;
|
|
2319
|
+
readonly formatting?: RunFormatting;
|
|
2320
|
+
/** Set when the run carries a tracked change. Unique only within its part. */
|
|
2321
|
+
readonly revisionId?: number;
|
|
2322
|
+
}
|
|
2323
|
+
/**
|
|
2324
|
+
* Character formatting, and — at selection level — the paragraph properties a toolbar reads
|
|
2325
|
+
* alongside it.
|
|
2326
|
+
*
|
|
2327
|
+
* One type serves both roles so a toolbar reads alignment, style and script state from the same
|
|
2328
|
+
* object as bold and italic. On a {@link Run} the selection-level fields stay absent: a run has
|
|
2329
|
+
* no alignment or paragraph style of its own.
|
|
2330
|
+
*/
|
|
2331
|
+
interface RunFormatting {
|
|
2332
|
+
readonly bold?: boolean;
|
|
2333
|
+
readonly italic?: boolean;
|
|
2334
|
+
readonly underline?: boolean;
|
|
2335
|
+
readonly strike?: boolean;
|
|
2336
|
+
readonly color?: ColorValue;
|
|
2337
|
+
readonly highlight?: string;
|
|
2338
|
+
readonly fontFamily?: string;
|
|
2339
|
+
readonly fontSizePt?: number;
|
|
2340
|
+
readonly superscript?: boolean;
|
|
2341
|
+
readonly subscript?: boolean;
|
|
2342
|
+
/** Paragraph alignment at the selection. `both` is OOXML's spelling of justify. */
|
|
2343
|
+
readonly alignment?: 'left' | 'center' | 'right' | 'both';
|
|
2344
|
+
/** Paragraph style id (`w:pStyle`) at the selection. */
|
|
2345
|
+
readonly styleId?: string;
|
|
2346
|
+
/**
|
|
2347
|
+
* Line spacing at the selection, in the unit its rule implies — LINES for `multiple`,
|
|
2348
|
+
* points for `exact` and `atLeast`. The same vocabulary `setLineSpacing` takes, so a
|
|
2349
|
+
* control can show what it reads and send back what it shows. Absent when the
|
|
2350
|
+
* selection's paragraphs disagree or state no line spacing.
|
|
2351
|
+
*/
|
|
2352
|
+
readonly lineSpacing?: {
|
|
2353
|
+
readonly rule: 'multiple' | 'exact' | 'atLeast';
|
|
2354
|
+
readonly value: number;
|
|
2355
|
+
};
|
|
2356
|
+
/**
|
|
2357
|
+
* Space above and below the paragraph at the selection, in points.
|
|
2358
|
+
*
|
|
2359
|
+
* The measurement the cascade STATES — `w:docDefaults`, the style chain and direct
|
|
2360
|
+
* formatting resolved together — not the gap the page finally draws. The two differ for a
|
|
2361
|
+
* paragraph carrying `w:beforeAutospacing`, where Word substitutes its own value and
|
|
2362
|
+
* ignores the measurement, and again where two paragraphs collapse their adjacent spacing.
|
|
2363
|
+
* Absent when the selection's paragraphs disagree or no level states it.
|
|
2364
|
+
*/
|
|
2365
|
+
readonly spaceBeforePt?: number;
|
|
2366
|
+
readonly spaceAfterPt?: number;
|
|
2367
|
+
/**
|
|
2368
|
+
* The paragraph flags the Paragraph dialog shows as checkboxes.
|
|
2369
|
+
*
|
|
2370
|
+
* Each is `true`, `false`, or `null` when the selection's paragraphs disagree — a
|
|
2371
|
+
* checkbox needs all three. Read through the cascade, so a flag a STYLE sets reads as on,
|
|
2372
|
+
* which is what the box has to show over a paragraph the page is visibly keeping with the
|
|
2373
|
+
* next. Absent on a `Run`, like every other selection-level field here.
|
|
2374
|
+
*/
|
|
2375
|
+
readonly paragraphFlags?: ParagraphFlags;
|
|
2376
|
+
/**
|
|
2377
|
+
* Which paragraph-level fields above are absent because the selection DISAGREES, as
|
|
2378
|
+
* opposed to because nothing states them.
|
|
2379
|
+
*
|
|
2380
|
+
* A `null`/absent value alone cannot tell those apart, and both readings have shipped as
|
|
2381
|
+
* bugs: a disagreement rendered as a concrete value is uncorrectable, because the value
|
|
2382
|
+
* that would fix it is the one already on screen; an absent value rendered as "mixed"
|
|
2383
|
+
* tells a single paragraph it disagrees with itself.
|
|
2384
|
+
*/
|
|
2385
|
+
readonly disagrees?: ParagraphDisagreements;
|
|
2386
|
+
/**
|
|
2387
|
+
* The paragraph's custom tab stops at the selection, cascade included. Absent when the
|
|
2388
|
+
* selection disagrees or the paragraphs have none.
|
|
2389
|
+
*/
|
|
2390
|
+
readonly tabStops?: readonly ParagraphTabStop[];
|
|
2391
|
+
/**
|
|
2392
|
+
* The EFFECTIVE paragraph indent at the selection — cascade and numbering merge
|
|
2393
|
+
* included, so a numbered item that authors no `w:ind` reports the indent its list
|
|
2394
|
+
* definition gives it. Absent when nothing is loaded, or when the selection is inside a
|
|
2395
|
+
* table (see {@link IndentFormatting}).
|
|
2396
|
+
*/
|
|
2397
|
+
readonly indent?: IndentFormatting;
|
|
2398
|
+
}
|
|
2399
|
+
/**
|
|
2400
|
+
* Indent at the selection, in twips.
|
|
2401
|
+
*
|
|
2402
|
+
* Unlike every other field here, this does NOT go absent when the selection's paragraphs
|
|
2403
|
+
* disagree. A ruler has to draw its handles somewhere, and Word draws them at the FIRST
|
|
2404
|
+
* selected paragraph's values — Select All is the commonest indent gesture, and hiding the
|
|
2405
|
+
* handles for it would be worse than showing one paragraph's truth. The values are
|
|
2406
|
+
* therefore always the first touched paragraph's, and {@link mixed} records per field
|
|
2407
|
+
* whether the rest agree.
|
|
2408
|
+
*
|
|
2409
|
+
* `firstLine` is ONE SIGNED offset: negative is a hanging indent. OOXML spells it as two
|
|
2410
|
+
* mutually exclusive attributes and this collapses them hanging-wins (§17.3.1.12), which
|
|
2411
|
+
* is the model Word itself keeps.
|
|
2412
|
+
*
|
|
2413
|
+
* Absent inside a table. The value would be correct there, but it is measured from the
|
|
2414
|
+
* cell's content edge while a ruler is drawn against the page's margin, and the ruler does
|
|
2415
|
+
* not know the cell.
|
|
2416
|
+
*/
|
|
2417
|
+
interface IndentFormatting {
|
|
2418
|
+
/** Left indent, signed. Negative pulls text into the margin, as Word allows. */
|
|
2419
|
+
readonly left: number;
|
|
2420
|
+
/** Right indent, signed. */
|
|
2421
|
+
readonly right: number;
|
|
2422
|
+
/** First-line offset from {@link left}, signed. Negative is a hanging indent. */
|
|
2423
|
+
readonly firstLine: number;
|
|
2424
|
+
/** Per field, whether the selection's paragraphs disagree about it. */
|
|
2425
|
+
readonly mixed: {
|
|
2426
|
+
readonly left: boolean;
|
|
2427
|
+
readonly right: boolean;
|
|
2428
|
+
readonly firstLine: boolean;
|
|
2429
|
+
};
|
|
2430
|
+
}
|
|
2431
|
+
/** A table: its rows, and the table style they resolve through. */
|
|
2432
|
+
interface Table {
|
|
2433
|
+
readonly kind: 'table';
|
|
2434
|
+
readonly rows: readonly TableRow[];
|
|
2435
|
+
readonly styleId?: string;
|
|
2436
|
+
}
|
|
2437
|
+
/** One table row. Cell count may vary between rows: `colSpan` and vertical merges reshape it. */
|
|
2438
|
+
interface TableRow {
|
|
2439
|
+
readonly cells: readonly TableCell[];
|
|
2440
|
+
}
|
|
2441
|
+
/**
|
|
2442
|
+
* One cell. Its `content` is ordinary blocks, so a cell may hold paragraphs, nested tables and
|
|
2443
|
+
* content controls alike.
|
|
2444
|
+
*/
|
|
2445
|
+
interface TableCell {
|
|
2446
|
+
readonly content: readonly Block[];
|
|
2447
|
+
/** Vertical merge span. Absent means 1. */
|
|
2448
|
+
readonly rowSpan?: number;
|
|
2449
|
+
/** `w:gridSpan`. Absent means 1. */
|
|
2450
|
+
readonly colSpan?: number;
|
|
2451
|
+
}
|
|
2452
|
+
/** Structured document tag (`w:sdt`). */
|
|
2453
|
+
interface ContentControl {
|
|
2454
|
+
readonly kind: 'contentControl';
|
|
2455
|
+
readonly id: string;
|
|
2456
|
+
readonly tag?: string;
|
|
2457
|
+
readonly alias?: string;
|
|
2458
|
+
readonly controlType: ContentControlType;
|
|
2459
|
+
readonly locked?: boolean;
|
|
2460
|
+
readonly content: readonly Block[];
|
|
2461
|
+
}
|
|
2462
|
+
/** Which kind of control a `w:sdt` is, and therefore what a value written into it must be. */
|
|
2463
|
+
type ContentControlType = 'richText' | 'plainText' | 'checkbox' | 'dropdown' | 'comboBox' | 'date' | 'picture' | 'repeatingSection';
|
|
2464
|
+
/**
|
|
2465
|
+
* The control kinds an insertion can author.
|
|
2466
|
+
*
|
|
2467
|
+
* A NARROWING of {@link ContentControlType}, not a separate vocabulary: a kind read off an
|
|
2468
|
+
* existing control can be handed straight back to `insertContentControl`. Three kinds are
|
|
2469
|
+
* absent because an insertion would have to invent what they carry — a checkbox needs its two
|
|
2470
|
+
* declared glyph states, a picture needs an image part, and a repeating section is a container
|
|
2471
|
+
* whose items have their own verbs. Reading still answers the wider type; a document may hold
|
|
2472
|
+
* kinds this cannot create.
|
|
2473
|
+
*
|
|
2474
|
+
* `dropDownList` is the same kind as `dropdown`, spelt as OOXML spells it. Both are accepted,
|
|
2475
|
+
* so a type read off a control can be handed back without translating it — and the OOXML
|
|
2476
|
+
* spelling is the one the automation protocol takes, so a caller who uses both surfaces can
|
|
2477
|
+
* write that one everywhere.
|
|
2478
|
+
*/
|
|
2479
|
+
type InsertableContentControlType = Extract<ContentControlType, 'richText' | 'plainText' | 'dropdown' | 'comboBox' | 'date'> | 'dropDownList';
|
|
2480
|
+
/**
|
|
2481
|
+
* Narrows a content-control query. Fields combine with AND; an empty filter matches every
|
|
2482
|
+
* control.
|
|
2483
|
+
*/
|
|
2484
|
+
interface ContentControlFilter {
|
|
2485
|
+
readonly tag?: string;
|
|
2486
|
+
readonly alias?: string;
|
|
2487
|
+
readonly controlType?: ContentControlType;
|
|
2488
|
+
}
|
|
2489
|
+
/**
|
|
2490
|
+
* A position in one story: a paragraph and a UTF-16 offset inside it.
|
|
2491
|
+
*
|
|
2492
|
+
* The same offset space the ops and the caret use, so an anchor read here can be handed
|
|
2493
|
+
* straight back to a selection without re-deriving anything.
|
|
2494
|
+
*/
|
|
2495
|
+
interface DocAnchorRange {
|
|
2496
|
+
/** Canonical part name of the story the range lives in, e.g. `/word/document.xml`. */
|
|
2497
|
+
readonly part: string;
|
|
2498
|
+
readonly startParagraphId: string;
|
|
2499
|
+
readonly startOffset: number;
|
|
2500
|
+
/** May sit in a later paragraph: the range markers are independent elements. */
|
|
2501
|
+
readonly endParagraphId: string;
|
|
2502
|
+
readonly endOffset: number;
|
|
2503
|
+
}
|
|
2504
|
+
/**
|
|
2505
|
+
* One comment or reply, as `comments.xml` records it.
|
|
2506
|
+
*
|
|
2507
|
+
* A reply is a comment with a `parentId`; OOXML gives replies no separate element, so the thread
|
|
2508
|
+
* is reconstructed from that link rather than from nesting.
|
|
2509
|
+
*/
|
|
2510
|
+
interface DocComment {
|
|
2511
|
+
readonly id: string;
|
|
2512
|
+
readonly author: string;
|
|
2513
|
+
/**
|
|
2514
|
+
* OPTIONAL, because `CT_Comment` makes `@w:date` optional and files omit it. A comment
|
|
2515
|
+
* with no date is a comment, not a defect, and fabricating one is a content change.
|
|
2516
|
+
*/
|
|
2517
|
+
readonly date?: string;
|
|
2518
|
+
readonly text: string;
|
|
2519
|
+
readonly parentId?: string;
|
|
2520
|
+
readonly resolved?: boolean;
|
|
2521
|
+
/**
|
|
2522
|
+
* Where the comment is anchored, absent when the file gave it no usable range.
|
|
2523
|
+
*
|
|
2524
|
+
* A comment lives in `comments.xml` and is placed by markers in a STORY, so the story is
|
|
2525
|
+
* part of the address: a comment anchored in a header belongs to a part the body never saw.
|
|
2526
|
+
*/
|
|
2527
|
+
readonly anchor?: DocAnchorRange;
|
|
2528
|
+
/**
|
|
2529
|
+
* True when the file gave this comment no usable range — a reference with no markers, or a
|
|
2530
|
+
* start with no end. Reported rather than dropped: a reviewer's remark vanishing silently
|
|
2531
|
+
* is worse than one that says it lost its text.
|
|
2532
|
+
*/
|
|
2533
|
+
readonly orphaned?: boolean;
|
|
2534
|
+
}
|
|
2535
|
+
/**
|
|
2536
|
+
* What kind of decision a revision represents.
|
|
2537
|
+
*
|
|
2538
|
+
* Wider than insert/delete/format, and it has to be. `w:moveFrom`/`w:moveTo` are not a
|
|
2539
|
+
* deletion and an insertion — resolving one half alone duplicates or loses the content;
|
|
2540
|
+
* `w:pPr/w:rPr/w:ins|w:del` decorates no characters at all and merges paragraphs when
|
|
2541
|
+
* resolved; a row or cell revision is structural. A reviewer shown only three kinds is a
|
|
2542
|
+
* reviewer who never learns about the rest.
|
|
2543
|
+
*/
|
|
2544
|
+
type RevisionType = 'insert' | 'delete'
|
|
2545
|
+
/** A deletion and an insertion that are one edit: text typed over a selection. */
|
|
2546
|
+
| 'replace' | 'moveFrom' | 'moveTo'
|
|
2547
|
+
/** `w:rPrChange` / `w:pPrChange` — the words are unchanged, their formatting is not. */
|
|
2548
|
+
| 'format'
|
|
2549
|
+
/** `w:pPr/w:rPr/w:ins|w:del` — a paragraph split or merge. */
|
|
2550
|
+
| 'paragraphMark'
|
|
2551
|
+
/** A row, cell, section or grid revision. */
|
|
2552
|
+
| 'structural';
|
|
2553
|
+
/**
|
|
2554
|
+
* One tracked change.
|
|
2555
|
+
*
|
|
2556
|
+
* Addressing needs BOTH `id` and `part`: `@w:id` is unique only within a part, so an id alone
|
|
2557
|
+
* names two revisions in any package that has a header or a comments part.
|
|
2558
|
+
*/
|
|
2559
|
+
interface Revision {
|
|
2560
|
+
/** Numeric, and unique only WITHIN a part. Pair with `part` to address one. */
|
|
2561
|
+
readonly id: number;
|
|
2562
|
+
readonly type: RevisionType;
|
|
2563
|
+
readonly author: string;
|
|
2564
|
+
/**
|
|
2565
|
+
* OPTIONAL. `CT_TrackChange` requires `@w:id` and `@w:author` and makes `@w:date`
|
|
2566
|
+
* optional, and producers that omit it are ordinary. Requiring it here forced either a
|
|
2567
|
+
* fabricated date — a content change — or dropping the revision from the list.
|
|
2568
|
+
*/
|
|
2569
|
+
readonly date?: string;
|
|
2570
|
+
/**
|
|
2571
|
+
* REQUIRED, and a canonical PART NAME rather than a three-value enum.
|
|
2572
|
+
*
|
|
2573
|
+
* `@w:id` is unique only within a part, so an address without one names two revisions in a
|
|
2574
|
+
* package that has both. The enum could not express the parts revisions actually occur in:
|
|
2575
|
+
* `header3.xml`, `footer1.xml`, `comments.xml`, and `styles.xml`, which carries
|
|
2576
|
+
* `w:pPrChange` inside style definitions with ids that collide with `document.xml`.
|
|
2577
|
+
*/
|
|
2578
|
+
readonly part: string;
|
|
2579
|
+
}
|
|
2580
|
+
/** `w:sectPr`: the page a section lays out on. Twips throughout, as the file stores them. */
|
|
2581
|
+
interface SectionProperties {
|
|
2582
|
+
readonly pageSize: {
|
|
2583
|
+
widthTwips: number;
|
|
2584
|
+
heightTwips: number;
|
|
2585
|
+
};
|
|
2586
|
+
readonly margins: PageMargins;
|
|
2587
|
+
readonly columns?: {
|
|
2588
|
+
count: number;
|
|
2589
|
+
gapTwips: number;
|
|
2590
|
+
};
|
|
2591
|
+
/** `w:titlePg` — whether the section's first page takes the `first` header/footer variant. */
|
|
2592
|
+
readonly titlePage?: boolean;
|
|
2593
|
+
}
|
|
2594
|
+
/** Page margins in twips. */
|
|
2595
|
+
interface PageMargins {
|
|
2596
|
+
readonly topTwips: number;
|
|
2597
|
+
readonly rightTwips: number;
|
|
2598
|
+
readonly bottomTwips: number;
|
|
2599
|
+
readonly leftTwips: number;
|
|
2600
|
+
}
|
|
2601
|
+
/**
|
|
2602
|
+
* `styles.xml`, split by the three style families that address separately.
|
|
2603
|
+
*
|
|
2604
|
+
* Keyed by style ID rather than by the name a reader sees, because the ID is what a paragraph or
|
|
2605
|
+
* run actually references.
|
|
2606
|
+
*/
|
|
2607
|
+
interface StyleDefinitions {
|
|
2608
|
+
readonly paragraph: ReadonlyMap<string, StyleDefinition>;
|
|
2609
|
+
readonly character: ReadonlyMap<string, StyleDefinition>;
|
|
2610
|
+
readonly table: ReadonlyMap<string, StyleDefinition>;
|
|
2611
|
+
}
|
|
2612
|
+
/** One style: the ID content references, the name a reader sees, and its inheritance link. */
|
|
2613
|
+
interface StyleDefinition {
|
|
2614
|
+
readonly id: string;
|
|
2615
|
+
readonly name: string;
|
|
2616
|
+
/** `w:basedOn` — the style this one inherits from. Absent at the root of a chain. */
|
|
2617
|
+
readonly basedOn?: string;
|
|
2618
|
+
}
|
|
2619
|
+
/** A paragraph's list membership: which `numbering.xml` definition, and at which level. */
|
|
2620
|
+
interface NumberingRef {
|
|
2621
|
+
readonly numId: string;
|
|
2622
|
+
/** Zero-based. OOXML numbering has nine levels, 0 through 8. */
|
|
2623
|
+
readonly level: number;
|
|
2624
|
+
}
|
|
2625
|
+
/**
|
|
2626
|
+
* A colour as the FILE expresses it, not as a resolved RGB string.
|
|
2627
|
+
*
|
|
2628
|
+
* A theme colour stays a theme reference — slot plus tint or shade — so that changing the theme
|
|
2629
|
+
* repaints the document the way Word does. Flattening to hex at read time would freeze the
|
|
2630
|
+
* resolved value and break that link. `auto` is Word's "let the renderer decide", usually black
|
|
2631
|
+
* on white.
|
|
2632
|
+
*/
|
|
2633
|
+
type ColorValue = {
|
|
2634
|
+
readonly kind: 'hex';
|
|
2635
|
+
readonly value: string;
|
|
2636
|
+
} | {
|
|
2637
|
+
readonly kind: 'theme';
|
|
2638
|
+
readonly slot: string;
|
|
2639
|
+
readonly tint?: number;
|
|
2640
|
+
readonly shade?: number;
|
|
2641
|
+
} | {
|
|
2642
|
+
readonly kind: 'auto';
|
|
2643
|
+
};
|
|
2644
|
+
/** `theme1.xml` — what a {@link ColorValue} of kind `theme` resolves against. */
|
|
2645
|
+
interface Theme {
|
|
2646
|
+
readonly colorScheme: ThemeColorScheme;
|
|
2647
|
+
readonly fontScheme?: Record<string, string>;
|
|
2648
|
+
}
|
|
2649
|
+
/** Theme colour slots (`accent1`, `dk1`, `lt2`, …) to hex. */
|
|
2650
|
+
type ThemeColorScheme = Readonly<Record<string, string>>;
|
|
2651
|
+
/** A watermark, which OOXML expresses as either text or an image — never both meaningfully. */
|
|
2652
|
+
interface Watermark {
|
|
2653
|
+
readonly text?: string;
|
|
2654
|
+
readonly imageData?: Uint8Array;
|
|
2655
|
+
}
|
|
2656
|
+
/** A size in EMUs, the unit DrawingML stores extents in. 914400 EMU = 1 inch. */
|
|
2657
|
+
interface Extent {
|
|
2658
|
+
readonly widthEmu: number;
|
|
2659
|
+
readonly heightEmu: number;
|
|
2660
|
+
}
|
|
2661
|
+
/** A font the document names, and whether its bytes travel inside the package. */
|
|
2662
|
+
interface FontDefinition {
|
|
2663
|
+
readonly family: string;
|
|
2664
|
+
readonly embedded: boolean;
|
|
2665
|
+
}
|
|
2666
|
+
/** An axis-aligned rectangle in points, the unit layout works in throughout. */
|
|
2667
|
+
interface Rect {
|
|
2668
|
+
readonly x: number;
|
|
2669
|
+
readonly y: number;
|
|
2670
|
+
readonly width: number;
|
|
2671
|
+
readonly height: number;
|
|
2672
|
+
}
|
|
2673
|
+
/** A position in points. */
|
|
2674
|
+
interface Point {
|
|
2675
|
+
readonly x: number;
|
|
2676
|
+
readonly y: number;
|
|
2677
|
+
}
|
|
2678
|
+
/** What every subscription returns. Calling it twice is safe. */
|
|
2679
|
+
type Unsubscribe = () => void;
|
|
2680
|
+
|
|
1934
2681
|
/** How deep controls may nest before a walk stops descending. Shared by every lane. */
|
|
1935
2682
|
declare const MAX_CONTENT_CONTROL_NESTING = 32;
|
|
1936
2683
|
/** Cap on controls one walk reports, so a hostile file cannot make a read unbounded. */
|
|
@@ -2373,10 +3120,14 @@ type TreeDocOp = SetFieldCodeOp | {
|
|
|
2373
3120
|
* changes made one decision, and one undo should restore all of them.
|
|
2374
3121
|
*/
|
|
2375
3122
|
readonly op: 'acceptAllRevisions';
|
|
3123
|
+
/** Exact canonical sites selected by bulk preflight. */
|
|
3124
|
+
readonly siteNodeIds?: readonly string[];
|
|
2376
3125
|
/** Internal shared-notes scope. When present, this must be the canonical id of a note root. */
|
|
2377
3126
|
readonly scopeRootId?: string;
|
|
2378
3127
|
} | {
|
|
2379
3128
|
readonly op: 'rejectAllRevisions';
|
|
3129
|
+
/** Exact canonical sites selected by bulk preflight. */
|
|
3130
|
+
readonly siteNodeIds?: readonly string[];
|
|
2380
3131
|
/** Internal shared-notes scope. When present, this must be the canonical id of a note root. */
|
|
2381
3132
|
readonly scopeRootId?: string;
|
|
2382
3133
|
} | {
|
|
@@ -3262,4 +4013,4 @@ type TreeOpResult = {
|
|
|
3262
4013
|
readonly detail?: string;
|
|
3263
4014
|
};
|
|
3264
4015
|
|
|
3265
|
-
export { type
|
|
4016
|
+
export { type RevisionBatchSkipReason as $, type IndentFormatting as A, type Block as B, type CommentRecord as C, type DocxDocument as D, type ExecResult as E, type ParagraphFlags as F, type ParagraphTabStop as G, type HeaderFooterSet as H, type InsertableContentControlType as I, type RevisionType as J, type Section as K, type SectionProperties as L, type StyleDefinition as M, type Theme as N, type OoxmlPart as O, type Paragraph as P, type ThemeColorScheme as Q, type ReviewModelInput as R, type StyleDefinitions as S, type Table as T, type OoxmlNodeId as U, type OoxmlGenericElementNode as V, type TreeDocOp as W, type OoxmlPackageLimits as X, type OoxmlPackageRejection as Y, type RevisionBatchEntry as Z, type RevisionBatchResult as _, type ReviewItem as a, type CommentPosition as a$, type OoxmlProperty as a0, type OoxmlElement as a1, type OoxmlContentControlNode as a2, type OoxmlContentControlContentNode as a3, type DrawingProjection as a4, type TreeOpRejection as a5, type AutomationTableMutation as a6, type SourceCrop as a7, type DrawingKind as a8, type ImageWrapTarget as a9, type OoxmlSeparatorNode as aA, type DrawingTreeDocOp as aB, type ImpactClass as aC, type TreeDocColorValue as aD, IMAGE_WRAP_TARGETS as aE, TEXT_FORM_FORMATS as aF, type TableBorderStyle as aG, type DrawingAccessibility as aH, type DrawingImageEffects as aI, type DrawingTransform as aJ, type VectorShapeProjection as aK, type OoxmlDrawingNode as aL, type OoxmlInvariantResult as aM, type RelationshipRecord as aN, type OoxmlInvariantIssue as aO, type OoxmlHardBreakNode as aP, type OoxmlFldCharNode as aQ, type OoxmlFldSimpleNode as aR, type OoxmlInstrTextNode as aS, type OoxmlAttribute as aT, type TreeOpResult as aU, type CommentThreadState as aV, ACCEPTED_PARAGRAPH_PROPERTIES as aW, ACCEPTED_RUN_PROPERTIES as aX, CONTENT_CONTROL_ID_MAX as aY, CONTENT_CONTROL_PROPERTY_ORDER as aZ, type CommentAnchor as a_, type DrawingPositionInput as aa, type DrawingLocks as ab, type ParagraphFormatCommand as ac, type Watermark as ad, type Rect as ae, type SelectionPin as af, type Unsubscribe as ag, type DocxDocumentJSON as ah, type DrawingHorizontalReferenceFrame as ai, type DrawingVerticalReferenceFrame as aj, type FontDefinition as ak, type NumberingRef as al, type PageMargins as am, type ParagraphDisagreements as an, type Point as ao, type Run as ap, type TableCell as aq, type TableRow as ar, type RevisionAttributionInput as as, type OoxmlParagraphNode as at, type OoxmlNoteNode as au, type OoxmlContinuationSeparatorNode as av, type OoxmlEndnotesNode as aw, type OoxmlFootnotesNode as ax, type OoxmlNoteRefNode as ay, type OoxmlNoteReferenceNode as az, type ReviewRevisionItem as b, type OoxmlRunNode as b$, type CommitTextFormFieldOp as b0, type ContentControlCheckbox as b1, type ContentControlCheckboxState as b2, type ContentControlDataBinding as b3, type ContentControlDateFormat as b4, type ContentControlEntry as b5, type ContentControlKind as b6, type ContentControlLevel as b7, type ContentControlListItem as b8, type ContentControlLock as b9, type OoxmlContentControlCheckedNode as bA, type OoxmlContentControlCheckedStateNode as bB, type OoxmlContentControlComboBoxNode as bC, type OoxmlContentControlDataBindingNode as bD, type OoxmlContentControlDateFormatNode as bE, type OoxmlContentControlDateNode as bF, type OoxmlContentControlDropDownListNode as bG, type OoxmlContentControlEndPropertiesNode as bH, type OoxmlContentControlLidNode as bI, type OoxmlContentControlListItemNode as bJ, type OoxmlContentControlPropertiesNode as bK, type OoxmlContentControlStoreMappedDataAsNode as bL, type OoxmlContentControlTextNode as bM, type OoxmlContentControlUncheckedStateNode as bN, type OoxmlDocumentNode as bO, type OoxmlExternalTarget as bP, type OoxmlGenericExtensionAttribute as bQ, type OoxmlHyperlinkNode as bR, type OoxmlInvariantIssueCode as bS, type OoxmlKnownNodeAttribute as bT, type OoxmlNamespaceBinding as bU, type OoxmlNodeIdentityRules as bV, type OoxmlPackageResult as bW, type OoxmlParagraphPropertiesNode as bX, type OoxmlPartMetadata as bY, type OoxmlReadRejection as bZ, type OoxmlReadResult as b_, type ContentControlProperties as ba, type ContentTypeError as bb, type ContentTypeIndex as bc, type ContentTypeRecords as bd, DEFAULT_OOXML_PACKAGE_LIMITS as be, DEFAULT_ZIP_LIMITS as bf, type DefaultRecord as bg, type DeleteTextOp as bh, HYPERLINK_RELATIONSHIP_TYPE as bi, type HyperlinkKind as bj, type HyperlinkTarget as bk, IMAGE_RELATIONSHIP_TYPE as bl, type ImageRelationshipResolution as bm, type IndexResult as bn, type InsertTextOp as bo, MAX_CONTENT_CONTROLS_PER_PART as bp, MAX_CONTENT_CONTROL_NESTING as bq, type NameRejection as br, type NameResult as bs, OFFICE_RELATIONSHIP_NAMESPACE_URI as bt, OOXML_NODE_IDENTITY_RULES as bu, type OoxmlBodyNode as bv, type OoxmlBookmarkEndNode as bw, type OoxmlBookmarkStartNode as bx, type OoxmlContentControlCalendarNode as by, type OoxmlContentControlCheckboxNode as bz, type ReviewCommentItem as c, isValidMime as c$, type OoxmlRunPropertiesNode as c0, type OoxmlTabNode as c1, type OoxmlTextElementNode as c2, type OoxmlTextNode as c3, type OoxmlWmlValAttribute as c4, type OoxmlXmlSpaceAttribute as c5, type OverrideRecord as c6, type RelationshipError as c7, type RelationshipSetResult as c8, type RelationshipTargetResolver as c9, childElements as cA, commentAnchorsOfStory as cB, commentsOfPart as cC, contentControlContentChildren as cD, contentControlContentNodeOf as cE, contentControlEndPropertiesNodeOf as cF, contentControlLevelOf as cG, contentControlPropertiesNodeOf as cH, contentControlPropertiesOf as cI, contentControlTextOf as cJ, contentControlsIn as cK, detectDuplicateNames as cL, extensionKey as cM, findContentControl as cN, findElement as cO, firstReviewRange as cP, flattenContentControls as cQ, hasAnyComment as cR, hyperlinkAnchorOf as cS, hyperlinkRelationshipIdOf as cT, hyperlinkTargetOf as cU, isContentControlContentNode as cV, isContentControlNode as cW, isContentControlWrapper as cX, isContentRevisionKind as cY, isHyperlinkNode as cZ, isRangeMarkerKind as c_, type ResolveResult as ca, type ResolvedRelationship as cb, type SetTextFormFieldDefaultOp as cc, TABLE_BORDER_STYLES as cd, type TabStopWrite as ce, type TargetMode as cf, type TextFormFieldOptions as cg, type TextFormFieldRange as ch, type TextFormFieldType as ci, type TreeDocOpKind as cj, type TreeOpEffect as ck, W15_NAMESPACE_URI as cl, WML_NAMESPACE_URI as cm, XMLNS_NAMESPACE_URI as cn, XML_NAMESPACE_URI as co, type XmlLimits as cp, type XmlNode as cq, type XmlRejection as cr, type XmlResult as cs, type ZipLimits as ct, type ZipReadResult as cu, type ZipRejection as cv, allocateContentControlId as cw, asciiFold as cx, buildContentTypeIndex as cy, buildRelationshipSet as cz, type ReviewCustomItem as d, lockForbidsEdit as d0, lockForbidsRemoval as d1, normalizePartName as d2, orderedContentControlProperties as d3, parseContentControlId as d4, partNameKey as d5, planRevisionBatch as d6, projectDrawing as d7, readOnOffChild as d8, readOoxmlPackage as d9, readOoxmlPart as da, readXml as db, readZip as dc, resolveContentControlLock as dd, resolveContentType as de, resolveImageRelationship as df, resolveInternalTarget as dg, resolveRelationship as dh, reviewItemKey as di, reviewItemRanges as dj, textContent as dk, textFormFieldsOf as dl, threadStateOfPart as dm, validateExternalTarget as dn, withPart as dp, writeOoxmlPackage as dq, writeZip as dr, type VectorShapeComponent as ds, activeReviewItem as dt, reviewItemPositionRank as du, reviewItemsAt as dv, reviewThreadRootOf as dw, type ReviewPosition as e, type ReviewRange as f, type ReviewRevisionKind as g, type RevisionAddress as h, type OoxmlNode as i, type OoxmlPackage as j, type ContentControlType as k, type DocTarget as l, type RunFormatting as m, type Extent as n, type ContainerRef as o, type ContentControlFilter as p, type DocRange as q, type Revision as r, type DocComment as s, type ColorValue as t, type ContentControl as u, type DocAnchor as v, type DocAnchorRange as w, type DocLocation as x, type DocumentBody as y, type ExecErrorCode as z };
|