@beyondwork/docx-react-component 1.0.102 → 1.0.103
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/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 +5 -5
- package/src/io/ooxml/parse-fields.ts +16 -15
- 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 +18 -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 +835 -833
- package/src/runtime/formatting/document-lookup.ts +3 -2
- package/src/runtime/formatting/formatting-context.ts +66 -25
- package/src/runtime/formatting/index.ts +18 -0
- package/src/runtime/formatting/layout-inputs.ts +256 -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/surface-projection.ts +31 -36
- package/src/session/import/normalize.ts +2 -1
- package/src/session/import/source-package-evidence.ts +612 -1
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.103",
|
|
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": [
|
|
@@ -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
|
}
|
|
@@ -2,7 +2,7 @@ import type { OpcRelationship } from "./part-manifest.ts";
|
|
|
2
2
|
import { normalizePartPath, resolveRelationshipTarget } from "./part-manifest.ts";
|
|
3
3
|
import type { InlineMediaPart } from "./parse-inline-media.ts";
|
|
4
4
|
import type { ChartPartLookup } from "./parse-complex-content.ts";
|
|
5
|
-
import type { DrawingFrameNode,
|
|
5
|
+
import type { AnchorGeometry, DrawingFrameNode, Mutable } from "../../model/canonical-document.ts";
|
|
6
6
|
import { parseAnchorGeometry } from "./parse-anchor.ts";
|
|
7
7
|
import { parsePicture } from "./parse-picture.ts";
|
|
8
8
|
import { parseShapeContent, type TxbxBlockParser } from "./parse-shapes.ts";
|
|
@@ -190,14 +190,14 @@ function resolveContent(
|
|
|
190
190
|
resolveRelationshipTarget(opts.sourcePartPath ?? "/word/document.xml", rel),
|
|
191
191
|
);
|
|
192
192
|
const mediaPart = opts.mediaParts?.get(partPath);
|
|
193
|
-
pic.packagePartName = partPath;
|
|
194
|
-
pic.mediaId = `media:${partPath.slice(1)}`;
|
|
193
|
+
(pic as Mutable<typeof pic>).packagePartName = partPath;
|
|
194
|
+
(pic as Mutable<typeof pic>).mediaId = `media:${partPath.slice(1)}`;
|
|
195
195
|
if (mediaPart?.contentType) {
|
|
196
|
-
pic.contentType = mediaPart.contentType;
|
|
196
|
+
(pic as Mutable<typeof pic>).contentType = mediaPart.contentType;
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
// F4.1 — preserve outer drawing XML for lossless round-trip serialization
|
|
200
|
-
pic.rawXml = rawXml;
|
|
200
|
+
(pic as Mutable<typeof pic>).rawXml = rawXml;
|
|
201
201
|
return pic;
|
|
202
202
|
}
|
|
203
203
|
}
|
|
@@ -328,6 +328,7 @@ import type {
|
|
|
328
328
|
TocInstructionModel,
|
|
329
329
|
TocRegion,
|
|
330
330
|
TocStructure,
|
|
331
|
+
Mutable,
|
|
331
332
|
} from "../../model/canonical-document.ts";
|
|
332
333
|
import { parseFieldSwitches } from "./parse-field-switches.ts";
|
|
333
334
|
|
|
@@ -379,14 +380,14 @@ export function classifyFieldInstruction(instruction: string): {
|
|
|
379
380
|
let switches: FieldNode["switches"] | undefined;
|
|
380
381
|
if (family === "REF" || family === "PAGEREF" || family === "NOTEREF" || family === "TOC") {
|
|
381
382
|
const raw = parseFieldSwitches(trimmed);
|
|
382
|
-
const sw: FieldNode["switches"] = {};
|
|
383
|
-
if (raw.hyperlink) sw.hyperlink = true;
|
|
384
|
-
if (raw.relativePosition) sw.relativePosition = true;
|
|
385
|
-
if (raw.numericRef) sw.numericRef = true;
|
|
386
|
-
if (raw.recursive) sw.recursive = true;
|
|
387
|
-
if (raw.suppressNonDelimiter) sw.suppressNonDelimiter = true;
|
|
388
|
-
if (raw.includeNumbering) sw.includeNumbering = true;
|
|
389
|
-
if (raw.includeLevel) sw.includeLevel = true;
|
|
383
|
+
const sw: Mutable<NonNullable<FieldNode["switches"]>> = {};
|
|
384
|
+
if (raw.hyperlink) (sw as Mutable<typeof sw>).hyperlink = true;
|
|
385
|
+
if (raw.relativePosition) (sw as Mutable<typeof sw>).relativePosition = true;
|
|
386
|
+
if (raw.numericRef) (sw as Mutable<typeof sw>).numericRef = true;
|
|
387
|
+
if (raw.recursive) (sw as Mutable<typeof sw>).recursive = true;
|
|
388
|
+
if (raw.suppressNonDelimiter) (sw as Mutable<typeof sw>).suppressNonDelimiter = true;
|
|
389
|
+
if (raw.includeNumbering) (sw as Mutable<typeof sw>).includeNumbering = true;
|
|
390
|
+
if (raw.includeLevel) (sw as Mutable<typeof sw>).includeLevel = true;
|
|
390
391
|
if (Object.keys(sw).length > 0) {
|
|
391
392
|
switches = sw;
|
|
392
393
|
}
|
|
@@ -430,7 +431,7 @@ export function buildFieldRegistry(
|
|
|
430
431
|
? { family: node.fieldFamily, supported: isSupportedFieldFamily(node.fieldFamily), target: node.fieldTarget, switches: node.switches }
|
|
431
432
|
: classifyFieldInstruction(node.instruction);
|
|
432
433
|
const displayText = flattenFieldText(node.children);
|
|
433
|
-
const entry: FieldRegistryEntry = {
|
|
434
|
+
const entry: Mutable<FieldRegistryEntry> = {
|
|
434
435
|
fieldIndex,
|
|
435
436
|
fieldFamily: classification.family,
|
|
436
437
|
supported: classification.supported,
|
|
@@ -460,7 +461,7 @@ export function buildFieldRegistry(
|
|
|
460
461
|
? { family: node.fieldFamily, supported: isSupportedFieldFamily(node.fieldFamily), target: node.fieldTarget, switches: node.switches }
|
|
461
462
|
: classifyFieldInstruction(node.instruction);
|
|
462
463
|
const displayText = flattenFieldText(node.children);
|
|
463
|
-
const entry: FieldRegistryEntry = {
|
|
464
|
+
const entry: Mutable<FieldRegistryEntry> = {
|
|
464
465
|
fieldIndex,
|
|
465
466
|
fieldFamily: classification.family,
|
|
466
467
|
supported: classification.supported,
|
|
@@ -512,7 +513,7 @@ export function parseTocLevelRange(instruction: string): { from: number; to: num
|
|
|
512
513
|
}
|
|
513
514
|
|
|
514
515
|
export function parseTocInstruction(instruction: string): TocInstructionModel {
|
|
515
|
-
const model: TocInstructionModel = {
|
|
516
|
+
const model: Mutable<TocInstructionModel> = {
|
|
516
517
|
raw: instruction,
|
|
517
518
|
outlineRange: { from: 1, to: 9 },
|
|
518
519
|
};
|
|
@@ -867,7 +868,7 @@ function tocLevelFromStyle(styleId: string | undefined): number {
|
|
|
867
868
|
}
|
|
868
869
|
|
|
869
870
|
function extractCachedTocEntry(
|
|
870
|
-
paragraph: ParagraphNode
|
|
871
|
+
paragraph: Mutable<ParagraphNode>,
|
|
871
872
|
paragraphIndexByNode: WeakMap<ParagraphNode, number>,
|
|
872
873
|
): TocCachedEntry | undefined {
|
|
873
874
|
if (!isTocParagraphStyle(paragraph.styleId)) {
|
|
@@ -1004,7 +1005,7 @@ export function resolveRefFieldText(
|
|
|
1004
1005
|
* applies these to the live document.
|
|
1005
1006
|
*/
|
|
1006
1007
|
export function refreshFieldRegistry(
|
|
1007
|
-
registry: FieldRegistry
|
|
1008
|
+
registry: Mutable<FieldRegistry>,
|
|
1008
1009
|
bookmarkNameMap: Map<string, { bookmarkId: string; paragraphIndex: number }>,
|
|
1009
1010
|
): FieldRegistry {
|
|
1010
1011
|
const refreshed: FieldRegistryEntry[] = registry.supported.map((entry) => {
|
|
@@ -1060,7 +1061,7 @@ function walkFieldDocument(
|
|
|
1060
1061
|
}
|
|
1061
1062
|
|
|
1062
1063
|
function walkSubPartFields(
|
|
1063
|
-
subParts: SubPartsCatalog
|
|
1064
|
+
subParts: Mutable<SubPartsCatalog>,
|
|
1064
1065
|
visit: (node: DocumentNode, paragraphIndex: number) => void,
|
|
1065
1066
|
): void {
|
|
1066
1067
|
for (const header of subParts.headers) {
|
|
@@ -1112,7 +1113,7 @@ function flattenParagraphInlineText(children: InlineNode[]): string {
|
|
|
1112
1113
|
}
|
|
1113
1114
|
|
|
1114
1115
|
function flattenBookmarkContent(
|
|
1115
|
-
paragraph: ParagraphNode
|
|
1116
|
+
paragraph: Mutable<ParagraphNode>,
|
|
1116
1117
|
bookmarkId: string,
|
|
1117
1118
|
): string {
|
|
1118
1119
|
let inside = false;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import type {
|
|
14
14
|
CanonicalFontEntry,
|
|
15
15
|
CanonicalFontTable,
|
|
16
|
+
Mutable,
|
|
16
17
|
} from "../../model/canonical-document.ts";
|
|
17
18
|
import type { XmlElementNode } from "./xml-element.ts";
|
|
18
19
|
import { parseXml } from "./xml-parser.ts";
|
|
@@ -32,7 +33,7 @@ export function parseFontTable(xml: string): CanonicalFontTable {
|
|
|
32
33
|
const name = child.attributes["w:name"] ?? child.attributes["name"];
|
|
33
34
|
if (!name) continue;
|
|
34
35
|
|
|
35
|
-
const entry: CanonicalFontEntry = { name };
|
|
36
|
+
const entry: Mutable<CanonicalFontEntry> = { name };
|
|
36
37
|
|
|
37
38
|
for (const sub of child.children) {
|
|
38
39
|
if (sub.type !== "element") continue;
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
TableNode,
|
|
12
12
|
TableRowNode,
|
|
13
13
|
TextMark,
|
|
14
|
+
Mutable,
|
|
14
15
|
} from "../../model/canonical-document.ts";
|
|
15
16
|
import { classifyFieldInstruction } from "./parse-fields.ts";
|
|
16
17
|
import { isSafeTableFieldInstruction } from "./table-opaque-preservation.ts";
|
|
@@ -644,7 +645,7 @@ function parseRunProperties(rElement: XmlElementNode): TextMark[] {
|
|
|
644
645
|
function readParagraphSpacing(pPr: XmlElementNode): ParagraphSpacing | undefined {
|
|
645
646
|
const spacingNode = findChildElementOptional(pPr, "spacing");
|
|
646
647
|
if (!spacingNode) return undefined;
|
|
647
|
-
const result: ParagraphSpacing = {};
|
|
648
|
+
const result: Mutable<ParagraphSpacing> = {};
|
|
648
649
|
const before = readStringAttr(spacingNode, "w:before");
|
|
649
650
|
if (before) result.before = Number.parseInt(before, 10);
|
|
650
651
|
const after = readStringAttr(spacingNode, "w:after");
|
|
@@ -661,7 +662,7 @@ function readParagraphSpacing(pPr: XmlElementNode): ParagraphSpacing | undefined
|
|
|
661
662
|
function readParagraphIndentation(pPr: XmlElementNode): ParagraphIndentation | undefined {
|
|
662
663
|
const indNode = findChildElementOptional(pPr, "ind");
|
|
663
664
|
if (!indNode) return undefined;
|
|
664
|
-
const result: ParagraphIndentation = {};
|
|
665
|
+
const result: Mutable<ParagraphIndentation> = {};
|
|
665
666
|
const left = readStringAttr(indNode, "w:left");
|
|
666
667
|
if (left) result.left = Number.parseInt(left, 10);
|
|
667
668
|
const right = readStringAttr(indNode, "w:right");
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
TableNode,
|
|
12
12
|
TableRowNode,
|
|
13
13
|
TextMark,
|
|
14
|
+
Mutable,
|
|
14
15
|
} from "../../model/canonical-document.ts";
|
|
15
16
|
import type { LegacyFormFieldNode } from "../../model/canonical-document.ts";
|
|
16
17
|
import { resolveHighlightColor } from "./highlight-colors.ts";
|
|
@@ -500,7 +501,7 @@ function parseRunElement(
|
|
|
500
501
|
const noteId =
|
|
501
502
|
readStringAttr(child, "w:id") ?? "";
|
|
502
503
|
if (noteId) {
|
|
503
|
-
const ref: FootnoteRefNode = {
|
|
504
|
+
const ref: Mutable<FootnoteRefNode> = {
|
|
504
505
|
type: "footnote_ref",
|
|
505
506
|
noteId,
|
|
506
507
|
noteKind: "footnote",
|
|
@@ -511,7 +512,7 @@ function parseRunElement(
|
|
|
511
512
|
const noteId =
|
|
512
513
|
readStringAttr(child, "w:id") ?? "";
|
|
513
514
|
if (noteId) {
|
|
514
|
-
const ref: FootnoteRefNode = {
|
|
515
|
+
const ref: Mutable<FootnoteRefNode> = {
|
|
515
516
|
type: "footnote_ref",
|
|
516
517
|
noteId,
|
|
517
518
|
noteKind: "endnote",
|
|
@@ -594,7 +595,7 @@ function parseRunChildNode(
|
|
|
594
595
|
const noteId =
|
|
595
596
|
readStringAttr(child, "w:id") ?? "";
|
|
596
597
|
if (noteId) {
|
|
597
|
-
const ref: FootnoteRefNode = {
|
|
598
|
+
const ref: Mutable<FootnoteRefNode> = {
|
|
598
599
|
type: "footnote_ref",
|
|
599
600
|
noteId,
|
|
600
601
|
noteKind: "footnote",
|
|
@@ -607,7 +608,7 @@ function parseRunChildNode(
|
|
|
607
608
|
const noteId =
|
|
608
609
|
readStringAttr(child, "w:id") ?? "";
|
|
609
610
|
if (noteId) {
|
|
610
|
-
const ref: FootnoteRefNode = {
|
|
611
|
+
const ref: Mutable<FootnoteRefNode> = {
|
|
611
612
|
type: "footnote_ref",
|
|
612
613
|
noteId,
|
|
613
614
|
noteKind: "endnote",
|
|
@@ -970,7 +971,7 @@ function parseRunProperties(rElement: XmlElementNode): TextMark[] {
|
|
|
970
971
|
function readParagraphSpacing(pPr: XmlElementNode): ParagraphSpacing | undefined {
|
|
971
972
|
const spacingNode = findChildElementOptional(pPr, "spacing");
|
|
972
973
|
if (!spacingNode) return undefined;
|
|
973
|
-
const result: ParagraphSpacing = {};
|
|
974
|
+
const result: Mutable<ParagraphSpacing> = {};
|
|
974
975
|
const before = readStringAttr(spacingNode, "w:before");
|
|
975
976
|
if (before) result.before = Number.parseInt(before, 10);
|
|
976
977
|
const after = readStringAttr(spacingNode, "w:after");
|
|
@@ -987,7 +988,7 @@ function readParagraphSpacing(pPr: XmlElementNode): ParagraphSpacing | undefined
|
|
|
987
988
|
function readParagraphIndentation(pPr: XmlElementNode): ParagraphIndentation | undefined {
|
|
988
989
|
const indNode = findChildElementOptional(pPr, "ind");
|
|
989
990
|
if (!indNode) return undefined;
|
|
990
|
-
const result: ParagraphIndentation = {};
|
|
991
|
+
const result: Mutable<ParagraphIndentation> = {};
|
|
991
992
|
const left = readStringAttr(indNode, "w:left");
|
|
992
993
|
if (left) result.left = Number.parseInt(left, 10);
|
|
993
994
|
const right = readStringAttr(indNode, "w:right");
|