@docx-editor.dev/core 2.30.0 → 2.32.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.
Files changed (133) hide show
  1. package/README.md +24 -0
  2. package/dist/automation.cjs +1 -1
  3. package/dist/automation.d.ts +18 -27
  4. package/dist/automation.js +1 -1
  5. package/dist/binding.cjs +1 -1
  6. package/dist/binding.d.ts +17 -16
  7. package/dist/binding.js +1 -1
  8. package/dist/bookmark-names-DDuAra_V.d.ts +37 -0
  9. package/dist/{chrome-print-BM3Js-6X.d.ts → chrome-print-CznJ0ucN.d.ts} +361 -41
  10. package/dist/chunk-25EXMBV2.cjs +5 -0
  11. package/dist/chunk-2CWQY27B.cjs +1 -0
  12. package/dist/chunk-3IEXDEFH.cjs +7 -0
  13. package/dist/chunk-65XBN67F.cjs +2 -0
  14. package/dist/chunk-6NVZNB7O.cjs +3 -0
  15. package/dist/chunk-6UDJUI3W.cjs +2 -0
  16. package/dist/chunk-ACLR4DMK.js +1 -0
  17. package/dist/{chunk-RJCQGJR7.js → chunk-B2BEELUE.js} +1 -1
  18. package/dist/chunk-DDFHKQFU.js +30 -0
  19. package/dist/chunk-E4IAO4CY.cjs +2 -0
  20. package/dist/chunk-ETDZFNMI.js +2 -0
  21. package/dist/chunk-FDSL5OJU.cjs +30 -0
  22. package/dist/chunk-FS7CMYLT.js +4 -0
  23. package/dist/chunk-GDS24SZN.js +30 -0
  24. package/dist/chunk-GIY6NT2X.js +5 -0
  25. package/dist/chunk-GWM3AKUD.js +18 -0
  26. package/dist/chunk-HDOXACHP.js +2 -0
  27. package/dist/chunk-IILEENID.js +1 -0
  28. package/dist/chunk-L5TYBFDB.js +1 -0
  29. package/dist/chunk-MNF2K7NN.cjs +30 -0
  30. package/dist/chunk-O324RB6R.cjs +1 -0
  31. package/dist/chunk-OKMEMSKB.cjs +1 -0
  32. package/dist/chunk-QXJKYNYZ.js +1 -0
  33. package/dist/chunk-RALTVLB6.js +2 -0
  34. package/dist/chunk-SRVKFUFI.js +3 -0
  35. package/dist/chunk-TELQ52LG.cjs +1 -0
  36. package/dist/chunk-TJHE5EET.cjs +1 -0
  37. package/dist/chunk-UMMRURPE.js +7 -0
  38. package/dist/chunk-WN7ICTA5.js +1 -0
  39. package/dist/{chunk-FLBEJC6X.cjs → chunk-XJYZVGQR.cjs} +1 -1
  40. package/dist/chunk-ZGTIE3QJ.cjs +4 -0
  41. package/dist/chunk-ZOZI27AW.cjs +18 -0
  42. package/dist/collaboration/replication.cjs +1 -1
  43. package/dist/collaboration/replication.d.ts +20 -5
  44. package/dist/collaboration/replication.js +1 -1
  45. package/dist/collaboration.cjs +1 -1
  46. package/dist/collaboration.d.ts +5 -6
  47. package/dist/collaboration.js +1 -1
  48. package/dist/contracts/document.d.ts +3 -3
  49. package/dist/contracts/editor.d.ts +13 -10
  50. package/dist/contracts/interaction.d.ts +2 -2
  51. package/dist/contracts/modules.d.ts +15 -13
  52. package/dist/contracts/types.d.ts +135 -2
  53. package/dist/{custom-node-writes-0v0Kgw1T.d.ts → custom-node-writes-CLJKGD9t.d.ts} +7 -2
  54. package/dist/{diagnostic-context-CcAO4q1s.d.ts → diagnostic-context-BtDUY3v2.d.ts} +3 -2
  55. package/dist/{diagnostic-hints-2Bke6H_w.d.ts → diagnostic-hints-DK8-V0fk.d.ts} +2 -2
  56. package/dist/{document-protection-8eyMWIJ0.d.ts → document-protection-NaniLHWF.d.ts} +1 -1
  57. package/dist/{editor-DaEJd2so.d.ts → editor-DZwOTmlR.d.ts} +386 -279
  58. package/dist/editor-fonts-D_-vjuJi.d.ts +53 -0
  59. package/dist/{editor-scope-7o9xweiJ.d.ts → editor-scope-B3L-1ALc.d.ts} +57 -4
  60. package/dist/editor.cjs +1 -1
  61. package/dist/editor.css +6 -4
  62. package/dist/editor.d.ts +646 -31
  63. package/dist/editor.js +1 -1
  64. package/dist/export.cjs +2 -2
  65. package/dist/export.d.ts +9 -16
  66. package/dist/export.js +2 -2
  67. package/dist/{failure-NS2lsya4.d.ts → failure-6KGFrDO9.d.ts} +1 -1
  68. package/dist/{font-resolver-CL9BVKZo.d.ts → font-resolver-BlQNGdvR.d.ts} +1 -1
  69. package/dist/{headless-document-view-DZQN8Bnx.d.ts → headless-document-view-Bcz9_Qva.d.ts} +115 -4
  70. package/dist/index.cjs +1 -1
  71. package/dist/index.d.ts +27 -26
  72. package/dist/index.js +1 -1
  73. package/dist/{layout-shaping-cEnVrhWg.d.ts → layout-shaping-E5J4Z1Gf.d.ts} +1 -1
  74. package/dist/layout.cjs +1 -1
  75. package/dist/layout.d.ts +95 -23
  76. package/dist/layout.js +1 -1
  77. package/dist/{note-properties-9FH8zAeG.d.ts → note-properties-Ds5R2_3F.d.ts} +1 -1
  78. package/dist/output.cjs +1 -1
  79. package/dist/output.d.ts +24 -10
  80. package/dist/output.js +1 -1
  81. package/dist/{protocol-CZ1uUlPO.d.ts → protocol-DKa4qt7F.d.ts} +167 -5
  82. package/dist/{review-paragraph-order-CqVelc5A.d.ts → review-paragraph-order-Dc17w_6v.d.ts} +1 -1
  83. package/dist/revision-projection-Cn6rZJ7H.d.ts +258 -0
  84. package/dist/{semantic-cell-selection-Dr9yxFZt.d.ts → semantic-cell-selection-BaUR0iJ4.d.ts} +2 -2
  85. package/dist/{semantic-interaction-Dc3pf3hr.d.ts → semantic-interaction-CJoHLoOl.d.ts} +1 -1
  86. package/dist/{semantic-paint-Bz3FBAoH.d.ts → semantic-paint-BPw_n0li.d.ts} +7 -4
  87. package/dist/{semantic-record-queries-Bx0pl6kL.d.ts → semantic-record-queries-C0rJ3sB4.d.ts} +1 -1
  88. package/dist/{semantic-records-CjcF26ZL.d.ts → semantic-records-BvN-WWst.d.ts} +365 -512
  89. package/dist/store.cjs +1 -1
  90. package/dist/store.d.ts +47 -22
  91. package/dist/store.js +1 -1
  92. package/dist/{types-barrel-CA0xB8kH.d.ts → tree-op-types-C_S2niXW.d.ts} +1239 -747
  93. package/dist/{tree-package-store-DKhdEVym.d.ts → tree-package-store-CRHvMyNj.d.ts} +676 -646
  94. package/dist/{tree-session-contract-CwnTEVLF.d.ts → tree-session-contract-D1awo_dA.d.ts} +26 -13
  95. package/dist/unsupported-elements-CVos5cqe.d.ts +23 -0
  96. package/docs/accept-reject-without-scrolling.md +95 -0
  97. package/docs/comment-on-found-text.md +72 -0
  98. package/docs/custom-review-cards.md +178 -0
  99. package/docs/highlight-ranges.md +48 -0
  100. package/docs/index.md +36 -0
  101. package/docs/propose-rewrite.md +247 -0
  102. package/docs/tracked-replacement.md +68 -0
  103. package/package.json +3 -2
  104. package/dist/chunk-2PV5L5NJ.js +0 -5
  105. package/dist/chunk-5OTS2EJ7.js +0 -7
  106. package/dist/chunk-5P4223J4.cjs +0 -27
  107. package/dist/chunk-5RRAZMBU.cjs +0 -1
  108. package/dist/chunk-5SPITS5F.js +0 -18
  109. package/dist/chunk-6JIJOZDW.js +0 -1
  110. package/dist/chunk-7ATNKARV.js +0 -2
  111. package/dist/chunk-BGCUTKWE.cjs +0 -5
  112. package/dist/chunk-BTQKU64Q.cjs +0 -1
  113. package/dist/chunk-EBCXSH2W.js +0 -3
  114. package/dist/chunk-ERECKTIR.cjs +0 -2
  115. package/dist/chunk-HYASLE2G.cjs +0 -1
  116. package/dist/chunk-JC47NRJC.cjs +0 -3
  117. package/dist/chunk-KJRTNY2Q.cjs +0 -2
  118. package/dist/chunk-NKPUH3QJ.js +0 -1
  119. package/dist/chunk-PF5NJWS3.js +0 -2
  120. package/dist/chunk-PWTRJSES.cjs +0 -18
  121. package/dist/chunk-QFKGI242.cjs +0 -30
  122. package/dist/chunk-RPPV4S6T.cjs +0 -4
  123. package/dist/chunk-T32MGBJS.js +0 -1
  124. package/dist/chunk-UM26GH5B.js +0 -30
  125. package/dist/chunk-VRCZBFLH.js +0 -27
  126. package/dist/chunk-WF7JZ755.cjs +0 -1
  127. package/dist/chunk-WK5X2MMA.cjs +0 -7
  128. package/dist/chunk-WPDD2Y32.js +0 -2
  129. package/dist/chunk-YBMWBXST.cjs +0 -2
  130. package/dist/chunk-YZGUBCHP.js +0 -1
  131. package/dist/chunk-ZOS2PM4A.js +0 -4
  132. package/dist/image-resources-Bipz8toD.d.ts +0 -211
  133. package/dist/omml-equation-DP2WpUbK.d.ts +0 -97
