@docx-editor.dev/core 2.27.0 → 2.29.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 (124) hide show
  1. package/dist/automation.cjs +1 -1
  2. package/dist/automation.d.ts +76 -16
  3. package/dist/automation.js +1 -1
  4. package/dist/binding.cjs +1 -1
  5. package/dist/binding.d.ts +31 -12
  6. package/dist/binding.js +1 -1
  7. package/dist/{index-CkQVRJtJ.d.ts → chrome-print-CAs51cpq.d.ts} +248 -115
  8. package/dist/chunk-236O4YQW.js +2 -0
  9. package/dist/chunk-4HENIAFG.js +1 -0
  10. package/dist/chunk-6JPL6ZAS.cjs +5 -0
  11. package/dist/chunk-6ZQP4HQ7.js +3 -0
  12. package/dist/{chunk-2GK7YQB2.cjs → chunk-7WQ7AAHW.cjs} +1 -1
  13. package/dist/chunk-BCXH4BXB.js +5 -0
  14. package/dist/chunk-BY2ACZZ6.cjs +1 -0
  15. package/dist/chunk-CAJEXXVG.cjs +4 -0
  16. package/dist/chunk-CPWLFPWC.js +30 -0
  17. package/dist/chunk-D7ZMDMPX.cjs +3 -0
  18. package/dist/chunk-DOHF6FA7.cjs +30 -0
  19. package/dist/chunk-DVX32P2P.js +27 -0
  20. package/dist/chunk-E4LOMDNL.js +1 -0
  21. package/dist/chunk-EKLM7NWB.cjs +7 -0
  22. package/dist/chunk-G3K63G7P.cjs +27 -0
  23. package/dist/chunk-G4HOFIKJ.js +1 -0
  24. package/dist/chunk-JLVBDYVQ.cjs +2 -0
  25. package/dist/chunk-LQX36Z5P.js +7 -0
  26. package/dist/chunk-LSZ6KPKK.js +1 -0
  27. package/dist/chunk-MM5QBMTE.cjs +1 -0
  28. package/dist/chunk-OMCG63ZF.js +1 -0
  29. package/dist/chunk-OSFOJTHU.cjs +18 -0
  30. package/dist/chunk-RCLZXP3B.js +2 -0
  31. package/dist/chunk-T6K2QYNZ.cjs +2 -0
  32. package/dist/chunk-TRGAVV2Y.js +4 -0
  33. package/dist/chunk-U4JZVSOE.js +2 -0
  34. package/dist/chunk-UHHYFIDT.cjs +1 -0
  35. package/dist/chunk-V3N4SOAK.cjs +1 -0
  36. package/dist/chunk-W35WTWAO.cjs +1 -0
  37. package/dist/chunk-YQ5G6LC7.js +18 -0
  38. package/dist/collaboration/replication.cjs +1 -1
  39. package/dist/collaboration/replication.d.ts +42 -6
  40. package/dist/collaboration/replication.js +1 -1
  41. package/dist/collaboration.cjs +1 -1
  42. package/dist/collaboration.d.ts +99 -7
  43. package/dist/collaboration.js +1 -1
  44. package/dist/contracts/document.d.ts +18 -3
  45. package/dist/contracts/editor.d.ts +19 -10
  46. package/dist/contracts/interaction.d.ts +31 -2
  47. package/dist/contracts/modules.cjs +1 -1
  48. package/dist/contracts/modules.d.ts +56 -8
  49. package/dist/contracts/modules.js +1 -1
  50. package/dist/contracts/types.d.ts +11 -2
  51. package/dist/{custom-node-writes-Vzpq9I8_.d.ts → custom-node-writes-Bn6uciLb.d.ts} +2 -2
  52. package/dist/diagnostic-context-B8M79cfK.d.ts +30 -0
  53. package/dist/diagnostic-hints-BeVjfNOv.d.ts +113 -0
  54. package/dist/{document-protection-9zpIHWTE.d.ts → document-protection-CUb55pl_.d.ts} +2 -2
  55. package/dist/{editor-B3OBYNrF.d.ts → editor-CZQZmTIU.d.ts} +770 -141
  56. package/dist/{editor-scope-OHPwVQ5l.d.ts → editor-scope-7o9xweiJ.d.ts} +1 -1
  57. package/dist/editor.cjs +1 -1
  58. package/dist/editor.css +5 -5
  59. package/dist/editor.d.ts +439 -33
  60. package/dist/editor.js +1 -1
  61. package/dist/export.cjs +2 -2
  62. package/dist/export.d.ts +23 -14
  63. package/dist/export.js +2 -2
  64. package/dist/failure-NS2lsya4.d.ts +115 -0
  65. package/dist/{font-resolver-DN0xNOf_.d.ts → font-resolver-lSBLirLR.d.ts} +3 -3
  66. package/dist/{headless-document-view-ICYqNkQ1.d.ts → headless-document-view-pp3q7wIh.d.ts} +2 -2
  67. package/dist/{image-resources-BDFxcu7W.d.ts → image-resources-tXLQShoC.d.ts} +10 -10
  68. package/dist/index.cjs +1 -1
  69. package/dist/index.d.ts +92 -20
  70. package/dist/index.js +1 -1
  71. package/dist/{layout-shaping-BvZD_VKP.d.ts → layout-shaping-BD-dF_rn.d.ts} +1 -1
  72. package/dist/layout.cjs +1 -1
  73. package/dist/layout.d.ts +168 -79
  74. package/dist/layout.js +1 -1
  75. package/dist/{note-properties-CkAk7g-n.d.ts → note-properties-qQUjO1GQ.d.ts} +3 -3
  76. package/dist/{omml-equation-DuczgG5o.d.ts → omml-equation-BUbU0utM.d.ts} +1 -1
  77. package/dist/output.cjs +1 -1
  78. package/dist/output.d.ts +18 -9
  79. package/dist/output.js +1 -1
  80. package/dist/{protocol-aKYr8r3u.d.ts → protocol-DYzzz2ej.d.ts} +44 -4
  81. package/dist/{review-paragraph-order-Ddj5d6rp.d.ts → review-paragraph-order-CN_0l2Cb.d.ts} +5 -2
  82. package/dist/{semantic-cell-selection-DoqYCz_F.d.ts → semantic-cell-selection-eYag3P47.d.ts} +8 -213
  83. package/dist/{semantic-interaction-G0bjmmmk.d.ts → semantic-interaction-kR_QB845.d.ts} +25 -34
  84. package/dist/{semantic-paint-CsMzF8-O.d.ts → semantic-paint-ZayFF3tD.d.ts} +17 -5
  85. package/dist/{semantic-record-queries-1du6lQqS.d.ts → semantic-record-queries-Bsgth6lv.d.ts} +1 -1
  86. package/dist/{semantic-records-B9OolWGN.d.ts → semantic-records-DQmumPgL.d.ts} +1367 -884
  87. package/dist/store.cjs +1 -1
  88. package/dist/store.d.ts +1611 -1586
  89. package/dist/store.js +1 -1
  90. package/dist/{tree-package-fragment-DYZIk1rY.d.ts → tree-package-store-CovjNARF.d.ts} +157 -137
  91. package/dist/{tree-session-contract-DQVJOOkv.d.ts → tree-session-contract-CZVAGl51.d.ts} +8 -6
  92. package/dist/{types-barrel-BFKR8Pzp.d.ts → types-barrel-DuC5QBNC.d.ts} +352 -231
  93. package/package.json +3 -3
  94. package/dist/chunk-4KZ6L5YF.cjs +0 -15
  95. package/dist/chunk-55AT3MOU.cjs +0 -25
  96. package/dist/chunk-6ZQMII6V.js +0 -1
  97. package/dist/chunk-7IGCWG4H.js +0 -2
  98. package/dist/chunk-7MYITTAH.js +0 -5
  99. package/dist/chunk-AVKVRU7Z.cjs +0 -5
  100. package/dist/chunk-CWRBFNK5.cjs +0 -5
  101. package/dist/chunk-DGPA3TST.cjs +0 -27
  102. package/dist/chunk-DNXVNQEO.js +0 -1
  103. package/dist/chunk-FQN4KSFL.cjs +0 -7
  104. package/dist/chunk-GVUOWHTO.cjs +0 -1
  105. package/dist/chunk-GWQJ5774.js +0 -5
  106. package/dist/chunk-HAQ72KD7.js +0 -1
  107. package/dist/chunk-HO5XFO32.cjs +0 -3
  108. package/dist/chunk-IGR23DV2.js +0 -1
  109. package/dist/chunk-JSIX2EOH.js +0 -3
  110. package/dist/chunk-K246T47S.cjs +0 -1
  111. package/dist/chunk-KAXOGCGA.js +0 -1
  112. package/dist/chunk-LZLTN5A3.cjs +0 -1
  113. package/dist/chunk-NBCVVZOM.cjs +0 -1
  114. package/dist/chunk-O5INAWZQ.js +0 -1
  115. package/dist/chunk-OHAXVTWG.cjs +0 -1
  116. package/dist/chunk-S74GRBNE.js +0 -7
  117. package/dist/chunk-UBLUVNZR.js +0 -27
  118. package/dist/chunk-UMRSBLO7.js +0 -15
  119. package/dist/chunk-VIPMGGUT.js +0 -25
  120. package/dist/chunk-WG4KMSX2.cjs +0 -2
  121. package/dist/chunk-WRLKVNNR.cjs +0 -1
  122. package/dist/chunk-ZU7IVN6G.js +0 -2
  123. package/dist/failure-BIPVQbRm.d.ts +0 -65
  124. package/dist/revision-projection-CSNFudZY.d.ts +0 -242
