@beyondwork/docx-react-component 1.0.17 → 1.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -2
- package/package.json +32 -34
- package/src/api/README.md +5 -1
- package/src/api/public-types.ts +374 -4
- package/src/api/session-state.ts +58 -0
- package/src/core/commands/formatting-commands.ts +1 -0
- package/src/core/commands/image-commands.ts +147 -0
- package/src/core/commands/index.ts +5 -1
- package/src/core/commands/list-commands.ts +231 -36
- package/src/core/commands/paragraph-layout-commands.ts +339 -0
- package/src/core/commands/section-layout-commands.ts +680 -0
- package/src/core/commands/style-commands.ts +262 -0
- package/src/core/search/search-text.ts +329 -0
- package/src/core/selection/mapping.ts +41 -0
- package/src/core/state/editor-state.ts +1 -1
- package/src/index.ts +30 -0
- package/src/io/docx-session.ts +260 -39
- package/src/io/export/serialize-main-document.ts +202 -5
- package/src/io/export/serialize-numbering.ts +28 -7
- package/src/io/normalize/normalize-text.ts +63 -25
- package/src/io/ooxml/numbering-sentinels.ts +44 -0
- package/src/io/ooxml/parse-footnotes.ts +212 -20
- package/src/io/ooxml/parse-headers-footers.ts +229 -25
- package/src/io/ooxml/parse-inline-media.ts +16 -0
- package/src/io/ooxml/parse-main-document.ts +411 -6
- package/src/io/ooxml/parse-numbering.ts +7 -0
- package/src/io/ooxml/parse-settings.ts +184 -0
- package/src/io/ooxml/parse-shapes.ts +25 -0
- package/src/io/ooxml/parse-styles.ts +463 -0
- package/src/io/ooxml/parse-theme.ts +32 -0
- package/src/model/canonical-document.ts +133 -3
- package/src/model/cds-1.0.0.ts +13 -0
- package/src/model/snapshot.ts +2 -1
- package/src/runtime/document-layout.ts +332 -0
- package/src/runtime/document-navigation.ts +564 -0
- package/src/runtime/document-runtime.ts +265 -35
- package/src/runtime/document-search.ts +145 -0
- package/src/runtime/numbering-prefix.ts +47 -26
- package/src/runtime/page-layout-estimation.ts +212 -0
- package/src/runtime/read-only-diagnostics-runtime.ts +1 -0
- package/src/runtime/session-capabilities.ts +2 -0
- package/src/runtime/story-context.ts +164 -0
- package/src/runtime/story-targeting.ts +162 -0
- package/src/runtime/surface-projection.ts +239 -12
- package/src/runtime/table-schema.ts +87 -5
- package/src/runtime/view-state.ts +459 -0
- package/src/ui/WordReviewEditor.tsx +1902 -312
- package/src/ui/browser-export.ts +52 -0
- package/src/ui/headless/preserve-editor-selection.ts +5 -0
- package/src/ui/headless/selection-helpers.ts +20 -0
- package/src/ui/headless/selection-toolbar-model.ts +22 -0
- package/src/ui/headless/use-editor-keyboard.ts +6 -1
- package/src/ui-tailwind/chrome/tw-page-ruler.tsx +386 -0
- package/src/ui-tailwind/chrome/tw-selection-toolbar.tsx +125 -14
- package/src/ui-tailwind/editor-surface/perf-probe.ts +107 -0
- package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +45 -6
- package/src/ui-tailwind/editor-surface/pm-contextual-ui.ts +31 -0
- package/src/ui-tailwind/editor-surface/pm-position-map.ts +2 -2
- package/src/ui-tailwind/editor-surface/pm-schema.ts +47 -5
- package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +95 -22
- package/src/ui-tailwind/editor-surface/search-plugin.ts +19 -68
- package/src/ui-tailwind/editor-surface/tw-inline-token.tsx +11 -0
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +394 -77
- package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +0 -1
- package/src/ui-tailwind/index.ts +2 -1
- package/src/ui-tailwind/review/tw-comment-sidebar.tsx +277 -147
- package/src/ui-tailwind/review/tw-review-rail.tsx +6 -6
- package/src/ui-tailwind/theme/editor-theme.css +123 -0
- package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +4 -0
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +291 -12
- package/src/ui-tailwind/tw-review-workspace.tsx +926 -27
- package/src/validation/compatibility-engine.ts +92 -20
- package/src/validation/diagnostics.ts +1 -0
- package/src/validation/docx-comment-proof.ts +487 -0
package/src/api/public-types.ts
CHANGED
|
@@ -6,12 +6,25 @@ export type ExternalDocumentSource =
|
|
|
6
6
|
bytes: Uint8Array | ArrayBuffer;
|
|
7
7
|
sourceLabel?: string;
|
|
8
8
|
}
|
|
9
|
+
| {
|
|
10
|
+
kind: "session";
|
|
11
|
+
sessionState: EditorSessionState;
|
|
12
|
+
sourceLabel?: string;
|
|
13
|
+
}
|
|
9
14
|
| {
|
|
10
15
|
kind: "snapshot";
|
|
11
16
|
snapshot: PersistedEditorSnapshot;
|
|
12
17
|
sourceLabel?: string;
|
|
13
18
|
};
|
|
14
19
|
|
|
20
|
+
export type LoadSourcePolicy = "prefer-saved-state" | "prefer-source-package";
|
|
21
|
+
|
|
22
|
+
export interface LoadRequest {
|
|
23
|
+
documentId: string;
|
|
24
|
+
loadRevision?: string;
|
|
25
|
+
loadSourcePolicy?: LoadSourcePolicy;
|
|
26
|
+
}
|
|
27
|
+
|
|
15
28
|
export interface EditorUser {
|
|
16
29
|
userId: string;
|
|
17
30
|
displayName: string;
|
|
@@ -43,11 +56,129 @@ export type EditorAnchorProjection =
|
|
|
43
56
|
reason: "deleted" | "invalidatedByStructureChange" | "importAmbiguity";
|
|
44
57
|
};
|
|
45
58
|
|
|
59
|
+
export type EditorStoryTarget =
|
|
60
|
+
| { kind: "main" }
|
|
61
|
+
| {
|
|
62
|
+
kind: "header";
|
|
63
|
+
relationshipId: string;
|
|
64
|
+
variant: "default" | "first" | "even";
|
|
65
|
+
sectionIndex?: number;
|
|
66
|
+
}
|
|
67
|
+
| {
|
|
68
|
+
kind: "footer";
|
|
69
|
+
relationshipId: string;
|
|
70
|
+
variant: "default" | "first" | "even";
|
|
71
|
+
sectionIndex?: number;
|
|
72
|
+
}
|
|
73
|
+
| { kind: "footnote"; noteId: string }
|
|
74
|
+
| { kind: "endnote"; noteId: string };
|
|
75
|
+
|
|
46
76
|
export interface SelectionSnapshot {
|
|
47
77
|
anchor: number;
|
|
48
78
|
head: number;
|
|
49
79
|
isCollapsed: boolean;
|
|
50
80
|
activeRange: EditorAnchorProjection;
|
|
81
|
+
storyTarget?: EditorStoryTarget;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface PageLayoutSnapshot {
|
|
85
|
+
sectionIndex: number;
|
|
86
|
+
sectionType?: "continuous" | "nextPage" | "evenPage" | "oddPage" | "nextColumn";
|
|
87
|
+
pageWidth: number;
|
|
88
|
+
pageHeight: number;
|
|
89
|
+
marginTop: number;
|
|
90
|
+
marginBottom: number;
|
|
91
|
+
marginLeft: number;
|
|
92
|
+
marginRight: number;
|
|
93
|
+
headerMargin: number;
|
|
94
|
+
footerMargin: number;
|
|
95
|
+
gutter: number;
|
|
96
|
+
orientation: "portrait" | "landscape";
|
|
97
|
+
columns: number;
|
|
98
|
+
differentFirstPage: boolean;
|
|
99
|
+
differentOddEvenPages: boolean;
|
|
100
|
+
pageNumbering?: {
|
|
101
|
+
format?: string;
|
|
102
|
+
start?: number;
|
|
103
|
+
chapterStyle?: string;
|
|
104
|
+
chapterSeparator?: string;
|
|
105
|
+
};
|
|
106
|
+
lineNumbering?: {
|
|
107
|
+
countBy?: number;
|
|
108
|
+
start?: number;
|
|
109
|
+
distance?: number;
|
|
110
|
+
restart?: "newPage" | "newSection" | "continuous";
|
|
111
|
+
};
|
|
112
|
+
pageBorders?: {
|
|
113
|
+
top?: { value?: string; size?: number; space?: number; color?: string };
|
|
114
|
+
left?: { value?: string; size?: number; space?: number; color?: string };
|
|
115
|
+
bottom?: { value?: string; size?: number; space?: number; color?: string };
|
|
116
|
+
right?: { value?: string; size?: number; space?: number; color?: string };
|
|
117
|
+
offsetFrom?: "page" | "text";
|
|
118
|
+
display?: "allPages" | "firstPage" | "notFirstPage";
|
|
119
|
+
zOrder?: "front" | "back";
|
|
120
|
+
};
|
|
121
|
+
documentGrid?: {
|
|
122
|
+
type?: "default" | "lines" | "linesAndChars" | "snapToChars";
|
|
123
|
+
linePitch?: number;
|
|
124
|
+
charSpace?: number;
|
|
125
|
+
};
|
|
126
|
+
columnDefinitions: Array<{ width: number; space?: number }>;
|
|
127
|
+
equalWidthColumns: boolean;
|
|
128
|
+
columnSeparator: boolean;
|
|
129
|
+
headerVariants: Array<{ variant: "default" | "first" | "even"; relationshipId: string }>;
|
|
130
|
+
footerVariants: Array<{ variant: "default" | "first" | "even"; relationshipId: string }>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export type WorkspaceMode = "canvas" | "page";
|
|
134
|
+
|
|
135
|
+
export type ZoomLevel = "pageWidth" | "onePage" | number;
|
|
136
|
+
|
|
137
|
+
export type SectionBreakType =
|
|
138
|
+
| "nextPage"
|
|
139
|
+
| "continuous"
|
|
140
|
+
| "evenPage"
|
|
141
|
+
| "oddPage"
|
|
142
|
+
| "nextColumn";
|
|
143
|
+
|
|
144
|
+
export interface SectionLayoutPatch {
|
|
145
|
+
pageSize?: Partial<{
|
|
146
|
+
width: number;
|
|
147
|
+
height: number;
|
|
148
|
+
orientation: "portrait" | "landscape";
|
|
149
|
+
}>;
|
|
150
|
+
pageMargins?: Partial<{
|
|
151
|
+
top: number;
|
|
152
|
+
right: number;
|
|
153
|
+
bottom: number;
|
|
154
|
+
left: number;
|
|
155
|
+
header: number;
|
|
156
|
+
footer: number;
|
|
157
|
+
gutter: number;
|
|
158
|
+
}>;
|
|
159
|
+
columns?: Partial<{
|
|
160
|
+
count: number;
|
|
161
|
+
space: number;
|
|
162
|
+
equalWidth: boolean;
|
|
163
|
+
columns: Array<{ width: number; space?: number }>;
|
|
164
|
+
separator: boolean;
|
|
165
|
+
}>;
|
|
166
|
+
titlePage?: boolean;
|
|
167
|
+
sectionType?: SectionBreakType;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface SectionPageNumberingPatch {
|
|
171
|
+
format?: string | null;
|
|
172
|
+
start?: number | null;
|
|
173
|
+
chapterStyle?: string | null;
|
|
174
|
+
chapterSeparator?: string | null;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface HeaderFooterLinkPatch {
|
|
178
|
+
kind: "header" | "footer";
|
|
179
|
+
variant: "default" | "first" | "even";
|
|
180
|
+
linkToPrevious: boolean;
|
|
181
|
+
relationshipId?: string | null;
|
|
51
182
|
}
|
|
52
183
|
|
|
53
184
|
export interface DocumentStats {
|
|
@@ -144,6 +275,7 @@ export interface FormattingStateSnapshot {
|
|
|
144
275
|
textColor?: string;
|
|
145
276
|
highlightColor?: string | null;
|
|
146
277
|
alignment?: FormattingAlignment;
|
|
278
|
+
paragraphStyleId?: string;
|
|
147
279
|
breadcrumb: FormattingBreadcrumbItem[];
|
|
148
280
|
}
|
|
149
281
|
|
|
@@ -158,6 +290,79 @@ export interface SearchResultSnapshot {
|
|
|
158
290
|
anchor: EditorAnchorProjection;
|
|
159
291
|
excerpt: string;
|
|
160
292
|
isActive: boolean;
|
|
293
|
+
storyTarget?: EditorStoryTarget;
|
|
294
|
+
sectionIndex?: number;
|
|
295
|
+
pageIndex?: number;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// ---------------------------------------------------------------------------
|
|
299
|
+
// Document Navigation Model (Wave 37)
|
|
300
|
+
// ---------------------------------------------------------------------------
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Runtime-owned snapshot of the document's page stack, heading outline, and
|
|
304
|
+
* navigation context. Derived from canonical document state and section
|
|
305
|
+
* properties — never from DOM scroll position or CSS layout.
|
|
306
|
+
*/
|
|
307
|
+
export interface DocumentNavigationSnapshot {
|
|
308
|
+
/** Total estimated page count across all sections. */
|
|
309
|
+
pageCount: number;
|
|
310
|
+
/** Ordered page descriptors, one per logical page. */
|
|
311
|
+
pages: DocumentPageSnapshot[];
|
|
312
|
+
/** Ordered heading outline extracted from paragraph styles. */
|
|
313
|
+
headings: DocumentHeadingSnapshot[];
|
|
314
|
+
/** Index of the page containing the current selection head. */
|
|
315
|
+
activePageIndex: number;
|
|
316
|
+
/** Section index containing the current selection head. */
|
|
317
|
+
activeSectionIndex: number;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** Runtime-derived descriptor for a single logical page. */
|
|
321
|
+
export interface DocumentPageSnapshot {
|
|
322
|
+
/** Zero-based page index within the whole document. */
|
|
323
|
+
pageIndex: number;
|
|
324
|
+
/** Section that owns this page (zero-based). */
|
|
325
|
+
sectionIndex: number;
|
|
326
|
+
/** Zero-based page index within its owning section. */
|
|
327
|
+
pageInSection: number;
|
|
328
|
+
/** Estimated character offset where the page begins in the main story. */
|
|
329
|
+
startOffset: number;
|
|
330
|
+
/** Estimated character offset where the page ends in the main story. */
|
|
331
|
+
endOffset: number;
|
|
332
|
+
/** Page layout properties inherited from the section. */
|
|
333
|
+
layout: PageLayoutSnapshot;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** A heading entry in the document outline. */
|
|
337
|
+
export interface DocumentHeadingSnapshot {
|
|
338
|
+
/** Stable identifier for the heading (derived from block position). */
|
|
339
|
+
headingId: string;
|
|
340
|
+
/** Outline level (1 = Heading 1, 2 = Heading 2, etc.). */
|
|
341
|
+
level: number;
|
|
342
|
+
/** Plain-text content of the heading paragraph. */
|
|
343
|
+
text: string;
|
|
344
|
+
/** Character offset of the heading in the main story. */
|
|
345
|
+
offset: number;
|
|
346
|
+
/** Zero-based page index where the heading lives. */
|
|
347
|
+
pageIndex: number;
|
|
348
|
+
/** Section index where the heading lives. */
|
|
349
|
+
sectionIndex: number;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export interface StyleCatalogEntrySnapshot {
|
|
353
|
+
styleId: string;
|
|
354
|
+
displayName: string;
|
|
355
|
+
kind: "paragraph" | "character" | "table";
|
|
356
|
+
isDefault: boolean;
|
|
357
|
+
basedOn?: string;
|
|
358
|
+
nextStyle?: string;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export interface StyleCatalogSnapshot {
|
|
362
|
+
paragraphs: StyleCatalogEntrySnapshot[];
|
|
363
|
+
characters: StyleCatalogEntrySnapshot[];
|
|
364
|
+
tables: StyleCatalogEntrySnapshot[];
|
|
365
|
+
fromPackage: boolean;
|
|
161
366
|
}
|
|
162
367
|
|
|
163
368
|
export interface InsertTableOptions {
|
|
@@ -234,7 +439,17 @@ export type SurfaceInlineSegment =
|
|
|
234
439
|
warningId: string;
|
|
235
440
|
label: string;
|
|
236
441
|
detail: string;
|
|
442
|
+
presentation?: "inline-chip" | "quiet-marker";
|
|
237
443
|
state: "locked-preserve-only";
|
|
444
|
+
}
|
|
445
|
+
| {
|
|
446
|
+
segmentId: string;
|
|
447
|
+
kind: "note_ref";
|
|
448
|
+
from: number;
|
|
449
|
+
to: number;
|
|
450
|
+
noteKind: "footnote" | "endnote";
|
|
451
|
+
noteId: string;
|
|
452
|
+
label: string;
|
|
238
453
|
};
|
|
239
454
|
|
|
240
455
|
export interface SurfaceTableCellSnapshot {
|
|
@@ -243,11 +458,19 @@ export interface SurfaceTableCellSnapshot {
|
|
|
243
458
|
colspan: number;
|
|
244
459
|
rowspan: number;
|
|
245
460
|
backgroundColor?: string | null;
|
|
461
|
+
verticalAlign?: "top" | "center" | "bottom" | null;
|
|
462
|
+
borderTop?: string | null;
|
|
463
|
+
borderRight?: string | null;
|
|
464
|
+
borderBottom?: string | null;
|
|
465
|
+
borderLeft?: string | null;
|
|
246
466
|
content: SurfaceBlockSnapshot[];
|
|
247
467
|
}
|
|
248
468
|
|
|
249
469
|
export interface SurfaceTableRowSnapshot {
|
|
250
470
|
cells: SurfaceTableCellSnapshot[];
|
|
471
|
+
height?: number;
|
|
472
|
+
heightRule?: "auto" | "atLeast" | "exact";
|
|
473
|
+
isHeader?: boolean;
|
|
251
474
|
}
|
|
252
475
|
|
|
253
476
|
export type SurfaceBlockSnapshot =
|
|
@@ -261,6 +484,8 @@ export type SurfaceBlockSnapshot =
|
|
|
261
484
|
numberingInstanceId: string;
|
|
262
485
|
level: number;
|
|
263
486
|
};
|
|
487
|
+
numberingPrefix?: string;
|
|
488
|
+
numberingSuffix?: "tab" | "space" | "nothing";
|
|
264
489
|
alignment?: "left" | "center" | "right" | "both" | "distribute";
|
|
265
490
|
spacing?: { before?: number; after?: number; line?: number; lineRule?: string };
|
|
266
491
|
indentation?: { left?: number; right?: number; firstLine?: number; hanging?: number };
|
|
@@ -272,6 +497,7 @@ export type SurfaceBlockSnapshot =
|
|
|
272
497
|
pageBreakBefore?: boolean;
|
|
273
498
|
outlineLevel?: number;
|
|
274
499
|
bidi?: boolean;
|
|
500
|
+
suppressLineNumbers?: boolean;
|
|
275
501
|
segments: SurfaceInlineSegment[];
|
|
276
502
|
}
|
|
277
503
|
| {
|
|
@@ -281,6 +507,15 @@ export type SurfaceBlockSnapshot =
|
|
|
281
507
|
to: number;
|
|
282
508
|
styleId?: string;
|
|
283
509
|
gridColumns: number[];
|
|
510
|
+
alignment?: "left" | "center" | "right";
|
|
511
|
+
tblLook?: {
|
|
512
|
+
firstRow?: boolean;
|
|
513
|
+
lastRow?: boolean;
|
|
514
|
+
firstColumn?: boolean;
|
|
515
|
+
lastColumn?: boolean;
|
|
516
|
+
noHBand?: boolean;
|
|
517
|
+
noVBand?: boolean;
|
|
518
|
+
};
|
|
284
519
|
rows: SurfaceTableRowSnapshot[];
|
|
285
520
|
}
|
|
286
521
|
| {
|
|
@@ -292,6 +527,11 @@ export type SurfaceBlockSnapshot =
|
|
|
292
527
|
alias?: string;
|
|
293
528
|
tag?: string;
|
|
294
529
|
lock?: string;
|
|
530
|
+
checkboxChecked?: boolean;
|
|
531
|
+
dateValue?: string;
|
|
532
|
+
dropdownItems?: Array<{ displayText?: string; value: string }>;
|
|
533
|
+
comboBoxItems?: Array<{ displayText?: string; value: string }>;
|
|
534
|
+
showingPlcHdr?: boolean;
|
|
295
535
|
children: SurfaceBlockSnapshot[];
|
|
296
536
|
}
|
|
297
537
|
| {
|
|
@@ -306,11 +546,19 @@ export type SurfaceBlockSnapshot =
|
|
|
306
546
|
state: "locked-preserve-only";
|
|
307
547
|
};
|
|
308
548
|
|
|
549
|
+
export interface SecondaryStorySurface {
|
|
550
|
+
target: EditorStoryTarget;
|
|
551
|
+
label: string;
|
|
552
|
+
storySize: number;
|
|
553
|
+
blocks: SurfaceBlockSnapshot[];
|
|
554
|
+
}
|
|
555
|
+
|
|
309
556
|
export interface EditorSurfaceSnapshot {
|
|
310
557
|
storySize: number;
|
|
311
558
|
plainText: string;
|
|
312
559
|
blocks: SurfaceBlockSnapshot[];
|
|
313
560
|
lockedFragmentIds: string[];
|
|
561
|
+
secondaryStories: SecondaryStorySurface[];
|
|
314
562
|
}
|
|
315
563
|
|
|
316
564
|
export type EditorWarningCode =
|
|
@@ -354,7 +602,7 @@ export interface EditorError {
|
|
|
354
602
|
code: EditorErrorCode;
|
|
355
603
|
message: string;
|
|
356
604
|
isFatal: boolean;
|
|
357
|
-
source: "import" | "runtime" | "validation" | "datastore" | "export";
|
|
605
|
+
source: "import" | "runtime" | "validation" | "datastore" | "host" | "export";
|
|
358
606
|
details?: Record<string, unknown>;
|
|
359
607
|
}
|
|
360
608
|
|
|
@@ -389,6 +637,52 @@ export interface CompatibilityPanelSnapshot {
|
|
|
389
637
|
featureEntries: CompatibilityFeatureEntry[];
|
|
390
638
|
}
|
|
391
639
|
|
|
640
|
+
export type ViewMode = "editing" | "review" | "view";
|
|
641
|
+
|
|
642
|
+
export type CaretAffinity = "forward" | "backward" | "none";
|
|
643
|
+
|
|
644
|
+
export interface ActiveListContext {
|
|
645
|
+
numberingInstanceId: string;
|
|
646
|
+
level: number;
|
|
647
|
+
isOrdered: boolean;
|
|
648
|
+
markerText?: string;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
export interface ActiveNoteContext {
|
|
652
|
+
noteKind: "footnote" | "endnote";
|
|
653
|
+
noteId: string;
|
|
654
|
+
referencePosition: number;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
export interface PageRegionHitTest {
|
|
658
|
+
region: "body" | "header" | "footer" | "margin" | "gutter";
|
|
659
|
+
sectionIndex: number;
|
|
660
|
+
columnIndex: number;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
export interface LayoutMeasurement {
|
|
664
|
+
pageRegions: PageRegionHitTest[];
|
|
665
|
+
caretAffinity: CaretAffinity;
|
|
666
|
+
tabStops: Array<{ pos: number; val?: string; leader?: string }>;
|
|
667
|
+
listMarkerLane?: { indent: number; markerWidth: number };
|
|
668
|
+
objectFrame?: { kind: "image" | "textbox" | "shape"; anchorPos: number; display: "inline" | "floating" };
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
export interface EditorViewStateSnapshot {
|
|
672
|
+
viewMode: ViewMode;
|
|
673
|
+
workspaceMode: WorkspaceMode;
|
|
674
|
+
zoomLevel: ZoomLevel;
|
|
675
|
+
activeStory: EditorStoryTarget;
|
|
676
|
+
selection: SelectionSnapshot;
|
|
677
|
+
caretAffinity: CaretAffinity;
|
|
678
|
+
activeListContext: ActiveListContext | null;
|
|
679
|
+
activeNoteContext: ActiveNoteContext | null;
|
|
680
|
+
activePageRegion: PageRegionHitTest | null;
|
|
681
|
+
activeObjectFrame: LayoutMeasurement["objectFrame"] | null;
|
|
682
|
+
measurement: LayoutMeasurement;
|
|
683
|
+
isFocused: boolean;
|
|
684
|
+
}
|
|
685
|
+
|
|
392
686
|
export interface CommandStateSnapshot {
|
|
393
687
|
canUndo: boolean;
|
|
394
688
|
canRedo: boolean;
|
|
@@ -404,6 +698,8 @@ export interface RuntimeRenderSnapshot {
|
|
|
404
698
|
isDirty: boolean;
|
|
405
699
|
readOnly: boolean;
|
|
406
700
|
selection: SelectionSnapshot;
|
|
701
|
+
activeStory: EditorStoryTarget;
|
|
702
|
+
pageLayout?: PageLayoutSnapshot;
|
|
407
703
|
documentStats: DocumentStats;
|
|
408
704
|
comments: CommentSidebarSnapshot;
|
|
409
705
|
trackedChanges: TrackedChangesSnapshot;
|
|
@@ -414,6 +710,20 @@ export interface RuntimeRenderSnapshot {
|
|
|
414
710
|
surface?: EditorSurfaceSnapshot;
|
|
415
711
|
}
|
|
416
712
|
|
|
713
|
+
export interface EditorSessionState {
|
|
714
|
+
sessionVersion: "editor-session-state/1";
|
|
715
|
+
schemaVersion: RuntimePersistedEditorSnapshot["schemaVersion"];
|
|
716
|
+
documentId: string;
|
|
717
|
+
docId: string;
|
|
718
|
+
createdAt: string;
|
|
719
|
+
updatedAt: string;
|
|
720
|
+
editorBuild: string;
|
|
721
|
+
canonicalDocument: RuntimePersistedEditorSnapshot["canonicalDocument"];
|
|
722
|
+
compatibility: CompatibilityReport;
|
|
723
|
+
warningLog: EditorWarning[];
|
|
724
|
+
sourcePackage?: RuntimePersistedEditorSnapshot["sourcePackage"];
|
|
725
|
+
}
|
|
726
|
+
|
|
417
727
|
export interface PersistedEditorSnapshot {
|
|
418
728
|
snapshotVersion: RuntimePersistedEditorSnapshot["snapshotVersion"];
|
|
419
729
|
schemaVersion: RuntimePersistedEditorSnapshot["schemaVersion"];
|
|
@@ -440,10 +750,16 @@ export interface ExportDocxOptions {
|
|
|
440
750
|
reason?: string;
|
|
441
751
|
}
|
|
442
752
|
|
|
753
|
+
export interface ExportDelivery {
|
|
754
|
+
mode: "downloaded" | "persisted-by-host" | "exported-bytes-only";
|
|
755
|
+
savedAt?: string;
|
|
756
|
+
}
|
|
757
|
+
|
|
443
758
|
export interface ExportResult {
|
|
444
759
|
bytes: Uint8Array;
|
|
445
760
|
mimeType: string;
|
|
446
761
|
fileName: string;
|
|
762
|
+
delivery: ExportDelivery;
|
|
447
763
|
}
|
|
448
764
|
|
|
449
765
|
export type AutosaveState =
|
|
@@ -462,7 +778,7 @@ export type WordReviewEditorEvent =
|
|
|
462
778
|
type: "ready";
|
|
463
779
|
documentId: string;
|
|
464
780
|
sessionId: string;
|
|
465
|
-
source: "docx" | "
|
|
781
|
+
source: "docx" | "session" | "snapshot";
|
|
466
782
|
stats: DocumentStats;
|
|
467
783
|
compatibility: CompatibilityReport;
|
|
468
784
|
comments: CommentSidebarSnapshot;
|
|
@@ -499,6 +815,11 @@ export type WordReviewEditorEvent =
|
|
|
499
815
|
documentId: string;
|
|
500
816
|
changeId: string;
|
|
501
817
|
}
|
|
818
|
+
| {
|
|
819
|
+
type: "story_changed";
|
|
820
|
+
documentId: string;
|
|
821
|
+
activeStory: EditorStoryTarget;
|
|
822
|
+
}
|
|
502
823
|
| {
|
|
503
824
|
type: "warning_added";
|
|
504
825
|
documentId: string;
|
|
@@ -526,6 +847,13 @@ export type WordReviewEditorEvent =
|
|
|
526
847
|
snapshot: PersistedEditorSnapshot;
|
|
527
848
|
isAutosave: boolean;
|
|
528
849
|
}
|
|
850
|
+
| {
|
|
851
|
+
type: "session_saved";
|
|
852
|
+
documentId: string;
|
|
853
|
+
sessionState: EditorSessionState;
|
|
854
|
+
savedAt: string;
|
|
855
|
+
isAutosave: boolean;
|
|
856
|
+
}
|
|
529
857
|
| {
|
|
530
858
|
type: "export_completed";
|
|
531
859
|
documentId: string;
|
|
@@ -546,6 +874,16 @@ export interface SaveSnapshotResult {
|
|
|
546
874
|
savedAt: string;
|
|
547
875
|
}
|
|
548
876
|
|
|
877
|
+
export interface SaveSessionParams {
|
|
878
|
+
documentId: string;
|
|
879
|
+
sessionState: EditorSessionState;
|
|
880
|
+
isAutosave: boolean;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
export interface SaveSessionResult {
|
|
884
|
+
savedAt: string;
|
|
885
|
+
}
|
|
886
|
+
|
|
549
887
|
export interface SaveExportParams {
|
|
550
888
|
documentId: string;
|
|
551
889
|
result: ExportResult;
|
|
@@ -561,10 +899,17 @@ export interface EditorTelemetryEvent {
|
|
|
561
899
|
detail?: Record<string, unknown>;
|
|
562
900
|
}
|
|
563
901
|
|
|
902
|
+
export interface EditorHostAdapter {
|
|
903
|
+
load?(params: LoadRequest): Promise<LoadResult>;
|
|
904
|
+
saveSession?(params: SaveSessionParams): Promise<SaveSessionResult>;
|
|
905
|
+
saveExport?(params: SaveExportParams): Promise<SaveExportResult>;
|
|
906
|
+
logEvent?(event: EditorTelemetryEvent): void;
|
|
907
|
+
}
|
|
908
|
+
|
|
564
909
|
export interface EditorDatastoreAdapter {
|
|
565
|
-
load(params:
|
|
910
|
+
load(params: LoadRequest): Promise<LoadResult>;
|
|
566
911
|
saveSnapshot(params: SaveSnapshotParams): Promise<SaveSnapshotResult>;
|
|
567
|
-
saveExport(params: SaveExportParams): Promise<SaveExportResult>;
|
|
912
|
+
saveExport?(params: SaveExportParams): Promise<SaveExportResult>;
|
|
568
913
|
logEvent?(event: EditorTelemetryEvent): void;
|
|
569
914
|
}
|
|
570
915
|
|
|
@@ -585,6 +930,7 @@ export interface WordReviewEditorRef {
|
|
|
585
930
|
acceptAllChanges(): void;
|
|
586
931
|
rejectAllChanges(): void;
|
|
587
932
|
exportDocx(options?: ExportDocxOptions): Promise<ExportResult>;
|
|
933
|
+
getSessionState(): EditorSessionState;
|
|
588
934
|
getSnapshot(): PersistedEditorSnapshot;
|
|
589
935
|
getRenderSnapshot(): RuntimeRenderSnapshot;
|
|
590
936
|
getCompatibilityReport(): CompatibilityReport;
|
|
@@ -595,6 +941,7 @@ export interface WordReviewEditorRef {
|
|
|
595
941
|
getTrackedChanges(): TrackedChangesSnapshot;
|
|
596
942
|
isDirty(): boolean;
|
|
597
943
|
getFormattingState(): FormattingStateSnapshot;
|
|
944
|
+
getStyleCatalog(): StyleCatalogSnapshot;
|
|
598
945
|
replaceText(text: string, target?: EditorAnchorProjection): void;
|
|
599
946
|
toggleBold(): void;
|
|
600
947
|
toggleItalic(): void;
|
|
@@ -607,6 +954,8 @@ export interface WordReviewEditorRef {
|
|
|
607
954
|
setTextColor(color: string | null): void;
|
|
608
955
|
setHighlightColor(color: string | null): void;
|
|
609
956
|
setAlignment(alignment: FormattingAlignment): void;
|
|
957
|
+
setParagraphStyle(styleId: string | null): void;
|
|
958
|
+
setTableStyle(styleId: string | null): void;
|
|
610
959
|
indent(): void;
|
|
611
960
|
outdent(): void;
|
|
612
961
|
insertPageBreak(): void;
|
|
@@ -627,20 +976,41 @@ export interface WordReviewEditorRef {
|
|
|
627
976
|
setSelection(selection: SelectionSnapshot | null): void;
|
|
628
977
|
scrollToRevision(revisionId: string): void;
|
|
629
978
|
scrollToComment(commentId: string): void;
|
|
979
|
+
openStory(target: EditorStoryTarget): void;
|
|
980
|
+
closeStory(): void;
|
|
981
|
+
getPageLayoutSnapshot(): PageLayoutSnapshot | null;
|
|
982
|
+
getDocumentNavigationSnapshot(): DocumentNavigationSnapshot;
|
|
983
|
+
getViewState(): EditorViewStateSnapshot;
|
|
984
|
+
setWorkspaceMode(mode: WorkspaceMode): void;
|
|
985
|
+
setZoom(level: ZoomLevel): void;
|
|
986
|
+
insertSectionBreak(type: SectionBreakType, options?: { afterSectionIndex?: number }): void;
|
|
987
|
+
deleteSectionBreak(sectionIndex: number): void;
|
|
988
|
+
updateSectionLayout(sectionIndex: number, patch: SectionLayoutPatch): void;
|
|
989
|
+
setSectionPageNumbering(
|
|
990
|
+
sectionIndex: number,
|
|
991
|
+
patch: SectionPageNumberingPatch | null,
|
|
992
|
+
): void;
|
|
993
|
+
setHeaderFooterLink(sectionIndex: number, params: HeaderFooterLinkPatch): void;
|
|
994
|
+
setImageLayout(mediaId: string, dimensions: { widthEmu: number; heightEmu: number }): void;
|
|
995
|
+
setImageFrame(mediaId: string, offsets: { horizontalOffsetEmu?: number; verticalOffsetEmu?: number }): void;
|
|
630
996
|
}
|
|
631
997
|
|
|
632
998
|
export interface WordReviewEditorProps {
|
|
633
999
|
documentId: string;
|
|
634
1000
|
currentUser: EditorUser;
|
|
635
1001
|
initialDocx?: Uint8Array | ArrayBuffer;
|
|
1002
|
+
initialSessionState?: EditorSessionState;
|
|
636
1003
|
initialSnapshot?: PersistedEditorSnapshot;
|
|
637
1004
|
initialSourceLabel?: string;
|
|
638
1005
|
externalDocumentRevision?: string;
|
|
639
1006
|
externalDocSource?: ExternalDocumentSource;
|
|
1007
|
+
loadRevision?: string;
|
|
1008
|
+
loadSourcePolicy?: LoadSourcePolicy;
|
|
640
1009
|
readOnly?: boolean;
|
|
641
1010
|
reviewMode?: "editing" | "review";
|
|
642
1011
|
markupDisplay?: "clean" | "simple" | "all";
|
|
643
1012
|
showReviewPanel?: boolean;
|
|
1013
|
+
hostAdapter?: EditorHostAdapter;
|
|
644
1014
|
datastore?: EditorDatastoreAdapter;
|
|
645
1015
|
autosave?: AutosaveConfig;
|
|
646
1016
|
onEvent?: (event: WordReviewEditorEvent) => void;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
EditorSessionState,
|
|
3
|
+
PersistedEditorSnapshot,
|
|
4
|
+
} from "./public-types.ts";
|
|
5
|
+
|
|
6
|
+
export const EDITOR_SESSION_STATE_VERSION = "editor-session-state/1" as const;
|
|
7
|
+
|
|
8
|
+
function cloneStructuredValue<T>(value: T): T {
|
|
9
|
+
return structuredClone(value);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createEditorSessionState(
|
|
13
|
+
input: Omit<EditorSessionState, "sessionVersion">,
|
|
14
|
+
): EditorSessionState {
|
|
15
|
+
return cloneStructuredValue({
|
|
16
|
+
sessionVersion: EDITOR_SESSION_STATE_VERSION,
|
|
17
|
+
...input,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function editorSessionStateFromPersistedSnapshot(
|
|
22
|
+
snapshot: PersistedEditorSnapshot,
|
|
23
|
+
): EditorSessionState {
|
|
24
|
+
return createEditorSessionState({
|
|
25
|
+
schemaVersion: snapshot.schemaVersion,
|
|
26
|
+
documentId: snapshot.documentId,
|
|
27
|
+
docId: snapshot.docId,
|
|
28
|
+
createdAt: snapshot.createdAt,
|
|
29
|
+
updatedAt: snapshot.updatedAt,
|
|
30
|
+
editorBuild: snapshot.editorBuild,
|
|
31
|
+
canonicalDocument: snapshot.canonicalDocument,
|
|
32
|
+
compatibility: snapshot.compatibility,
|
|
33
|
+
warningLog: snapshot.warningLog,
|
|
34
|
+
sourcePackage: snapshot.sourcePackage,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function persistedSnapshotFromEditorSessionState(
|
|
39
|
+
sessionState: EditorSessionState,
|
|
40
|
+
options: {
|
|
41
|
+
savedAt: string;
|
|
42
|
+
},
|
|
43
|
+
): PersistedEditorSnapshot {
|
|
44
|
+
return cloneStructuredValue({
|
|
45
|
+
snapshotVersion: "persisted-editor-snapshot/2",
|
|
46
|
+
schemaVersion: sessionState.schemaVersion,
|
|
47
|
+
documentId: sessionState.documentId,
|
|
48
|
+
docId: sessionState.docId,
|
|
49
|
+
createdAt: sessionState.createdAt,
|
|
50
|
+
updatedAt: sessionState.updatedAt,
|
|
51
|
+
savedAt: options.savedAt,
|
|
52
|
+
editorBuild: sessionState.editorBuild,
|
|
53
|
+
canonicalDocument: sessionState.canonicalDocument,
|
|
54
|
+
compatibility: sessionState.compatibility,
|
|
55
|
+
warningLog: sessionState.warningLog,
|
|
56
|
+
sourcePackage: sessionState.sourcePackage,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -271,6 +271,7 @@ export function getFormattingStateFromRenderSnapshot(
|
|
|
271
271
|
alignment: getConsistentValue(paragraphs, (paragraph) =>
|
|
272
272
|
toPublicAlignment(paragraph.alignment),
|
|
273
273
|
),
|
|
274
|
+
paragraphStyleId: getConsistentValue(paragraphs, (paragraph) => paragraph.styleId),
|
|
274
275
|
breadcrumb: getSelectionBreadcrumb(surface.blocks, snapshot.selection),
|
|
275
276
|
};
|
|
276
277
|
}
|