@beyondwork/docx-react-component 1.0.101 → 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/export/build-app-properties-xml.ts +24 -0
- package/src/io/normalize/normalize-text.ts +6 -5
- package/src/io/ooxml/docprops.ts +298 -0
- 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 +920 -815
- 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/export/stateful-export-pipeline.ts +9 -4
- package/src/session/export/stateful-export.ts +22 -6
- package/src/session/import/canonical-assembly.ts +2 -3
- package/src/session/import/loader-types.ts +3 -1
- package/src/session/import/loader.ts +12 -0
- package/src/session/import/normalize.ts +2 -1
- package/src/session/import/source-package-evidence.ts +1016 -0
- package/src/session/shared/session-utils.ts +9 -0
|
@@ -41,6 +41,7 @@ import type {
|
|
|
41
41
|
ShapeContent,
|
|
42
42
|
VmlShapeNode,
|
|
43
43
|
WordArtNode,
|
|
44
|
+
Mutable,
|
|
44
45
|
} from "../model/canonical-document.ts";
|
|
45
46
|
import {
|
|
46
47
|
describeOpaqueFragment,
|
|
@@ -575,7 +576,7 @@ function createSurfaceBlock(
|
|
|
575
576
|
|
|
576
577
|
function createTableBlock(
|
|
577
578
|
tableIndex: number,
|
|
578
|
-
table: TableNode
|
|
579
|
+
table: Mutable<TableNode>,
|
|
579
580
|
document: CanonicalDocumentEnvelope,
|
|
580
581
|
cursor: number,
|
|
581
582
|
counters: {
|
|
@@ -769,7 +770,7 @@ function createTableBlock(
|
|
|
769
770
|
};
|
|
770
771
|
}
|
|
771
772
|
|
|
772
|
-
function computeTableRowSpans(table: TableNode): Map<string, number> {
|
|
773
|
+
function computeTableRowSpans(table: Mutable<TableNode>): Map<string, number> {
|
|
773
774
|
const positionedRows = table.rows.map((row) => {
|
|
774
775
|
let startColumn = 0;
|
|
775
776
|
|
|
@@ -933,7 +934,7 @@ function toSurfaceFrameProperties(
|
|
|
933
934
|
}
|
|
934
935
|
|
|
935
936
|
function resolveSurfaceParagraphFormatting(
|
|
936
|
-
formatting: CanonicalParagraphFormatting
|
|
937
|
+
formatting: Mutable<CanonicalParagraphFormatting>,
|
|
937
938
|
themeResolver: ThemeColorResolver | undefined,
|
|
938
939
|
): CanonicalParagraphFormatting {
|
|
939
940
|
if (!formatting.shading) {
|
|
@@ -1065,7 +1066,7 @@ function resolveCellBorderStyles(
|
|
|
1065
1066
|
|
|
1066
1067
|
function createSdtBlock(
|
|
1067
1068
|
sdtIndex: number,
|
|
1068
|
-
block: SdtNode
|
|
1069
|
+
block: Mutable<SdtNode>,
|
|
1069
1070
|
document: CanonicalDocumentEnvelope,
|
|
1070
1071
|
cursor: number,
|
|
1071
1072
|
counters: {
|
|
@@ -1123,7 +1124,7 @@ function createSdtBlock(
|
|
|
1123
1124
|
|
|
1124
1125
|
function createParagraphBlock(
|
|
1125
1126
|
paragraphIndex: number,
|
|
1126
|
-
paragraph: ParagraphNode
|
|
1127
|
+
paragraph: Mutable<ParagraphNode>,
|
|
1127
1128
|
document: CanonicalDocumentEnvelope,
|
|
1128
1129
|
start: number,
|
|
1129
1130
|
formattingContext: FormattingContext,
|
|
@@ -1757,13 +1758,7 @@ function appendInlineSegments(
|
|
|
1757
1758
|
const fieldLabel =
|
|
1758
1759
|
node.fieldFamily === "TOC"
|
|
1759
1760
|
? "Table of Contents"
|
|
1760
|
-
: node.fieldFamily
|
|
1761
|
-
? "Current page number"
|
|
1762
|
-
: node.fieldFamily === "NUMPAGES"
|
|
1763
|
-
? "Total pages"
|
|
1764
|
-
: node.fieldFamily === "SECTIONPAGES"
|
|
1765
|
-
? "Section pages"
|
|
1766
|
-
: `${node.fieldFamily ?? "Field"}: ${node.fieldTarget ?? node.instruction.trim()}`;
|
|
1761
|
+
: `${node.fieldFamily ?? "Field"}: ${node.fieldTarget ?? node.instruction.trim()}`;
|
|
1767
1762
|
paragraph.segments.push({
|
|
1768
1763
|
segmentId: `${paragraph.blockId}-segment-${paragraph.segments.length}`,
|
|
1769
1764
|
kind: "field_ref",
|
|
@@ -1804,7 +1799,7 @@ function appendInlineSegments(
|
|
|
1804
1799
|
}
|
|
1805
1800
|
|
|
1806
1801
|
function registerParsedChartPreview(
|
|
1807
|
-
node: ChartPreviewNode
|
|
1802
|
+
node: Mutable<ChartPreviewNode>,
|
|
1808
1803
|
document: CanonicalDocumentEnvelope,
|
|
1809
1804
|
): string | undefined {
|
|
1810
1805
|
if (!node.parsedData) return undefined;
|
|
@@ -1946,7 +1941,7 @@ function surfaceAnchorFromGeometry(
|
|
|
1946
1941
|
* fast-path image rendering.
|
|
1947
1942
|
*/
|
|
1948
1943
|
function surfacePictureEffectsFromContent(
|
|
1949
|
-
content: PictureContent
|
|
1944
|
+
content: Mutable<PictureContent>,
|
|
1950
1945
|
themeResolver?: ThemeColorResolver,
|
|
1951
1946
|
): SurfacePictureEffects | undefined {
|
|
1952
1947
|
const outerShadow = resolveSurfacePictureShadow(content.outerShadow, themeResolver);
|
|
@@ -2159,7 +2154,7 @@ function appendTextBoxSegment(
|
|
|
2159
2154
|
return { nextCursor: start + 1, lockedFragmentIds: [] };
|
|
2160
2155
|
}
|
|
2161
2156
|
|
|
2162
|
-
function shouldRenderSecondaryStoryVmlTextBox(node: VmlShapeNode): boolean {
|
|
2157
|
+
function shouldRenderSecondaryStoryVmlTextBox(node: Mutable<VmlShapeNode>): boolean {
|
|
2163
2158
|
return Boolean(node.text) && (!node.shapeType || /_x0000_t202$/iu.test(node.shapeType));
|
|
2164
2159
|
}
|
|
2165
2160
|
|
|
@@ -2174,7 +2169,7 @@ function isMicrosoftSensitivityLabelShape(
|
|
|
2174
2169
|
/"Placement"\s*:\s*"Footer"/iu.test(node.rawXml);
|
|
2175
2170
|
}
|
|
2176
2171
|
|
|
2177
|
-
function createChartDetail(node: ChartPreviewNode): string {
|
|
2172
|
+
function createChartDetail(node: Mutable<ChartPreviewNode>): string {
|
|
2178
2173
|
const parts = ["Embedded chart."];
|
|
2179
2174
|
if (node.previewMediaId) {
|
|
2180
2175
|
parts.push(`Preview available via fallback image (${node.previewMediaId}).`);
|
|
@@ -2185,7 +2180,7 @@ function createChartDetail(node: ChartPreviewNode): string {
|
|
|
2185
2180
|
return parts.join(" ");
|
|
2186
2181
|
}
|
|
2187
2182
|
|
|
2188
|
-
function createSmartArtDetail(node: SmartArtPreviewNode): string {
|
|
2183
|
+
function createSmartArtDetail(node: Mutable<SmartArtPreviewNode>): string {
|
|
2189
2184
|
const parts = ["SmartArt diagram."];
|
|
2190
2185
|
if (node.previewMediaId) {
|
|
2191
2186
|
parts.push(`Preview available via fallback image (${node.previewMediaId}).`);
|
|
@@ -2196,7 +2191,7 @@ function createSmartArtDetail(node: SmartArtPreviewNode): string {
|
|
|
2196
2191
|
return parts.join(" ");
|
|
2197
2192
|
}
|
|
2198
2193
|
|
|
2199
|
-
function createShapeDetail(node: ShapeNode): string {
|
|
2194
|
+
function createShapeDetail(node: Mutable<ShapeNode>): string {
|
|
2200
2195
|
if (node.isTextBox) {
|
|
2201
2196
|
const parts = ["Text box."];
|
|
2202
2197
|
if (node.text) parts.push(`Content: "${node.text}".`);
|
|
@@ -2210,7 +2205,7 @@ function createShapeDetail(node: ShapeNode): string {
|
|
|
2210
2205
|
return parts.join(" ");
|
|
2211
2206
|
}
|
|
2212
2207
|
|
|
2213
|
-
function createWordArtDetail(node: WordArtNode): string {
|
|
2208
|
+
function createWordArtDetail(node: Mutable<WordArtNode>): string {
|
|
2214
2209
|
const parts = ["WordArt decorative text."];
|
|
2215
2210
|
if (node.text) parts.push(`Text: "${node.text}".`);
|
|
2216
2211
|
if (node.geometry) parts.push(`Effect: ${node.geometry}.`);
|
|
@@ -2218,7 +2213,7 @@ function createWordArtDetail(node: WordArtNode): string {
|
|
|
2218
2213
|
return parts.join(" ");
|
|
2219
2214
|
}
|
|
2220
2215
|
|
|
2221
|
-
function createVmlDetail(node: VmlShapeNode): string {
|
|
2216
|
+
function createVmlDetail(node: Mutable<VmlShapeNode>): string {
|
|
2222
2217
|
const parts = ["Legacy VML drawing."];
|
|
2223
2218
|
if (node.shapeType) parts.push(`Type: ${node.shapeType}.`);
|
|
2224
2219
|
if (node.text) parts.push(`Text content: "${node.text}".`);
|
|
@@ -2587,22 +2582,22 @@ function toSurfaceTabStop(
|
|
|
2587
2582
|
}
|
|
2588
2583
|
|
|
2589
2584
|
function buildDirectParagraphFormattingFromNode(
|
|
2590
|
-
paragraph: ParagraphNode
|
|
2585
|
+
paragraph: Mutable<ParagraphNode>,
|
|
2591
2586
|
): CanonicalParagraphFormatting | undefined {
|
|
2592
|
-
const direct: CanonicalParagraphFormatting = {};
|
|
2593
|
-
if (paragraph.spacing) direct.spacing = paragraph.spacing;
|
|
2594
|
-
if (paragraph.indentation) direct.indentation = paragraph.indentation;
|
|
2595
|
-
if (paragraph.alignment) direct.alignment = paragraph.alignment;
|
|
2596
|
-
if (paragraph.borders) direct.borders = paragraph.borders;
|
|
2597
|
-
if (paragraph.shading) direct.shading = paragraph.shading;
|
|
2598
|
-
if (paragraph.tabStops && paragraph.tabStops.length > 0) direct.tabStops = [...paragraph.tabStops];
|
|
2599
|
-
if (paragraph.contextualSpacing !== undefined) direct.contextualSpacing = paragraph.contextualSpacing;
|
|
2600
|
-
if (paragraph.keepNext !== undefined) direct.keepNext = paragraph.keepNext;
|
|
2601
|
-
if (paragraph.keepLines !== undefined) direct.keepLines = paragraph.keepLines;
|
|
2602
|
-
if (paragraph.widowControl !== undefined) direct.widowControl = paragraph.widowControl;
|
|
2603
|
-
if (paragraph.pageBreakBefore !== undefined) direct.pageBreakBefore = paragraph.pageBreakBefore;
|
|
2604
|
-
if (paragraph.outlineLevel !== undefined) direct.outlineLevel = paragraph.outlineLevel;
|
|
2605
|
-
if (paragraph.bidi !== undefined) direct.bidi = paragraph.bidi;
|
|
2587
|
+
const direct: Mutable<CanonicalParagraphFormatting> = {};
|
|
2588
|
+
if (paragraph.spacing) (direct as Mutable<typeof direct>).spacing = paragraph.spacing;
|
|
2589
|
+
if (paragraph.indentation) (direct as Mutable<typeof direct>).indentation = paragraph.indentation;
|
|
2590
|
+
if (paragraph.alignment) (direct as Mutable<typeof direct>).alignment = paragraph.alignment;
|
|
2591
|
+
if (paragraph.borders) (direct as Mutable<typeof direct>).borders = paragraph.borders;
|
|
2592
|
+
if (paragraph.shading) (direct as Mutable<typeof direct>).shading = paragraph.shading;
|
|
2593
|
+
if (paragraph.tabStops && paragraph.tabStops.length > 0) (direct as Mutable<typeof direct>).tabStops = [...paragraph.tabStops];
|
|
2594
|
+
if (paragraph.contextualSpacing !== undefined) (direct as Mutable<typeof direct>).contextualSpacing = paragraph.contextualSpacing;
|
|
2595
|
+
if (paragraph.keepNext !== undefined) (direct as Mutable<typeof direct>).keepNext = paragraph.keepNext;
|
|
2596
|
+
if (paragraph.keepLines !== undefined) (direct as Mutable<typeof direct>).keepLines = paragraph.keepLines;
|
|
2597
|
+
if (paragraph.widowControl !== undefined) (direct as Mutable<typeof direct>).widowControl = paragraph.widowControl;
|
|
2598
|
+
if (paragraph.pageBreakBefore !== undefined) (direct as Mutable<typeof direct>).pageBreakBefore = paragraph.pageBreakBefore;
|
|
2599
|
+
if (paragraph.outlineLevel !== undefined) (direct as Mutable<typeof direct>).outlineLevel = paragraph.outlineLevel;
|
|
2600
|
+
if (paragraph.bidi !== undefined) (direct as Mutable<typeof direct>).bidi = paragraph.bidi;
|
|
2606
2601
|
if (paragraph.suppressLineNumbers !== undefined) direct.suppressLineNumbers = paragraph.suppressLineNumbers;
|
|
2607
2602
|
return Object.keys(direct).length > 0 ? direct : undefined;
|
|
2608
2603
|
}
|
|
@@ -2947,7 +2942,7 @@ function createFloatingImageDetail(
|
|
|
2947
2942
|
return parts.join(" ");
|
|
2948
2943
|
}
|
|
2949
2944
|
|
|
2950
|
-
function hasMediaItem(media: MediaCatalog
|
|
2945
|
+
function hasMediaItem(media: Mutable<MediaCatalog>, mediaId: string): boolean {
|
|
2951
2946
|
return mediaId in media.items;
|
|
2952
2947
|
}
|
|
2953
2948
|
|
|
@@ -136,7 +136,7 @@ export function ensureHostMetadataParts(
|
|
|
136
136
|
if (!corePropertiesPart || corePropertiesPart.contentType !== CORE_PROPERTIES_CONTENT_TYPE) {
|
|
137
137
|
exportSession.replaceOwnedPart({
|
|
138
138
|
path: CORE_PROPERTIES_PART_PATH,
|
|
139
|
-
bytes:
|
|
139
|
+
bytes: new TextEncoder().encode(buildCorePropertiesXml(document)),
|
|
140
140
|
contentType: CORE_PROPERTIES_CONTENT_TYPE,
|
|
141
141
|
compression: corePropertiesPart?.compression,
|
|
142
142
|
});
|
|
@@ -146,7 +146,7 @@ export function ensureHostMetadataParts(
|
|
|
146
146
|
if (!appPropertiesPart || appPropertiesPart.contentType !== APP_PROPERTIES_CONTENT_TYPE) {
|
|
147
147
|
exportSession.replaceOwnedPart({
|
|
148
148
|
path: APP_PROPERTIES_PART_PATH,
|
|
149
|
-
bytes:
|
|
149
|
+
bytes: new TextEncoder().encode(buildAppPropertiesXml(document.metadata.appProperties)),
|
|
150
150
|
contentType: APP_PROPERTIES_CONTENT_TYPE,
|
|
151
151
|
compression: appPropertiesPart?.compression,
|
|
152
152
|
});
|
|
@@ -305,11 +305,16 @@ export function buildCorePropertiesXml(document: CanonicalDocumentEnvelope): str
|
|
|
305
305
|
xmlNode("dc:title", metadata.title),
|
|
306
306
|
xmlNode("dc:subject", metadata.subject),
|
|
307
307
|
xmlNode("dc:description", metadata.description),
|
|
308
|
+
xmlNode("dc:creator", metadata.creator),
|
|
308
309
|
xmlNode("dc:language", metadata.language),
|
|
309
310
|
xmlNode("cp:keywords", keywords),
|
|
310
311
|
xmlNode("cp:category", metadata.category),
|
|
311
|
-
xmlNode(
|
|
312
|
-
xmlNode(
|
|
312
|
+
xmlNode("cp:lastModifiedBy", metadata.lastModifiedBy),
|
|
313
|
+
xmlNode("cp:contentStatus", metadata.contentStatus),
|
|
314
|
+
xmlNode("cp:revision", metadata.revision),
|
|
315
|
+
xmlNode("cp:version", metadata.version),
|
|
316
|
+
xmlNode('dcterms:created xsi:type="dcterms:W3CDTF"', metadata.createdUtc ?? document.createdAt),
|
|
317
|
+
xmlNode('dcterms:modified xsi:type="dcterms:W3CDTF"', metadata.modifiedUtc ?? document.updatedAt),
|
|
313
318
|
].filter((line): line is string => Boolean(line));
|
|
314
319
|
|
|
315
320
|
return [
|
|
@@ -83,6 +83,7 @@ import {
|
|
|
83
83
|
import { toEditorSessionState } from "../import/canonical-assembly.ts";
|
|
84
84
|
import {
|
|
85
85
|
serializeCanonicalDocumentForExport,
|
|
86
|
+
serializeNumberingCatalogForExport,
|
|
86
87
|
} from "../shared/session-utils.ts";
|
|
87
88
|
import { withDocumentRelatedParts } from "../import/package-parts.ts";
|
|
88
89
|
import {
|
|
@@ -290,6 +291,14 @@ export async function runStatefulExport(
|
|
|
290
291
|
state.sourcePeoplePartPath ?? PEOPLE_PART_PATH;
|
|
291
292
|
const numberingPartPath =
|
|
292
293
|
state.sourceNumberingPartPath ?? NUMBERING_PART_PATH;
|
|
294
|
+
const sourceNumberingPart = state.sourceNumberingPartPath
|
|
295
|
+
? state.sourcePackage.parts.get(numberingPartPath)
|
|
296
|
+
: undefined;
|
|
297
|
+
const numberingSignatureMatch =
|
|
298
|
+
serializeNumberingCatalogForExport(currentDocument.numbering as NumberingCatalog) ===
|
|
299
|
+
state.initialNumberingSignature;
|
|
300
|
+
const canReuseSourceNumberingPart =
|
|
301
|
+
numberingSignatureMatch && sourceNumberingPart !== undefined;
|
|
293
302
|
const serializedNumberingXml = hasSerializableNumberingEntries(
|
|
294
303
|
currentDocument.numbering as NumberingCatalog,
|
|
295
304
|
)
|
|
@@ -303,6 +312,7 @@ export async function runStatefulExport(
|
|
|
303
312
|
partPath: numberingPartPath,
|
|
304
313
|
existingRelationshipId: state.sourceNumberingRelationshipId,
|
|
305
314
|
include:
|
|
315
|
+
canReuseSourceNumberingPart ||
|
|
306
316
|
Boolean(serializedNumberingXml) ||
|
|
307
317
|
Boolean(state.sourceNumberingPartPath),
|
|
308
318
|
},
|
|
@@ -423,16 +433,22 @@ export async function runStatefulExport(
|
|
|
423
433
|
relationships: nextRelationships,
|
|
424
434
|
});
|
|
425
435
|
|
|
426
|
-
if (serializedNumberingXml || state.sourceNumberingPartPath) {
|
|
436
|
+
if (canReuseSourceNumberingPart || serializedNumberingXml || state.sourceNumberingPartPath) {
|
|
437
|
+
const numberingBytes =
|
|
438
|
+
canReuseSourceNumberingPart && sourceNumberingPart
|
|
439
|
+
? sourceNumberingPart.bytes
|
|
440
|
+
: new TextEncoder().encode(
|
|
441
|
+
serializedNumberingXml ??
|
|
442
|
+
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"></w:numbering>`,
|
|
443
|
+
);
|
|
444
|
+
|
|
427
445
|
exportSession.replaceOwnedPart({
|
|
428
446
|
path: numberingPartPath,
|
|
429
|
-
bytes:
|
|
430
|
-
serializedNumberingXml ??
|
|
431
|
-
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"></w:numbering>`,
|
|
432
|
-
),
|
|
447
|
+
bytes: numberingBytes,
|
|
433
448
|
contentType:
|
|
434
|
-
|
|
449
|
+
sourceNumberingPart?.contentType ??
|
|
435
450
|
WORD_NUMBERING_CONTENT_TYPE,
|
|
451
|
+
compression: sourceNumberingPart?.compression,
|
|
436
452
|
});
|
|
437
453
|
}
|
|
438
454
|
|
|
@@ -133,6 +133,7 @@ export function createImportedCanonicalDocument(input: {
|
|
|
133
133
|
subParts?: SubPartsCatalog;
|
|
134
134
|
parsedStyles?: ParseStylesResult;
|
|
135
135
|
fontTable?: CanonicalDocument["fontTable"];
|
|
136
|
+
metadata?: CanonicalDocument["metadata"];
|
|
136
137
|
preservation: CanonicalDocument["preservation"];
|
|
137
138
|
diagnostics: CanonicalDocument["diagnostics"];
|
|
138
139
|
review: CanonicalDocument["review"];
|
|
@@ -166,9 +167,7 @@ export function createImportedCanonicalDocument(input: {
|
|
|
166
167
|
docId: createCanonicalDocumentId(input.documentId),
|
|
167
168
|
createdAt: input.timestamp,
|
|
168
169
|
updatedAt: input.timestamp,
|
|
169
|
-
metadata: {
|
|
170
|
-
customProperties: {},
|
|
171
|
-
},
|
|
170
|
+
metadata: input.metadata ?? { customProperties: {} },
|
|
172
171
|
styles,
|
|
173
172
|
numbering,
|
|
174
173
|
media: input.media,
|
|
@@ -252,7 +252,8 @@ export interface LoadedDocxEditorSession {
|
|
|
252
252
|
* State captured at import time that the export pipeline consumes to
|
|
253
253
|
* round-trip the package. Carries source bytes, the OPC package
|
|
254
254
|
* snapshot, per-part relationships, preserved-part manifest, and the
|
|
255
|
-
* initial canonical
|
|
255
|
+
* initial canonical signatures used for fast-path byte reuse and
|
|
256
|
+
* preserve-first per-part export decisions.
|
|
256
257
|
*
|
|
257
258
|
* Load path builds this; `exportDocxEditorSession` consumes it via
|
|
258
259
|
* the closure captured at open time.
|
|
@@ -299,6 +300,7 @@ export interface ImportedDocxState {
|
|
|
299
300
|
preservedCommentDefinitions: readonly ImportedCommentDefinition[];
|
|
300
301
|
blockingCommentDiagnostics: readonly CommentImportDiagnostic[];
|
|
301
302
|
initialCanonicalSignature: string;
|
|
303
|
+
initialNumberingSignature: string;
|
|
302
304
|
sourceSubPartPaths: {
|
|
303
305
|
headers: Array<{ partPath: string; relationshipId: string }>;
|
|
304
306
|
footers: Array<{ partPath: string; relationshipId: string }>;
|
|
@@ -97,6 +97,7 @@ import {
|
|
|
97
97
|
} from "../../io/ooxml/parse-revisions.ts";
|
|
98
98
|
import { parseCommentsFromOoxml } from "../../io/ooxml/parse-comments.ts";
|
|
99
99
|
import { parseNumberingXml } from "../../io/ooxml/parse-numbering.ts";
|
|
100
|
+
import { parseDocumentMetadataFromOpcParts } from "../../io/ooxml/docprops.ts";
|
|
100
101
|
import {
|
|
101
102
|
parseHeaderFooterReferences,
|
|
102
103
|
parseHeaderXml,
|
|
@@ -131,6 +132,7 @@ import {
|
|
|
131
132
|
decodeUtf8,
|
|
132
133
|
extractDocumentRootAttributes,
|
|
133
134
|
serializeCanonicalDocumentForExport,
|
|
135
|
+
serializeNumberingCatalogForExport,
|
|
134
136
|
toUint8Array,
|
|
135
137
|
} from "../shared/session-utils.ts";
|
|
136
138
|
import {
|
|
@@ -285,6 +287,7 @@ export async function loadDocxSessionAsync(
|
|
|
285
287
|
}),
|
|
286
288
|
);
|
|
287
289
|
}
|
|
290
|
+
const packageMetadata = parseDocumentMetadataFromOpcParts(sourcePackage.parts);
|
|
288
291
|
stages.emit("opc");
|
|
289
292
|
await scheduler.yield();
|
|
290
293
|
const embeddedWorkflowPayload = parseWorkflowPayloadEnvelopeFromPackage(sourcePackage);
|
|
@@ -1018,6 +1021,7 @@ export async function loadDocxSessionAsync(
|
|
|
1018
1021
|
subParts,
|
|
1019
1022
|
parsedStyles,
|
|
1020
1023
|
fontTable: parsedFontTable,
|
|
1024
|
+
metadata: packageMetadata,
|
|
1021
1025
|
preservation: buildImportPreservation(normalizedDocument.preservation, sourcePackage, [
|
|
1022
1026
|
mainDocumentPath,
|
|
1023
1027
|
numberingPartPath,
|
|
@@ -1152,6 +1156,9 @@ export async function loadDocxSessionAsync(
|
|
|
1152
1156
|
BLOCKING_COMMENT_DIAGNOSTIC_CODES.has(diagnostic.code),
|
|
1153
1157
|
),
|
|
1154
1158
|
initialCanonicalSignature: serializeCanonicalDocumentForExport(document),
|
|
1159
|
+
initialNumberingSignature: serializeNumberingCatalogForExport(
|
|
1160
|
+
document.numbering as _NumberingCatalog,
|
|
1161
|
+
),
|
|
1155
1162
|
sourceSubPartPaths: {
|
|
1156
1163
|
headers: sourceHeaderPaths,
|
|
1157
1164
|
footers: sourceFooterPaths,
|
|
@@ -1229,6 +1236,7 @@ export function loadDocxSessionSync(
|
|
|
1229
1236
|
}),
|
|
1230
1237
|
);
|
|
1231
1238
|
}
|
|
1239
|
+
const packageMetadata = parseDocumentMetadataFromOpcParts(sourcePackage.parts);
|
|
1232
1240
|
stages.emit("opc");
|
|
1233
1241
|
const embeddedWorkflowPayload = parseWorkflowPayloadEnvelopeFromPackage(sourcePackage);
|
|
1234
1242
|
const embeddedWorkflowMetadata = embeddedWorkflowPayload?.workflowMetadata;
|
|
@@ -1697,6 +1705,7 @@ export function loadDocxSessionSync(
|
|
|
1697
1705
|
subParts,
|
|
1698
1706
|
parsedStyles,
|
|
1699
1707
|
fontTable: parsedFontTable,
|
|
1708
|
+
metadata: packageMetadata,
|
|
1700
1709
|
preservation: buildImportPreservation(normalizedDocument.preservation, sourcePackage, [
|
|
1701
1710
|
mainDocumentPath,
|
|
1702
1711
|
numberingPartPath,
|
|
@@ -1808,6 +1817,9 @@ export function loadDocxSessionSync(
|
|
|
1808
1817
|
BLOCKING_COMMENT_DIAGNOSTIC_CODES.has(diagnostic.code),
|
|
1809
1818
|
),
|
|
1810
1819
|
initialCanonicalSignature: serializeCanonicalDocumentForExport(document),
|
|
1820
|
+
initialNumberingSignature: serializeNumberingCatalogForExport(
|
|
1821
|
+
document.numbering as _NumberingCatalog,
|
|
1822
|
+
),
|
|
1811
1823
|
sourceSubPartPaths: {
|
|
1812
1824
|
headers: sourceHeaderPaths,
|
|
1813
1825
|
footers: sourceFooterPaths,
|
|
@@ -22,6 +22,7 @@ import type {
|
|
|
22
22
|
CanonicalDocument,
|
|
23
23
|
FootnoteCollection,
|
|
24
24
|
OpaqueFragmentRecord,
|
|
25
|
+
Mutable,
|
|
25
26
|
} from "../../model/canonical-document.ts";
|
|
26
27
|
|
|
27
28
|
/** Warning shape carried on `CanonicalDocument.diagnostics.warnings`. */
|
|
@@ -130,7 +131,7 @@ export function normalizeFootnoteCollectionOpaqueBlocks(
|
|
|
130
131
|
if (!collection) return;
|
|
131
132
|
const notes = kind === "footnote" ? collection.footnotes : collection.endnotes;
|
|
132
133
|
for (const definition of Object.values(notes)) {
|
|
133
|
-
definition.blocks = normalizeSubPartOpaqueBlocks(
|
|
134
|
+
(definition as Mutable<typeof definition>).blocks = normalizeSubPartOpaqueBlocks(
|
|
134
135
|
definition.blocks,
|
|
135
136
|
opaqueFragments,
|
|
136
137
|
warnings,
|