@@ -1,139 +1,14 @@
1
- import { q as ResolvedRevisionMarkup, a as ReviewDisplayMode } from './semantic-records-CjcF26ZL.js';
2
- import { t as DocAnchor, g as ReviewRevisionKind, c as ReviewCommentItem, b as ReviewRevisionItem, d as ReviewCustomItem, aJ as SourceCrop, Y as DrawingKind, a1 as ImageWrapTarget, _ as DrawingPositionInput, Z as DrawingLocks, r as ColorValue, x as ExecErrorCode, a5 as ParagraphFormatCommand, af as Watermark, E as ExecResult, n as ContentControlFilter, o as DocRange, k as RunFormatting, p as Revision, a7 as Rect, ab as SelectionPin, ae as Unsubscribe } from './types-barrel-CA0xB8kH.js';
3
- import { H as HistoryDiagnostic, V as ViewScope, b as HistoryGroup, a as EditorExecOptions, E as EditorScope } from './editor-scope-7o9xweiJ.js';
1
+ import { d as ResolvedRevisionMarkup, a as ReviewDisplayMode } from './revision-projection-Cn6rZJ7H.js';
2
+ import { ResolvedReviewPane } from './contracts/types.js';
3
+ import { V as ViewScope, b as HistoryDiagnostic, c as HistoryGroup, a as EditorExecOptions, E as EditorScope, d as HistoryGroupOptions } from './editor-scope-B3L-1ALc.js';
4
+ import { E as EditorFontErrorCode, a as FontFaceRequest } from './editor-fonts-D_-vjuJi.js';
5
+ import { t as DocAnchor, g as ReviewRevisionKind, c as ReviewCommentItem, b as ReviewRevisionItem, d as ReviewCustomItem, aT as SourceCrop, a8 as DrawingKind, ag as ImageWrapTarget, aa as DrawingPositionInput, a9 as DrawingLocks, af as ImageResourceState, r as ColorValue, x as ExecErrorCode, ah as ParagraphFormatCommand, an as SupportedImageMime, ar as Watermark, E as ExecResult, at as WatermarkState, n as ContentControlFilter, o as DocRange, k as RunFormatting, p as Revision, ak as Rect, am as SelectionPin, ao as Unsubscribe } from './tree-op-types-C_S2niXW.js';
6
+ import { C as CollaborationDiagnosticCode, c as CustomNodeDiagnosticCode, D as DiagnosticErrorName, F as FailureStage, B as ByteSizeBucket, b as CountBucket, f as DocumentOpenDiagnosticCode, a as DocumentPartKind, g as DocumentSaveDiagnosticCode, E as EditDiagnosticCode, j as ReviewDiagnosticCode, k as ReviewOperation, R as ReviewChangeKind, i as FormattingChangeKind, h as FontDiagnosticCode, H as HistoryDiagnosticCode, P as PerformanceDiagnosticCode } from './diagnostic-hints-DK8-V0fk.js';
4
7
  import { DocEdits, DocQueries, DocQueryResults, ContentControlSummary } from './contracts/document.js';
5
8
  import { InteractionOutcome } from './contracts/interaction.js';
6
- import { a as SemanticSelection, S as SemanticPosition } from './semantic-interaction-Dc3pf3hr.js';
7
- import { I as ImageResourceState, S as SupportedImageMime } from './image-resources-Bipz8toD.js';
8
- import { a as DocumentProtectionState } from './document-protection-8eyMWIJ0.js';
9
- import { C as CollaborationStatus } from './failure-NS2lsya4.js';
10
- import { C as CollaborationDiagnosticCode, c as CustomNodeDiagnosticCode, D as DiagnosticErrorName, F as FailureStage, B as ByteSizeBucket, b as CountBucket, f as DocumentOpenDiagnosticCode, a as DocumentPartKind, g as DocumentSaveDiagnosticCode, E as EditDiagnosticCode, j as ReviewDiagnosticCode, k as ReviewOperation, R as ReviewChangeKind, i as FormattingChangeKind, h as FontDiagnosticCode, H as HistoryDiagnosticCode, P as PerformanceDiagnosticCode } from './diagnostic-hints-2Bke6H_w.js';
11
-
12
- /**
13
- * When the review pane opens by itself.
14
- *
15
- * - `'auto'`: the pane opens when a document with review items loads, and when a tracked
16
- * change is made while it is closed, in both cases when the pane has items to list. With
17
- * `revisionsIn: 'balloons'` the pane lists no tracked change and no reply to one, so
18
- * tracked changes and their replies alone do not open it.
19
- * - `'manual'`: the pane stays closed until the host or the user opens it. Use it when the
20
- * host shows review items its own way, such as in balloons or margin markers.
21
- *
22
- * @public
23
- */
24
- type ReviewPaneOpening = 'auto' | 'manual';
25
- /**
26
- * What the open review pane does when its full card column does not fit beside the page at
27
- * the page's zoom.
28
- *
29
- * - `'float'`: the pane shrinks to a strip of markers, and the open card floats over the
30
- * page.
31
- * - `'shrinkPage'`: under a fit zoom mode, the page may shrink down to the mode's
32
- * `minZoom` (or 10%) so that the full column fits. The pane changes to the marker strip
33
- * only when the column does not fit at that floor either. A fixed zoom behaves as
34
- * `'float'`.
35
- * - `'scroll'`: the page keeps the size it has beside the closed pane's marker strip, and
36
- * the full column stands beside it. The document and the column scroll together: the
37
- * viewport scrolls sideways to reach the cards.
38
- *
39
- * The setting applies to the review pane only. The navigation pane stays docked at its side
40
- * in every mode: it never scrolls with the document, and it takes its room beside the page
41
- * exactly as it does with no review pane.
42
- *
43
- * @public
44
- */
45
- type ReviewPaneOverflow = 'float' | 'shrinkPage' | 'scroll';
46
- /**
47
- * Where tracked changes open.
48
- *
49
- * - `'pane'`: the review pane lists tracked changes as cards beside the comments.
50
- * - `'balloons'`: the pane lists comments only, except comments that reply to a tracked
51
- * change: the change's balloon shows those. A tracked change opens in a balloon at its
52
- * text when the reader clicks it, or when Next Change, Previous Change, or
53
- * `setActiveReviewItem(key, { announce: true })` reaches it.
54
- *
55
- * @public
56
- */
57
- type RevisionDisplay = 'pane' | 'balloons';
58
- /**
59
- * How a collapsed comment marker looks.
60
- *
61
- * - `'initials'`: a badge with the thread author's initials in the author's color, a reply
62
- * count, and a check mark when the thread is resolved.
63
- * - `'icon'`: the comment icon.
64
- *
65
- * @public
66
- */
67
- type CommentMarkerStyle = 'initials' | 'icon';
68
- /**
69
- * Review pane settings to change. Every field is optional, and an omitted field keeps its
70
- * current value.
71
- *
72
- * @public
73
- */
74
- interface ReviewPaneOptions {
75
- /** Default `'auto'`. */
76
- readonly opening?: ReviewPaneOpening;
77
- /** Default `'float'`. */
78
- readonly overflow?: ReviewPaneOverflow;
79
- /** Default `'pane'`. */
80
- readonly revisionsIn?: RevisionDisplay;
81
- /** Default `'icon'`. */
82
- readonly commentMarkers?: CommentMarkerStyle;
83
- }
84
- /**
85
- * The review pane settings in force, with every field resolved.
86
- *
87
- * @public
88
- */
89
- interface ResolvedReviewPane {
90
- /** When the pane opens by itself. */
91
- readonly opening: ReviewPaneOpening;
92
- /** What the open pane does when its card column does not fit beside the page. */
93
- readonly overflow: ReviewPaneOverflow;
94
- /** Where tracked changes open. */
95
- readonly revisionsIn: RevisionDisplay;
96
- /** How a collapsed comment marker looks. */
97
- readonly commentMarkers: CommentMarkerStyle;
98
- }
99
- /** The settings an editor starts with when nothing sets them. @public */
100
- declare const DEFAULT_REVIEW_PANE: ResolvedReviewPane;
101
- /**
102
- * Merge `options` over `base`. Throws a `TypeError` for an unknown field or value, so a
103
- * misspelled setting fails loudly instead of being ignored. Returns `base` itself when
104
- * nothing changes, so the snapshot keeps its reference.
105
- *
106
- * @public
107
- */
108
- declare function resolveReviewPane(options: ReviewPaneOptions | undefined, base?: ResolvedReviewPane): ResolvedReviewPane;
109
- /**
110
- * The fields of a review item that decide whether the review pane lists it. A
111
- * `ReviewItem` and a review item placement both have them.
112
- *
113
- * @public
114
- */
115
- interface ReviewPaneItemFields {
116
- /** The item kind, as `ReviewItem.kind` gives it. */
117
- readonly kind: 'revision' | 'comment' | 'custom';
118
- /** For a comment, the tracked change it replies to. */
119
- readonly parentRevisionId?: string;
120
- }
121
- /**
122
- * Whether the review pane lists a card for `item` under `revisionsIn`.
123
- *
124
- * With `'balloons'`, a balloon at the text shows every tracked change and every comment
125
- * that replies to a tracked change, so the pane lists neither. Give the item as an
126
- * unfiltered `getReviewItems()` read returns it: a query that excludes revision kinds
127
- * removes `parentRevisionId` from replies to the changes it drops.
128
- *
129
- * The engine applies this rule to every review item when it decides whether the pane opens
130
- * by itself or closes after a settings change. A review pane must apply the same rule before
131
- * its own filters, such as a hidden kind or a host filter. Those filters can hide every card,
132
- * and then the pane that the engine opens is empty.
133
- *
134
- * @public
135
- */
136
- declare function reviewPaneListsItem(revisionsIn: RevisionDisplay, item: ReviewPaneItemFields): boolean;
9
+ import { a as SemanticSelection, S as SemanticPosition } from './semantic-interaction-CJoHLoOl.js';
10
+ import { a as DocumentProtectionState } from './document-protection-NaniLHWF.js';
11
+ import { a as CollaborationStatus } from './failure-6KGFrDO9.js';
137
12
 