@@ -1,12 +1,139 @@
1
- import { d as ResolvedRevisionMarkup, a as ReviewDisplayMode } from './revision-projection-CSNFudZY.js';
2
- import { t as DocAnchor, a8 as SourceCrop, a9 as DrawingKind, aa as ImageWrapTarget, ab as DrawingPositionInput, ac as DrawingLocks, r as ColorValue, x as ExecErrorCode, ad as ParagraphFormatCommand, ae as Watermark, E as ExecResult, g as ReviewRevisionKind, c as ReviewCommentItem, b as ReviewRevisionItem, d as ReviewCustomItem, n as ContentControlFilter, o as DocRange, k as RunFormatting, p as Revision, af as Rect, ag as SelectionPin, ah as Unsubscribe } from './types-barrel-BFKR8Pzp.js';
3
- import { H as HistoryDiagnostic, V as ViewScope, a as HistoryGroup, b as EditorExecOptions, E as EditorScope } from './editor-scope-OHPwVQ5l.js';
1
+ import { q as ResolvedRevisionMarkup, a as ReviewDisplayMode } from './semantic-records-DQmumPgL.js';
2
+ import { t as DocAnchor, g as ReviewRevisionKind, c as ReviewCommentItem, b as ReviewRevisionItem, d as ReviewCustomItem, aI 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-DuC5QBNC.js';
3
+ import { H as HistoryDiagnostic, V as ViewScope, b as HistoryGroup, a as EditorExecOptions, E as EditorScope } from './editor-scope-7o9xweiJ.js';
4
4
  import { DocEdits, DocQueries, DocQueryResults, ContentControlSummary } from './contracts/document.js';
5
5
  import { InteractionOutcome } from './contracts/interaction.js';
6
- import { a as SemanticSelection, S as SemanticPosition } from './semantic-interaction-G0bjmmmk.js';
7
- import { b as ImageResourceState, S as SupportedImageMime } from './image-resources-BDFxcu7W.js';
8
- import { D as DocumentProtectionState } from './document-protection-9zpIHWTE.js';
9
- import { C as CollaborationStatus } from './failure-BIPVQbRm.js';
6
+ import { a as SemanticSelection, S as SemanticPosition } from './semantic-interaction-kR_QB845.js';
7
+ import { I as ImageResourceState, S as SupportedImageMime } from './image-resources-tXLQShoC.js';
8
+ import { a as DocumentProtectionState } from './document-protection-CUb55pl_.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, E as EditDiagnosticCode, i as ReviewDiagnosticCode, j as ReviewOperation, R as ReviewChangeKind, h as FormattingChangeKind, g as FontDiagnosticCode, H as HistoryDiagnosticCode, P as PerformanceDiagnosticCode } from './diagnostic-hints-BeVjfNOv.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;
10
137
 
11
138
  /**
12
139
  * What a fit mode fits the page to.
@@ -40,6 +167,241 @@ type ZoomMode = {
40
167
  readonly maxZoom?: number;
41
168
  };
42
169
 
170
+ /**
171
+ * Anonymous diagnostics: why something failed, as stable codes and bucketed numbers.
172
+ *
173
+ * A document is user data. Its text, names, part names, relationship targets, author names and
174
+ * font names never appear in a diagnostic. Every field below is a closed enum, a boolean or a
175
+ * number, so an event can go to an error tracker or a metrics backend as it is. The internal
176
+ * rejection reasons stay internal: they map many-to-one onto {@link DiagnosticCode}, which is
177
+ * the public, versioned vocabulary a host can match on.
178
+ *
179
+ * @packageDocumentation
180
+ */
181
+
182
+ /** Version of the {@link EditorDiagnostic} shape. Raised only when a field changes meaning. @public */
183
+ declare const DIAGNOSTIC_SCHEMA_VERSION = 1;
184
+
185
+ /** The bucketed shape of an opened document. @public */
186
+ interface DocumentShape {
187
+ /** XML parts in the package. */
188
+ readonly parts: CountBucket;
189
+ readonly paragraphs: CountBucket;
190
+ /** Tracked changes and comments, as the review queue lists them. */
191
+ readonly reviewItems: CountBucket;
192
+ readonly embeddedFonts: CountBucket;
193
+ }
194
+ /** Fields every diagnostic carries. @public */
195
+ interface DiagnosticBase {
196
+ /** {@link DIAGNOSTIC_SCHEMA_VERSION} when the event was made. */
197
+ readonly schemaVersion: number;
198
+ /**
199
+ * Random for each editor instance and never stored, so one open failure can be linked to the
200
+ * edits after it. It identifies no person and no document.
201
+ */
202
+ readonly editorSessionId: string;
203
+ /** Milliseconds since the epoch. */
204
+ readonly time: number;
205
+ }
206
+ /**
207
+ * Anonymous detail of a failure, for the engineer who fixes it. Every field is optional and
208
+ * comes from a closed list: never a part name, an element name, a message, or document text.
209
+ *
210
+ * @public
211
+ */
212
+ interface DiagnosticFailureDetail {
213
+ /**
214
+ * The engine's own reason, such as `undeclared-prefix` under `open.xml-malformed`, or
215
+ * `exception` for an error the engine did not expect. Causes can change between engine
216
+ * versions: match on `code`, and include the `cause` when you report a problem. See
217
+ * `diagnosticCauses()` for every value.
218
+ */
219
+ readonly cause?: string;
220
+ /** The class of the exception when `cause` is `exception`. Its message is never reported. */
221
+ readonly errorName?: DiagnosticErrorName;
222
+ /** Where the exception was caught, when `cause` is `exception`. */
223
+ readonly stage?: FailureStage;
224
+ }
225
+ /** A document opened, or failed to open. @public */
226
+ type DocumentOpenDiagnostic = DiagnosticBase & {
227
+ readonly kind: 'document.open';
228
+ } & ({
229
+ readonly outcome: 'opened';
230
+ /** Compressed size of the bytes the editor was given. */
231
+ readonly sizeBucket: ByteSizeBucket;
232
+ /** Pages after the first layout. Absent on a headless host that does not paginate. */
233
+ readonly pagesBucket?: CountBucket;
234
+ /**
235
+ * More of the document's shape, in buckets. A telemetry client sends it only when you
236
+ * ask for the detailed shape: several counts together describe a document more closely.
237
+ */
238
+ readonly shape?: DocumentShape;
239
+ /** Milliseconds from the start of the open to the mounted first layout. */
240
+ readonly durationMs: number;
241
+ } | (DiagnosticFailureDetail & {
242
+ readonly outcome: 'rejected';
243
+ readonly code: DocumentOpenDiagnosticCode;
244
+ /** Compressed size of the bytes, absent when the source was not bytes at all. */
245
+ readonly sizeBucket?: ByteSizeBucket;
246
+ /** The role of the part that failed, such as `'header'`. Never its name. */
247
+ readonly part?: DocumentPartKind;
248
+ }));
249
+ /** Where a refused edit came from. @public */
250
+ type EditRejectionOrigin = 'command' | 'input' | 'automation';
251
+ /** An edit, a command or a tracked change was refused. @public */
252
+ interface EditRejectedDiagnostic extends DiagnosticBase, DiagnosticFailureDetail {
253
+ readonly kind: 'edit.rejected';
254
+ readonly code: EditDiagnosticCode;
255
+ /**
256
+ * `'command'` for `exec(...)`, `'input'` for typing, clipboard, drag and pointer edits, and
257
+ * `'automation'` for a batch from the editing API.
258
+ */
259
+ readonly origin: EditRejectionOrigin;
260
+ /** True when the editor was suggesting (tracking changes) at the time. */
261
+ readonly tracked: boolean;
262
+ /** The command type for `origin: 'command'`, such as `'insertTable'`. */
263
+ readonly command?: EditorCommand['type'];
264
+ }
265
+ /**
266
+ * An accept, reject or re-author request skipped one or more tracked changes. One event for each
267
+ * code and kind of change in the request.
268
+ *
269
+ * @public
270
+ */
271
+ interface ReviewSkippedDiagnostic extends DiagnosticBase {
272
+ readonly kind: 'review.skipped';
273
+ readonly code: ReviewDiagnosticCode;
274
+ /** How many items were skipped for this code and kind in the one request. */
275
+ readonly count: number;
276
+ /** What the request asked: accept, reject, or attribute to another author. */
277
+ readonly operation?: ReviewOperation;
278
+ /** The kind of the skipped changes, absent when the change no longer exists. */
279
+ readonly changeKind?: ReviewChangeKind;
280
+ /** For `changeKind: 'format'`, which property change it is. */
281
+ readonly formattingKind?: FormattingChangeKind;
282
+ /** The role of the part the changes are in, such as `'footnotes'`. Never its name. */
283
+ readonly part?: DocumentPartKind;
284
+ /**
285
+ * For `review.revision-unsupported`, the engine condition that refused the change, such as
286
+ * `unaddressed` (no `w:id` or author) or `unrecorded-properties`. See `diagnosticCauses()`.
287
+ */
288
+ readonly cause?: string;
289
+ }
290
+ /** A font failed to load. The editor kept working with a substitute. @public */
291
+ interface FontFailedDiagnostic extends DiagnosticBase {
292
+ readonly kind: 'font.failed';
293
+ readonly code: FontDiagnosticCode;
294
+ }
295
+ /**
296
+ * A collaboration session changed status: it joined, disconnected, failed, or healed.
297
+ *
298
+ * @public
299
+ */
300
+ interface CollaborationStatusDiagnostic extends DiagnosticBase {
301
+ readonly kind: 'collab.status';
302
+ readonly status: CollaborationStatus;
303
+ /** The status before this change; `'none'` for the first status the editor saw. */
304
+ readonly previous: CollaborationStatus | 'none';
305
+ /** Why the session holds `status`, when something is wrong. */
306
+ readonly code?: CollaborationDiagnosticCode;
307
+ /** True when the session will heal on its own; wait instead of rejoining. */
308
+ readonly recovering: boolean;
309
+ /**
310
+ * Milliseconds from the editor attaching the session to its first `ready`. Present only on
311
+ * that change, and only when the editor saw the wait: a session that was already ready when
312
+ * the editor attached, as `useHocuspocusCollaboration` makes it, reports none.
313
+ */
314
+ readonly connectMs?: number;
315
+ }
316
+ /** The undo history did not group edits as the gesture intended. Informational. @public */
317
+ interface HistoryDiagnosticEvent extends DiagnosticBase {
318
+ readonly kind: 'history';
319
+ readonly code: HistoryDiagnosticCode;
320
+ }
321
+ /** A custom node's stored payload could not be read. The node and its data are not named. @public */
322
+ interface CustomNodeDiagnosticEvent extends DiagnosticBase {
323
+ readonly kind: 'custom-node';
324
+ readonly code: CustomNodeDiagnosticCode;
325
+ }
326
+ /** The number of people in the collaboration room changed. @public */
327
+ interface CollaborationParticipantsDiagnostic extends DiagnosticBase {
328
+ readonly kind: 'collab.participants';
329
+ /** People present, this editor included. A person with two tabs counts twice. */
330
+ readonly count: number;
331
+ }
332
+ /**
333
+ * Timings of one kind over a performance window. Every value is in milliseconds, rounded to
334
+ * whole milliseconds.
335
+ *
336
+ * @public
337
+ */
338
+ interface TimingSummary {
339
+ /** Timings measured in the window. */
340
+ readonly count: number;
341
+ /** Median. Exact up to 2048 timings; above that, from a uniform sample of 2048. */
342
+ readonly p50Ms: number;
343
+ /** 95th percentile, from the same sample as the median. */
344
+ readonly p95Ms: number;
345
+ /** The slowest timing, always exact. */
346
+ readonly maxMs: number;
347
+ /**
348
+ * Timings per band, always exact. Eight counts: up to 16, 33, 50, 100, 200, 500, and 1000
349
+ * ms, then over 1000 ms. A metrics backend builds a histogram from these.
350
+ */
351
+ readonly bands: readonly number[];
352
+ }
353
+ /**
354
+ * How the editor performed while it was used: one summary per window, never one event per key
355
+ * press. Sent after a minute of use, when the page is hidden, and when the editor is destroyed,
356
+ * if anything was measured since the last summary.
357
+ *
358
+ * @public
359
+ */
360
+ interface PerformanceDiagnostic extends DiagnosticBase {
361
+ readonly kind: 'performance';
362
+ /**
363
+ * Present when the summary needs attention: `performance.slow-interaction` when at least 20
364
+ * presses were timed and more than one in 20 took over 200 ms.
365
+ */
366
+ readonly code?: PerformanceDiagnosticCode;
367
+ /** Milliseconds from the window's first timing to the summary. */
368
+ readonly windowMs: number;
369
+ /** Pages in the document at the last paint. */
370
+ readonly pagesBucket?: CountBucket;
371
+ /**
372
+ * Key presses and pointer presses on the pages, from the browser event to the next frame on
373
+ * screen: the delay a person feels. Presses queued behind slow work count with their full
374
+ * delay. Presses of modifier keys alone, and presses while the page is hidden, are not timed.
375
+ */
376
+ readonly interaction?: TimingSummary;
377
+ /**
378
+ * Engine layout passes that the person causes, by an edit or a view change such as zoom.
379
+ * Each pass includes its main-thread work in the background, and the work of a pass that a
380
+ * newer edit replaced. Layouts that loading causes are not here: the opening layout, which
381
+ * `document.open` reports as `durationMs`, and layouts after fonts or images arrive.
382
+ */
383
+ readonly layout?: TimingSummary;
384
+ /** Engine paints of the pages. */
385
+ readonly paint?: TimingSummary;
386
+ }
387
+ /**
388
+ * One anonymous diagnostic. Switch on `kind` to narrow `code`.
389
+ *
390
+ * @example
391
+ * ```ts
392
+ * editor.on('diagnostic', (event) => {
393
+ * if (event.kind === 'edit.rejected') {
394
+ * console.warn(event.code, explainDiagnostic(event.code).hint);
395
+ * }
396
+ * });
397
+ * ```
398
+ *
399
+ * @public
400
+ */
401
+ type EditorDiagnostic = DocumentOpenDiagnostic | EditRejectedDiagnostic | ReviewSkippedDiagnostic | FontFailedDiagnostic | HistoryDiagnosticEvent | CustomNodeDiagnosticEvent | CollaborationStatusDiagnostic | CollaborationParticipantsDiagnostic | PerformanceDiagnostic;
402
+ /** The `kind` of every {@link EditorDiagnostic}. @public */
403
+ type EditorDiagnosticKind = EditorDiagnostic['kind'];
404
+
43
405
  /**
44
406
  * What `editor.on(...)` can be subscribed to, and what each handler receives.
45
407
  *
@@ -56,7 +418,71 @@ interface EditorEvents {
56
418
  selectionChange: (snapshot: EditorSnapshot) => void;
57
419
  error: (error: EditorError) => void;
58
420
  historyDiagnostic: (diagnostic: HistoryDiagnostic) => void;
421
+ /**
422
+ * An anonymous diagnostic: a document opened or failed to open, an edit or a tracked change
423
+ * was refused, a font failed. Carries stable codes and bucketed numbers, never document
424
+ * content, so a handler may send it to an error tracker as it is.
425
+ *
426
+ * A document passed at construction opens before a host can subscribe. To see that open,
427
+ * register a module with `onDiagnostic` instead.
428
+ *
429
+ * @example
430
+ * ```ts
431
+ * editor.on('diagnostic', (event) => {
432
+ * if (event.kind === 'edit.rejected') console.warn(explainDiagnostic(event.code).hint);
433
+ * });
434
+ * ```
435
+ */
436
+ diagnostic: (event: EditorDiagnostic) => void;
437
+ /**
438
+ * An explicit request landed on a review item, and its card or balloon should open.
439
+ *
440
+ * Fires each time Next Change or Previous Change lands (`source: 'navigate'`), and each time
441
+ * `setActiveReviewItem(key, { announce: true })` succeeds (`source: 'host'`). It fires again
442
+ * when the item was already active, so a card the reader closed can open again.
443
+ *
444
+ * It does not fire for a caret move, a click in the page, a dismissal (`key` of `null`), a
445
+ * refused activation, or `setActiveReviewItem(key)` without `announce: true`. A remote edit in a
446
+ * collaboration session never fires it: it is a local view event.
447
+ *
448
+ * @example
449
+ * ```ts
450
+ * editor.on('reviewItemReveal', ({ key, source }) => {
451
+ * openMyBalloon(key); // `source` is 'navigate' or 'host'
452
+ * });
453
+ * ```
454
+ */
455
+ reviewItemReveal: (event: ReviewItemRevealEvent) => void;
456
+ }
457
+ /**
458
+ * The payload of the `reviewItemReveal` event.
459
+ *
460
+ * @public
461
+ */
462
+ interface ReviewItemRevealEvent {
463
+ /**
464
+ * The key of the review item to open, as `getReviewItems()` without `pairReplacements`
465
+ * lists it. Next Change and Previous Change step through that unpaired queue, so for a
466
+ * replacement this is the key of its deletion or its insertion. `setActiveReviewItem`
467
+ * reports the key it was given, so a call with a pair's key reports that key here and in
468
+ * {@link ReviewItemRevealEvent.pairKey}.
469
+ */
470
+ readonly key: string;
471
+ /**
472
+ * The key that `getReviewItems({ pairReplacements: true })` gives the replacement this item
473
+ * belongs to. Present only when the item is a paired replacement or one half of one. A
474
+ * host that lists pairs opens `pairKey ?? key`.
475
+ */
476
+ readonly pairKey?: string;
477
+ /**
478
+ * What asked for the item. `'navigate'` is Next Change or Previous Change, from the menu,
479
+ * the toolbar, a shortcut, or `exec({ type: 'navigateReviewChange' })`. `'host'` is a call
480
+ * to `setActiveReviewItem` (and so `useReview().setActive`) with `announce: true`.
481
+ */
482
+ readonly source: ReviewItemRevealSource;
59
483
  }
