@beyondwork/docx-react-component 1.0.102 → 1.0.104
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/package.json +1 -1
- package/src/api/public-types.ts +63 -1
- package/src/api/v3/_runtime-handle.ts +2 -0
- package/src/api/v3/ai/outline.ts +2 -7
- package/src/api/v3/runtime/geometry.ts +79 -0
- package/src/core/commands/formatting-commands.ts +8 -7
- package/src/core/commands/paragraph-layout-commands.ts +11 -10
- package/src/core/commands/section-layout-commands.ts +7 -6
- package/src/core/commands/style-commands.ts +3 -2
- package/src/io/normalize/normalize-text.ts +6 -5
- package/src/io/ooxml/parse-anchor.ts +15 -15
- package/src/io/ooxml/parse-drawing.ts +103 -5
- package/src/io/ooxml/parse-fields.ts +43 -21
- package/src/io/ooxml/parse-font-table.ts +2 -1
- package/src/io/ooxml/parse-footnotes.ts +3 -2
- package/src/io/ooxml/parse-headers-footers.ts +7 -6
- package/src/io/ooxml/parse-main-document.ts +41 -40
- package/src/io/ooxml/parse-numbering.ts +3 -2
- package/src/io/ooxml/parse-object.ts +6 -6
- package/src/io/ooxml/parse-paragraph-formatting.ts +12 -11
- package/src/io/ooxml/parse-picture.ts +16 -16
- package/src/io/ooxml/parse-run-formatting.ts +11 -10
- package/src/io/ooxml/parse-settings.ts +2 -1
- package/src/io/ooxml/parse-shapes.ts +148 -17
- package/src/io/ooxml/parse-styles.ts +16 -16
- package/src/io/ooxml/parse-theme.ts +5 -4
- package/src/model/canonical-document.ts +869 -836
- package/src/model/canonical-layout-inputs.ts +979 -0
- package/src/model/layout/index.ts +6 -0
- package/src/model/layout/page-graph-types.ts +61 -0
- package/src/model/layout/runtime-page-graph-types.ts +10 -0
- package/src/runtime/collab/runtime-collab-sync.ts +3 -3
- package/src/runtime/debug/build-debug-inspector-snapshot.ts +17 -4
- package/src/runtime/document-runtime.ts +30 -14
- package/src/runtime/event-refresh-hints.ts +3 -0
- package/src/runtime/formatting/document-lookup.ts +3 -2
- package/src/runtime/formatting/formatting-context.ts +176 -34
- package/src/runtime/formatting/index.ts +20 -0
- package/src/runtime/formatting/layout-inputs.ts +320 -0
- package/src/runtime/formatting/numbering/geometry.ts +13 -12
- package/src/runtime/formatting/style-cascade.ts +2 -1
- package/src/runtime/formatting/table-style-resolver.ts +8 -7
- package/src/runtime/geometry/caret-geometry.ts +82 -10
- package/src/runtime/geometry/geometry-facet.ts +36 -0
- package/src/runtime/geometry/geometry-index.ts +891 -0
- package/src/runtime/geometry/geometry-types.ts +221 -1
- package/src/runtime/geometry/index.ts +26 -0
- package/src/runtime/geometry/inert-geometry-facet.ts +3 -0
- package/src/runtime/geometry/replacement-envelope.ts +41 -2
- package/src/runtime/layout/layout-engine-version.ts +16 -1
- package/src/runtime/layout/page-graph.ts +191 -1
- package/src/runtime/prerender/graph-canonicalize.ts +30 -0
- package/src/runtime/surface-projection.ts +74 -39
- package/src/runtime/workflow/coordinator.ts +57 -11
- package/src/session/import/normalize.ts +2 -1
- package/src/session/import/source-package-evidence.ts +612 -1
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +3 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beyondwork/docx-react-component",
|
|
3
3
|
"publisher": "beyondwork",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.104",
|
|
5
5
|
"description": "Embeddable React Word (docx) editor with review, comments, tracked changes, and round-trip OOXML fidelity.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": [
|
package/src/api/public-types.ts
CHANGED
|
@@ -1223,6 +1223,23 @@ export interface SurfacePictureEffects {
|
|
|
1223
1223
|
glow?: { radius: number; color: string; colorType: "srgbClr" | "schemeClr" };
|
|
1224
1224
|
}
|
|
1225
1225
|
|
|
1226
|
+
export interface SurfacePreserveOnlyObjectSizing {
|
|
1227
|
+
sourceId?: string;
|
|
1228
|
+
display: "inline" | "floating" | "unknown";
|
|
1229
|
+
extentEmu?: { widthEmu: number; heightEmu: number };
|
|
1230
|
+
fallbackHint:
|
|
1231
|
+
| "drawing-inline"
|
|
1232
|
+
| "drawing-floating"
|
|
1233
|
+
| "chart"
|
|
1234
|
+
| "smartart"
|
|
1235
|
+
| "shape"
|
|
1236
|
+
| "wordart"
|
|
1237
|
+
| "vml-shape"
|
|
1238
|
+
| "ole-object"
|
|
1239
|
+
| "opaque-object";
|
|
1240
|
+
relationshipIds?: string[];
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1226
1243
|
export type SurfaceInlineSegment =
|
|
1227
1244
|
| {
|
|
1228
1245
|
segmentId: string;
|
|
@@ -1338,6 +1355,20 @@ export type SurfaceInlineSegment =
|
|
|
1338
1355
|
* can render `ChartSurface` instead of the fallback bitmap or badge.
|
|
1339
1356
|
*/
|
|
1340
1357
|
parsedChartId?: string;
|
|
1358
|
+
/**
|
|
1359
|
+
* PE2 preserve-only object handoff. Present for unsupported drawing,
|
|
1360
|
+
* chart, SmartArt, WordArt, VML, and opaque-object previews when import
|
|
1361
|
+
* could recover source ids, relationship ids, fallback hints, or
|
|
1362
|
+
* extents. Layout consumers may size placeholders from this metadata;
|
|
1363
|
+
* it is not a layout computation.
|
|
1364
|
+
*/
|
|
1365
|
+
preserveOnlyObject?: SurfacePreserveOnlyObjectSizing;
|
|
1366
|
+
/**
|
|
1367
|
+
* Drawing anchor geometry for preserve-only objects that originated in a
|
|
1368
|
+
* `drawing_frame`. Mirrors image/shape anchor semantics so L04 can join
|
|
1369
|
+
* the object to source/canonical/layout rows without re-parsing OOXML.
|
|
1370
|
+
*/
|
|
1371
|
+
anchor?: SurfaceDrawingAnchor;
|
|
1341
1372
|
state: "locked-preserve-only";
|
|
1342
1373
|
}
|
|
1343
1374
|
| {
|
|
@@ -1403,6 +1434,7 @@ export type SurfaceInlineSegment =
|
|
|
1403
1434
|
isTextBox?: boolean;
|
|
1404
1435
|
/** Text box body layout from `wps:bodyPr` / `a:bodyPr`. */
|
|
1405
1436
|
textBoxBody?: SurfaceTextBoxBodyProperties;
|
|
1437
|
+
preserveOnlyObject?: SurfacePreserveOnlyObjectSizing;
|
|
1406
1438
|
/** First-paragraph plain-text preview when `isTextBox` is true. */
|
|
1407
1439
|
txbxText?: string;
|
|
1408
1440
|
/** Run-level marks from the first text-box text run, when available. */
|
|
@@ -3609,6 +3641,11 @@ export interface WordReviewEditorPasteEvent {
|
|
|
3609
3641
|
source: "paste" | "drop";
|
|
3610
3642
|
}
|
|
3611
3643
|
|
|
3644
|
+
export interface WorkflowEventOrigin {
|
|
3645
|
+
readonly source: "api" | "runtime" | "collab" | string;
|
|
3646
|
+
readonly at?: string;
|
|
3647
|
+
}
|
|
3648
|
+
|
|
3612
3649
|
export type WordReviewEditorEvent =
|
|
3613
3650
|
| {
|
|
3614
3651
|
type: "ready";
|
|
@@ -3724,16 +3761,38 @@ export type WordReviewEditorEvent =
|
|
|
3724
3761
|
type: "workflow_overlay_changed";
|
|
3725
3762
|
documentId: string;
|
|
3726
3763
|
snapshot: WorkflowScopeSnapshot;
|
|
3764
|
+
origin?: WorkflowEventOrigin;
|
|
3727
3765
|
}
|
|
3728
3766
|
| {
|
|
3729
3767
|
type: "workflow_active_work_item_changed";
|
|
3730
3768
|
documentId: string;
|
|
3731
3769
|
activeWorkItemId: string | null;
|
|
3770
|
+
origin?: WorkflowEventOrigin;
|
|
3732
3771
|
}
|
|
3733
3772
|
| {
|
|
3734
3773
|
type: "workflow_metadata_changed";
|
|
3735
3774
|
documentId: string;
|
|
3736
3775
|
snapshot: WorkflowMetadataSnapshot;
|
|
3776
|
+
origin?: WorkflowEventOrigin;
|
|
3777
|
+
}
|
|
3778
|
+
| {
|
|
3779
|
+
type: "workflow_shared_state_changed";
|
|
3780
|
+
documentId: string;
|
|
3781
|
+
state: SharedWorkflowState | null;
|
|
3782
|
+
origin: WorkflowEventOrigin;
|
|
3783
|
+
}
|
|
3784
|
+
| {
|
|
3785
|
+
type: "workflow_visibility_policy_changed";
|
|
3786
|
+
documentId: string;
|
|
3787
|
+
kind?: OverlayKind;
|
|
3788
|
+
policy?: OverlayVisibilityPolicy | null;
|
|
3789
|
+
origin: WorkflowEventOrigin;
|
|
3790
|
+
}
|
|
3791
|
+
| {
|
|
3792
|
+
type: "workflow_markup_mode_policy_changed";
|
|
3793
|
+
documentId: string;
|
|
3794
|
+
policy: WorkflowMarkupModePolicy | null;
|
|
3795
|
+
origin: WorkflowEventOrigin;
|
|
3737
3796
|
}
|
|
3738
3797
|
| {
|
|
3739
3798
|
type: "host_annotation_overlay_changed";
|
|
@@ -5010,7 +5069,10 @@ export interface WordReviewEditorRef {
|
|
|
5010
5069
|
* `replaceText` calls to block with `workflow_comment_only`.
|
|
5011
5070
|
*/
|
|
5012
5071
|
getWorkflowOverlay(): WorkflowOverlay | null;
|
|
5013
|
-
setSharedWorkflowState(
|
|
5072
|
+
setSharedWorkflowState(
|
|
5073
|
+
state: SharedWorkflowState | null,
|
|
5074
|
+
origin?: WorkflowEventOrigin,
|
|
5075
|
+
): void;
|
|
5014
5076
|
getWorkflowScopeSnapshot(): WorkflowScopeSnapshot | null;
|
|
5015
5077
|
getInteractionGuardSnapshot(): InteractionGuardSnapshot;
|
|
5016
5078
|
getWorkflowMarkupSnapshot(): WorkflowMarkupSnapshot;
|
|
@@ -48,6 +48,7 @@ export type RuntimeApiHandle = Pick<
|
|
|
48
48
|
| "getCompatibilityReport"
|
|
49
49
|
| "getWarnings"
|
|
50
50
|
| "getRenderSnapshot"
|
|
51
|
+
| "getDocumentNavigationSnapshot"
|
|
51
52
|
// Canonical document read (ai.inspect + ai.bundle + ai.resolve families,
|
|
52
53
|
// added in refactor/08 Slice 2/3 graduations)
|
|
53
54
|
| "getCanonicalDocument"
|
|
@@ -155,6 +156,7 @@ export const RUNTIME_API_HANDLE_SHAPE_CHECK: Record<keyof RuntimeApiHandle, true
|
|
|
155
156
|
getCompatibilityReport: true,
|
|
156
157
|
getWarnings: true,
|
|
157
158
|
getRenderSnapshot: true,
|
|
159
|
+
getDocumentNavigationSnapshot: true,
|
|
158
160
|
getCanonicalDocument: true,
|
|
159
161
|
findAllText: true,
|
|
160
162
|
replaceText: true,
|
package/src/api/v3/ai/outline.ts
CHANGED
|
@@ -19,7 +19,6 @@ import type {
|
|
|
19
19
|
DocumentOutlineHeadingSnapshot,
|
|
20
20
|
DocumentOutlineSnapshot,
|
|
21
21
|
} from "../../public-types.ts";
|
|
22
|
-
import { createDocumentNavigationSnapshot } from "../../../runtime/document-navigation.ts";
|
|
23
22
|
import { createDocumentOutlineSnapshot } from "../../../runtime/document-outline.ts";
|
|
24
23
|
import {
|
|
25
24
|
computeBlockPositions,
|
|
@@ -68,7 +67,7 @@ export const getDocumentOutlineMetadata: ApiV3FnMetadata = {
|
|
|
68
67
|
stateClass: "A-canonical",
|
|
69
68
|
persistsTo: "canonical",
|
|
70
69
|
rwdReference:
|
|
71
|
-
"§AI API § ai.getDocumentOutline. Composes
|
|
70
|
+
"§AI API § ai.getDocumentOutline. Composes runtime.getDocumentNavigationSnapshot() (L04 graph-derived navigation) with createDocumentOutlineSnapshot (L07) to surface the heading tree. Read-only; no audit emission.",
|
|
72
71
|
};
|
|
73
72
|
|
|
74
73
|
export function createOutlineFamily(runtime: RuntimeApiHandle) {
|
|
@@ -82,11 +81,7 @@ export function createOutlineFamily(runtime: RuntimeApiHandle) {
|
|
|
82
81
|
const snapshot = runtime.getRenderSnapshot();
|
|
83
82
|
const document = runtime.getCanonicalDocument();
|
|
84
83
|
const selectionHead = snapshot.selection.head;
|
|
85
|
-
const navigation =
|
|
86
|
-
document,
|
|
87
|
-
selectionHead,
|
|
88
|
-
snapshot.activeStory,
|
|
89
|
-
);
|
|
84
|
+
const navigation = runtime.getDocumentNavigationSnapshot();
|
|
90
85
|
const outline = createDocumentOutlineSnapshot({
|
|
91
86
|
navigation,
|
|
92
87
|
activeStory: snapshot.activeStory,
|
|
@@ -15,6 +15,26 @@ import type { RuntimeApiHandle } from "../_runtime-handle.ts";
|
|
|
15
15
|
import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
|
|
16
16
|
import { mockPayload } from "../_mocks.ts";
|
|
17
17
|
import type { MockPayload } from "../_layer-metadata.ts";
|
|
18
|
+
import type {
|
|
19
|
+
GeometryIndex,
|
|
20
|
+
GeometryIndexCoverage,
|
|
21
|
+
} from "../../../runtime/geometry/index.ts";
|
|
22
|
+
|
|
23
|
+
function createUnavailableGeometryCoverage(): GeometryIndexCoverage {
|
|
24
|
+
return {
|
|
25
|
+
status: "unavailable",
|
|
26
|
+
pageCount: 0,
|
|
27
|
+
regionCount: 0,
|
|
28
|
+
sliceCount: 0,
|
|
29
|
+
lineCount: 0,
|
|
30
|
+
anchorCount: 0,
|
|
31
|
+
hitTargetCount: 0,
|
|
32
|
+
semanticEntryCount: 0,
|
|
33
|
+
replacementEnvelopeCount: 0,
|
|
34
|
+
objectHandleCount: 0,
|
|
35
|
+
precision: { exact: 0, "within-tolerance": 0, heuristic: 0 },
|
|
36
|
+
};
|
|
37
|
+
}
|
|
18
38
|
|
|
19
39
|
export interface BlockRectEntry {
|
|
20
40
|
readonly blockId: string;
|
|
@@ -57,6 +77,50 @@ export interface HitTestResult {
|
|
|
57
77
|
readonly __mock?: true;
|
|
58
78
|
}
|
|
59
79
|
|
|
80
|
+
/* ================================================================== */
|
|
81
|
+
/* PE2 geometry index + coverage */
|
|
82
|
+
/* ================================================================== */
|
|
83
|
+
|
|
84
|
+
export const getGeometryIndexMetadata: ApiV3FnMetadata = {
|
|
85
|
+
name: "runtime.geometry.getGeometryIndex",
|
|
86
|
+
status: "live-with-adapter",
|
|
87
|
+
sourceLayer: "geometry-projection",
|
|
88
|
+
liveEvidence: {
|
|
89
|
+
runnerTest: "test/api/v3/geometry-uses-geometry-handle.test.ts",
|
|
90
|
+
commit: "refactor-07-pe2-geometry-index-read-surface",
|
|
91
|
+
},
|
|
92
|
+
uxIntent: { uiVisible: false, expectsUxResponse: "none" },
|
|
93
|
+
agentMetadata: {
|
|
94
|
+
readOrMutate: "read",
|
|
95
|
+
boundedScope: "document",
|
|
96
|
+
auditCategory: "geometry-read",
|
|
97
|
+
},
|
|
98
|
+
stateClass: "A-canonical",
|
|
99
|
+
persistsTo: "canonical",
|
|
100
|
+
rwdReference:
|
|
101
|
+
"§Runtime API § runtime.geometry.getGeometryIndex. PE2 read surface over GeometryFacet.getGeometryIndex(): renderer-neutral pages, regions, slices, lines, anchors, hit targets, semantic entries, replacement envelopes, object handles, and coverage. Returns null when no geometry facet or render frame is warm. Promotes to live when L05 projects directly from L04 page slices instead of the render-frame adapter.",
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const getGeometryCoverageMetadata: ApiV3FnMetadata = {
|
|
105
|
+
name: "runtime.geometry.getGeometryCoverage",
|
|
106
|
+
status: "live-with-adapter",
|
|
107
|
+
sourceLayer: "geometry-projection",
|
|
108
|
+
liveEvidence: {
|
|
109
|
+
runnerTest: "test/api/v3/geometry-uses-geometry-handle.test.ts",
|
|
110
|
+
commit: "refactor-07-pe2-geometry-index-read-surface",
|
|
111
|
+
},
|
|
112
|
+
uxIntent: { uiVisible: false, expectsUxResponse: "none" },
|
|
113
|
+
agentMetadata: {
|
|
114
|
+
readOrMutate: "read",
|
|
115
|
+
boundedScope: "document",
|
|
116
|
+
auditCategory: "geometry-read",
|
|
117
|
+
},
|
|
118
|
+
stateClass: "A-canonical",
|
|
119
|
+
persistsTo: "canonical",
|
|
120
|
+
rwdReference:
|
|
121
|
+
"§Runtime API § runtime.geometry.getGeometryCoverage. PE2 lightweight status read over GeometryFacet.getGeometryCoverage(). Always returns a coverage object; unwired/pre-paint states report status:'unavailable' with zero counts so agents and evidence runners can distinguish no geometry from empty geometry.",
|
|
122
|
+
};
|
|
123
|
+
|
|
60
124
|
/* ================================================================== */
|
|
61
125
|
/* getCaret — Slice-4 caret geometry (Slice X3 of §4 of coord-05) */
|
|
62
126
|
/* ================================================================== */
|
|
@@ -224,6 +288,21 @@ export function createGeometryFamily(runtime: RuntimeApiHandle) {
|
|
|
224
288
|
const geometry = runtime.geometry;
|
|
225
289
|
|
|
226
290
|
return {
|
|
291
|
+
getGeometryIndex(): GeometryIndex | null {
|
|
292
|
+
// @endStateApi — live-with-adapter. Exposes the Layer-05 PE2
|
|
293
|
+
// geometry index through the v3 runtime seam. The current L05
|
|
294
|
+
// index is projected from the render frame; callers still get
|
|
295
|
+
// renderer-neutral value objects and no DOM/PM/runtime instances.
|
|
296
|
+
return geometry?.getGeometryIndex() ?? null;
|
|
297
|
+
},
|
|
298
|
+
|
|
299
|
+
getGeometryCoverage(): GeometryIndexCoverage {
|
|
300
|
+
// @endStateApi — live-with-adapter. Coverage is intentionally
|
|
301
|
+
// total: an unwired/pre-paint handle reports an unavailable zero
|
|
302
|
+
// summary instead of null so evidence code can branch on status.
|
|
303
|
+
return geometry?.getGeometryCoverage() ?? createUnavailableGeometryCoverage();
|
|
304
|
+
},
|
|
305
|
+
|
|
227
306
|
getBlockRects(blockIds: readonly string[]): ReadonlyArray<BlockRectEntry & Partial<MockPayload>> {
|
|
228
307
|
// @endStateApi — live-with-adapter. Routes directly through the
|
|
229
308
|
// Layer-05 GeometryFacet's `getBlockRects(blockId)`, which walks
|
|
@@ -37,6 +37,7 @@ import type {
|
|
|
37
37
|
ParagraphNode,
|
|
38
38
|
TextMark,
|
|
39
39
|
TextNode,
|
|
40
|
+
Mutable,
|
|
40
41
|
} from "../../model/canonical-document.ts";
|
|
41
42
|
|
|
42
43
|
// ---------------------------------------------------------------------------
|
|
@@ -659,7 +660,7 @@ export function applyTextMarkOperationToDocumentRange(
|
|
|
659
660
|
updateMarks,
|
|
660
661
|
);
|
|
661
662
|
if (transformed.changed) {
|
|
662
|
-
block.children = transformed.nodes;
|
|
663
|
+
(block as Mutable<typeof block>).children = transformed.nodes;
|
|
663
664
|
changed = true;
|
|
664
665
|
}
|
|
665
666
|
}
|
|
@@ -862,7 +863,7 @@ function resolveMarkUpdater(
|
|
|
862
863
|
}
|
|
863
864
|
|
|
864
865
|
function applyAlignment(
|
|
865
|
-
paragraph: ParagraphNode
|
|
866
|
+
paragraph: Mutable<ParagraphNode>,
|
|
866
867
|
alignment: FormattingAlignment,
|
|
867
868
|
): boolean {
|
|
868
869
|
const nextAlignment = alignment === "justify" ? "both" : alignment;
|
|
@@ -880,7 +881,7 @@ function applyAlignment(
|
|
|
880
881
|
* must clone first if the source is shared. Returns `false` when no change
|
|
881
882
|
* occurred (already at the 0 / 8 bound, or no-op).
|
|
882
883
|
*/
|
|
883
|
-
export function applyIndentation(paragraph: ParagraphNode
|
|
884
|
+
export function applyIndentation(paragraph: Mutable<ParagraphNode>, delta: -1 | 1): boolean {
|
|
884
885
|
if (paragraph.numbering) {
|
|
885
886
|
const nextLevel = clamp(paragraph.numbering.level + delta, 0, 8);
|
|
886
887
|
if (nextLevel === paragraph.numbering.level) {
|
|
@@ -904,10 +905,10 @@ export function applyIndentation(paragraph: ParagraphNode, delta: -1 | 1): boole
|
|
|
904
905
|
...(paragraph.indentation ?? {}),
|
|
905
906
|
};
|
|
906
907
|
if (nextLeft > 0) {
|
|
907
|
-
nextIndentation.left = nextLeft;
|
|
908
|
+
(nextIndentation as Mutable<typeof nextIndentation>).left = nextLeft;
|
|
908
909
|
paragraph.indentation = nextIndentation;
|
|
909
910
|
} else if (paragraph.indentation) {
|
|
910
|
-
delete nextIndentation.left;
|
|
911
|
+
delete (nextIndentation as Mutable<typeof nextIndentation>).left;
|
|
911
912
|
paragraph.indentation =
|
|
912
913
|
Object.keys(nextIndentation).length > 0 ? nextIndentation : undefined;
|
|
913
914
|
}
|
|
@@ -1042,7 +1043,7 @@ function getConsistentValue<TItem, TValue>(
|
|
|
1042
1043
|
function visitParagraphBindings(
|
|
1043
1044
|
blocks: BlockNode[],
|
|
1044
1045
|
surfaceBlocks: SurfaceBlockSnapshot[],
|
|
1045
|
-
visitor: (paragraph: ParagraphNode
|
|
1046
|
+
visitor: (paragraph: Mutable<ParagraphNode>, surface: ParagraphSurfaceBlock) => void,
|
|
1046
1047
|
): void {
|
|
1047
1048
|
for (let index = 0; index < Math.min(blocks.length, surfaceBlocks.length); index += 1) {
|
|
1048
1049
|
const block = blocks[index];
|
|
@@ -1146,7 +1147,7 @@ function transformInlineNodes(
|
|
|
1146
1147
|
}
|
|
1147
1148
|
|
|
1148
1149
|
function transformTextNode(
|
|
1149
|
-
node: TextNode
|
|
1150
|
+
node: Mutable<TextNode>,
|
|
1150
1151
|
start: number,
|
|
1151
1152
|
selectionFrom: number,
|
|
1152
1153
|
selectionTo: number,
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
TableCellNode,
|
|
12
12
|
TableNode,
|
|
13
13
|
TableRowNode,
|
|
14
|
+
Mutable,
|
|
14
15
|
} from "../../model/canonical-document.ts";
|
|
15
16
|
|
|
16
17
|
export interface ParagraphLayoutCommandContext {
|
|
@@ -26,7 +27,7 @@ export interface ParagraphLayoutMutationResult {
|
|
|
26
27
|
export function setActiveParagraphIndentation(
|
|
27
28
|
document: CanonicalDocumentEnvelope,
|
|
28
29
|
snapshot: RuntimeRenderSnapshot,
|
|
29
|
-
indentation: ParagraphIndentation
|
|
30
|
+
indentation: Mutable<ParagraphIndentation>,
|
|
30
31
|
_context: ParagraphLayoutCommandContext,
|
|
31
32
|
): ParagraphLayoutMutationResult {
|
|
32
33
|
return mutateActiveParagraph(document, snapshot, (paragraph) => {
|
|
@@ -66,7 +67,7 @@ export function setActiveParagraphTabStops(
|
|
|
66
67
|
function mutateActiveParagraph(
|
|
67
68
|
document: CanonicalDocumentEnvelope,
|
|
68
69
|
snapshot: RuntimeRenderSnapshot,
|
|
69
|
-
mutate: (paragraph: ParagraphNode) => boolean,
|
|
70
|
+
mutate: (paragraph: Mutable<ParagraphNode>) => boolean,
|
|
70
71
|
): ParagraphLayoutMutationResult {
|
|
71
72
|
const surface = snapshot.surface;
|
|
72
73
|
if (!surface) {
|
|
@@ -190,27 +191,27 @@ function collectCanonicalParagraphs(
|
|
|
190
191
|
return output;
|
|
191
192
|
}
|
|
192
193
|
|
|
193
|
-
function collectParagraphsFromTable(table: TableNode
|
|
194
|
+
function collectParagraphsFromTable(table: Mutable<TableNode>, output: ParagraphNode[]): void {
|
|
194
195
|
for (const row of table.rows) {
|
|
195
196
|
collectParagraphsFromRow(row, output);
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
199
|
|
|
199
|
-
function collectParagraphsFromRow(row: TableRowNode
|
|
200
|
+
function collectParagraphsFromRow(row: Mutable<TableRowNode>, output: ParagraphNode[]): void {
|
|
200
201
|
for (const cell of row.cells) {
|
|
201
202
|
collectParagraphsFromCell(cell, output);
|
|
202
203
|
}
|
|
203
204
|
}
|
|
204
205
|
|
|
205
|
-
function collectParagraphsFromCell(cell: TableCellNode
|
|
206
|
+
function collectParagraphsFromCell(cell: Mutable<TableCellNode>, output: ParagraphNode[]): void {
|
|
206
207
|
collectCanonicalParagraphs(cell.children, output);
|
|
207
208
|
}
|
|
208
209
|
|
|
209
210
|
function mergeIndentationPatch(
|
|
210
211
|
current: ParagraphIndentation | undefined,
|
|
211
|
-
patch: ParagraphIndentation
|
|
212
|
+
patch: Mutable<ParagraphIndentation>,
|
|
212
213
|
): ParagraphIndentation | undefined {
|
|
213
|
-
const merged: ParagraphIndentation = {
|
|
214
|
+
const merged: Mutable<ParagraphIndentation> = {
|
|
214
215
|
...(current ?? {}),
|
|
215
216
|
};
|
|
216
217
|
|
|
@@ -237,9 +238,9 @@ function mergeIndentationPatch(
|
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
function normalizeIndentation(
|
|
240
|
-
indentation: ParagraphIndentation
|
|
241
|
+
indentation: Mutable<ParagraphIndentation>,
|
|
241
242
|
): ParagraphIndentation | undefined {
|
|
242
|
-
const normalized: ParagraphIndentation = {};
|
|
243
|
+
const normalized: Mutable<ParagraphIndentation> = {};
|
|
243
244
|
if (indentation.left !== undefined && indentation.left > 0) {
|
|
244
245
|
normalized.left = Math.round(indentation.left);
|
|
245
246
|
}
|
|
@@ -250,7 +251,7 @@ function normalizeIndentation(
|
|
|
250
251
|
normalized.firstLine = Math.round(indentation.firstLine);
|
|
251
252
|
}
|
|
252
253
|
if (indentation.hanging !== undefined && indentation.hanging > 0) {
|
|
253
|
-
normalized.hanging = Math.round(indentation.hanging);
|
|
254
|
+
(normalized as Mutable<typeof normalized>).hanging = Math.round(indentation.hanging);
|
|
254
255
|
delete normalized.firstLine;
|
|
255
256
|
}
|
|
256
257
|
return Object.keys(normalized).length > 0 ? normalized : undefined;
|
|
@@ -21,6 +21,7 @@ import type {
|
|
|
21
21
|
PageSize,
|
|
22
22
|
SectionBreakNode,
|
|
23
23
|
SectionProperties,
|
|
24
|
+
Mutable,
|
|
24
25
|
} from "../../model/canonical-document.ts";
|
|
25
26
|
import type {
|
|
26
27
|
MarginPresetDefinition,
|
|
@@ -145,7 +146,7 @@ export function insertSectionBreak(
|
|
|
145
146
|
|
|
146
147
|
const sectionTarget = resolveSectionTarget(cloned, surface.blocks, position);
|
|
147
148
|
const inheritedProperties = cloneSectionProperties(sectionTarget?.properties);
|
|
148
|
-
const sectionBreak: SectionBreakNode = {
|
|
149
|
+
const sectionBreak: Mutable<SectionBreakNode> = {
|
|
149
150
|
type: "section_break",
|
|
150
151
|
sectionProperties: {
|
|
151
152
|
...inheritedProperties,
|
|
@@ -178,7 +179,7 @@ export function insertSectionBreakAfterSectionIndex(
|
|
|
178
179
|
const inheritedProperties = cloneSectionProperties(
|
|
179
180
|
getSectionPropertiesAtIndex(cloned, sectionIndex),
|
|
180
181
|
);
|
|
181
|
-
const sectionBreak: SectionBreakNode = {
|
|
182
|
+
const sectionBreak: Mutable<SectionBreakNode> = {
|
|
182
183
|
type: "section_break",
|
|
183
184
|
sectionProperties: {
|
|
184
185
|
...inheritedProperties,
|
|
@@ -364,9 +365,9 @@ export function setSectionPageNumberingAtSectionIndex(
|
|
|
364
365
|
|
|
365
366
|
const nextProperties = cloneSectionProperties(target.properties);
|
|
366
367
|
if (pageNumbering === null) {
|
|
367
|
-
delete nextProperties.pageNumbering;
|
|
368
|
+
delete (nextProperties as Mutable<typeof nextProperties>).pageNumbering;
|
|
368
369
|
} else {
|
|
369
|
-
nextProperties.pageNumbering = {
|
|
370
|
+
(nextProperties as Mutable<typeof nextProperties>).pageNumbering = {
|
|
370
371
|
...(target.properties?.pageNumbering ?? {}),
|
|
371
372
|
...pageNumbering,
|
|
372
373
|
};
|
|
@@ -683,10 +684,10 @@ function findNearestSectionBreak(
|
|
|
683
684
|
}
|
|
684
685
|
|
|
685
686
|
function applySectionLayoutPatch(
|
|
686
|
-
existing: SectionProperties
|
|
687
|
+
existing: Mutable<SectionProperties>,
|
|
687
688
|
patch: SectionLayoutPatch,
|
|
688
689
|
): SectionProperties {
|
|
689
|
-
const result: SectionProperties = { ...existing };
|
|
690
|
+
const result: Mutable<SectionProperties> = { ...existing };
|
|
690
691
|
|
|
691
692
|
if (patch.pageSize) {
|
|
692
693
|
result.pageSize = {
|
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
DocumentRootNode,
|
|
9
9
|
ParagraphNode,
|
|
10
10
|
TableNode,
|
|
11
|
+
Mutable,
|
|
11
12
|
} from "../../model/canonical-document.ts";
|
|
12
13
|
|
|
13
14
|
type CanonicalDocumentEnvelope = PersistedEditorSnapshot["canonicalDocument"];
|
|
@@ -161,7 +162,7 @@ function isValidTableStyleId(
|
|
|
161
162
|
function visitParagraphBindings(
|
|
162
163
|
blocks: BlockNode[],
|
|
163
164
|
surfaceBlocks: SurfaceBlockSnapshot[],
|
|
164
|
-
visitor: (paragraph: ParagraphNode
|
|
165
|
+
visitor: (paragraph: Mutable<ParagraphNode>, surface: Extract<SurfaceBlockSnapshot, { kind: "paragraph" }>) => void,
|
|
165
166
|
): void {
|
|
166
167
|
for (let index = 0; index < Math.min(blocks.length, surfaceBlocks.length); index += 1) {
|
|
167
168
|
const block = blocks[index];
|
|
@@ -203,7 +204,7 @@ function visitParagraphBindings(
|
|
|
203
204
|
function visitTableBindings(
|
|
204
205
|
blocks: BlockNode[],
|
|
205
206
|
surfaceBlocks: SurfaceBlockSnapshot[],
|
|
206
|
-
visitor: (table: TableNode
|
|
207
|
+
visitor: (table: Mutable<TableNode>, surface: Extract<SurfaceBlockSnapshot, { kind: "table" }>) => void,
|
|
207
208
|
): void {
|
|
208
209
|
for (let index = 0; index < Math.min(blocks.length, surfaceBlocks.length); index += 1) {
|
|
209
210
|
const block = blocks[index];
|
|
@@ -18,6 +18,7 @@ import type {
|
|
|
18
18
|
TextMark,
|
|
19
19
|
TextNode,
|
|
20
20
|
SdtNode,
|
|
21
|
+
Mutable,
|
|
21
22
|
} from "../../model/canonical-document.ts";
|
|
22
23
|
import type {
|
|
23
24
|
ParsedAltChunkNode,
|
|
@@ -108,7 +109,7 @@ export function normalizeParsedTextDocument(
|
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
const content: DocumentRootNode = { type: "doc", children };
|
|
112
|
+
const content: Mutable<DocumentRootNode> = { type: "doc", children };
|
|
112
113
|
|
|
113
114
|
return {
|
|
114
115
|
content,
|
|
@@ -180,7 +181,7 @@ export async function normalizeParsedTextDocumentAsync(
|
|
|
180
181
|
}
|
|
181
182
|
}
|
|
182
183
|
|
|
183
|
-
const content: DocumentRootNode = { type: "doc", children };
|
|
184
|
+
const content: Mutable<DocumentRootNode> = { type: "doc", children };
|
|
184
185
|
|
|
185
186
|
return {
|
|
186
187
|
content,
|
|
@@ -432,7 +433,7 @@ function normalizeInlineChildren(
|
|
|
432
433
|
|
|
433
434
|
const previous = normalized[normalized.length - 1];
|
|
434
435
|
if (previous?.type === "text" && sameMarks(previous.marks, node.marks)) {
|
|
435
|
-
previous.text += node.text;
|
|
436
|
+
(previous as Mutable<typeof previous>).text += node.text;
|
|
436
437
|
} else {
|
|
437
438
|
normalized.push({
|
|
438
439
|
type: "text",
|
|
@@ -752,7 +753,7 @@ function normalizeHyperlink(node: ParsedHyperlinkNode): {
|
|
|
752
753
|
}
|
|
753
754
|
const previous = children[children.length - 1];
|
|
754
755
|
if (previous?.type === "text" && sameMarks(previous.marks, child.marks)) {
|
|
755
|
-
previous.text += child.text;
|
|
756
|
+
(previous as Mutable<typeof previous>).text += child.text;
|
|
756
757
|
} else {
|
|
757
758
|
children.push({
|
|
758
759
|
type: "text",
|
|
@@ -835,7 +836,7 @@ function recordOpaqueFragment(
|
|
|
835
836
|
const rangeStart = state.cursor;
|
|
836
837
|
const rangeEnd = state.cursor + 1;
|
|
837
838
|
|
|
838
|
-
const record: OpaqueFragmentRecord = {
|
|
839
|
+
const record: Mutable<OpaqueFragmentRecord> = {
|
|
839
840
|
fragmentId,
|
|
840
841
|
payloadKind: "xml-subtree",
|
|
841
842
|
payloadReference: rawXml,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnchorGeometry } from "../../model/canonical-document.ts";
|
|
1
|
+
import type { AnchorGeometry, Mutable } from "../../model/canonical-document.ts";
|
|
2
2
|
import {
|
|
3
3
|
type XmlElementNode,
|
|
4
4
|
findFirstChild,
|
|
@@ -46,11 +46,11 @@ export function parseAnchorGeometry(container: XmlElementNode): AnchorGeometry {
|
|
|
46
46
|
const dp: NonNullable<AnchorGeometry["docPr"]> = {
|
|
47
47
|
id: docPrEl.attributes.id ?? "",
|
|
48
48
|
};
|
|
49
|
-
if (docPrEl.attributes.name) dp.name = docPrEl.attributes.name;
|
|
50
|
-
if (docPrEl.attributes.descr) dp.descr = docPrEl.attributes.descr;
|
|
49
|
+
if (docPrEl.attributes.name) (dp as Mutable<typeof dp>).name = docPrEl.attributes.name;
|
|
50
|
+
if (docPrEl.attributes.descr) (dp as Mutable<typeof dp>).descr = docPrEl.attributes.descr;
|
|
51
51
|
// Phase 4.6 G8 — wp:docPr hidden flag
|
|
52
52
|
const hidden = readBoolAttr(docPrEl, "hidden");
|
|
53
|
-
if (hidden !== undefined) dp.hidden = hidden;
|
|
53
|
+
if (hidden !== undefined) (dp as Mutable<typeof dp>).hidden = hidden;
|
|
54
54
|
return dp;
|
|
55
55
|
})()
|
|
56
56
|
: undefined;
|
|
@@ -62,21 +62,21 @@ export function parseAnchorGeometry(container: XmlElementNode): AnchorGeometry {
|
|
|
62
62
|
// Phase 4.2 G1 — wrapPolygon coords for wrapTight / wrapThrough.
|
|
63
63
|
const wrapPolygon = readWrapPolygon(container);
|
|
64
64
|
|
|
65
|
-
const geometry: AnchorGeometry = {
|
|
65
|
+
const geometry: Mutable<AnchorGeometry> = {
|
|
66
66
|
display,
|
|
67
67
|
extent,
|
|
68
68
|
wrapMode,
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
-
if (wrapPolygon) geometry.wrapPolygon = wrapPolygon;
|
|
72
|
-
if (positionHEl) geometry.positionH = readAxisPosition(positionHEl);
|
|
73
|
-
if (positionVEl) geometry.positionV = readAxisPosition(positionVEl);
|
|
74
|
-
if (distMargins) geometry.distMargins = distMargins;
|
|
75
|
-
if (relativeHeight !== undefined) geometry.relativeHeight = relativeHeight;
|
|
76
|
-
if (behindDoc !== undefined) geometry.behindDoc = behindDoc;
|
|
77
|
-
if (layoutInCell !== undefined) geometry.layoutInCell = layoutInCell;
|
|
78
|
-
if (allowOverlap !== undefined) geometry.allowOverlap = allowOverlap;
|
|
79
|
-
if (simplePos !== undefined) geometry.simplePos = simplePos;
|
|
71
|
+
if (wrapPolygon) (geometry as Mutable<typeof geometry>).wrapPolygon = wrapPolygon;
|
|
72
|
+
if (positionHEl) (geometry as Mutable<typeof geometry>).positionH = readAxisPosition(positionHEl);
|
|
73
|
+
if (positionVEl) (geometry as Mutable<typeof geometry>).positionV = readAxisPosition(positionVEl);
|
|
74
|
+
if (distMargins) (geometry as Mutable<typeof geometry>).distMargins = distMargins;
|
|
75
|
+
if (relativeHeight !== undefined) (geometry as Mutable<typeof geometry>).relativeHeight = relativeHeight;
|
|
76
|
+
if (behindDoc !== undefined) (geometry as Mutable<typeof geometry>).behindDoc = behindDoc;
|
|
77
|
+
if (layoutInCell !== undefined) (geometry as Mutable<typeof geometry>).layoutInCell = layoutInCell;
|
|
78
|
+
if (allowOverlap !== undefined) (geometry as Mutable<typeof geometry>).allowOverlap = allowOverlap;
|
|
79
|
+
if (simplePos !== undefined) (geometry as Mutable<typeof geometry>).simplePos = simplePos;
|
|
80
80
|
if (docPr) geometry.docPr = docPr;
|
|
81
81
|
if (frameLocks) geometry.frameLocks = frameLocks;
|
|
82
82
|
|
|
@@ -136,7 +136,7 @@ function readFrameLocks(
|
|
|
136
136
|
const keys = ["noChangeAspect", "noResize", "noMove", "noRot", "noSelect", "noGrp"] as const;
|
|
137
137
|
for (const key of keys) {
|
|
138
138
|
const v = readBoolAttr(locks, key);
|
|
139
|
-
if (v !== undefined) result[key] = v;
|
|
139
|
+
if (v !== undefined) (result as Mutable<typeof result>)[key] = v;
|
|
140
140
|
}
|
|
141
141
|
return Object.keys(result).length > 0 ? result : undefined;
|
|
142
142
|
}
|