138
13
  /**
139
14
  * What a fit mode fits the page to.
@@ -167,6 +42,52 @@ type ZoomMode = {
167
42
  readonly maxZoom?: number;
168
43
  };
169
44
 
45
+ /**
46
+ * One occurrence of a search query in the document.
47
+ *
48
+ * Carries TWO addresses on purpose. `blockId` + `start` is the engine's own: stable
49
+ * across edits and independent of ordering. `paragraphIndex` + `runIndex` + `runOffset`
50
+ * is the positional one a find/replace UI needs to show and navigate results, and it is
51
+ * derived from the same walk rather than left to the caller to reconstruct — a caller
52
+ * guessing at run boundaries would send the selection to the wrong place.
53
+ *
54
+ * A match can span runs when formatting changes mid-word; the run address is where it
55
+ * STARTS. `scope` identifies a non-body story so navigation opens the correct surface.
56
+ * A frame scope selects its anchoring drawing and never places a caret inside its story.
57
+ * A match inside a field result reports the field atom's model range. Its `length` is one,
58
+ * while `text` carries the visible match and can be longer. Select with `start` and `length`.
59
+ * Never derive the selected length from `text.length`.
60
+ */
61
+ interface TextMatch {
62
+ readonly blockId: string;
63
+ /** Character offset within the paragraph's concatenated run text. */
64
+ readonly start: number;
65
+ readonly length: number;
66
+ /**
67
+ * Paragraph ordinal within this match's story. Table and nested-table paragraphs count.
68
+ * Non-paragraph blocks add no ordinal.
69
+ */
70
+ readonly paragraphIndex: number;
71
+ /** Index of the run the match starts in, and the offset within that run. */
72
+ readonly runIndex: number;
73
+ readonly runOffset: number;
74
+ /** Story containing the match. Absence means the body. */
75
+ readonly scope?: ViewScope;
76
+ /** The matched text as it appears in the document. */
77
+ readonly text: string;
78
+ /**
79
+ * Paragraph text immediately before and after the match, bounded at the derivation
80
+ * boundary. A results list shows the match in its sentence — "…as described in this
81
+ * **Exhi**bit A" — and nothing else in the contract can reach paragraph text, so a
82
+ * caller would otherwise have to re-read the document to render one row.
83
+ *
84
+ * Optional and additive: an implementation that has not derived them omits them, and a
85
+ * consumer treats absent as empty.
86
+ */
87
+ readonly contextBefore?: string;
88
+ readonly contextAfter?: string;
89
+ }
90
+
170
91
  /**
171
92
  * Anonymous diagnostics: why something failed, as stable codes and bucketed numbers.
172
93
  *
@@ -488,7 +409,11 @@ interface EditorEvents {
488
409
  revisionMarkupChange: (settings: ResolvedRevisionMarkup) => void;
489
410
  /** A document mutation committed, with the ids it touched. */
490
411
  change: (change: DocumentChange) => void;
491
- /** The selection or its derived formatting moved. */
412
+ /**
413
+ * Observable editor state moved without a document change: the selection or its derived
414
+ * formatting, the armed typing format, the open header or footer, or the collaboration
415
+ * session's status.
416
+ */
492
417
  selectionChange: (snapshot: EditorSnapshot) => void;
493
418
  error: (error: EditorError) => void;
494
419
  historyDiagnostic: (diagnostic: HistoryDiagnostic) => void;