484
+ /** What asked to reveal a review item. See {@link ReviewItemRevealEvent.source}. @public */
485
+ type ReviewItemRevealSource = 'navigate' | 'host';
60
486
  /**
61
487
  * The payload of the `change` event / `onChange`. It carries revision + identity
62
488
  * deltas, NOT serialized bytes: serializing a whole DOCX on every keystroke would
@@ -73,13 +499,30 @@ interface DocumentChange {
73
499
  readonly dirty?: readonly string[];
74
500
  }
75
501
 
502
+ /**
503
+ * Where a scroll places its target in the viewport.
504
+ *
505
+ * - `'start'`: near the top, like a jump to a heading.
506
+ * - `'center'`: centred.
507
+ * - `'centerIfNeeded'`: still while the target is on screen, centred when it has to move.
508
+ * - `'nearest'`: the minimum scroll, which leaves the target at the edge it came in from.
509
+ *
510
+ * Each method that takes a placement states its own default.
511
+ *
512
+ * @public
513
+ */
514
+ type ScrollPlacement = 'start' | 'center' | 'centerIfNeeded' | 'nearest';
76
515
  /**
77
516
  * Scroll settings for {@link EditorAnchorNavigation.scrollToAnchor}. Every field is optional.
78
517
  * The fields match document refresh `NavigateToChangeOptions`. @public
79
518
  */
