@stll/folio-core 0.55.0 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/apply.js +169 -38
- package/dist/ai-edits/headless.js +2 -2
- package/dist/ai-edits/types.d.ts +7 -1
- package/dist/compare/compare.js +1 -0
- package/dist/compare/reproducible-package.d.ts +0 -17
- package/dist/compare/reproducible-package.js +12 -18
- package/dist/controller/canonicalClipboard.d.ts +23 -0
- package/dist/controller/canonicalClipboard.js +476 -0
- package/dist/controller/canonicalClipboardResources.d.ts +21 -0
- package/dist/controller/canonicalClipboardResources.js +382 -0
- package/dist/controller/canonicalComposition.d.ts +20 -3
- package/dist/controller/canonicalComposition.js +166 -38
- package/dist/controller/canonicalInlineProjection.d.ts +113 -0
- package/dist/controller/canonicalInlineProjection.js +393 -0
- package/dist/controller/canonicalInput.d.ts +13 -4
- package/dist/controller/canonicalInput.js +52 -13
- package/dist/controller/canonicalInputTimer.d.ts +7 -0
- package/dist/controller/canonicalInputTimer.js +11 -0
- package/dist/controller/canonicalPublicOperations.d.ts +48 -0
- package/dist/controller/canonicalPublicOperations.js +556 -0
- package/dist/controller/canonicalSession.d.ts +24 -6
- package/dist/controller/canonicalSession.js +259 -111
- package/dist/controller/canonicalStoryEditor.d.ts +5 -3
- package/dist/controller/canonicalStoryEditor.js +7 -2
- package/dist/controller/canonicalStructure.js +57 -4
- package/dist/controller/canonicalTocSelection.d.ts +11 -0
- package/dist/controller/canonicalTocSelection.js +43 -0
- package/dist/controller/folioEditor.d.ts +2 -9
- package/dist/controller/folioEditor.js +5 -4
- package/dist/controller/headerFooterEditorManager.d.ts +2 -1
- package/dist/controller/headerFooterEditorManager.js +8 -7
- package/dist/controller/hiddenEditorApi.d.ts +12 -2
- package/dist/controller/hiddenEditorApi.js +4 -0
- package/dist/controller/hiddenEditorManager.d.ts +3 -1
- package/dist/controller/hiddenEditorManager.js +216 -34
- package/dist/controller/noteEditorManager.d.ts +2 -1
- package/dist/controller/noteEditorManager.js +8 -7
- package/dist/document-operations.d.ts +8 -1
- package/dist/document-operations.js +6 -4
- package/dist/docx/blockPlainText.d.ts +1 -1
- package/dist/docx/blockPlainText.js +11 -3
- package/dist/docx/canonicalResourceSave.d.ts +16 -0
- package/dist/docx/canonicalResourceSave.js +27 -0
- package/dist/docx/canonicalSave.d.ts +29 -0
- package/dist/docx/canonicalSave.js +101 -0
- package/dist/docx/canonicalStoryRepack.d.ts +1 -1
- package/dist/docx/canonicalStoryRepack.js +38 -5
- package/dist/docx/documentParser.d.ts +1 -13
- package/dist/docx/documentParser.js +1 -47
- package/dist/docx/ensureParaIds.js +10 -4
- package/dist/docx/footnoteParser.d.ts +1 -11
- package/dist/docx/footnoteParser.js +1 -16
- package/dist/docx/headerFooterParser.d.ts +1 -9
- package/dist/docx/headerFooterParser.js +1 -12
- package/dist/docx/headerFooterVerbatim.d.ts +26 -1
- package/dist/docx/headerFooterVerbatim.js +81 -3
- package/dist/docx/imageParser.d.ts +13 -1
- package/dist/docx/imageParser.js +20 -11
- package/dist/docx/metadataPrivacy.js +6 -1
- package/dist/docx/packageParts.js +9 -3
- package/dist/docx/paragraphPropertySource.js +2 -1
- package/dist/docx/parser.js +2 -1
- package/dist/docx/removeHeaderFooterParts.js +17 -6
- package/dist/docx/rezip.d.ts +49 -5
- package/dist/docx/rezip.js +745 -229
- package/dist/docx/saveDiagnostics.d.ts +11 -0
- package/dist/docx/selectiveSave.d.ts +2 -1
- package/dist/docx/selectiveSave.js +32 -3
- package/dist/docx/selectiveXmlPatch.js +7 -5
- package/dist/docx/serializer/documentSerializer.d.ts +9 -2
- package/dist/docx/serializer/documentSerializer.js +29 -10
- package/dist/docx/server/applyDocxXmlPatchProposal.js +14 -9
- package/dist/docx/storyBlockReplay.d.ts +21 -1
- package/dist/docx/storyBlockReplay.js +113 -9
- package/dist/docx/storyPlainText.d.ts +20 -0
- package/dist/docx/storyPlainText.js +23 -0
- package/dist/docx/structuralXmlPatch.js +10 -22
- package/dist/docx/styleParser.d.ts +5 -1
- package/dist/docx/styleParser.js +1 -1
- package/dist/docx/tableParser.d.ts +1 -8
- package/dist/docx/tableParser.js +1 -28
- package/dist/docx/textBoxParser.d.ts +1 -5
- package/dist/docx/textBoxParser.js +1 -20
- package/dist/docx/unzip.js +6 -1
- package/dist/internal/acceptedBlockProjection.d.ts +12 -0
- package/dist/internal/acceptedBlockProjection.js +45 -0
- package/dist/managers/DocumentLoaderManager.js +2 -1
- package/dist/markdown/escape.d.ts +3 -1
- package/dist/markdown/escape.js +9 -2
- package/dist/markdown/renderBlock.js +5 -120
- package/dist/markdown/renderParagraph.js +4 -2
- package/dist/markdown/renderRuns.d.ts +7 -1
- package/dist/markdown/renderRuns.js +32 -13
- package/dist/prosemirror/canonicalCommands.d.ts +28 -4
- package/dist/prosemirror/canonicalCommands.js +11 -4
- package/dist/prosemirror/canonicalSelectionRange.d.ts +9 -0
- package/dist/prosemirror/canonicalSelectionRange.js +15 -0
- package/dist/prosemirror/clipboardIntent.d.ts +7 -0
- package/dist/prosemirror/clipboardIntent.js +9 -0
- package/dist/prosemirror/commands/pageBreak.js +2 -2
- package/dist/prosemirror/commands/pastePlainText.js +2 -1
- package/dist/prosemirror/conversion/hyphenTextCarriers.d.ts +8 -0
- package/dist/prosemirror/conversion/hyphenTextCarriers.js +8 -0
- package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -1
- package/dist/prosemirror/conversion/toProseDoc.js +5 -4
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +39 -30
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +56 -28
- package/dist/prosemirror/extensions/marks/markUtils.js +3 -1
- package/dist/prosemirror/insertOperations.js +2 -1
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +7 -1
- package/dist/prosemirror/paragraphPropertyCarry.js +8 -3
- package/dist/prosemirror/plugins/suggestionMode.js +7 -5
- package/dist/types/canonicalCapabilities.d.ts +215 -0
- package/dist/types/canonicalCapabilities.js +212 -0
- package/dist/types/canonicalSave.d.ts +11 -0
- package/dist/types/canonicalSave.js +0 -0
- package/dist/types/docxSerialization.d.ts +14 -0
- package/dist/types/docxSerialization.js +7 -0
- package/package.json +4 -4
|
@@ -15,7 +15,7 @@ const readFingerprint = (hf) => {
|
|
|
15
15
|
});
|
|
16
16
|
return value;
|
|
17
17
|
};
|
|
18
|
-
const BASELINE_HANDLE = Symbol("
|
|
18
|
+
const BASELINE_HANDLE = Symbol("package-source-baseline");
|
|
19
19
|
const contentBaselines = /* @__PURE__ */ new WeakMap();
|
|
20
20
|
const captureContentBaseline = (hf) => {
|
|
21
21
|
const fingerprint = hf.verbatimFingerprint;
|
|
@@ -23,6 +23,7 @@ const captureContentBaseline = (hf) => {
|
|
|
23
23
|
const handle = {};
|
|
24
24
|
const content = structuredClone(hf.content);
|
|
25
25
|
contentBaselines.set(handle, {
|
|
26
|
+
type: "headerFooter",
|
|
26
27
|
fingerprint,
|
|
27
28
|
xml: hf.verbatimXml,
|
|
28
29
|
contentFingerprint: canonicalJson(content),
|
|
@@ -46,6 +47,33 @@ const captureHeaderFooterPackageBaselines = (document) => {
|
|
|
46
47
|
}
|
|
47
48
|
packageBaselines.set(document.originalBuffer, handles);
|
|
48
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* Transfer body, header and footer capture handles across a trusted
|
|
52
|
+
* document graph clone. `structuredClone` drops symbol-keyed properties, so a
|
|
53
|
+
* clone would otherwise read an edited part as uncaptured ("missing") rather
|
|
54
|
+
* than as a mismatch against its source.
|
|
55
|
+
*/
|
|
56
|
+
const copyHeaderFooterBaselineHandles = (target, source) => {
|
|
57
|
+
const sourceBody = source.package.document;
|
|
58
|
+
if (BASELINE_HANDLE in sourceBody) Object.defineProperty(target.package.document, BASELINE_HANDLE, {
|
|
59
|
+
value: sourceBody[BASELINE_HANDLE],
|
|
60
|
+
enumerable: true,
|
|
61
|
+
configurable: true
|
|
62
|
+
});
|
|
63
|
+
for (const kind of ["headers", "footers"]) {
|
|
64
|
+
const targets = target.package[kind];
|
|
65
|
+
for (const [rId, sourcePart] of source.package[kind] ?? []) {
|
|
66
|
+
if (!(BASELINE_HANDLE in sourcePart)) continue;
|
|
67
|
+
const targetPart = targets?.get(rId);
|
|
68
|
+
if (!targetPart) continue;
|
|
69
|
+
Object.defineProperty(targetPart, BASELINE_HANDLE, {
|
|
70
|
+
value: sourcePart[BASELINE_HANDLE],
|
|
71
|
+
enumerable: true,
|
|
72
|
+
configurable: true
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
49
77
|
/** Transfer the parsed package registry only across a trusted document graph clone. */
|
|
50
78
|
const copyHeaderFooterPackageBaselines = (target, source) => {
|
|
51
79
|
if (!target.originalBuffer || !source.originalBuffer) return;
|
|
@@ -59,7 +87,7 @@ const getHeaderFooterSourceBaseline = (hf, originalBuffer) => {
|
|
|
59
87
|
if (handle === void 0 && !(BASELINE_HANDLE in hf)) return { type: "missing" };
|
|
60
88
|
if (typeof handle !== "object" || handle === null) return { type: "mismatch" };
|
|
61
89
|
const baseline = contentBaselines.get(handle);
|
|
62
|
-
if (!baseline || baseline.fingerprint !== hf.verbatimFingerprint || baseline.xml !== hf.verbatimXml || baseline.contentFingerprint !== canonicalJson(baseline.content)) return { type: "mismatch" };
|
|
90
|
+
if (!baseline || baseline.type !== "headerFooter" || baseline.fingerprint !== hf.verbatimFingerprint || baseline.xml !== hf.verbatimXml || baseline.contentFingerprint !== canonicalJson(baseline.content)) return { type: "mismatch" };
|
|
63
91
|
return {
|
|
64
92
|
type: "captured",
|
|
65
93
|
content: baseline.content
|
|
@@ -119,5 +147,55 @@ const clearHeaderFooterVerbatimXml = (hf) => {
|
|
|
119
147
|
delete ext.verbatimFingerprint;
|
|
120
148
|
Reflect.deleteProperty(hf, BASELINE_HANDLE);
|
|
121
149
|
};
|
|
150
|
+
/** Capture the body in the same trusted package registry as secondary stories. */
|
|
151
|
+
const captureDocumentSourceBaseline = (document, xml) => {
|
|
152
|
+
const body = structuredClone(document.package.document);
|
|
153
|
+
const handle = {};
|
|
154
|
+
contentBaselines.set(handle, {
|
|
155
|
+
type: "body",
|
|
156
|
+
fingerprint: { type: "pending" },
|
|
157
|
+
xml,
|
|
158
|
+
body,
|
|
159
|
+
resourceStyles: structuredClone(document.package.styles),
|
|
160
|
+
resourceRelationships: structuredClone(document.package.relationships),
|
|
161
|
+
resourceMedia: new Map([...document.package.media ?? []].map(([path, media]) => [path, {
|
|
162
|
+
data: media.data,
|
|
163
|
+
mimeType: media.mimeType
|
|
164
|
+
}]))
|
|
165
|
+
});
|
|
166
|
+
Object.defineProperty(document.package.document, BASELINE_HANDLE, {
|
|
167
|
+
value: handle,
|
|
168
|
+
enumerable: true,
|
|
169
|
+
configurable: true
|
|
170
|
+
});
|
|
171
|
+
if (document.originalBuffer) {
|
|
172
|
+
const registry = packageBaselines.get(document.originalBuffer) ?? /* @__PURE__ */ new Map();
|
|
173
|
+
registry.set("word/document.xml", /* @__PURE__ */ new Map([["body", handle]]));
|
|
174
|
+
packageBaselines.set(document.originalBuffer, registry);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
const getDocumentSourceBaseline = (document) => {
|
|
178
|
+
const body = document.package.document;
|
|
179
|
+
const handle = BASELINE_HANDLE in body ? body[BASELINE_HANDLE] : document.originalBuffer && packageBaselines.get(document.originalBuffer)?.get("word/document.xml")?.get("body");
|
|
180
|
+
if (handle === void 0) return { type: "missing" };
|
|
181
|
+
if (typeof handle !== "object" || handle === null) return { type: "mismatch" };
|
|
182
|
+
const baseline = contentBaselines.get(handle);
|
|
183
|
+
if (!baseline || baseline.type !== "body") return { type: "mismatch" };
|
|
184
|
+
const fingerprint = JSON.stringify(baseline.body);
|
|
185
|
+
if (baseline.fingerprint.type === "pending") baseline.fingerprint = {
|
|
186
|
+
type: "captured",
|
|
187
|
+
value: fingerprint
|
|
188
|
+
};
|
|
189
|
+
if (baseline.fingerprint.value !== fingerprint) return { type: "mismatch" };
|
|
190
|
+
return {
|
|
191
|
+
type: "captured",
|
|
192
|
+
body: baseline.body,
|
|
193
|
+
xml: baseline.xml,
|
|
194
|
+
fingerprint,
|
|
195
|
+
resourceStyles: baseline.resourceStyles,
|
|
196
|
+
resourceRelationships: baseline.resourceRelationships,
|
|
197
|
+
resourceMedia: baseline.resourceMedia
|
|
198
|
+
};
|
|
199
|
+
};
|
|
122
200
|
//#endregion
|
|
123
|
-
export { assignHeaderFooterVerbatimXml, canReplayHeaderFooterBlocks, canReplayHeaderFooterVerbatim, captureHeaderFooterPackageBaselines, clearHeaderFooterVerbatimXml, copyHeaderFooterPackageBaselines, getHeaderFooterSourceBaseline, getHeaderFooterVerbatimXml, refreshHeaderFooterVerbatimFingerprint };
|
|
201
|
+
export { assignHeaderFooterVerbatimXml, canReplayHeaderFooterBlocks, canReplayHeaderFooterVerbatim, captureDocumentSourceBaseline, captureHeaderFooterPackageBaselines, clearHeaderFooterVerbatimXml, copyHeaderFooterBaselineHandles, copyHeaderFooterPackageBaselines, getDocumentSourceBaseline, getHeaderFooterSourceBaseline, getHeaderFooterVerbatimXml, refreshHeaderFooterVerbatimFingerprint };
|
|
@@ -22,6 +22,18 @@ declare function resolveImageData(rId: string | undefined, rels: document_d_expo
|
|
|
22
22
|
mimeType?: string;
|
|
23
23
|
filename?: string;
|
|
24
24
|
};
|
|
25
|
+
type ImageDerivedFactsOptions = {
|
|
26
|
+
id: string | undefined;
|
|
27
|
+
pictureNames: NonNullable<document_d_exports.Image["pictureNames"]>;
|
|
28
|
+
imageData: ReturnType<typeof resolveImageData>;
|
|
29
|
+
};
|
|
30
|
+
/** Facts the parser obtains from exported drawing markup and image relationships. */
|
|
31
|
+
declare const imageDerivedFactsOf: ({ id, pictureNames, imageData }: ImageDerivedFactsOptions) => {
|
|
32
|
+
filename?: string;
|
|
33
|
+
mimeType?: string;
|
|
34
|
+
pictureNames?: import("@stll/docx-core/model").NonVisualDrawingNames;
|
|
35
|
+
id?: string;
|
|
36
|
+
};
|
|
25
37
|
/**
|
|
26
38
|
* Parse a w:drawing element
|
|
27
39
|
*
|
|
@@ -97,4 +109,4 @@ declare function getWrapDistancesPx(image: document_d_exports.Image): {
|
|
|
97
109
|
*/
|
|
98
110
|
declare function needsTextWrapping(image: document_d_exports.Image): boolean;
|
|
99
111
|
//#endregion
|
|
100
|
-
export { DECORATIVE_EXTENSION_URI, DECORATIVE_NAMESPACE, getImageDimensionsPx, getImageHeightPx, getImageWidthPx, getWrapDistancesPx, hasAltText, isBehindText, isDecorativeImage, isFloatingImage, isInFrontOfText, isInlineImage, needsTextWrapping, parseDrawing, parseImage, resolveImageData };
|
|
112
|
+
export { DECORATIVE_EXTENSION_URI, DECORATIVE_NAMESPACE, getImageDimensionsPx, getImageHeightPx, getImageWidthPx, getWrapDistancesPx, hasAltText, imageDerivedFactsOf, isBehindText, isDecorativeImage, isFloatingImage, isInFrontOfText, isInlineImage, needsTextWrapping, parseDrawing, parseImage, resolveImageData };
|
package/dist/docx/imageParser.js
CHANGED
|
@@ -10,7 +10,7 @@ import { RELATIONSHIP_TYPES, resolveRelationshipIdOfType } from "./relsParser.js
|
|
|
10
10
|
import { isTextBoxDrawing } from "./textBoxParser.js";
|
|
11
11
|
import { percentageSpelling } from "./transitionalSpelling.js";
|
|
12
12
|
import { captureVerbatimXml } from "./verbatimCapture.js";
|
|
13
|
-
import { findByFullName, findChildByNamespaceUri, findChildrenByNamespaceUri, getAttribute, getChildElements, getLocalName, getNamespaceUri, parseNumericAttribute, parseOnOffAttribute, parseOnOffValue } from "./xmlParser.js";
|
|
13
|
+
import { OFFICE_RELATIONSHIP_NAMESPACE_URIS, findAttributeByNamespaceUri, findByFullName, findChildByNamespaceUri, findChildrenByNamespaceUri, getAttribute, getChildElements, getLocalName, getNamespaceUri, parseNumericAttribute, parseOnOffAttribute, parseOnOffValue } from "./xmlParser.js";
|
|
14
14
|
import { relationshipIdOf } from "@stll/docx-core/model";
|
|
15
15
|
//#region src/docx/imageParser.ts
|
|
16
16
|
/**
|
|
@@ -129,7 +129,7 @@ const parseDocPropsExtensions = (docPr) => {
|
|
|
129
129
|
const parseDocPrLink = (docPr, localName) => {
|
|
130
130
|
const element = findChildByNamespaceUri(docPr, DRAWINGML_NAMESPACE_URIS, localName);
|
|
131
131
|
if (!element) return;
|
|
132
|
-
const rId =
|
|
132
|
+
const rId = findAttributeByNamespaceUri(element, OFFICE_RELATIONSHIP_NAMESPACE_URIS, "id")?.value;
|
|
133
133
|
return {
|
|
134
134
|
xml: captureVerbatimXml(element),
|
|
135
135
|
...rId == null ? {} : { rId }
|
|
@@ -382,6 +382,13 @@ function resolveImageData(rId, rels, media) {
|
|
|
382
382
|
...filename !== void 0 ? { filename } : {}
|
|
383
383
|
};
|
|
384
384
|
}
|
|
385
|
+
/** Facts the parser obtains from exported drawing markup and image relationships. */
|
|
386
|
+
const imageDerivedFactsOf = ({ id, pictureNames, imageData }) => ({
|
|
387
|
+
...id ? { id } : {},
|
|
388
|
+
...Object.keys(pictureNames).length > 0 ? { pictureNames } : {},
|
|
389
|
+
...imageData.mimeType ? { mimeType: imageData.mimeType } : {},
|
|
390
|
+
...imageData.filename ? { filename: imageData.filename } : {}
|
|
391
|
+
});
|
|
385
392
|
/**
|
|
386
393
|
* Parse a wp:inline element (inline image)
|
|
387
394
|
*
|
|
@@ -411,18 +418,19 @@ function parseInline(inlineEl, rels, media) {
|
|
|
411
418
|
size,
|
|
412
419
|
wrap
|
|
413
420
|
};
|
|
414
|
-
|
|
421
|
+
Object.assign(image, imageDerivedFactsOf({
|
|
422
|
+
id: props.id,
|
|
423
|
+
pictureNames,
|
|
424
|
+
imageData
|
|
425
|
+
}));
|
|
415
426
|
if (props.name !== void 0) image.docPrName = props.name;
|
|
416
427
|
if (props.alt !== void 0) image.alt = props.alt;
|
|
417
428
|
if (props.title !== void 0) image.title = props.title;
|
|
418
|
-
if (Object.keys(pictureNames).length > 0) image.pictureNames = pictureNames;
|
|
419
429
|
if (props.decorative !== void 0) image.decorative = props.decorative;
|
|
420
430
|
if (props.hidden !== void 0) image.hidden = props.hidden;
|
|
421
431
|
if (props.docPrExtensions !== void 0) image.docPrExtensions = props.docPrExtensions;
|
|
422
432
|
const safeSrc = sanitizeImageSrc(imageData.src);
|
|
423
433
|
if (safeSrc) image.src = safeSrc;
|
|
424
|
-
if (imageData.mimeType) image.mimeType = imageData.mimeType;
|
|
425
|
-
if (imageData.filename) image.filename = imageData.filename;
|
|
426
434
|
if (padding) image.padding = padding;
|
|
427
435
|
if (transform) image.transform = transform;
|
|
428
436
|
if (crop) image.crop = crop;
|
|
@@ -492,18 +500,19 @@ function parseAnchor(anchorEl, rels, media) {
|
|
|
492
500
|
size,
|
|
493
501
|
wrap
|
|
494
502
|
};
|
|
495
|
-
|
|
503
|
+
Object.assign(image, imageDerivedFactsOf({
|
|
504
|
+
id: props.id,
|
|
505
|
+
pictureNames,
|
|
506
|
+
imageData
|
|
507
|
+
}));
|
|
496
508
|
if (props.name !== void 0) image.docPrName = props.name;
|
|
497
509
|
if (props.alt !== void 0) image.alt = props.alt;
|
|
498
510
|
if (props.title !== void 0) image.title = props.title;
|
|
499
|
-
if (Object.keys(pictureNames).length > 0) image.pictureNames = pictureNames;
|
|
500
511
|
if (props.decorative !== void 0) image.decorative = props.decorative;
|
|
501
512
|
if (props.hidden !== void 0) image.hidden = props.hidden;
|
|
502
513
|
if (props.docPrExtensions !== void 0) image.docPrExtensions = props.docPrExtensions;
|
|
503
514
|
const safeSrc = sanitizeImageSrc(imageData.src);
|
|
504
515
|
if (safeSrc) image.src = safeSrc;
|
|
505
|
-
if (imageData.mimeType) image.mimeType = imageData.mimeType;
|
|
506
|
-
if (imageData.filename) image.filename = imageData.filename;
|
|
507
516
|
if (position) image.position = position;
|
|
508
517
|
if (padding) image.padding = padding;
|
|
509
518
|
if (transform) image.transform = transform;
|
|
@@ -628,4 +637,4 @@ function needsTextWrapping(image) {
|
|
|
628
637
|
].includes(image.wrap.type);
|
|
629
638
|
}
|
|
630
639
|
//#endregion
|
|
631
|
-
export { DECORATIVE_EXTENSION_URI, DECORATIVE_NAMESPACE, getImageDimensionsPx, getImageHeightPx, getImageWidthPx, getWrapDistancesPx, hasAltText, isBehindText, isDecorativeImage, isFloatingImage, isInFrontOfText, isInlineImage, needsTextWrapping, parseDrawing, parseImage, resolveImageData };
|
|
640
|
+
export { DECORATIVE_EXTENSION_URI, DECORATIVE_NAMESPACE, getImageDimensionsPx, getImageHeightPx, getImageWidthPx, getWrapDistancesPx, hasAltText, imageDerivedFactsOf, isBehindText, isDecorativeImage, isFloatingImage, isInFrontOfText, isInlineImage, needsTextWrapping, parseDrawing, parseImage, resolveImageData };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { countCentralDirectoryRecords, createInflationBudget, inflateEntryWithinLimits } from "./archiveInflation.js";
|
|
2
2
|
import { elementToXml, getLocalName, parseXmlDocument } from "./xmlParser.js";
|
|
3
3
|
import { TaggedError } from "better-result";
|
|
4
|
+
import { writeZipPart } from "@stll/docx-core/zip";
|
|
4
5
|
import JSZip from "jszip";
|
|
5
6
|
//#region src/docx/metadataPrivacy.ts
|
|
6
7
|
const FOLIO_DOCUMENT_METADATA_PROPERTIES = Object.freeze([
|
|
@@ -152,7 +153,11 @@ const rewriteDocxMetadataPrivacy = async (buffer, { transforms }) => {
|
|
|
152
153
|
removedMetadataProperties: []
|
|
153
154
|
}
|
|
154
155
|
};
|
|
155
|
-
|
|
156
|
+
writeZipPart({
|
|
157
|
+
zip,
|
|
158
|
+
path: coreProperties.name,
|
|
159
|
+
data: rewritten.xml
|
|
160
|
+
});
|
|
156
161
|
return {
|
|
157
162
|
buffer: await zip.generateAsync({
|
|
158
163
|
type: "arraybuffer",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Result } from "better-result";
|
|
2
|
+
import { writeZipPart } from "@stll/docx-core/zip";
|
|
2
3
|
//#region src/docx/packageParts.ts
|
|
3
4
|
/**
|
|
4
5
|
* What a repack carries out of the source package, and the guarantee that
|
|
@@ -129,9 +130,14 @@ const readRelationshipParts = async (zip) => {
|
|
|
129
130
|
return parts;
|
|
130
131
|
};
|
|
131
132
|
const writePart = ({ zip, path, xml, compressionLevel }) => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
writeZipPart({
|
|
134
|
+
zip,
|
|
135
|
+
path,
|
|
136
|
+
data: xml,
|
|
137
|
+
options: {
|
|
138
|
+
compression: "DEFLATE",
|
|
139
|
+
compressionOptions: { level: compressionLevel }
|
|
140
|
+
}
|
|
135
141
|
});
|
|
136
142
|
};
|
|
137
143
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { modelParagraphFormattingEmission } from "../internal/paragraphFormattingSerialization.js";
|
|
2
2
|
import { canonicalJson } from "../utils/canonicalJson.js";
|
|
3
|
-
import { copyHeaderFooterPackageBaselines } from "./headerFooterVerbatim.js";
|
|
3
|
+
import { copyHeaderFooterBaselineHandles, copyHeaderFooterPackageBaselines } from "./headerFooterVerbatim.js";
|
|
4
4
|
import { visitDocxParagraphs } from "./paragraphTraversal.js";
|
|
5
5
|
import { TaggedError, panic } from "better-result";
|
|
6
6
|
import { PluginKey } from "prosemirror-state";
|
|
@@ -244,6 +244,7 @@ const cloneDocumentWithParagraphPropertySources = (document) => {
|
|
|
244
244
|
copyParagraphPropertySource(target, source);
|
|
245
245
|
}
|
|
246
246
|
copyDocumentParagraphPropertySourceContract(cloned, document);
|
|
247
|
+
copyHeaderFooterBaselineHandles(cloned, document);
|
|
247
248
|
copyHeaderFooterPackageBaselines(cloned, document);
|
|
248
249
|
return cloned;
|
|
249
250
|
};
|
package/dist/docx/parser.js
CHANGED
|
@@ -15,7 +15,7 @@ import { parseFontTable } from "./fontTableParser.js";
|
|
|
15
15
|
import { parseEndnotes, parseFootnotes } from "./footnoteParser.js";
|
|
16
16
|
import { parseFooter, parseHeader } from "./headerFooterParser.js";
|
|
17
17
|
import { DANGLING_FOOTER_REFERENCE_WARNING, DANGLING_HEADER_REFERENCE_WARNING, assignHeaderFooterRoles, normalizeHeaderFooterReferences } from "./headerFooterReferenceNormalization.js";
|
|
18
|
-
import { assignHeaderFooterVerbatimXml, canReplayHeaderFooterVerbatim, captureHeaderFooterPackageBaselines, refreshHeaderFooterVerbatimFingerprint } from "./headerFooterVerbatim.js";
|
|
18
|
+
import { assignHeaderFooterVerbatimXml, canReplayHeaderFooterVerbatim, captureDocumentSourceBaseline, captureHeaderFooterPackageBaselines, refreshHeaderFooterVerbatimFingerprint } from "./headerFooterVerbatim.js";
|
|
19
19
|
import { extractMetafileRaster, isMetafileMimeType } from "./metafileRaster.js";
|
|
20
20
|
import { renderEmfSvg } from "./metafileSvg.js";
|
|
21
21
|
import { DocxModelValidationError, formatDocumentModelIssues, validateFolioDocumentModel } from "./modelValidation.js";
|
|
@@ -474,6 +474,7 @@ async function parseDocxWithPreviewBudget(input, options, previewBudget) {
|
|
|
474
474
|
}
|
|
475
475
|
onProgress("Complete", 100);
|
|
476
476
|
captureHeaderFooterPackageBaselines(document);
|
|
477
|
+
if (raw.documentXml) captureDocumentSourceBaseline(document, raw.documentXml);
|
|
477
478
|
return document;
|
|
478
479
|
} catch (error) {
|
|
479
480
|
if (error instanceof DocxEncryptionError) throw error;
|
|
@@ -4,6 +4,7 @@ import { captureVerbatimXml } from "./verbatimCapture.js";
|
|
|
4
4
|
import { OFFICE_RELATIONSHIP_NAMESPACE_URIS, cloneElement, getAttribute, getLocalName, getNamespaceUri, parseXmlDocument } from "./xmlParser.js";
|
|
5
5
|
import { panic } from "better-result";
|
|
6
6
|
import { OOXML_NS } from "@stll/docx-utils";
|
|
7
|
+
import { writeZipPart } from "@stll/docx-core/zip";
|
|
7
8
|
//#region src/docx/removeHeaderFooterParts.ts
|
|
8
9
|
const DOCUMENT_RELS_PATH = "word/_rels/document.xml.rels";
|
|
9
10
|
const officeRelationshipHasType = (type, kind) => [...OFFICE_RELATIONSHIP_NAMESPACE_URIS].some((namespace) => type === `${namespace}/${kind}`);
|
|
@@ -54,9 +55,14 @@ const removeResolvedHeaderFooterParts = async ({ document, zip, removedReference
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
const compressionOptions = { level: compressionLevel };
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
writeZipPart({
|
|
59
|
+
zip,
|
|
60
|
+
path: DOCUMENT_RELS_PATH,
|
|
61
|
+
data: withoutChildren(relsXml, (child) => getNamespaceUri(child) === OOXML_NS.pr && getLocalName(child.name) === "Relationship" && removedIds.has(getAttribute(child, null, "Id") ?? "")),
|
|
62
|
+
options: {
|
|
63
|
+
compression: "DEFLATE",
|
|
64
|
+
compressionOptions
|
|
65
|
+
}
|
|
60
66
|
});
|
|
61
67
|
if (document.package.relationships) {
|
|
62
68
|
document.package.relationships = new Map(document.package.relationships);
|
|
@@ -78,9 +84,14 @@ const removeResolvedHeaderFooterParts = async ({ document, zip, removedReference
|
|
|
78
84
|
const contentTypes = zip.file("[Content_Types].xml");
|
|
79
85
|
if (!contentTypes) return panic("The package has no content types");
|
|
80
86
|
const contentTypesXml = await contentTypes.async("text");
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
writeZipPart({
|
|
88
|
+
zip,
|
|
89
|
+
path: "[Content_Types].xml",
|
|
90
|
+
data: withoutChildren(contentTypesXml, (child) => getNamespaceUri(child) === OOXML_NS.ct && getLocalName(child.name) === "Override" && candidates.has((getAttribute(child, null, "PartName") ?? "").replace(/^\//u, ""))),
|
|
91
|
+
options: {
|
|
92
|
+
compression: "DEFLATE",
|
|
93
|
+
compressionOptions
|
|
94
|
+
}
|
|
84
95
|
});
|
|
85
96
|
};
|
|
86
97
|
//#endregion
|
package/dist/docx/rezip.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { CANONICAL_GAP } from "../types/canonicalCapabilities.js";
|
|
2
3
|
import { SaveDiagnosticOptions } from "./saveDiagnostics.js";
|
|
3
4
|
import { BlockContent, Hyperlink } from "../types/content.js";
|
|
5
|
+
import { DocumentBodyAuthorityOptions } from "./serializer/documentSerializer.js";
|
|
4
6
|
import { RawDocxContent } from "./unzip.js";
|
|
5
7
|
import JSZip from "jszip";
|
|
6
8
|
//#region src/docx/rezip.d.ts
|
|
@@ -38,16 +40,46 @@ declare class DocxDuplicateSectionCarrierError extends DocxPackageFidelityError
|
|
|
38
40
|
*/
|
|
39
41
|
declare function findMaxRId(relsXml: string): number;
|
|
40
42
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
+
* Every serialized section has exactly one model record, and vice versa.
|
|
44
|
+
*
|
|
45
|
+
* A split paragraph's duplicated `w:sectPr` is a section nobody added,
|
|
46
|
+
* repeating the real one's `w:rsidSect` and claiming its revision history too.
|
|
47
|
+
* Two carriers over one record are therefore invalid regardless of whether a
|
|
48
|
+
* separate deletion makes the total section count rise, fall, or stay equal.
|
|
49
|
+
*
|
|
50
|
+
* The count is a separate invariant: `serializeSectionProperties` fails closed
|
|
51
|
+
* to `""` for a record holding settings it cannot write, so carrier uniqueness
|
|
52
|
+
* alone does not prove the package states the sections the model holds.
|
|
43
53
|
*/
|
|
54
|
+
declare const assertSectionCarriersMatchModel: ({ doc, serializedSectionCount }: {
|
|
55
|
+
doc: document_d_exports.Document;
|
|
56
|
+
serializedSectionCount: number;
|
|
57
|
+
}) => void;
|
|
58
|
+
declare const CanonicalImageRelationshipRefusalError_base: import("better-result").TaggedErrorClass<"CanonicalImageRelationshipRefusalError">;
|
|
59
|
+
declare class CanonicalImageRelationshipRefusalError extends CanonicalImageRelationshipRefusalError_base<{
|
|
60
|
+
message: string;
|
|
61
|
+
gap: typeof CANONICAL_GAP.save;
|
|
62
|
+
part: string;
|
|
63
|
+
relationshipId: string;
|
|
64
|
+
reason: "conflict" | "unresolved" | "missingMedia" | "unsafeTarget";
|
|
65
|
+
}> {}
|
|
66
|
+
type PublishCanonicalImageResourcesOptions = {
|
|
67
|
+
document: document_d_exports.Document;
|
|
68
|
+
zip: JSZip;
|
|
69
|
+
compressionLevel: number;
|
|
70
|
+
};
|
|
71
|
+
/** Publish allocated pictures into each owning story without rebinding canonical ids. */
|
|
72
|
+
declare const publishCanonicalImageResources: ({ document, zip, compressionLevel }: PublishCanonicalImageResourcesOptions) => Promise<void>;
|
|
73
|
+
/** Newly authored text links; the census shares the complete owning-part traversal. */
|
|
44
74
|
declare function collectHyperlinksWithoutRId(blocks: BlockContent[]): Hyperlink[];
|
|
45
75
|
/** The selective save boundary must use the same resource census as full repack. */
|
|
46
76
|
declare const hasUnmaterializedInlineResources: (blocks: BlockContent[]) => boolean;
|
|
77
|
+
/** Compare against the already loaded source ZIP, without mutating model or package. */
|
|
78
|
+
declare const hasUnmaterializedHyperlinkBindings: (document: document_d_exports.Document, zip: JSZip) => Promise<boolean>;
|
|
47
79
|
/**
|
|
48
80
|
* Options for repacking DOCX
|
|
49
81
|
*/
|
|
50
|
-
type RepackOptions = SaveDiagnosticOptions & {
|
|
82
|
+
type RepackOptions = SaveDiagnosticOptions & DocumentBodyAuthorityOptions & {
|
|
51
83
|
/** Compression level (0-9, default: 6) */
|
|
52
84
|
compressionLevel?: number;
|
|
53
85
|
/** Whether to update modification date in docProps/core.xml */
|
|
@@ -190,6 +222,18 @@ type CollectHeaderFooterUpdatesOptions = SaveDiagnosticOptions & {
|
|
|
190
222
|
sourceZip: JSZip;
|
|
191
223
|
};
|
|
192
224
|
declare function collectHeaderFooterUpdates(doc: document_d_exports.Document, { sourceZip, onDiagnostic }: CollectHeaderFooterUpdatesOptions): Promise<Map<string, string>>;
|
|
225
|
+
type AddedStylesPlan = {
|
|
226
|
+
type: "unchanged";
|
|
227
|
+
} | {
|
|
228
|
+
type: "materialize";
|
|
229
|
+
styles: document_d_exports.StyleDefinitions;
|
|
230
|
+
} | {
|
|
231
|
+
type: "patch";
|
|
232
|
+
path: string;
|
|
233
|
+
xml: string;
|
|
234
|
+
};
|
|
235
|
+
/** One append-only style owner for full repack and selective overlays. */
|
|
236
|
+
declare function planAddedStyles(doc: document_d_exports.Document, originalZip: JSZip): Promise<AddedStylesPlan>;
|
|
193
237
|
/** `word/Footnotes.xml` -> `word/_rels/Footnotes.xml.rels` (casing preserved). */
|
|
194
238
|
declare function notePartRelsPath(partPath: string): string;
|
|
195
239
|
/** Update existing core-property values without synthesizing absent metadata. */
|
|
@@ -223,7 +267,7 @@ declare function isDocxBuffer(buffer: ArrayBuffer): boolean;
|
|
|
223
267
|
* ignored for a document that carries a source package, which keeps the
|
|
224
268
|
* properties that package already states.
|
|
225
269
|
*/
|
|
226
|
-
type DocumentPropertiesOptions = SaveDiagnosticOptions & {
|
|
270
|
+
type DocumentPropertiesOptions = SaveDiagnosticOptions & DocumentBodyAuthorityOptions & {
|
|
227
271
|
/** `dc:creator` in `docProps/core.xml`. Omitted when absent. */
|
|
228
272
|
creator?: string;
|
|
229
273
|
/** `Application` in `docProps/app.xml`. Omitted, with `AppVersion`, when absent. */
|
|
@@ -246,4 +290,4 @@ declare function createEmptyDocx(properties?: DocumentPropertiesOptions): Promis
|
|
|
246
290
|
*/
|
|
247
291
|
declare function createDocx(doc: document_d_exports.Document, properties?: DocumentPropertiesOptions): Promise<ArrayBuffer>;
|
|
248
292
|
//#endregion
|
|
249
|
-
export { COMMENTS_CONTENT_TYPE, COMMENTS_EXTENDED_CONTENT_TYPE, COMMENTS_EXTENDED_PART, COMMENTS_EXTENDED_PART_LOWER, DocumentPropertiesOptions, DocxDuplicateSectionCarrierError, DocxPackageFidelityError, RepackOptions, addCommentsExtendedOverride, addCommentsExtendedRelationship, addMedia, addRelationship, applyUpdatesToZip, collectHeaderFooterUpdates, collectHyperlinksWithoutRId, createDocx, createEmptyDocx, findMaxRId, hasModelDrivenPictureWatermark, hasUnmaterializedHeaderFooter, hasUnmaterializedInlineResources, isDocxBuffer, notePartRelsPath, removeCommentsExtendedOverride, removeCommentsExtendedRelationship, repackDocx, repackDocxFromRaw, updateCoreProperties, updateDocumentXml, updateMultipleFiles, updateXmlFile, validateDocx, withoutAttachedTemplate };
|
|
293
|
+
export { COMMENTS_CONTENT_TYPE, COMMENTS_EXTENDED_CONTENT_TYPE, COMMENTS_EXTENDED_PART, COMMENTS_EXTENDED_PART_LOWER, CanonicalImageRelationshipRefusalError, DocumentPropertiesOptions, DocxDuplicateSectionCarrierError, DocxPackageFidelityError, RepackOptions, addCommentsExtendedOverride, addCommentsExtendedRelationship, addMedia, addRelationship, applyUpdatesToZip, assertSectionCarriersMatchModel, collectHeaderFooterUpdates, collectHyperlinksWithoutRId, createDocx, createEmptyDocx, findMaxRId, hasModelDrivenPictureWatermark, hasUnmaterializedHeaderFooter, hasUnmaterializedHyperlinkBindings, hasUnmaterializedInlineResources, isDocxBuffer, notePartRelsPath, planAddedStyles, publishCanonicalImageResources, removeCommentsExtendedOverride, removeCommentsExtendedRelationship, repackDocx, repackDocxFromRaw, updateCoreProperties, updateDocumentXml, updateMultipleFiles, updateXmlFile, validateDocx, withoutAttachedTemplate };
|