@@ -527,7 +452,42 @@ interface EditorEvents {
527
452
  * ```
528
453
  */
529
454
  reviewItemReveal: (event: ReviewItemRevealEvent) => void;
455
+ /**
456
+ * The editor's pages are now in another document: it was attached for the first time, moved
457
+ * into another element or window, detached (`document` is `null`), or found its element
458
+ * moved to another window by the host. Custom chrome that listens on the editor's document
459
+ * or measures its window re-binds here.
460
+ *
461
+ * @example
462
+ * ```ts
463
+ * editor.on('hostChange', ({ document }) => {
464
+ * stopShortcuts?.();
465
+ * stopShortcuts = document ? listenForShortcuts(document) : undefined;
466
+ * });
467
+ * ```
468
+ */
469
+ hostChange: (event: EditorHostChange) => void;
470
+ }
471
+ /**
472
+ * The payload of the `hostChange` event.
473
+ *
474
+ * @public
475
+ */
476
+ interface EditorHostChange {
477
+ /** The document the pages are mounted in now, or `null` while the editor is detached. */
478
+ readonly document: EditorHostDocument | null;
530
479
  }
480
+ /**
481
+ * The DOM `Document`, wherever DOM types are loaded (every browser host).
482
+ *
483
+ * Read from `globalThis` rather than named, so this contract also compiles in the engine's
484
+ * DOM-free lanes and on servers, where it falls back to `object`.
485
+ *
486
+ * @public
487
+ */
488
+ type EditorHostDocument = typeof globalThis extends {
489
+ readonly document: infer D;
490
+ } ? D : object;
531
491
  /**
532
492
  * The payload of the `reviewItemReveal` event.
533
493
  *
@@ -535,17 +495,18 @@ interface EditorEvents {
535
495
  */
536
496
  interface ReviewItemRevealEvent {
537
497
  /**
538
- * The key of the review item to open, as `getReviewItems()` without `pairReplacements`
539
- * lists it. Next Change and Previous Change step through that unpaired queue, so for a
540
- * replacement this is the key of its deletion or its insertion. `setActiveReviewItem`
498
+ * The key of the review item to open, as `getReviewItems({ pairReplacements: false })`
499
+ * lists it, so for a replacement this is the key of its deletion or its insertion. Next
500
+ * Change and Previous Change stop once on a replacement and report its deletion's key,
501
+ * with the pair's key in {@link ReviewItemRevealEvent.pairKey}. `setActiveReviewItem`
541
502
  * reports the key it was given, so a call with a pair's key reports that key here and in
542
503
  * {@link ReviewItemRevealEvent.pairKey}.
543
504
  */
544
505
  readonly key: string;
545
506
  /**
546
- * The key that `getReviewItems({ pairReplacements: true })` gives the replacement this item
547
- * belongs to. Present only when the item is a paired replacement or one half of one. A
548
- * host that lists pairs opens `pairKey ?? key`.
507
+ * The key that `getReviewItems()` gives the replacement this item belongs to, since it
508
+ * pairs replacements by default. Present only when the item is a paired replacement or one
509
+ * half of one. A host that reads the default list opens `pairKey ?? key`.
549
510
  */
550
511
  readonly pairKey?: string;
551
512
  /**
@@ -897,7 +858,7 @@ interface EditorReviewHits {
897
858
  *
898
859
  * Filtering revision kinds is how a host hides structural cards it has no UI for,
899
860
  * `placement: false` skips the layout pass entirely when only metadata is wanted, and
900
- * `pairReplacements` lists a typed-over selection as one decision.
861
+ * `pairReplacements: false` lists a typed-over selection as its two halves.
901
862
  */
902
863
  interface ReviewItemQuery {
903
864
  /**
@@ -910,8 +871,12 @@ interface ReviewItemQuery {
910
871
  /** When false, skip layout geometry; metadata is unchanged and anchors are null. Default true. */
911
872
  readonly placement?: boolean;
912
873
  /**
913
- * When true, list a deletion and the insertion that directly follows it as one
914
- * `'replace'` item. Default false.
874
+ * Whether to list a deletion and the insertion that directly follows it as one
875
+ * `'replace'` item. Default true. Set it to false to list the deletion and the insertion as
876
+ * separate items, for example to accept or reject each half on its own.
877
+ *
878
+ * A host that steps through the list with `setActiveReviewItem` stops once on
879
+ * each replacement with the default, as Next Change does.
915
880
  *
916
881
  * Two revisions pair when they are next to each other among the queue's revisions, the
917
882
  * deletion comes first, both have the same author, nesting level and `readOnly` value, and
@@ -931,6 +896,43 @@ interface ReviewItemQuery {
931
896
  readonly pairReplacements?: boolean;
932
897
  }
933
898
 
899
+ /**
900
+ * The refused-open read model, split out of `editor.ts`.
901
+ *
902
+ * Re-exported from `editor.ts`, so consumers keep importing
903
+ * `@docx-editor.dev/core/contracts/editor`.
904
+ */
905
+
906
+ /**
907
+ * What a person can do about a document that did not open. It groups the open codes so a
908
+ * host can pick a message without listing every code:
909
+ *
910
+ * - `damaged`: the archive or its XML is broken. Saving the file again in a desktop editor
911
+ * can repair it.
912
+ * - `not-docx`: the bytes are not a `.docx` document, or hold no main document.
913
+ * - `too-large`: the file crosses a size, count or depth limit.
914
+ * - `blocked`: the file uses XML features that the editor refuses for security.
915
+ * - `unknown`: any other failure.
916
+ *
917
+ * @public
918
+ */
919
+ type DocumentOpenFailureReason = 'damaged' | 'not-docx' | 'too-large' | 'blocked' | 'unknown';
920
+ /**
921
+ * A document the editor refused to open. It carries a stable code only, never the file's
922
+ * content or name, so a host can show it, log it, or send it with a support request.
923
+ *
924
+ * Each refusal is a new object, so a host can compare it by reference to tell a second
925
+ * refusal of the same file from the first.
926
+ *
927
+ * @public
928
+ */
929
+ interface DocumentOpenFailure {
930
+ /** The stable open code, the same one the `document.open` diagnostic reports. */
931
+ readonly code: DocumentOpenDiagnosticCode;
932
+ /** The group of {@link DocumentOpenFailure.code} that picks the message. */
933
+ readonly reason: DocumentOpenFailureReason;
934
+ }
935
+
934
936
  /**
935
937
  * How activating a review item places it in the viewport, and whether it announces the
936
938
  * reveal.
@@ -1046,8 +1048,8 @@ interface ReviewRevisionPlacement extends ReviewItemPlacementBase {
1046
1048
  readonly revisionKind: ReviewRevisionKind;
1047
1049
  /**
1048
1050
  * The words a replacement decision removes when {@link revisionKind} is `'replace'`.
1049
- * The built-in reader lists separate deletion and insertion cards unless the query sets
1050
- * {@link ReviewItemQuery.pairReplacements}.
1051
+ * The built-in reader lists separate deletion and insertion cards when the query sets
1052
+ * {@link ReviewItemQuery.pairReplacements} to false.
1051
1053
  */
1052
1054
  readonly replacedText?: string;
1053
1055
  readonly item: ReviewRevisionItem;
@@ -1319,7 +1321,8 @@ interface EditorFormatPainterCommands {
1319
1321
  * direct paragraph properties as well.
1320
1322
  *
1321
1323
  * Non-mutating: the capture lives on the editor, not in the document, and it survives
1322
- * until the next capture or until the editor is detached.
1324
+ * until the next capture, a document load, or `destroy()`, including across a `detach()`
1325
+ * and a later `attach()`.
1323
1326
  */
1324
1327
  copyFormatting: Record<never, never>;
1325
1328
  /**
@@ -1450,6 +1453,110 @@ interface SelectedImageState {
1450
1453
  */
1451
1454
  type ImageContext = SelectedImageState;
1452
1455
 
1456
+ /**
1457
+ * Which kind of story a bookmark is in: the main text, a header or footer, or a note.
1458
+ *
1459
+ * @public
1460
+ */
1461
+ type BookmarkStory = 'body' | 'headerFooter' | 'note';
1462
+ /**
1463
+ * Where a bookmark is, finer than {@link BookmarkStory}: the main text, a header, a footer, a
1464
+ * footnote or an endnote.
1465
+ *
1466
+ * @public
1467
+ */
1468
+ type BookmarkPlace = 'body' | 'header' | 'footer' | 'footnote' | 'endnote';
1469
+ /**
1470
+ * One bookmark, as the `bookmarks` query lists it.
1471
+ *
1472
+ * @public
1473
+ */
1474
+ interface BookmarkSummary {
1475
+ /** The name as the document writes it. Names compare without case. */
1476
+ readonly name: string;
1477
+ /** Whether the name starts with an underscore. Hidden bookmarks mark application targets. */
1478
+ readonly hidden: boolean;
1479
+ /** The story the bookmark starts in. */
1480
+ readonly story: BookmarkStory;
1481
+ /** The same story, telling a header from a footer and a footnote from an endnote. */
1482
+ readonly place: BookmarkPlace;
1483
+ /**
1484
+ * Position in document order: the main text first, then headers, footers and notes. Sort by
1485
+ * this value to list bookmarks by location.
1486
+ */
1487
+ readonly order: number;
1488
+ /** Whether the bookmark marks a point rather than a range of text. */
1489
+ readonly empty: boolean;
1490
+ /** Whether the start of the selection is inside the bookmark, edges included. */
1491
+ readonly atSelection: boolean;
1492
+ /**
1493
+ * How many other places carry the same name. Usually 0. Collaborators who add one name while
1494
+ * offline can leave copies; the list, Go To and links use this bookmark, the first in
1495
+ * document order. Adding the name again at this bookmark keeps it and removes the copies.
1496
+ */
1497
+ readonly duplicates: number;
1498
+ }
1499
+ /**
1500
+ * The bookmark commands an editor accepts.
1501
+ *
1502
+ * @public
1503
+ */
1504
+ interface EditorBookmarkCommands {
1505
+ /**
1506
+ * Bookmark the selection under `name`, or the caret position when the selection is
1507
+ * collapsed. A bookmark that already has the name, compared without case, moves here, also
1508
+ * from another story, in one undo step. Two collaborators who add one name offline both keep
1509
+ * their bookmark; every replica reads the first in document order until the next write of the
1510
+ * name, which replaces or removes both.
1511
+ * Refused with `invalidArgs` for a name that does not start with a letter, holds a
1512
+ * character other than a letter, a digit or an underscore, or has more than 40 characters.
1513
+ */
1514
+ insertBookmark: {
1515
+ name: string;
1516
+ };
1517
+ /**
1518
+ * Remove the bookmark with this name, compared without case, and any copies of it in other
1519
+ * places. The text stays.
1520
+ */
1521
+ deleteBookmark: {
1522
+ name: string;
1523
+ };
1524
+ /**
1525
+ * Keep the bookmark this name means, the first in document order, and remove its copies, in
1526
+ * one undo step. The selection does not move. Collaborators who add one name while offline
1527
+ * can leave copies; `BookmarkSummary.duplicates` counts them. Refused with `notFound` when no
1528
+ * bookmark has the name, and with `unsupported` when it has no copies.
1529
+ */
1530
+ keepFirstBookmark: {
1531
+ name: string;
1532
+ };
1533
+ /** Select the bookmark's text, or put the caret at a point bookmark, and scroll to it. */
1534
+ goToBookmark: {
1535
+ name: string;
1536
+ };
1537
+ /** Show or hide bracket marks at bookmarks. A view command: the document does not change. */
1538
+ toggleBookmarks: Record<never, never>;
1539
+ /**
1540
+ * Open the host's Go To UI, the Go to tab of `DocxEditor.Navigation`, the request its
1541
+ * shortcut (Ctrl+G, Cmd+Option+G on macOS) sends. Allowed in a read-only document. Refused
1542
+ * with `unsupported` while no host shows one. To jump without UI, run `goToBookmark`.
1543
+ *
1544
+ * `fromShortcut: true` asks as the shortcut does: also refused with `unsupported` when the
1545
+ * Go To UI turned its shortcut off (`GoToChromeHandlers.shortcut`). Chrome that forwards the
1546
+ * chord sends it, and a menu asks `can` with it before it shows the shortcut.
1547
+ */
1548
+ openGoTo: {
1549
+ readonly fromShortcut?: boolean;
1550
+ };
1551
+ /**
1552
+ * Open the Bookmark dialog the host registered, the same request the Insert menu and
1553
+ * Ctrl/Cmd+Shift+F5 send. Allowed in a read-only document, where Go To still works.
1554
+ * Refused with `unsupported` while no host shows a bookmark dialog, for example when the
1555
+ * `bookmark` popup is `false`.
1556
+ */
1557
+ openBookmarkDialog: Record<never, never>;
1558
+ }
1559
+
1453
1560
  /** Where the caret sits inside a table: its shape and current cell. */
1454
1561
  interface TableContext {
1455
1562
  readonly rows: number;
@@ -1550,57 +1657,6 @@ interface DocumentHandle {
1550
1657
  * where a new array per render rebuilds the editor per render.
1551
1658
  */
1552
1659
  type DocumentSource = ArrayBuffer | Uint8Array | DocumentHandle | 'blank';
1553
- /** A concrete font face requested by authored document content. */
1554
- interface FontFaceRequest {
1555
- readonly family: string;
1556
- readonly weight: number;
1557
- readonly style: 'normal' | 'italic';
1558
- }
1559
- /** Immutable, byte-backed font face supplied to layout and browser paint. */
1560
- interface FontSource {
1561
- readonly request: FontFaceRequest;
1562
- readonly id: string;
1563
- readonly bytes: Uint8Array;
1564
- readonly hash: string;
1565
- readonly faceIndex: number;
1566
- readonly availability?: 'available' | 'forbidden';
1567
- }
1568
- /** An explicit authored-font substitution. No implicit platform fallback is performed. */
1569
- interface FontSourceSubstitution {
1570
- readonly from: FontFaceRequest;
1571
- readonly to: FontFaceRequest;
1572
- /** Word line-box metrics for the requested face, expressed as em ratios. */
1573
- readonly lineMetrics?: {
1574
- readonly heightEm: number;
1575
- readonly baselineEm: number;
1576
- };
1577
- }
1578
- /**
1579
- * Public font source configuration sampled when an adapter mounts. It must be immutable for that
1580
- * editor lifetime; remount the adapter to replace bytes or substitutions atomically.
1581
- */
1582
- interface FontConfiguration {
1583
- /** Selectable provider families, independent of loaded bytes. Listing them performs no fetch. */
1584
- readonly supportedFamilies?: readonly string[];
1585
- readonly epoch: number;
1586
- readonly maxFontBytes: number;
1587
- readonly sources: readonly FontSource[];
1588
- readonly substitutions?: readonly FontSourceSubstitution[];
1589
- readonly defaultFont: {
1590
- readonly family: string;
1591
- readonly sizeHalfPoints: number;
1592
- };
1593
- readonly language?: string;
1594
- }
1595
- /**
1596
- * Why a font was not admitted.
1597
- *
1598
- * Distinguished rather than collapsed because the responses differ: `overLimit` and `malformed`
1599
- * are the caller's own bytes, while `forbidden` and `hashMismatch` mean the source was not what
1600
- * it claimed and the load should not be retried. `wasmUnavailable` alone is a HOST fault — the
1601
- * shaper's WASM never loaded, `diagnostic` carries the remedy — surface it as a setup error.
1602
- */
1603
- type EditorFontErrorCode = 'initializationFailed' | 'wasmUnavailable' | 'missing' | 'forbidden' | 'overLimit' | 'malformed' | 'hashMismatch' | 'metadataMismatch' | 'fontFaceLoadFailed' | 'unsupportedFaceIndex' | 'missingFont' | 'hashInvalid' | 'fontMismatch' | 'unsupportedFace' | 'loadFailed';
1604
1660
  /** Typed adapter error reported both through `onFontError` and accessible alert UI. */
1605
1661
  declare class EditorFontError extends Error {
1606
1662
  readonly name: string;
@@ -1682,6 +1738,11 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewH
1682
1738
  * Serialize the current document, finalizing pending text form values first.
1683
1739
  * Invalid input rejects with `EditorError.code === 'invalidArgs'` and remains editable.
1684
1740
  * Validation does not open a dialog. Other write refusals also reject the save.
1741
+ *
1742
+ * The bytes describe the document as it was when you called `save()`. The file is written
1743
+ * in short tasks, so input stays responsive while a long document saves, and edits made
1744
+ * meanwhile belong to the next save. Paragraphs and table rows unchanged since an earlier
1745
+ * save are not written again, so autosave after a small edit stays cheap.
1685
1746
  */
1686
1747
  save(): Promise<ArrayBuffer>;
1687
1748
  getDocumentHandle(): DocumentHandle;
@@ -1789,6 +1850,13 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewH
1789
1850
  * The search narrows to the body and its selectable text boxes when other stories cannot open.
1790
1851
  * This includes viewing mode and surfaces without header, footer, or note entry methods.
1791
1852
  * Text boxes in footnotes and endnotes remain excluded until their drawings are selectable.
1853
+ *
1854
+ * Pass a match to `exec({ type: 'replaceMatch', match, text })` to replace it, which records a
1855
+ * tracked replacement in suggesting mode, or to {@link selectMatch} and then
1856
+ * {@link addComment} to comment on it. For headless or server use, see `body.search` in
1857
+ * `@docx-editor.dev/editor-api`.
1858
+ *
1859
+ * @see {@link https://www.docx-editor.dev/docs/2.x/recipes/tracked-replacement | Replace as a tracked change}
1792
1860
  */
1793
1861
  findMatches(query: string, options?: {
1794
1862
  readonly matchCase?: boolean;
@@ -1835,11 +1903,11 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewH
1835
1903
  setTableInteractionLabel(resolver: (key: 'table.insertRowBelow' | 'table.insertColumnRight') => string): void;
1836
1904
  /** Section page setup — size, orientation and margins — for the page-setup dialog. */
1837
1905
  getPageSetup(): PageSetup | null;
1838
- /** The document watermark, for the watermark dialog. */
1839
- getWatermark(): {
1840
- readonly kind: 'text' | 'image';
1841
- readonly text?: string;
1842
- } | null;
1906
+ /**
1907
+ * The watermark the document shows, read from the first section's headers; null when it
1908
+ * shows none. For a picture watermark's bytes, use `query({ type: 'watermark' })`.
1909
+ */
1910
+ getWatermark(): WatermarkState | null;
1843
1911
  /** Header/footer editing state: which region is being edited, if any. */
1844
1912
  getHeaderFooterState(): HeaderFooterState | null;
1845
1913
  /** Resolved and authored note properties for the caret section — properties dialog read-model. */
@@ -1932,8 +2000,32 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewH
1932
2000
  * Anchored to the RETAINED range when there is one, so a compose box that took focus does
1933
2001
  * not lose the words it is about — that is what retention exists for. Refused on a
1934
2002
  * collapsed caret: a comment with no range has nothing to point at, and Word writes none.
2003
+ *
2004
+ * A refused write names its cause, as every review write does: `code: 'locked'` with
2005
+ * `'the document is open for viewing'` in viewing or under read-only protection, and
2006
+ * `code: 'unsupported'` with the external refresh sentence or a collaboration reason token
2007
+ * such as `'collaboration-session-not-ready'` (wait for the session, then retry). Branch on
2008
+ * `diagnosticCodeOfRefusal(result.reason, result.code)`, not on the text.
2009
+ *
2010
+ * Pass `options.historyGroup` to make the comment part of a larger undo step, such as a
2011
+ * review decision that also resolves changes. See {@link HistoryGroupOptions}.
2012
+ *
2013
+ * @example
2014
+ * ```ts
2015
+ * editor.addComment('Counter-proposal: 45 days.', { historyGroup: decision });
2016
+ * editor.addComment('Approved.', 'Legal team', { historyGroup: decision });
2017
+ * ```
2018
+ *
2019
+ * To comment on found text, select it first with {@link findMatches} and
2020
+ * {@link selectMatch}. In a React or Vue host with the review module, `useReview().comment`
2021
+ * calls this. For headless or server use, see `Range.insertComment` in
2022
+ * `@docx-editor.dev/editor-api`.
2023
+ *
2024
+ * @see {@link https://www.docx-editor.dev/docs/2.x/recipes/comment-on-found-text | Comment on found text}
1935
2025
  */
1936
- addComment(text: string, author?: string): ExecResult;
2026
+ addComment(text: string, options?: HistoryGroupOptions): ExecResult;
2027
+ /** {@link addComment} with an author for this call, overriding the configured author. */
2028
+ addComment(text: string, author?: string, options?: HistoryGroupOptions): ExecResult;
1937
2029
  /**
1938
2030
  * Where a comment on the current selection would sit, in the same space as
1939
2031
  * {@link ReviewItemPlacement.anchorY}, or null when nothing is selected.
@@ -1957,6 +2049,11 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewH
1957
2049
  * With `options.announce: true`, a call that lands fires `reviewItemReveal` with
1958
2050
  * `source: 'host'`, also when the item was already active, so the packaged review UI opens
1959
2051
  * the item's balloon or card. By default it fires nothing. A `null` key fires nothing.
2052
+ *
2053
+ * Pass `{ reveal: false }` to open the item without scrolling, for a host whose own list
2054
+ * drives the scroll. `useReview().setActive` calls this.
2055
+ *
2056
+ * @see {@link https://www.docx-editor.dev/docs/2.x/recipes/accept-reject-without-scrolling | Accept or reject without scrolling}
1960
2057
  */
1961
2058
  setActiveReviewItem(key: string | null, options?: ReviewActivationOptions): ExecResult;
1962
2059
  /**
@@ -1969,16 +2066,15 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewH
1969
2066
  * caret that merely lands in a change leaves this `null`. Open a balloon or card for the
1970
2067
  * activated item, and highlight the caret-active one.
1971
2068
  *
1972
- * Pass the query you read items with, so the key matches theirs: with
1973
- * `pairReplacements: true`, a paired replacement reports the pair's key; without it, the
1974
- * key of the half the caret is in. The value changes with the selection, so read it again
1975
- * on `selectionChange`.
2069
+ * Pass the query you read items with, so the key matches theirs. By default a paired
2070
+ * replacement reports the pair's key; with `pairReplacements: false`, the key of the half
2071
+ * the caret is in. The value changes with the selection, so read it again on
2072
+ * `selectionChange`.
1976
2073
  *
1977
2074
  * @example
1978
2075
  * ```ts
1979
- * const query = { pairReplacements: true };
1980
2076
  * editor.on('selectionChange', () => {
1981
- * const activated = editor.getActivatedReviewItemKey(query);
2077
+ * const activated = editor.getActivatedReviewItemKey();
1982
2078
  * if (activated !== null) showMyCard(activated);
1983
2079
  * });
1984
2080
  * ```
@@ -2005,17 +2101,26 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewH
2005
2101
  *
2006
2102
  * Refused for a card whose kind the engine cannot resolve structurally, which is why
2007
2103
  * `readOnly` is on the item — a surface should not offer the button in the first place.
2104
+ * Other refusals name their cause, as {@link addComment} describes.
2105
+ *
2106
+ * Neither call scrolls. In a React or Vue host with the review module, `useReview().accept`
2107
+ * and `useReview().reject` call these. For headless or server use, see `Revision.accept()`
2108
+ * and `Revision.reject()` in `@docx-editor.dev/editor-api`.
2109
+ *
2110
+ * @see {@link https://www.docx-editor.dev/docs/2.x/recipes/accept-reject-without-scrolling | Accept or reject without scrolling}
2008
2111
  */
2009
- acceptReviewItem(key: string): ExecResult;
2010
- rejectReviewItem(key: string): ExecResult;
2112
+ acceptReviewItem(key: string, options?: HistoryGroupOptions): ExecResult;
2113
+ /** The rejecting half of {@link acceptReviewItem}, with the same rules and options. */
2114
+ rejectReviewItem(key: string, options?: HistoryGroupOptions): ExecResult;
2011
2115
  /**
2012
2116
  * Resolve or reopen the comment thread behind a review card.
2013
2117
  *
2014
2118
  * The thread state is written through the same package transaction as every other comment
2015
2119
  * mutation, so `commentsExtended.xml`, Undo and save/reopen cannot disagree. Repeating the
2016
- * state already on the item succeeds without adding an undo entry.
2120
+ * state already on the item succeeds without adding an undo entry. A refusal names its cause,
2121
+ * as {@link addComment} describes.
2017
2122
  */
2018
- setCommentResolved(key: string, resolved: boolean): ExecResult;
2123
+ setCommentResolved(key: string, resolved: boolean, options?: HistoryGroupOptions): ExecResult;
2019
2124
  /**
2020
2125
  * Discard the item behind a card: the destructive half of the review verbs.
2021
2126
  *
@@ -2029,9 +2134,10 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewH
2029
2134
  * a surface can put one "remove this" affordance on every card instead of branching.
2030
2135
  *
2031
2136
  * Refused on a custom node's card, which is informational, and on a revision kind the engine
2032
- * cannot resolve — the same rule {@link rejectReviewItem} follows.
2137
+ * cannot resolve — the same rule {@link rejectReviewItem} follows. Other refusals name their
2138
+ * cause, as {@link addComment} describes, and leave the open card and its draft open.
2033
2139
  */
2034
- deleteReviewItem(key: string): ExecResult;
2140
+ deleteReviewItem(key: string, options?: HistoryGroupOptions): ExecResult;
2035
2141
  /**
2036
2142
  * Reply to a review item.
2037
2143
  *
@@ -2042,8 +2148,14 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewH
2042
2148
  * The author is AMBIENT — `DocxEditorConfig.author`, the way the rest of the authored commands
2043
2149
  * source it — and the argument overrides it for one call. `CT_Comment` makes `@w:author`
2044
2150
  * required, so a reply with neither is refused rather than written as an empty attribute.
2151
+ * Other refusals name their cause, as {@link addComment} describes.
2152
+ *
2153
+ * In a React or Vue host with the review module, `useReview().reply` calls this. For
2154
+ * headless or server use, see `Comment.reply` in `@docx-editor.dev/editor-api`.
2045
2155
  */
2046
- replyToReviewItem(key: string, text: string, author?: string): ExecResult;
2156
+ replyToReviewItem(key: string, text: string, options?: HistoryGroupOptions): ExecResult;
2157
+ /** {@link replyToReviewItem} with an author for this call, overriding the configured author. */
2158
+ replyToReviewItem(key: string, text: string, author?: string, options?: HistoryGroupOptions): ExecResult;
2047
2159
  setActiveScope(scope: ViewScope): void;
2048
2160
  getActiveScope(): ViewScope;
2049
2161
  query<K extends keyof EditorQueries>(query: {
@@ -2070,7 +2182,8 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewH
2070
2182
  */
2071
2183
  /**
2072
2184
  * Scroll a page or a block into view. Returns false when the target does not exist or
2073
- * the host has no scroll container — a caller can tell "not found" from "scrolled".
2185
+ * the host has no scroll container. During a large open, a target not laid out yet answers
2186
+ * true and scrolls once it is; input cancels that, and a page past the end never scrolls.
2074
2187
  */
2075
2188
  scrollToPage(pageNumber: number): boolean;
2076
2189
  /**
@@ -2167,7 +2280,7 @@ type TrackedChangeFilterMode = 'accept' | 'reject';
2167
2280
  * selection, view state, chrome modes, header/footer and note editing. An interface rather than a
2168
2281
  * closed union so an extension can widen it by declaration merging.
2169
2282
  */
2170
- interface EditorCommands extends EditorCommandShape<DocEdits>, EditorHeaderFooterCommands, EditorNoteCommands, EditorFormatPainterCommands {
2283
+ interface EditorCommands extends EditorCommandShape<DocEdits>, EditorHeaderFooterCommands, EditorNoteCommands, EditorFormatPainterCommands, EditorBookmarkCommands {
2171
2284
  /** Switch how edits are written. A view command: it changes no document state. */
2172
2285
  setEditingMode: {
2173
2286
  mode: DocumentEditingMode;
@@ -2186,7 +2299,17 @@ interface EditorCommands extends EditorCommandShape<DocEdits>, EditorHeaderFoote
2186
2299
  toggleParagraphMarks: Record<never, never>;
2187
2300
  /** Word's Protect Document: enforce filling-in-forms protection, or lift the enforced one. */
2188
2301
  toggleDocumentProtection: Record<never, never>;
2189
- /** Navigate tracked changes, including hidden formatting balloons, and wrap at the end. */
2302
+ /**
2303
+ * Navigate tracked changes, including hidden formatting balloons, and wrap at the end.
2304
+ *
2305
+ * A replacement is one stop in every review layout. A replacement is a deletion and the
2306
+ * touching insertion from the same author that took its place. Navigation lands on the
2307
+ * deletion, highlights both halves, and `reviewItemReveal` carries the pair's `pairKey`.
2308
+ *
2309
+ * Navigation steps through the changes {@link Editor.getReviewItems} returns, so a
2310
+ * reviewer or `setTrackedChangesFilter` filter applies. When a filter hides one half of a
2311
+ * replacement, the other half is a stop of its own.
2312
+ */
2190
2313
  navigateReviewChange: {
2191
2314
  direction: 'next' | 'previous';
2192
2315
  };
@@ -2394,11 +2517,21 @@ interface EditorCommands extends EditorCommandShape<DocEdits>, EditorHeaderFoote
2394
2517
  positionTwips: number;
2395
2518
  };
2396
2519
  /**
2397
- * Replace one found match with `text`. Addressed by {@link TextMatch} rather than a
2398
- * `DocTarget` because that is what `findMatches` hands back, and re-deriving a target
2399
- * from it in the caller is where an off-by-one would come from. An empty `text`
2400
- * deletes the match, which is what a find/replace dialog means by replacing with
2401
- * nothing.
2520
+ * Replace one found match with `text`, addressed by the {@link TextMatch} `findMatches`
2521
+ * returns. An empty `text` deletes it. The selection and scroll position stay put. In
2522
+ * suggesting mode it is a tracked replacement under the editor's author, refused where
2523
+ * `proposeReplacement` would be. The match must be in the open story, not a text box.
2524
+ *
2525
+ * For headless or server use, see `range.insertText(text, 'Replace')` with
2526
+ * `document.changeTrackingMode` set to `'TrackMineOnly'` in `@docx-editor.dev/editor-api`.
2527
+ *
2528
+ * @example
2529
+ * ```ts
2530
+ * const [match] = editor.findMatches('30 days', { matchCase: true });
2531
+ * if (match) editor.exec({ type: 'replaceMatch', match, text: '45 days' });
2532
+ * ```
2533
+ *
2534
+ * @see {@link https://www.docx-editor.dev/docs/2.x/recipes/tracked-replacement | Replace as a tracked change}
2402
2535
  */
2403
2536
  replaceMatch: {
2404
2537
  match: TextMatch;
@@ -2505,6 +2638,11 @@ interface EditorCommands extends EditorCommandShape<DocEdits>, EditorHeaderFoote
2505
2638
  drawingNodeId?: string;
2506
2639
  expectedPackageRevision?: number;
2507
2640
  };
2641
+ /**
2642
+ * Replace the document watermark in every header the document shows; null removes it. One
2643
+ * undo step. Refuses with `invalidArgs` for an invalid option and `locked` in a protected
2644
+ * document; a refusal writes nothing. See {@link Watermark} for the options and defaults.
2645
+ */
2508
2646
  setWatermark: {
2509
2647
  watermark: Watermark | null;
2510
2648
  };
@@ -2614,6 +2752,8 @@ interface EditorQueries extends DocQueries {
2614
2752
  pos: number;
2615
2753
  };
2616
2754
  trackedChanges: Record<never, never>;
2755
+ /** Every bookmark in the document, hidden ones included, in document order. */
2756
+ bookmarks: Record<never, never>;
2617
2757
  }
2618
2758
  /**
2619
2759
  * One query, as a discriminated union derived from {@link EditorQueries}.
@@ -2640,51 +2780,7 @@ interface EditorQueryResults extends DocQueryResults {
2640
2780
  contentControlAt: ContentControlSummary | null;
2641
2781
  isInsideToc: boolean;
2642
2782
  trackedChanges: readonly Revision[];
2643
- }
2644
- /**
2645
- * One occurrence of a search query in the document.
2646
- *
2647
- * Carries TWO addresses on purpose. `blockId` + `start` is the engine's own: stable
2648
- * across edits and independent of ordering. `paragraphIndex` + `runIndex` + `runOffset`
2649
- * is the positional one a find/replace UI needs to show and navigate results, and it is
2650
- * derived from the same walk rather than left to the caller to reconstruct — a caller
2651
- * guessing at run boundaries would send the selection to the wrong place.
2652
- *
2653
- * A match can span runs when formatting changes mid-word; the run address is where it
2654
- * STARTS. `scope` identifies a non-body story so navigation opens the correct surface.
2655
- * A frame scope selects its anchoring drawing and never places a caret inside its story.
2656
- * A match inside a field result reports the field atom's model range. Its `length` is one,
2657
- * while `text` carries the visible match and can be longer. Select with `start` and `length`.
2658
- * Never derive the selected length from `text.length`.
2659
- */
2660
- interface TextMatch {
2661
- readonly blockId: string;
2662
- /** Character offset within the paragraph's concatenated run text. */
2663
- readonly start: number;
2664
- readonly length: number;
2665
- /**
2666
- * Paragraph ordinal within this match's story. Table and nested-table paragraphs count.
2667
- * Non-paragraph blocks add no ordinal.
2668
- */
2669
- readonly paragraphIndex: number;
2670
- /** Index of the run the match starts in, and the offset within that run. */
2671
- readonly runIndex: number;
2672
- readonly runOffset: number;
2673
- /** Story containing the match. Absence means the body. */
2674
- readonly scope?: ViewScope;
2675
- /** The matched text as it appears in the document. */
2676
- readonly text: string;
2677
- /**
2678
- * Paragraph text immediately before and after the match, bounded at the derivation
2679
- * boundary. A results list shows the match in its sentence — "…as described in this
2680
- * **Exhi**bit A" — and nothing else in the contract can reach paragraph text, so a
2681
- * caller would otherwise have to re-read the document to render one row.
2682
- *
2683
- * Optional and additive: an implementation that has not derived them omits them, and a
2684
- * consumer treats absent as empty.
2685
- */
2686
- readonly contextBefore?: string;
2687
- readonly contextAfter?: string;
2783
+ bookmarks: readonly BookmarkSummary[];
2688
2784
  }
2689
2785
  /**
2690
2786
  * The hyperlink under a position: where it points, how far it reaches, and what Word shows on
@@ -2734,16 +2830,23 @@ interface EditorSnapshot {
2734
2830
  * point on — it never depends on one existing. */
2735
2831
  readonly isLoading: boolean;
2736
2832
  /**
2737
- * Whether a supplied document is still on its way to painted pages. Opening a large
2738
- * document mounts behind one painted frame so a loading screen can show instead of a
2739
- * frozen page; this is true for exactly that window, and across it the previous
2740
- * document (if any) stays on screen. Show a loading overlay while it holds — but gate
2741
- * only chrome on it, never the mount point, which must stay mounted for the open to
2742
- * complete ({@link EditorSnapshot.isLoading} is the gate-safe flag). Optional and
2833
+ * Whether a supplied document is still on its way to painted pages. A large document
2834
+ * mounts behind one painted frame so a loading screen can show instead of a frozen page,
2835
+ * with the previous document (if any) still on screen. Show an overlay while it holds,
2836
+ * but gate only chrome on it, never the mount point, which must stay mounted for the open
2837
+ * to complete ({@link EditorSnapshot.isLoading} is the gate-safe flag). It turns false
2838
+ * when the first pages paint; they take input while the rest lay out. Optional and
2743
2839
  * additive: absent means the implementation has not derived it, read as `false`.
2744
2840
  */
2745
2841
  readonly isOpening?: boolean;
2746
2842
  readonly parseError: string | null;
2843
+ /**
2844
+ * Why the last supplied document did not open, or `null` while it opens or after it opened.
2845
+ * Unlike {@link EditorSnapshot.parseError}, it holds a stable code and never quotes the
2846
+ * file, so a host can show it to a person. `DocxEditor.OpenFailure` renders it. Optional
2847
+ * and additive: absent means the implementation has not derived it, read as `null`.
2848
+ */
2849
+ readonly openFailure?: DocumentOpenFailure | null;
2747
2850
  /** Whether the loaded document is being edited: a patchable document opened in edit mode. A
2748
2851
  * read-only document (tables/SDTs/unpreservable) or `mode: 'view'` reports false. */
2749
2852
  readonly editable: boolean;
@@ -2819,6 +2922,8 @@ interface EditorSnapshot {
2819
2922
  readonly reviewPane: ResolvedReviewPane;
2820
2923
  /** Whether Show/Hide paragraph marks is enabled. */
2821
2924
  readonly showParagraphMarks?: boolean;
2925
+ /** Whether bracket marks are shown at bookmarks. */
2926
+ readonly showBookmarks?: boolean;
2822
2927
  /** The document's `w:documentProtection`, as the file states it; null with no document. */
2823
2928
  readonly documentProtection?: DocumentProtectionState | null;
2824
2929
  /** The displayed revision projection. The document and its revision history stay unchanged. */
@@ -2889,11 +2994,13 @@ interface EditorSnapshot {
2889
2994
  * An error the engine raised, carrying a machine-readable `code` alongside the message.
2890
2995
  *
2891
2996
  * `code` is optional because an `Error` from deeper down (a parser, a codec) is surfaced as-is
2892
- * rather than wrapped in a fabricated code.
2997
+ * rather than wrapped in a fabricated code. The editor's own codes: `invalidTarget` (`attach`
2998
+ * cannot mount there), `unsupported` (a source it refuses to open), and `hostCallback` (a host
2999
+ * callback such as a bookmark mark's `decorate` threw; the editor kept its default behavior).
2893
3000
  */
2894
3001
  interface EditorError extends Error {
2895
3002
  readonly code?: string;
2896
3003
  }
2897
3004
 
2898
- export { DIAGNOSTIC_SCHEMA_VERSION as D, resolveReviewPane as a$, DEFAULT_REVIEW_PANE as aQ, cropPercentFromCropPermille as aW, cropPercentFromPermille as aX, cropPercentFromSourceCrop as aY, cropPermilleFromCropPercent as aZ, cropPermilleFromPercent as a_, reviewPaneListsItem as b0, sourceCropFromCropPercent as b1, validateImageCropPercent as b2, EditorFontError as z };
2899
- export type { HeaderFooterState as $, AnchorHighlightAnimation as A, EditorFontErrorCode as B, CanResult as C, EditorDiagnostic as E, EditorFormatPainterCommands as F, EditorHeaderFooterCommands as G, EditorHighlights as H, EditorNoteCommands as I, EditorPosition as J, EditorQueries as K, EditorQuery as L, EditorQueryResults as M, EditorReviewHits as N, EditorSelection as O, EditorSnapshot as P, FontConfiguration as Q, ReviewPaneOptions as R, FontFaceRequest as S, FontFailedDiagnostic as T, FontSource as U, FontSourceSubstitution as V, FormatPainterLevel as W, FormatPainterMode as X, FormatPainterSurfaceState as Y, FurnitureVariant as Z, HeaderFooterSlotArgs as _, EditorDiagnosticKind as a, HighlightHit as a0, HighlightOptions as a1, HighlightRange as a2, HighlightRect as a3, HighlightResult as a4, HistoryDiagnosticEvent as a5, HyperlinkInfo as a6, ImageContext as a7, ImageCropPercent as a8, NoteKind as a9, TableBorderStyle as aA, TableBorderTarget as aB, TableCellVerticalAlignment as aC, TableColumnDividerResizeTarget as aD, TableColumnOccurrenceTarget as aE, TableContext as aF, TableRightEdgeResizeTarget as aG, TableRowOccurrenceTarget as aH, TextMatch as aI, TimingSummary as aJ, TrackedChangeFilterMode as aK, TrackedChangePredicate as aL, ZoomFitTarget as aM, ZoomMode as aN, ReviewPaneOverflow as aO, CommentMarkerStyle as aP, ImageCropPermille as aR, ResolvedReviewPane as aS, ReviewPaneItemFields as aT, ReviewPaneOpening as aU, RevisionDisplay as aV, NotePropertiesSide as aa, NotePropertiesState as ab, PageSetup as ac, PerformanceDiagnostic as ad, ResolveReviewChangesOptions as ae, ResolvedNoteNumbering as af, ReviewActivationOptions as ag, ReviewChangesAttribution as ah, ReviewCommentPlacement as ai, ReviewCustomPlacement as aj, ReviewItemHit as ak, ReviewItemPlacement as al, ReviewItemPlacementBase as am, ReviewItemQuery as an, ReviewItemRevealEvent as ao, ReviewItemRevealSource as ap, ReviewRevisionPlacement as aq, ReviewSkippedDiagnostic as ar, ScrollPlacement as as, ScrollToAnchorOptions as at, SelectedImageState as au, SessionActivity as av, SessionDiagnostic as aw, SetReviewChangesAuthorOptions as ax, TableBorderEdgeTarget as ay, TableBorderSpec as az, EditorCommand as b, AnchorHighlightOptions as c, AuthoredNoteNumbering as d, ClearAnchorHighlightOptions as e, CollaborationParticipantsDiagnostic as f, CollaborationStatusDiagnostic as g, CustomNodeDiagnosticEvent as h, DiagnosticBase as i, DiagnosticFailureDetail as j, DocumentChange as k, DocumentEditingMode as l, DocumentHandle as m, DocumentOpenDiagnostic as n, DocumentSaveDiagnostic as o, DocumentShape as p, DocumentSource as q, EditRejectedDiagnostic as r, EditRejectionOrigin as s, Editor as t, EditorAnchorNavigation as u, EditorCommandShape as v, EditorCommands as w, EditorError as x, EditorEvents as y };
3005
+ export { DIAGNOSTIC_SCHEMA_VERSION as D, EditorFontError as J, cropPercentFromCropPermille as aR, cropPercentFromPermille as aS, cropPercentFromSourceCrop as aT, cropPermilleFromCropPercent as aU, cropPermilleFromPercent as aV, sourceCropFromCropPercent as aW, validateImageCropPercent as aX };
3006
+ export type { FurnitureVariant as $, AnchorHighlightAnimation as A, BookmarkPlace as B, CanResult as C, EditorDiagnostic as E, EditorCommandShape as F, EditorCommands as G, EditorError as H, EditorEvents as I, EditorFormatPainterCommands as K, EditorHeaderFooterCommands as L, EditorHighlights as M, EditorHostChange as N, EditorHostDocument as O, EditorNoteCommands as P, EditorPosition as Q, EditorQueries as R, EditorQuery as S, EditorQueryResults as T, EditorReviewHits as U, EditorSelection as V, EditorSnapshot as W, FontFailedDiagnostic as X, FormatPainterLevel as Y, FormatPainterMode as Z, FormatPainterSurfaceState as _, EditorDiagnosticKind as a, HeaderFooterSlotArgs as a0, HeaderFooterState as a1, HighlightHit as a2, HighlightOptions as a3, HighlightRange as a4, HighlightRect as a5, HighlightResult as a6, HistoryDiagnosticEvent as a7, HyperlinkInfo as a8, ImageContext as a9, TableBorderEdgeTarget as aA, TableBorderSpec as aB, TableBorderStyle as aC, TableBorderTarget as aD, TableCellVerticalAlignment as aE, TableColumnDividerResizeTarget as aF, TableColumnOccurrenceTarget as aG, TableContext as aH, TableRightEdgeResizeTarget as aI, TableRowOccurrenceTarget as aJ, TextMatch as aK, TimingSummary as aL, TrackedChangeFilterMode as aM, TrackedChangePredicate as aN, ZoomFitTarget as aO, ZoomMode as aP, ImageCropPermille as aQ, ImageCropPercent as aa, NoteKind as ab, NotePropertiesSide as ac, NotePropertiesState as ad, PageSetup as ae, PerformanceDiagnostic as af, ResolveReviewChangesOptions as ag, ResolvedNoteNumbering as ah, ReviewActivationOptions as ai, ReviewChangesAttribution as aj, ReviewCommentPlacement as ak, ReviewCustomPlacement as al, ReviewItemHit as am, ReviewItemPlacement as an, ReviewItemPlacementBase as ao, ReviewItemQuery as ap, ReviewItemRevealEvent as aq, ReviewItemRevealSource as ar, ReviewRevisionPlacement as as, ReviewSkippedDiagnostic as at, ScrollPlacement as au, ScrollToAnchorOptions as av, SelectedImageState as aw, SessionActivity as ax, SessionDiagnostic as ay, SetReviewChangesAuthorOptions as az, EditorCommand as b, AnchorHighlightOptions as c, AuthoredNoteNumbering as d, BookmarkStory as e, BookmarkSummary as f, ClearAnchorHighlightOptions as g, CollaborationParticipantsDiagnostic as h, CollaborationStatusDiagnostic as i, CustomNodeDiagnosticEvent as j, DiagnosticBase as k, DiagnosticFailureDetail as l, DocumentChange as m, DocumentEditingMode as n, DocumentHandle as o, DocumentOpenDiagnostic as p, DocumentOpenFailure as q, DocumentOpenFailureReason as r, DocumentSaveDiagnostic as s, DocumentShape as t, DocumentSource as u, EditRejectedDiagnostic as v, EditRejectionOrigin as w, Editor as x, EditorAnchorNavigation as y, EditorBookmarkCommands as z };