80
519
  interface ScrollToAnchorOptions {
81
- /** Target alignment. Default: centerIfNeeded, which keeps the viewport still for a visible target. */
82
- readonly block?: 'start' | 'center' | 'centerIfNeeded' | 'nearest';
520
+ /**
521
+ * Target placement. The default depends on the method: `scrollToAnchor` uses
522
+ * `'centerIfNeeded'`, which keeps the viewport still for a visible target, and
523
+ * `scrollToBlock` uses `'start'`.
524
+ */
525
+ readonly block?: ScrollPlacement;
83
526
  /** Default: instant. Reduced motion uses instant even when smooth is requested. */
84
527
  readonly behavior?: 'instant' | 'smooth';
85
528
  /** Edge padding for start/nearest placement, in CSS pixels. Default: 24. Finite and nonnegative. */
@@ -310,6 +753,243 @@ interface EditorHighlights {
310
753
  getHighlightsAt<R extends HighlightRange = HighlightRange>(clientX: number, clientY: number): readonly HighlightHit<R>[];
311
754
  }
312
755
 
756
+ /** One review item under a client point. @public */
757
+ interface ReviewItemHit {
758
+ /** The item, as `getReviewItems()` with the same query returns it. */
759
+ readonly placement: ReviewItemPlacement;
760
+ /**
761
+ * The item's painted band on the line under the point, in client coordinates. It covers the
762
+ * part of the item's range on that line, not the whole range. Anchor popovers to it.
763
+ */
764
+ readonly rect: HighlightRect;
765
+ }
766
+ /** Hit testing for hosts that draw their own review chrome. @public */
767
+ interface EditorReviewHits {
768
+ /**
769
+ * The review items whose text is under a client point, innermost first.
770
+ *
771
+ * An item hits when the CHARACTER under the point is inside one of its ranges, so the
772
+ * right half of a range's last character still hits, and the left half of the next
773
+ * character does not. Ranges that cover no characters, such as a tracked paragraph mark or
774
+ * a comment on an empty range, never hit. Items without a range never hit.
775
+ *
776
+ * The test covers every story the review queue lists and the pages paint: the body,
777
+ * tables, headers, footers, footnotes, and endnotes. Only painted pages are tested, so a
778
+ * point over a page that is not built returns no items.
779
+ *
780
+ * The result reports every item whose range covers the character, including replies,
781
+ * which share their thread's range, and resolved comments. Filter on
782
+ * `placement.parentId`, `placement.parentRevisionId`, or `placement.resolved` to find the
783
+ * card that owns the hit. Order follows the review queue's own rule for the caret: the
784
+ * narrowest range first, then comments before custom nodes before revisions, then the
785
+ * most deeply nested revision.
786
+ *
787
+ * A point hits the glyph band of a line, the same band a text highlight marks. A point in
788
+ * the spacing between lines hits nothing. `query` filters the items the same way it
789
+ * filters `getReviewItems()`. Coordinates that are not finite numbers return an empty
790
+ * array. Each call reads the whole review queue, so call it from a click, not on every
791
+ * pointer move.
792
+ *
793
+ * @example
794
+ * ```ts
795
+ * pages.addEventListener('click', (event) => {
796
+ * const [hit] = editor.getReviewItemsAt(event.clientX, event.clientY);
797
+ * if (hit) showBalloon(hit.placement.key, hit.rect);
798
+ * });
799
+ * ```
800
+ * @public
801
+ */
802
+ getReviewItemsAt(clientX: number, clientY: number, query?: ReviewItemQuery): readonly ReviewItemHit[];
803
+ /**
804
+ * The bands one review item paints, one per line part, in client coordinates.
805
+ *
806
+ * `key` is a `ReviewItemPlacement.key`. Bands follow page order, and within a page the
807
+ * body comes before headers, footers, and notes. Only painted pages contribute. An unknown
808
+ * key, an item without a range, or an item with no text on a painted page returns an
809
+ * empty array. Anchor a balloon to the first band, or join the bands for an outline.
810
+ *
811
+ * @example
812
+ * ```ts
813
+ * const [first] = editor.getReviewItemRects(placement.key);
814
+ * if (first) positionBalloon(first);
815
+ * ```
816
+ * @public
817
+ */
818
+ getReviewItemRects(key: string): readonly HighlightRect[];
819
+ }
820
+
821
+ /**
822
+ * Narrows what `getReviewItems` returns.
823
+ *
824
+ * Filtering revision kinds is how a host hides structural cards it has no UI for,
825
+ * `placement: false` skips the layout pass entirely when only metadata is wanted, and
826
+ * `pairReplacements` lists a typed-over selection as one decision.
827
+ */
828
+ interface ReviewItemQuery {
829
+ /**
830
+ * Revision kinds to leave out of the returned items, for example structural kinds that the
831
+ * host has no card for. Default: none. Comments and custom items are never removed. This
832
+ * filters only the returned data; to stop the caret from activating the same kinds, call
833
+ * `setReviewActivationExclusions`.
834
+ */
835
+ readonly excludeRevisionKinds?: readonly ReviewRevisionKind[];
836
+ /** When false, skip layout geometry; metadata is unchanged and anchors are null. Default true. */
837
+ readonly placement?: boolean;
838
+ /**
839
+ * When true, list a deletion and the insertion that directly follows it as one
840
+ * `'replace'` item. Default false.
841
+ *
842
+ * Two revisions pair when they are next to each other among the queue's revisions, the
843
+ * deletion comes first, both have the same author, nesting level and `readOnly` value, and
844
+ * the deletion's last range ends at the same paragraph and offset where the insertion's
845
+ * first range starts. The pair's `text` is the inserted words and `replacedText` the
846
+ * deleted words. The two halves are not listed separately.
847
+ *
848
+ * Kinds in {@link excludeRevisionKinds} are removed before pairing, so an excluded deletion
849
+ * or insertion never pairs. Excluding `'replace'` removes the pairs too.
850
+ *
851
+ * The pair's `key` is stable while both halves are pending, and every key-addressed verb
852
+ * accepts it whatever query you read it with. Accepting or rejecting it resolves both
853
+ * halves in one transaction and one undo step. Activating it opens the deletion; the pair
854
+ * reports `isActive` while either half is active. A reply anchors over the inserted words,
855
+ * and replies to either half are listed under the pair.
856
+ */
857
+ readonly pairReplacements?: boolean;
858
+ }
859
+
860
+ /**
861
+ * How activating a review item places it in the viewport, and whether it announces the
862
+ * reveal.
863
+ *
864
+ * @public
865
+ */
866
+ interface ReviewActivationOptions {
867
+ /**
868
+ * Where the item lands, or `false` to open it without scrolling at all.
869
+ *
870
+ * Default `'centerIfNeeded'`: silent while the item is already on screen, centred when it
871
+ * has to travel. `'nearest'` scrolls the minimum instead, which parks the item flush
872
+ * against the edge it came in from; `'start'` puts it near the top, the way a jump to a
873
+ * heading reads. `false` is for a host whose own list already drives the scroll and does
874
+ * not want the engine competing with it.
875
+ *
876
+ * It governs the reveal of the ITEM. An item in a header, a footer or a note also opens
877
+ * that story, and opening one always brings its band into view — a story the reader cannot
878
+ * see is one they cannot read the change in, which is the whole point of activating it.
879
+ */
880
+ readonly reveal?: ScrollPlacement | false;
881
+ /**
882
+ * Whether a successful activation fires the `reviewItemReveal` event. Default `false`.
883
+ *
884
+ * Pass `true` to open the item the way Next Change does: the packaged review UI opens its
885
+ * balloon, or opens a closed review pane at its card when the pane's `opening` setting is
886
+ * `'auto'`. The item becomes active either way.
887
+ *
888
+ * @example
889
+ * ```ts
890
+ * editor.setActiveReviewItem(key, { announce: true });
891
+ * ```
892
+ */
893
+ readonly announce?: boolean;
894
+ }
895
+
896
+ /**
897
+ * What every review card carries, whatever kind of decision it represents.
898
+ *
899
+ * Presentation-ready by design: author, initials, date and text are derived by the ENGINE,
900
+ * because deriving them means walking runs and reading `w15:commentsEx`. An adapter doing that
901
+ * walk would put document derivation in the host and would have to be written once per
902
+ * framework.
903
+ */
904
+ interface ReviewItemPlacementBase {
905
+ /** Stable and unique per decision within this editor instance. */
906
+ readonly key: string;
907
+ /** The engine's own id for the comment, the revision, or the custom node. */
908
+ readonly id: string;
909
+ readonly author: string;
910
+ /** Initials for an avatar: `@w:initials` when the file carries one, else from the name. */
911
+ readonly initials: string;
912
+ /** `@w:date`, absent when the file omits it — Word does when date stamping is off. */
913
+ readonly date?: string;
914
+ /**
915
+ * The comment's body, the words the revision covers, or the custom card's detail.
916
+ *
917
+ * PLAIN TEXT, and it must be rendered as text: a `.docx` is a zip of XML an attacker
918
+ * controls end to end, so this string is untrusted and never markup.
919
+ */
920
+ readonly text: string;
921
+ /**
922
+ * Replies to this item, in document order.
923
+ *
924
+ * Comments AND revisions carry them: OOXML gives `w:ins` and `w:del` no body, so replying
925
+ * to a tracked change writes a comment over the change's own range, and the reply belongs
926
+ * inside the card for the change rather than beside it.
927
+ */
928
+ readonly replyIds: readonly string[];
929
+ /**
930
+ * True when the engine cannot resolve this kind structurally, so accept and reject must
931
+ * not be offered. A card offering a button the engine will refuse is worse than one that
932
+ * explains why it cannot.
933
+ */
934
+ readonly readOnly: boolean;
935
+ /**
936
+ * Whether {@link Editor.setActiveReviewItem} would take this key.
937
+ *
938
+ * False for an item with no resolvable range, for a custom node without `reviewCard`
939
+ * (`carded: false`), and for a revision kind the host's rail excluded through
940
+ * {@link Editor.setReviewActivationExclusions} — the queue still LISTS
941
+ * those, because `getReviewItems` answers "what does this document hold" rather than "what
942
+ * may be clicked", and a host filtering the two apart needs to be told which is which. A
943
+ * card drawn for an item that cannot be activated is a card that does nothing when clicked.
944
+ */
945
+ readonly activatable: boolean;
946
+ /** Document-space Y of the anchor, or null when the item has no resolvable range. */
947
+ readonly anchorY: number | null;
948
+ readonly pageIndex: number | null;
949
+ readonly isActive: boolean;
950
+ }
951
+ /** A comment thread's card. @public */
952
+ interface ReviewCommentPlacement extends ReviewItemPlacementBase {
953
+ readonly kind: 'comment';
954
+ /** Whether `w15:commentsEx` marks the thread done. */
955
+ readonly resolved: boolean;
956
+ /** The comment this replies to, absent at the top of a thread. */
957
+ readonly parentId?: string;
958
+ /**
959
+ * The REVISION this comment answers, absent unless it does.
960
+ *
961
+ * A surface listing top-level cards must skip these as well as the ones with a
962
+ * {@link parentId}: the card is rendered inside the change it answers, and a rail that
963
+ * only checked `parentId` drew the reply twice.
964
+ */
965
+ readonly parentRevisionId?: string;
966
+ readonly item: ReviewCommentItem;
967
+ }
968
+ /** A tracked change's card. @public */
969
+ interface ReviewRevisionPlacement extends ReviewItemPlacementBase {
970
+ readonly kind: 'revision';
971
+ /** Which decision this is. */
972
+ readonly revisionKind: ReviewRevisionKind;
973
+ /**
974
+ * The words a replacement decision removes when {@link revisionKind} is `'replace'`.
975
+ * The built-in reader lists separate deletion and insertion cards unless the query sets
976
+ * {@link ReviewItemQuery.pairReplacements}.
977
+ */
978
+ readonly replacedText?: string;
979
+ readonly item: ReviewRevisionItem;
980
+ }
981
+ /** A custom node's card (`defineCustomNode` with a `reviewCard` hook). @public */
982
+ interface ReviewCustomPlacement extends ReviewItemPlacementBase {
983
+ readonly kind: 'custom';
984
+ readonly item: ReviewCustomItem;
985
+ }
986
+ /**
987
+ * A DISCRIMINATED union on {@link ReviewItemPlacementBase.kind}: narrowing the kind
988
+ * narrows `item` and the kind-specific fields with it, so a consumer never writes the
989
+ * `placement.kind === 'custom' && placement.item.kind === 'custom'` double check.
990
+ */
991
+ type ReviewItemPlacement = ReviewCommentPlacement | ReviewRevisionPlacement | ReviewCustomPlacement;
992
+
313
993
  /** Selection and unsupported-change policy for a bulk review decision. @public */
314
994
  interface ResolveReviewChangesOptions {
315
995
  action: 'accept' | 'reject';
@@ -320,6 +1000,40 @@ interface ResolveReviewChangesOptions {
320
1000
  /** Defaults to skip. Strict refuses the entire selection if any target cannot resolve. */
321
1001
  unsupported?: 'skip' | 'fail';
322
1002
  }
1003
+ /**
1004
+ * Who and when a change of tracked-change author records. Shared by both selections.
1005
+ * @public
1006
+ */
1007
+ interface ReviewChangesAttribution {
1008
+ /**
1009
+ * The author to record. Defaults to the editor's `author`, so a reviewer adopts changes as
1010
+ * their own. A command with neither refuses, because `w:author` is required.
1011
+ */
1012
+ author?: string;
1013
+ /** An ISO 8601 `xsd:dateTime` to record. Omit it to keep each change's own date. */
1014
+ date?: string;
1015
+ /** Defaults to skip. Strict refuses the entire selection if any target cannot change. */
1016
+ unsupported?: 'skip' | 'fail';
1017
+ }
1018
+ /**
1019
+ * Selection and attribution for a change of tracked-change author. The changes stay pending.
1020
+ *
1021
+ * Select exact `keys` from `getReviewItems()`, or a `scope` narrowed by `authors`. The two
1022
+ * selections exclude each other.
1023
+ * @public
1024
+ */
1025
+ type SetReviewChangesAuthorOptions = ReviewChangesAttribution & ({
1026
+ /** Exact keys from getReviewItems(). Duplicate keys change once. */
1027
+ keys: readonly string[];
1028
+ scope?: never;
1029
+ authors?: never;
1030
+ } | {
1031
+ keys?: never;
1032
+ /** Defaults to revisions shown by author visibility and the tracked-changes filter. */
1033
+ scope?: 'visible' | 'document';
1034
+ /** Only the changes these authors made, within `scope`. Matches `w:author` exactly. */
1035
+ authors?: readonly string[];
1036
+ });
323
1037
 
324
1038
  /**
325
1039
  * How a keystroke reaches the document.
@@ -880,7 +1594,7 @@ type CanResult = {
880
1594
  * const bytesOut = await editor.save();
881
1595
  * ```
882
1596
  */
883
- interface Editor extends EditorAnchorNavigation, EditorHighlights {
1597
+ interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewHits {
884
1598
  /**
885
1599
  * Load a new document (DOCX bytes, `'blank'`, or a handle), replacing the current one.
886
1600
  *
@@ -1165,8 +1879,37 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights {
1165
1879
  * {@link setReviewActivationExclusions}), for a custom node without `reviewCard`, and when
1166
1880
  * the story it lives in will not open — and a host walking a queue with next/previous
1167
1881
  * controls has no other way to learn that a step did nothing. Consult {@link ReviewItemPlacement.activatable} to avoid asking.
1882
+ *
1883
+ * With `options.announce: true`, a call that lands fires `reviewItemReveal` with
1884
+ * `source: 'host'`, also when the item was already active, so the packaged review UI opens
1885
+ * the item's balloon or card. By default it fires nothing. A `null` key fires nothing.
1168
1886
  */
1169
1887
  setActiveReviewItem(key: string | null, options?: ReviewActivationOptions): ExecResult;
1888
+ /**
1889
+ * The key of the ACTIVATED review item: the one {@link setActiveReviewItem}, Next Change, or
1890
+ * Previous Change made active, while the caret stays in it.
1891
+ *
1892
+ * Two ideas of "active" exist. The caret-active item is the one the caret is in, however it
1893
+ * got there: `isActive` on the placements {@link getReviewItems} returns, and `activeKey` in
1894
+ * `useReview()`. The activated item is narrower: only an explicit activation sets it, so a
1895
+ * caret that merely lands in a change leaves this `null`. Open a balloon or card for the
1896
+ * activated item, and highlight the caret-active one.
1897
+ *
1898
+ * Pass the query you read items with, so the key matches theirs: with
1899
+ * `pairReplacements: true`, a paired replacement reports the pair's key; without it, the
1900
+ * key of the half the caret is in. The value changes with the selection, so read it again
1901
+ * on `selectionChange`.
1902
+ *
1903
+ * @example
1904
+ * ```ts
1905
+ * const query = { pairReplacements: true };
1906
+ * editor.on('selectionChange', () => {
1907
+ * const activated = editor.getActivatedReviewItemKey(query);
1908
+ * if (activated !== null) showMyCard(activated);
1909
+ * });
1910
+ * ```
1911
+ */
1912
+ getActivatedReviewItemKey(query?: ReviewItemQuery): string | null;
1170
1913
  /**
1171
1914
  * Revision kinds the caret must never activate, or null for none.
1172
1915
  *
@@ -1256,7 +1999,12 @@ interface Editor extends EditorAnchorNavigation, EditorHighlights {
1256
1999
  * the host has no scroll container — a caller can tell "not found" from "scrolled".
1257
2000
  */
1258
2001
  scrollToPage(pageNumber: number): boolean;
1259
- scrollToBlock(blockId: string): boolean;
2002
+ /**
2003
+ * `options` takes the {@link ScrollToAnchorOptions} fields. `block` defaults to `'start'`
2004
+ * here (`scrollToAnchor` defaults to `'centerIfNeeded'`), `behavior` to `'instant'`, and
2005
+ * `offsetPx` to 24. An invalid option also returns false, and nothing scrolls.
2006
+ */
2007
+ scrollToBlock(blockId: string, options?: ScrollToAnchorOptions): boolean;
1260
2008
  getZoom(): number;
1261
2009
  /**
1262
2010
  * Set the display scale. Values outside a sane range are rejected rather than
@@ -1337,134 +2085,6 @@ type EditorCommandShape<T> = {
1337
2085
  type TrackedChangePredicate = (revision: ReviewRevisionItem) => boolean;
1338
2086
  /** How revisions excluded by a tracked-changes predicate project into the view. */
1339
2087
  type TrackedChangeFilterMode = 'accept' | 'reject';
1340
- /**
1341
- * Narrows what `getReviewItems` returns.
1342
- *
1343
- * Both fields exist to keep the review rail cheap: filtering revision kinds is how a host hides
1344
- * structural cards it has no UI for, and `placement: false` skips the layout pass entirely when
1345
- * only metadata is wanted.
1346
- */
1347
- interface ReviewItemQuery {
1348
- readonly excludeRevisionKinds?: readonly ReviewRevisionKind[];
1349
- /** When false, skip layout geometry; metadata is unchanged and anchors are null. Default true. */
1350
- readonly placement?: boolean;
1351
- }
1352
- /**
1353
- * What every review card carries, whatever kind of decision it represents.
1354
- *
1355
- * Presentation-ready by design: author, initials, date and text are derived by the ENGINE,
1356
- * because deriving them means walking runs and reading `w15:commentsEx`. An adapter doing that
1357
- * walk would put document derivation in the host and would have to be written once per
1358
- * framework.
1359
- */
1360
- interface ReviewItemPlacementBase {
1361
- /** Stable and unique per decision within this editor instance. */
1362
- readonly key: string;
1363
- /** The engine's own id for the comment, the revision, or the custom node. */
1364
- readonly id: string;
1365
- readonly author: string;
1366
- /** Initials for an avatar: `@w:initials` when the file carries one, else from the name. */
1367
- readonly initials: string;
1368
- /** `@w:date`, absent when the file omits it — Word does when date stamping is off. */
1369
- readonly date?: string;
1370
- /**
1371
- * The comment's body, the words the revision covers, or the custom card's detail.
1372
- *
1373
- * PLAIN TEXT, and it must be rendered as text: a `.docx` is a zip of XML an attacker
1374
- * controls end to end, so this string is untrusted and never markup.
1375
- */
1376
- readonly text: string;
1377
- /**
1378
- * Replies to this item, in document order.
1379
- *
1380
- * Comments AND revisions carry them: OOXML gives `w:ins` and `w:del` no body, so replying
1381
- * to a tracked change writes a comment over the change's own range, and the reply belongs
1382
- * inside the card for the change rather than beside it.
1383
- */
1384
- readonly replyIds: readonly string[];
1385
- /**
1386
- * True when the engine cannot resolve this kind structurally, so accept and reject must
1387
- * not be offered. A card offering a button the engine will refuse is worse than one that
1388
- * explains why it cannot.
1389
- */
1390
- readonly readOnly: boolean;
1391
- /**
1392
- * Whether {@link Editor.setActiveReviewItem} would take this key.
1393
- *
1394
- * False for an item with no resolvable range, for a custom node without `reviewCard`
1395
- * (`carded: false`), and for a revision kind the host's rail excluded through
1396
- * {@link Editor.setReviewActivationExclusions} — the queue still LISTS
1397
- * those, because `getReviewItems` answers "what does this document hold" rather than "what
1398
- * may be clicked", and a host filtering the two apart needs to be told which is which. A
1399
- * card drawn for an item that cannot be activated is a card that does nothing when clicked.
1400
- */
1401
- readonly activatable: boolean;
1402
- /** Document-space Y of the anchor, or null when the item has no resolvable range. */
1403
- readonly anchorY: number | null;
1404
- readonly pageIndex: number | null;
1405
- readonly isActive: boolean;
1406
- }
1407
- /**
1408
- * How activating a review item places it in the viewport.
1409
- *
1410
- * @public
1411
- */
1412
- interface ReviewActivationOptions {
1413
- /**
1414
- * Where the item lands, or `false` to open it without scrolling at all.
1415
- *
1416
- * Default `'centerIfNeeded'`: silent while the item is already on screen, centred when it
1417
- * has to travel. `'nearest'` scrolls the minimum instead, which parks the item flush
1418
- * against the edge it came in from; `'start'` puts it near the top, the way a jump to a
1419
- * heading reads. `false` is for a host whose own list already drives the scroll and does
1420
- * not want the engine competing with it.
1421
- *
1422
- * It governs the reveal of the ITEM. An item in a header, a footer or a note also opens
1423
- * that story, and opening one always brings its band into view — a story the reader cannot
1424
- * see is one they cannot read the change in, which is the whole point of activating it.
1425
- */
1426
- readonly reveal?: 'start' | 'center' | 'centerIfNeeded' | 'nearest' | false;
1427
- }
1428
- /** A comment thread's card. @public */
1429
- interface ReviewCommentPlacement extends ReviewItemPlacementBase {
1430
- readonly kind: 'comment';
1431
- /** Whether `w15:commentsEx` marks the thread done. */
1432
- readonly resolved: boolean;
1433
- /** The comment this replies to, absent at the top of a thread. */
1434
- readonly parentId?: string;
1435
- /**
1436
- * The REVISION this comment answers, absent unless it does.
1437
- *
1438
- * A surface listing top-level cards must skip these as well as the ones with a
1439
- * {@link parentId}: the card is rendered inside the change it answers, and a rail that
1440
- * only checked `parentId` drew the reply twice.
1441
- */
1442
- readonly parentRevisionId?: string;
1443
- readonly item: ReviewCommentItem;
1444
- }
1445
- /** A tracked change's card. @public */
1446
- interface ReviewRevisionPlacement extends ReviewItemPlacementBase {
1447
- readonly kind: 'revision';
1448
- /** Which decision this is. */
1449
- readonly revisionKind: ReviewRevisionKind;
1450
- /**
1451
- * The words a custom replacement decision removes when {@link revisionKind} is `'replace'`.
1452
- * The built-in reader exposes separate deletion and insertion cards.
1453
- */
1454
- readonly replacedText?: string;
1455
- readonly item: ReviewRevisionItem;
1456
- }
1457
- /** A custom node's card (`defineCustomNode` with a `reviewCard` hook). @public */
1458
- interface ReviewCustomPlacement extends ReviewItemPlacementBase {
1459
- readonly kind: 'custom';
1460
- readonly item: ReviewCustomItem;
1461
- }
1462
- /**
1463
- * A DISCRIMINATED union on {@link ReviewItemPlacementBase.kind}: narrowing the kind
1464
- * narrows `item` and the kind-specific fields with it, so a consumer never writes the
1465
- * `placement.kind === 'custom' && placement.item.kind === 'custom'` double check.
1466
- */
1467
- type ReviewItemPlacement = ReviewCommentPlacement | ReviewRevisionPlacement | ReviewCustomPlacement;
1468
2088
 
1469
2089
  /**
1470
2090
  * Every command the editor accepts, keyed by name with its payload as the value.
@@ -1498,6 +2118,8 @@ interface EditorCommands extends EditorCommandShape<DocEdits>, EditorHeaderFoote
1498
2118
  };
1499
2119
  /** Resolve eligible changes shown by the active filters, or an explicit scope, in one undo step. */
1500
2120
  resolveAllReviewChanges: ResolveReviewChangesOptions;
2121
+ /** Attribute eligible changes to another author, keeping them pending, in one undo step. */
2122
+ setReviewChangesAuthor: SetReviewChangesAuthorOptions;
1501
2123
  /** Change the review projection without accepting or rejecting document revisions. */
1502
2124
  setReviewDisplayMode: {
1503
2125
  mode: ReviewDisplayMode;
@@ -2114,6 +2736,13 @@ interface EditorSnapshot {
2114
2736
  * value-equal snapshot correctly refuses to re-render.
2115
2737
  */
2116
2738
  readonly reviewPaneOpen?: boolean;
2739
+ /**
2740
+ * The review pane settings in force: every field of `ReviewPaneOptions`, such as when the
2741
+ * pane opens by itself and what it does when its card column does not fit. Change them with
2742
+ * `setReviewPaneOptions`. Never saved. Always
2743
+ * set: an editor without a review module reports `DEFAULT_REVIEW_PANE`.
2744
+ */
2745
+ readonly reviewPane: ResolvedReviewPane;
2117
2746
  /** Whether Show/Hide paragraph marks is enabled. */
2118
2747
  readonly showParagraphMarks?: boolean;
2119
2748
  /** The document's `w:documentProtection`, as the file states it; null with no document. */
@@ -2192,5 +2821,5 @@ interface EditorError extends Error {
2192
2821
  readonly code?: string;
2193
2822
  }
2194
2823
 
2195
- export { EditorFontError as E, cropPercentFromCropPermille as r, cropPercentFromPermille as s, cropPercentFromSourceCrop as t, cropPermilleFromCropPercent as u, cropPermilleFromPercent as v, sourceCropFromCropPercent as w, validateImageCropPercent as x };
2196
- export type { EditorPosition as $, AnchorHighlightOptions as A, TableBorderSpec as B, CanResult as C, DocumentSource as D, FontFaceRequest as F, TableBorderStyle as G, HighlightRange as H, ImageContext as I, TableContext as J, AuthoredNoteNumbering as K, DocumentChange as L, DocumentEditingMode as M, DocumentHandle as N, EditorAnchorNavigation as O, EditorCommandShape as P, EditorCommands as Q, EditorError as R, ScrollToAnchorOptions as S, TextMatch as T, EditorEvents as U, EditorFontErrorCode as V, EditorFormatPainterCommands as W, EditorHeaderFooterCommands as X, EditorHighlights as Y, ZoomMode as Z, EditorNoteCommands as _, FontConfiguration as a, EditorQueries as a0, EditorQuery as a1, EditorQueryResults as a2, EditorSelection as a3, FormatPainterLevel as a4, FormatPainterMode as a5, FurnitureVariant as a6, HeaderFooterSlotArgs as a7, HeaderFooterState as a8, HyperlinkInfo as a9, NoteKind as aa, NotePropertiesSide as ab, NotePropertiesState as ac, PageSetup as ad, ResolveReviewChangesOptions as ae, ResolvedNoteNumbering as af, ReviewActivationOptions as ag, ReviewCommentPlacement as ah, ReviewCustomPlacement as ai, ReviewItemPlacement as aj, ReviewItemPlacementBase as ak, ReviewItemQuery as al, ReviewRevisionPlacement as am, TableBorderTarget as an, TableCellVerticalAlignment as ao, TableColumnDividerResizeTarget as ap, TableColumnOccurrenceTarget as aq, TableRightEdgeResizeTarget as ar, TableRowOccurrenceTarget as as, ZoomFitTarget as at, FontSource as b, FontSourceSubstitution as c, EditorSnapshot as d, EditorCommand as e, ClearAnchorHighlightOptions as f, AnchorHighlightAnimation as g, Editor as h, HighlightResult as i, HighlightOptions as j, HighlightHit as k, HighlightRect as l, ImageCropPercent as m, ImageCropPermille as n, SelectedImageState as o, TrackedChangeFilterMode as p, TrackedChangePredicate as q, FormatPainterSurfaceState as y, TableBorderEdgeTarget as z };
2824
+ export { DIAGNOSTIC_SCHEMA_VERSION as D, validateImageCropPercent as a$, DEFAULT_REVIEW_PANE as aN, cropPercentFromCropPermille as aT, cropPercentFromPermille as aU, cropPercentFromSourceCrop as aV, cropPermilleFromCropPercent as aW, cropPermilleFromPercent as aX, resolveReviewPane as aY, reviewPaneListsItem as aZ, sourceCropFromCropPercent as a_, EditorFontError as y };
2825
+ export type { HighlightHit as $, AnchorHighlightAnimation as A, EditorFormatPainterCommands as B, CanResult as C, EditorDiagnostic as E, EditorHeaderFooterCommands as F, EditorHighlights as G, EditorNoteCommands as H, EditorPosition as I, EditorQueries as J, EditorQuery as K, EditorQueryResults as L, EditorReviewHits as M, EditorSelection as N, EditorSnapshot as O, FontConfiguration as P, FontFaceRequest as Q, ReviewPaneOptions as R, FontFailedDiagnostic as S, FontSource as T, FontSourceSubstitution as U, FormatPainterLevel as V, FormatPainterMode as W, FormatPainterSurfaceState as X, FurnitureVariant as Y, HeaderFooterSlotArgs as Z, HeaderFooterState as _, EditorDiagnosticKind as a, HighlightOptions as a0, HighlightRange as a1, HighlightRect as a2, HighlightResult as a3, HistoryDiagnosticEvent as a4, HyperlinkInfo as a5, ImageContext as a6, ImageCropPercent as a7, NoteKind as a8, NotePropertiesSide as a9, TableColumnDividerResizeTarget as aA, TableColumnOccurrenceTarget as aB, TableContext as aC, TableRightEdgeResizeTarget as aD, TableRowOccurrenceTarget as aE, TextMatch as aF, TimingSummary as aG, TrackedChangeFilterMode as aH, TrackedChangePredicate as aI, ZoomFitTarget as aJ, ZoomMode as aK, ReviewPaneOverflow as aL, CommentMarkerStyle as aM, ImageCropPermille as aO, ResolvedReviewPane as aP, ReviewPaneItemFields as aQ, ReviewPaneOpening as aR, RevisionDisplay as aS, NotePropertiesState as aa, PageSetup as ab, PerformanceDiagnostic as ac, ResolveReviewChangesOptions as ad, ResolvedNoteNumbering as ae, ReviewActivationOptions as af, ReviewChangesAttribution as ag, ReviewCommentPlacement as ah, ReviewCustomPlacement as ai, ReviewItemHit as aj, ReviewItemPlacement as ak, ReviewItemPlacementBase as al, ReviewItemQuery as am, ReviewItemRevealEvent as an, ReviewItemRevealSource as ao, ReviewRevisionPlacement as ap, ReviewSkippedDiagnostic as aq, ScrollPlacement as ar, ScrollToAnchorOptions as as, SelectedImageState as at, SetReviewChangesAuthorOptions as au, TableBorderEdgeTarget as av, TableBorderSpec as aw, TableBorderStyle as ax, TableBorderTarget as ay, TableCellVerticalAlignment 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, DocumentShape as o, DocumentSource as p, EditRejectedDiagnostic as q, EditRejectionOrigin as r, Editor as s, EditorAnchorNavigation as t, EditorCommandShape as u, EditorCommands as v, EditorError as w, EditorEvents as x, EditorFontErrorCode as z };