@stll/folio-core 0.47.7 → 0.48.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/controller/fontReadiness.js +3 -3
- package/dist/controller/hyphenationReadiness.d.ts +19 -0
- package/dist/controller/hyphenationReadiness.js +47 -0
- package/dist/controller/layoutPipeline.d.ts +3 -0
- package/dist/controller/layoutPipeline.js +59 -17
- package/dist/display-list/build/buildDisplayList.js +39 -12
- package/dist/display-list/build/pageFurniture.d.ts +7 -1
- package/dist/display-list/build/pageFurniture.js +21 -8
- package/dist/display-list/build/paragraphPrimitives.js +5 -4
- package/dist/display-list/build/tablePrimitives.js +10 -6
- package/dist/docx/attributeRemainder.js +10 -2
- package/dist/docx/blockContentParser.d.ts +2 -0
- package/dist/docx/blockContentParser.js +77 -62
- package/dist/docx/commentParser.d.ts +2 -1
- package/dist/docx/commentParser.js +57 -45
- package/dist/docx/containerChildren.d.ts +21 -8
- package/dist/docx/containerChildren.js +39 -9
- package/dist/docx/documentParser.d.ts +5 -1
- package/dist/docx/documentParser.js +8 -5
- package/dist/docx/documentSectionFacts.d.ts +22 -0
- package/dist/docx/documentSectionFacts.js +43 -0
- package/dist/docx/fieldParser.d.ts +8 -1
- package/dist/docx/fieldParser.js +47 -3
- package/dist/docx/fontTableParser.js +34 -27
- package/dist/docx/footnoteParser.d.ts +3 -2
- package/dist/docx/footnoteParser.js +15 -12
- package/dist/docx/groupDrawingParser.d.ts +2 -1
- package/dist/docx/groupDrawingParser.js +3 -6
- package/dist/docx/headerFooterParser.d.ts +7 -2
- package/dist/docx/headerFooterParser.js +15 -5
- package/dist/docx/hyperlinkParser.d.ts +48 -36
- package/dist/docx/hyperlinkParser.js +97 -82
- package/dist/docx/numberingParser.js +108 -84
- package/dist/docx/paragraphParser.d.ts +5 -1
- package/dist/docx/paragraphParser.js +381 -362
- package/dist/docx/paragraphProperties.js +123 -109
- package/dist/docx/paragraphPropertySource.d.ts +6 -1
- package/dist/docx/paragraphPropertySource.js +9 -1
- package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
- package/dist/docx/paragraphTextBoxEnrichment.js +17 -6
- package/dist/docx/parser.d.ts +7 -1
- package/dist/docx/parser.js +33 -16
- package/dist/docx/previewBudget.d.ts +55 -33
- package/dist/docx/previewBudget.js +59 -65
- package/dist/docx/rezip.js +41 -58
- package/dist/docx/runParser.d.ts +4 -1
- package/dist/docx/runParser.js +172 -184
- package/dist/docx/sdtProperties.js +87 -84
- package/dist/docx/sectionParser.js +169 -160
- package/dist/docx/serializer/paragraphSerializer.js +42 -38
- package/dist/docx/serializer/settingsSerializer.js +19 -1
- package/dist/docx/settingsParser.js +8 -0
- package/dist/docx/streamingXmlParser.d.ts +6 -2
- package/dist/docx/streamingXmlParser.js +12 -7
- package/dist/docx/styleParser.js +34 -8
- package/dist/docx/tableParser.d.ts +21 -12
- package/dist/docx/tableParser.js +518 -441
- package/dist/docx/textBoxParser.d.ts +8 -3
- package/dist/docx/textBoxParser.js +3 -3
- package/dist/docx/verbatimCapture.d.ts +10 -8
- package/dist/docx/verbatimCapture.js +45 -2
- package/dist/docx/vmlImageParser.d.ts +15 -13
- package/dist/docx/vmlImageParser.js +75 -60
- package/dist/docx/vmlPreview.d.ts +3 -3
- package/dist/docx/vmlPreview.js +3 -4
- package/dist/docx/xmlNamespaceContext.d.ts +9 -0
- package/dist/docx/xmlNamespaceContext.js +54 -0
- package/dist/docx/xmlParser.d.ts +6 -3
- package/dist/docx/xmlParser.js +11 -41
- package/dist/docx/xmlResourceLimits.d.ts +2 -1
- package/dist/docx/xmlResourceLimits.js +4 -1
- package/dist/fonts/headlessMeasure.js +0 -0
- package/dist/headless-layout.d.ts +11 -2
- package/dist/headless-layout.js +153 -107
- package/dist/internal/paragraphFormattingSerialization.js +3 -3
- package/dist/layout-bridge/convert/endnoteLayout.d.ts +65 -0
- package/dist/layout-bridge/convert/endnoteLayout.js +227 -0
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +19 -3
- package/dist/layout-bridge/convert/footnoteLayout.js +40 -31
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -7
- package/dist/layout-bridge/convert/headerFooterLayout.js +5 -20
- package/dist/layout-bridge/convert/paragraphMarkFormatting.d.ts +10 -0
- package/dist/layout-bridge/convert/paragraphMarkFormatting.js +59 -0
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +29 -1
- package/dist/layout-bridge/convert/toFlowBlocks.js +258 -35
- package/dist/layout-bridge/engine/hitTest.js +5 -3
- package/dist/layout-bridge/engine/selectionRects.js +5 -3
- package/dist/layout-engine/anchorLayoutInCellCompatibility.d.ts +10 -0
- package/dist/layout-engine/anchorLayoutInCellCompatibility.js +22 -0
- package/dist/layout-engine/index.d.ts +2 -2
- package/dist/layout-engine/index.js +70 -11
- package/dist/layout-engine/justificationCompatibility.d.ts +1 -1
- package/dist/layout-engine/justificationCompatibility.js +9 -5
- package/dist/layout-engine/keep-together.d.ts +11 -5
- package/dist/layout-engine/keep-together.js +39 -16
- package/dist/layout-engine/layoutInstrumentation.d.ts +8 -2
- package/dist/layout-engine/layoutInstrumentation.js +8 -1
- package/dist/layout-engine/measure/advanceComposition.js +4 -7
- package/dist/layout-engine/measure/hyphenationDictionaries.d.ts +74 -0
- package/dist/layout-engine/measure/hyphenationDictionaries.js +138 -0
- package/dist/layout-engine/measure/hyphenationPreload.d.ts +11 -0
- package/dist/layout-engine/measure/hyphenationPreload.js +24 -0
- package/dist/layout-engine/measure/lineBreakProvider.d.ts +12 -2
- package/dist/layout-engine/measure/lineBreakProvider.js +30 -30
- package/dist/layout-engine/measure/lineBreaks.d.ts +6 -1
- package/dist/layout-engine/measure/lineBreaks.js +10 -3
- package/dist/layout-engine/measure/listMarkerWidth.d.ts +9 -6
- package/dist/layout-engine/measure/listMarkerWidth.js +20 -22
- package/dist/layout-engine/measure/measureBlocks.js +42 -8
- package/dist/layout-engine/measure/measureContainer.js +5 -5
- package/dist/layout-engine/measure/measureHelpers.d.ts +15 -3
- package/dist/layout-engine/measure/measureHelpers.js +21 -5
- package/dist/layout-engine/measure/measureParagraph.js +109 -30
- package/dist/layout-engine/measure/measureTypes.d.ts +5 -0
- package/dist/layout-engine/measure/tabCalculator.d.ts +2 -0
- package/dist/layout-engine/measure/tabCalculator.js +2 -1
- package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
- package/dist/layout-engine/measure/tableCellFloating.js +51 -19
- package/dist/layout-engine/measure/tableCellGrid.d.ts +28 -3
- package/dist/layout-engine/measure/tableCellGrid.js +45 -5
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
- package/dist/layout-engine/noteAreaFlow.d.ts +19 -0
- package/dist/layout-engine/noteAreaFlow.js +83 -0
- package/dist/layout-engine/paginator.d.ts +10 -1
- package/dist/layout-engine/paginator.js +13 -1
- package/dist/layout-engine/tableRowBreak.js +3 -1
- package/dist/layout-engine/types.d.ts +89 -3
- package/dist/layout-engine/types.js +96 -1
- package/dist/layout-painter/index.d.ts +3 -0
- package/dist/layout-painter/renderPage.js +32 -83
- package/dist/layout-painter/renderParagraph.d.ts +6 -1
- package/dist/layout-painter/renderParagraph.js +34 -22
- package/dist/layout-painter/renderTable.js +26 -13
- package/dist/prosemirror/attrs/index.d.ts +9 -9
- package/dist/prosemirror/attrs/index.js +43 -11
- package/dist/prosemirror/conversion/fromProseDoc.js +8 -1
- package/dist/prosemirror/conversion/markInterner.d.ts +21 -0
- package/dist/prosemirror/conversion/markInterner.js +90 -0
- package/dist/prosemirror/conversion/toProseDoc.js +77 -41
- package/dist/prosemirror/extensions/core/DocExtension.js +2 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +6 -2
- package/dist/prosemirror/extensions/marks/markUtils.js +39 -51
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +2 -1
- package/dist/prosemirror/listMarker.d.ts +1 -0
- package/dist/prosemirror/listMarker.js +2 -0
- package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
- package/dist/prosemirror/listRenderingAttrs.js +3 -0
- package/dist/prosemirror/schema/nodes.d.ts +13 -1
- package/dist/prosemirror/textBoxHostParagraph.d.ts +13 -0
- package/dist/prosemirror/textBoxHostParagraph.js +21 -0
- package/dist/prosemirror/validation.js +91 -80
- package/dist/utils/createDocument.js +10 -1
- package/dist/utils/scriptSegments.d.ts +33 -4
- package/dist/utils/scriptSegments.js +39 -6
- package/dist/utils/textFormattingMerge.d.ts +17 -3
- package/dist/utils/textFormattingMerge.js +18 -12
- package/dist/utils/trailingText.d.ts +22 -0
- package/dist/utils/trailingText.js +32 -0
- package/package.json +2 -2
|
@@ -1,28 +1,5 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
1
2
|
//#region src/docx/previewBudget.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Every synthetic preview a parse attaches to the model, and the budget each
|
|
4
|
-
* one answers to.
|
|
5
|
-
*
|
|
6
|
-
* A preview is not document content. It is a drawing folio makes up so a shape
|
|
7
|
-
* it cannot project still occupies the page, and the package round-trips from
|
|
8
|
-
* its preserved XML whether the preview exists or not. So a preview is the one
|
|
9
|
-
* thing in the model that may be dropped, and a package that would retain more
|
|
10
|
-
* of it than it is worth has it dropped rather than being refused.
|
|
11
|
-
*
|
|
12
|
-
* Producer and budget have to agree on what a preview looks like. They used to
|
|
13
|
-
* agree by coincidence: the VML producer wrote its filename as a literal and
|
|
14
|
-
* the budget recognized it as a constant in another file, so renaming one
|
|
15
|
-
* would have stopped the other charging for it without anything failing. The
|
|
16
|
-
* table below is that agreement written once, and a producer builds its image
|
|
17
|
-
* out of the entry the budget matches against.
|
|
18
|
-
*
|
|
19
|
-
* An entry says what backs the preview, because that decides what there is to
|
|
20
|
-
* agree on. A source-backed preview is image data in `src`, recognized by the
|
|
21
|
-
* strings its producer stamps on it and charged by the character. A
|
|
22
|
-
* descriptor-backed preview is no picture at all, so it carries none of those
|
|
23
|
-
* strings: a table that offered them would be offering a cap over nothing and
|
|
24
|
-
* a prefix nothing can start with.
|
|
25
|
-
*/
|
|
26
3
|
type PreviewKindName = "vmlShape" | "wpGroup" | "smartArt";
|
|
27
4
|
declare const PREVIEW_KINDS: {
|
|
28
5
|
/** A VML shape folio renders rather than projects (`v:shape`, `v:rect`, ...). */
|
|
@@ -39,9 +16,9 @@ declare const PREVIEW_KINDS: {
|
|
|
39
16
|
* The group's shapes, their text and any picture they carry are drawn into
|
|
40
17
|
* one SVG, so a package with many groups retains as much generated text as a
|
|
41
18
|
* package of VML shapes does, from a producer bounded per drawing the same
|
|
42
|
-
* way. It was missing from this table, which
|
|
43
|
-
* cap but a preview with none: the
|
|
44
|
-
* package was ever charged for one.
|
|
19
|
+
* way. It was once missing from this table, which was not a preview with a
|
|
20
|
+
* generous cap but a preview with none: the budget never recognized it, so
|
|
21
|
+
* no package was ever charged for one.
|
|
45
22
|
*/
|
|
46
23
|
readonly wpGroup: {
|
|
47
24
|
readonly backing: "source";
|
|
@@ -75,11 +52,56 @@ type SourceBackedKindName = { [Name in PreviewKindName]: (typeof PREVIEW_KINDS)[
|
|
|
75
52
|
*/
|
|
76
53
|
type PreviewBudgetOverrides = Partial<Record<SourceBackedKindName, number>>;
|
|
77
54
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
|
|
55
|
+
* Everything a preview image states except what the ledger stamps on it: its
|
|
56
|
+
* geometry, wrap, position and names. A preview has no relationship behind
|
|
57
|
+
* it, so its frame cannot name one.
|
|
58
|
+
*/
|
|
59
|
+
type PreviewFrame = Omit<document_d_exports.Image, "type" | "rId" | "src" | "mimeType" | "filename">;
|
|
60
|
+
/** The one way a producer builds a preview image. */
|
|
61
|
+
type PreviewLedger = {
|
|
62
|
+
/**
|
|
63
|
+
* Build a `kind` preview that draws `svg` over `frame`, registered against
|
|
64
|
+
* the package's allowance for that kind.
|
|
65
|
+
*/
|
|
66
|
+
readonly svgImage: (kind: SourceBackedKindName, svg: string, frame: PreviewFrame) => document_d_exports.Image;
|
|
67
|
+
/**
|
|
68
|
+
* Withdraw every preview inside content the parse built and then discarded,
|
|
69
|
+
* so it spends no allowance. Walks only `discarded`.
|
|
70
|
+
*/
|
|
71
|
+
readonly release: (discarded: unknown) => void;
|
|
72
|
+
};
|
|
73
|
+
/** One parse's ledger, and the budget that charges it. */
|
|
74
|
+
type PackagePreviewBudget = {
|
|
75
|
+
readonly ledger: PreviewLedger;
|
|
76
|
+
/**
|
|
77
|
+
* Charge every registered preview against its kind's allowance and drop the
|
|
78
|
+
* `src` of those past it. Dropping leaves the image in place with its size
|
|
79
|
+
* and wrap, so the page still reserves the space the drawing occupies, and
|
|
80
|
+
* never touches the preserved XML the package saves from.
|
|
81
|
+
*
|
|
82
|
+
* Previews are charged in the order the parse built them, which is the
|
|
83
|
+
* order it read the parts: the body (a text box's content right after the
|
|
84
|
+
* paragraph that anchors it), then headers and footers in relationship
|
|
85
|
+
* order, footnotes, endnotes, and comments last. Past an allowance, the
|
|
86
|
+
* previews built first keep their `src`.
|
|
87
|
+
*/
|
|
88
|
+
readonly enforce: (overrides?: PreviewBudgetOverrides) => void;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* One parse's previews and their budget.
|
|
92
|
+
*
|
|
93
|
+
* A parse that builds content and then discards it (a note repeating an id, a
|
|
94
|
+
* separator note, a duplicate comment, a watermark's host paragraph) releases
|
|
95
|
+
* that content, or its previews would spend allowance no retained preview can
|
|
96
|
+
* use. A missed release errs towards dropping a preview, never towards
|
|
97
|
+
* retaining more than the cap; the budget's tests pin that a package's ledger
|
|
98
|
+
* holds exactly the previews its model carries.
|
|
99
|
+
*/
|
|
100
|
+
declare const createPackagePreviewBudget: () => PackagePreviewBudget;
|
|
101
|
+
/**
|
|
102
|
+
* A ledger for a read that builds no package: one part parsed on its own,
|
|
103
|
+
* whose previews no package budget charges.
|
|
82
104
|
*/
|
|
83
|
-
declare const
|
|
105
|
+
declare const standalonePreviewLedger: () => PreviewLedger;
|
|
84
106
|
//#endregion
|
|
85
|
-
export {
|
|
107
|
+
export { PackagePreviewBudget, PreviewBudgetOverrides, PreviewLedger, createPackagePreviewBudget, standalonePreviewLedger };
|
|
@@ -21,9 +21,9 @@ const PREVIEW_KINDS = {
|
|
|
21
21
|
* The group's shapes, their text and any picture they carry are drawn into
|
|
22
22
|
* one SVG, so a package with many groups retains as much generated text as a
|
|
23
23
|
* package of VML shapes does, from a producer bounded per drawing the same
|
|
24
|
-
* way. It was missing from this table, which
|
|
25
|
-
* cap but a preview with none: the
|
|
26
|
-
* package was ever charged for one.
|
|
24
|
+
* way. It was once missing from this table, which was not a preview with a
|
|
25
|
+
* generous cap but a preview with none: the budget never recognized it, so
|
|
26
|
+
* no package was ever charged for one.
|
|
27
27
|
*/
|
|
28
28
|
wpGroup: {
|
|
29
29
|
backing: "source",
|
|
@@ -45,75 +45,69 @@ const PREVIEW_KINDS = {
|
|
|
45
45
|
*/
|
|
46
46
|
smartArt: { backing: "descriptor" }
|
|
47
47
|
};
|
|
48
|
-
const KIND_NAMES = Object.keys(PREVIEW_KINDS);
|
|
49
48
|
/**
|
|
50
|
-
*
|
|
51
|
-
* one: the predicate reads the same field `SourceBackedKindName` selects on.
|
|
52
|
-
*/
|
|
53
|
-
const isSourceBacked = (name) => {
|
|
54
|
-
const kind = PREVIEW_KINDS[name];
|
|
55
|
-
switch (kind.backing) {
|
|
56
|
-
case "source": return true;
|
|
57
|
-
case "descriptor": return false;
|
|
58
|
-
default: return kind;
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
const SOURCE_BACKED_KIND_NAMES = KIND_NAMES.filter(isSourceBacked);
|
|
62
|
-
/**
|
|
63
|
-
* The kind a model image was generated as, or `undefined` for one the package
|
|
64
|
-
* actually carries. A generated preview has no relationship behind it; the
|
|
65
|
-
* filename and data-URL prefix name which producer made it.
|
|
66
|
-
*
|
|
67
|
-
* "No relationship" is read as the one spelling `RelationshipId` leaves: a
|
|
68
|
-
* field that is absent or `undefined`. The walk takes an unvalidated object,
|
|
69
|
-
* so the check stays, but it no longer has a second spelling to accept.
|
|
49
|
+
* One parse's previews and their budget.
|
|
70
50
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return SOURCE_BACKED_KIND_NAMES.find((name) => {
|
|
78
|
-
const kind = PREVIEW_KINDS[name];
|
|
79
|
-
return mimeType === kind.mimeType && filename === kind.filename && src.startsWith(kind.srcPrefix);
|
|
80
|
-
});
|
|
81
|
-
};
|
|
82
|
-
/**
|
|
83
|
-
* Charge every generated preview in the model against its kind's allowance and
|
|
84
|
-
* drop the `src` of those past it. Dropping leaves the image in place with its
|
|
85
|
-
* size and wrap, so the page still reserves the space the drawing occupies,
|
|
86
|
-
* and never touches the preserved XML the package saves from.
|
|
51
|
+
* A parse that builds content and then discards it (a note repeating an id, a
|
|
52
|
+
* separator note, a duplicate comment, a watermark's host paragraph) releases
|
|
53
|
+
* that content, or its previews would spend allowance no retained preview can
|
|
54
|
+
* use. A missed release errs towards dropping a preview, never towards
|
|
55
|
+
* retaining more than the cap; the budget's tests pin that a package's ledger
|
|
56
|
+
* holds exactly the previews its model carries.
|
|
87
57
|
*/
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (value
|
|
96
|
-
|
|
58
|
+
const createPackagePreviewBudget = () => {
|
|
59
|
+
const entries = [];
|
|
60
|
+
const registered = /* @__PURE__ */ new WeakSet();
|
|
61
|
+
const released = /* @__PURE__ */ new WeakSet();
|
|
62
|
+
const release = (value, seen) => {
|
|
63
|
+
if (value === null || typeof value !== "object" || seen.has(value) || value instanceof ArrayBuffer || ArrayBuffer.isView(value)) return;
|
|
64
|
+
seen.add(value);
|
|
65
|
+
if (registered.has(value)) {
|
|
66
|
+
released.add(value);
|
|
97
67
|
return;
|
|
98
68
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
69
|
+
for (const child of value instanceof Map ? value.values() : Object.values(value)) release(child, seen);
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
ledger: {
|
|
73
|
+
svgImage: (kind, svg, frame) => {
|
|
74
|
+
const { srcPrefix, mimeType, filename } = PREVIEW_KINDS[kind];
|
|
75
|
+
const image = {
|
|
76
|
+
type: "image",
|
|
77
|
+
src: `${srcPrefix}${encodeURIComponent(svg)}`,
|
|
78
|
+
mimeType,
|
|
79
|
+
filename,
|
|
80
|
+
...frame
|
|
81
|
+
};
|
|
82
|
+
entries.push({
|
|
83
|
+
kind,
|
|
84
|
+
image
|
|
85
|
+
});
|
|
86
|
+
registered.add(image);
|
|
87
|
+
return image;
|
|
88
|
+
},
|
|
89
|
+
release: (discarded) => {
|
|
90
|
+
release(discarded, /* @__PURE__ */ new WeakSet());
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
enforce: (overrides = {}) => {
|
|
94
|
+
const remaining = /* @__PURE__ */ new Map();
|
|
95
|
+
for (const { kind, image } of entries) {
|
|
96
|
+
if (image.src === void 0 || released.has(image)) continue;
|
|
97
|
+
const left = remaining.get(kind) ?? Math.max(0, overrides[kind] ?? PREVIEW_KINDS[kind].maxPackageCharacters);
|
|
98
|
+
if (image.src.length <= left) remaining.set(kind, left - image.src.length);
|
|
99
|
+
else {
|
|
100
|
+
remaining.set(kind, 0);
|
|
101
|
+
delete image.src;
|
|
102
|
+
}
|
|
112
103
|
}
|
|
113
104
|
}
|
|
114
|
-
for (const child of Object.values(value)) visit(child);
|
|
115
105
|
};
|
|
116
|
-
visit(root);
|
|
117
106
|
};
|
|
107
|
+
/**
|
|
108
|
+
* A ledger for a read that builds no package: one part parsed on its own,
|
|
109
|
+
* whose previews no package budget charges.
|
|
110
|
+
*/
|
|
111
|
+
const standalonePreviewLedger = () => createPackagePreviewBudget().ledger;
|
|
118
112
|
//#endregion
|
|
119
|
-
export {
|
|
113
|
+
export { createPackagePreviewBudget, standalonePreviewLedger };
|
package/dist/docx/rezip.js
CHANGED
|
@@ -4,10 +4,10 @@ import { isAllowedExternalWatermarkImageUrl } from "../watermark/index.js";
|
|
|
4
4
|
import { appVersionInSchemaForm, normalizeAppVersionInExtendedProperties } from "./appVersionNormalization.js";
|
|
5
5
|
import { withoutOrphanCommentRanges } from "./commentRangeIntegrity.js";
|
|
6
6
|
import { applyReplyThreadMarkers } from "./commentReplyMarkers.js";
|
|
7
|
+
import { readDocumentSectionFacts } from "./documentSectionFacts.js";
|
|
7
8
|
import { normalizeDrawingIds } from "./drawingIdNormalization.js";
|
|
8
9
|
import { rebindDrawingImageRelationship } from "./drawingRelationships.js";
|
|
9
10
|
import { parseEndnotes, parseFootnotes } from "./footnoteParser.js";
|
|
10
|
-
import { parseHeaderFooterType } from "./headerFooterRefParser.js";
|
|
11
11
|
import { assertValidFolioDocumentModel } from "./modelValidation.js";
|
|
12
12
|
import { isNewDataUrlDrawing } from "./newImage.js";
|
|
13
13
|
import { missingNoteReferenceStyles, noteReferenceNeeds } from "./noteReferenceStyles.js";
|
|
@@ -30,8 +30,7 @@ import { readRootNamespaceBindings } from "./serializer/partNamespaces.js";
|
|
|
30
30
|
import { serializeSettingsXml } from "./serializer/settingsSerializer.js";
|
|
31
31
|
import { serializeStyle, serializeStylesXml } from "./serializer/stylesSerializer.js";
|
|
32
32
|
import { serializeThemeXml } from "./serializer/themeSerializer.js";
|
|
33
|
-
import {
|
|
34
|
-
import { assertXmlResourceLimits } from "./xmlResourceLimits.js";
|
|
33
|
+
import { WORDPROCESSINGML_NAMESPACE_URIS, findChild, findChildByNamespaceUri, findChildrenByNamespaceUri, getAttribute, getAttributeByNamespaceUri, getChildElements, getLocalName, getNamespaceUri, matchesName, parseXml, parseXmlDocument } from "./xmlParser.js";
|
|
35
34
|
import { TaggedError, panic } from "better-result";
|
|
36
35
|
import { escapeXmlAttribute, escapeXmlText, validateDocxPackage } from "@stll/docx-core";
|
|
37
36
|
import { mintRelationshipId } from "@stll/docx-core/model";
|
|
@@ -108,47 +107,6 @@ function findMaxRId(relsXml) {
|
|
|
108
107
|
}
|
|
109
108
|
return maxId;
|
|
110
109
|
}
|
|
111
|
-
const isWordprocessingElement = (element, localName) => getLocalName(element.name) === localName && WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(element) ?? "");
|
|
112
|
-
const countDocumentSections = (xml) => {
|
|
113
|
-
assertXmlResourceLimits({ xml });
|
|
114
|
-
let count = 0;
|
|
115
|
-
const pending = [{
|
|
116
|
-
element: parseXml(xml),
|
|
117
|
-
insidePropertyChange: false
|
|
118
|
-
}];
|
|
119
|
-
while (pending.length > 0) {
|
|
120
|
-
const current = pending.pop();
|
|
121
|
-
if (!current) break;
|
|
122
|
-
const { element, insidePropertyChange } = current;
|
|
123
|
-
const isPropertyChange = isWordprocessingElement(element, "sectPrChange");
|
|
124
|
-
if (!insidePropertyChange && isWordprocessingElement(element, "sectPr")) count += 1;
|
|
125
|
-
for (const child of getChildElements(element)) pending.push({
|
|
126
|
-
element: child,
|
|
127
|
-
insidePropertyChange: insidePropertyChange || isPropertyChange
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
return count;
|
|
131
|
-
};
|
|
132
|
-
const extractHeaderFooterReferences = (xml) => {
|
|
133
|
-
const references = [];
|
|
134
|
-
assertXmlResourceLimits({ xml });
|
|
135
|
-
const pending = [parseXml(xml)];
|
|
136
|
-
while (pending.length > 0) {
|
|
137
|
-
const node = pending.pop();
|
|
138
|
-
if (!node) break;
|
|
139
|
-
const element = getLocalName(node.name);
|
|
140
|
-
if ((element === "headerReference" || element === "footerReference") && isWordprocessingElement(node, element)) {
|
|
141
|
-
const rId = getAttributeByNamespaceUri(node, OFFICE_RELATIONSHIP_NAMESPACE_URIS, "id");
|
|
142
|
-
if (rId) references.push({
|
|
143
|
-
element,
|
|
144
|
-
type: parseHeaderFooterType(getAttributeByNamespaceUri(node, WORDPROCESSINGML_NAMESPACE_URIS, "type")),
|
|
145
|
-
rId
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
pending.push(...getChildElements(node));
|
|
149
|
-
}
|
|
150
|
-
return references;
|
|
151
|
-
};
|
|
152
110
|
const hasParsedHeaderFooterPart = (doc, ref) => {
|
|
153
111
|
return (ref.element === "headerReference" ? doc.package.headers : doc.package.footers)?.has(ref.rId) ?? false;
|
|
154
112
|
};
|
|
@@ -201,9 +159,10 @@ const assertSectionCarriersMatchModel = ({ doc, serializedSectionCount }) => {
|
|
|
201
159
|
const modelSectionCount = carriers.length + (finalSectionProperties === void 0 ? 0 : 1);
|
|
202
160
|
if (serializedSectionCount !== modelSectionCount) throw new DocxPackageFidelityError(`Full DOCX repack would write ${serializedSectionCount} sections where the editor holds ${modelSectionCount}.`);
|
|
203
161
|
};
|
|
204
|
-
function assertDocumentPackageFidelity({
|
|
205
|
-
const
|
|
206
|
-
const
|
|
162
|
+
function assertDocumentPackageFidelity({ originalDocumentFacts, serializedDocumentXml, doc, sectionEndpointRemoval, sectionReferenceRemovals = [] }) {
|
|
163
|
+
const serializedDocumentFacts = readDocumentSectionFacts(serializedDocumentXml);
|
|
164
|
+
const originalSectionCount = originalDocumentFacts.sectionCount;
|
|
165
|
+
const serializedSectionCount = serializedDocumentFacts.sectionCount;
|
|
207
166
|
const trackedRemovedSectionCount = sectionEndpointRemoval ? sectionEndpointRemoval.sourceParagraphEndpointCount - sectionEndpointRemoval.expectedParagraphEndpointCount : 0;
|
|
208
167
|
const exactTrackedSectionRemoval = trackedRemovedSectionCount > 0 && originalSectionCount - trackedRemovedSectionCount === serializedSectionCount && serializedSectionCount < originalSectionCount;
|
|
209
168
|
if (serializedSectionCount < originalSectionCount && !exactTrackedSectionRemoval) throw new DocxPackageFidelityError("Full DOCX repack would drop section properties. Use selective patching instead.");
|
|
@@ -212,14 +171,14 @@ function assertDocumentPackageFidelity({ originalDocumentXml, serializedDocument
|
|
|
212
171
|
serializedSectionCount
|
|
213
172
|
});
|
|
214
173
|
const serializedReferenceCounts = /* @__PURE__ */ new Map();
|
|
215
|
-
for (const reference of
|
|
174
|
+
for (const reference of serializedDocumentFacts.headerFooterReferences) incrementReferenceCount(serializedReferenceCounts, headerFooterReferenceKey(reference));
|
|
216
175
|
const removedReferenceCounts = /* @__PURE__ */ new Map();
|
|
217
176
|
if (exactTrackedSectionRemoval && sectionEndpointRemoval) for (const { part, type, relationshipId } of sectionEndpointRemoval.removedReferences) incrementReferenceCount(removedReferenceCounts, `${part}Reference:${type}:${relationshipId}`);
|
|
218
177
|
const resolvedReferenceCounts = /* @__PURE__ */ new Map();
|
|
219
178
|
for (const { part, type, relationshipId } of sectionReferenceRemovals) incrementReferenceCount(resolvedReferenceCounts, `${part}Reference:${type}:${relationshipId}`);
|
|
220
179
|
for (const [key, count] of resolvedReferenceCounts) removedReferenceCounts.set(key, Math.max(count, removedReferenceCounts.get(key) ?? 0));
|
|
221
180
|
const missingRefs = [];
|
|
222
|
-
for (const reference of
|
|
181
|
+
for (const reference of originalDocumentFacts.headerFooterReferences) {
|
|
223
182
|
if (!hasParsedHeaderFooterPart(doc, reference)) continue;
|
|
224
183
|
const key = headerFooterReferenceKey(reference);
|
|
225
184
|
if (consumeReferenceCount(serializedReferenceCounts, key) || consumeReferenceCount(removedReferenceCounts, key)) continue;
|
|
@@ -614,6 +573,30 @@ const generateDocxZip = async (zip, compressionLevel) => {
|
|
|
614
573
|
compressionOptions: { level: compressionLevel }
|
|
615
574
|
});
|
|
616
575
|
};
|
|
576
|
+
/**
|
|
577
|
+
* Section facts of each source package's `word/document.xml`, keyed by the
|
|
578
|
+
* source buffer. Hosts save repeatedly against one baseline buffer, often
|
|
579
|
+
* through a fresh `Document` each time, so the buffer is the identity that
|
|
580
|
+
* survives between saves. The facts are reused only while the part read from
|
|
581
|
+
* it is still the same string, so a buffer rewritten in place is read again.
|
|
582
|
+
*/
|
|
583
|
+
const sourceDocumentSectionFacts = /* @__PURE__ */ new WeakMap();
|
|
584
|
+
const originalDocumentPart = (buffer, xml) => {
|
|
585
|
+
if (xml === void 0) return;
|
|
586
|
+
return {
|
|
587
|
+
xml,
|
|
588
|
+
sectionFacts: () => {
|
|
589
|
+
const cached = sourceDocumentSectionFacts.get(buffer);
|
|
590
|
+
if (cached?.xml === xml) return cached.facts;
|
|
591
|
+
const facts = readDocumentSectionFacts(xml);
|
|
592
|
+
sourceDocumentSectionFacts.set(buffer, {
|
|
593
|
+
xml,
|
|
594
|
+
facts
|
|
595
|
+
});
|
|
596
|
+
return facts;
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
};
|
|
617
600
|
const parsedZipSources = /* @__PURE__ */ new WeakMap();
|
|
618
601
|
const loadParsedZipSource = async (document, buffer) => {
|
|
619
602
|
const cached = parsedZipSources.get(document);
|
|
@@ -624,7 +607,7 @@ const loadParsedZipSource = async (document, buffer) => {
|
|
|
624
607
|
const source = {
|
|
625
608
|
buffer,
|
|
626
609
|
zip,
|
|
627
|
-
documentXml,
|
|
610
|
+
document: originalDocumentPart(buffer, documentXml),
|
|
628
611
|
corePropertiesXml
|
|
629
612
|
};
|
|
630
613
|
parsedZipSources.set(document, source);
|
|
@@ -644,7 +627,7 @@ const normalizeExportDrawingIds = ({ package: docxPackage }) => {
|
|
|
644
627
|
...docxPackage.endnotes !== void 0 ? { endnotes: docxPackage.endnotes } : {}
|
|
645
628
|
});
|
|
646
629
|
};
|
|
647
|
-
const finishRepack = async ({ document, originalZip, outputZip,
|
|
630
|
+
const finishRepack = async ({ document, originalZip, outputZip, originalDocument, originalCorePropertiesXml, compressionLevel, updateModifiedDate, modifiedBy, changedNoteParaIds, sectionEndpointRemoval, sectionReferenceRemovals }) => {
|
|
648
631
|
await materializeNewHeaderFooterParts(document, outputZip, compressionLevel);
|
|
649
632
|
await materializeEmbeddedMedia({
|
|
650
633
|
document,
|
|
@@ -657,9 +640,9 @@ const finishRepack = async ({ document, originalZip, outputZip, originalDocument
|
|
|
657
640
|
await processNewHyperlinks(parts, outputZip, compressionLevel);
|
|
658
641
|
assertValidFolioDocumentModel(document, "Cannot repack invalid DOCX document model");
|
|
659
642
|
applyReplyThreadMarkers(document);
|
|
660
|
-
const documentXml = serializeDocument(document,
|
|
661
|
-
if (
|
|
662
|
-
|
|
643
|
+
const documentXml = serializeDocument(document, originalDocument === void 0 ? void 0 : readRootNamespaceBindings(originalDocument.xml));
|
|
644
|
+
if (originalDocument?.xml) assertDocumentPackageFidelity({
|
|
645
|
+
originalDocumentFacts: originalDocument.sectionFacts(),
|
|
663
646
|
serializedDocumentXml: documentXml,
|
|
664
647
|
doc: document,
|
|
665
648
|
...sectionEndpointRemoval !== void 0 && { sectionEndpointRemoval },
|
|
@@ -712,7 +695,7 @@ async function repackDocxWithSectionEndpointRemoval({ document: doc, options, se
|
|
|
712
695
|
document: exportDocument,
|
|
713
696
|
originalZip,
|
|
714
697
|
outputZip: newZip,
|
|
715
|
-
originalDocumentXml,
|
|
698
|
+
originalDocument: originalDocumentPart(doc.originalBuffer, originalDocumentXml),
|
|
716
699
|
originalCorePropertiesXml,
|
|
717
700
|
compressionLevel,
|
|
718
701
|
updateModifiedDate,
|
|
@@ -770,7 +753,7 @@ async function repackDocxFromRaw(doc, rawContent, options = {}) {
|
|
|
770
753
|
applyReplyThreadMarkers(exportDocument);
|
|
771
754
|
const documentXml = serializeDocument(exportDocument, rawContent.documentXml ? readRootNamespaceBindings(rawContent.documentXml) : void 0);
|
|
772
755
|
if (rawContent.documentXml) assertDocumentPackageFidelity({
|
|
773
|
-
|
|
756
|
+
originalDocumentFacts: readDocumentSectionFacts(rawContent.documentXml),
|
|
774
757
|
serializedDocumentXml: documentXml,
|
|
775
758
|
doc: exportDocument
|
|
776
759
|
});
|
|
@@ -1790,7 +1773,7 @@ async function createDocx(doc, properties = {}) {
|
|
|
1790
1773
|
document: withoutOrphanCommentRanges(doc),
|
|
1791
1774
|
originalZip: source.zip,
|
|
1792
1775
|
outputZip: cloneDocxZip(source.zip),
|
|
1793
|
-
|
|
1776
|
+
originalDocument: source.document,
|
|
1794
1777
|
originalCorePropertiesXml: source.corePropertiesXml,
|
|
1795
1778
|
compressionLevel: 6,
|
|
1796
1779
|
updateModifiedDate: true
|
|
@@ -1801,7 +1784,7 @@ async function createDocx(doc, properties = {}) {
|
|
|
1801
1784
|
document: withoutOrphanCommentRanges(doc),
|
|
1802
1785
|
originalZip: zip,
|
|
1803
1786
|
outputZip: zip,
|
|
1804
|
-
|
|
1787
|
+
originalDocument: void 0,
|
|
1805
1788
|
originalCorePropertiesXml: await zip.file("docProps/core.xml")?.async("text"),
|
|
1806
1789
|
compressionLevel: 6,
|
|
1807
1790
|
updateModifiedDate: true
|
package/dist/docx/runParser.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
import { XmlElement } from "./xmlParser.js";
|
|
3
|
+
import { PreviewLedger } from "./previewBudget.js";
|
|
3
4
|
import { StyleMap } from "./styleParser.js";
|
|
4
5
|
//#region src/docx/runParser.d.ts
|
|
5
6
|
/**
|
|
@@ -71,9 +72,11 @@ declare function parseRunProperties(rPr: XmlElement | null, theme: document_d_ex
|
|
|
71
72
|
* @param theme - Theme for resolving theme colors/fonts
|
|
72
73
|
* @param rels - Relationship map for resolving image references
|
|
73
74
|
* @param media - Media files map for image data
|
|
75
|
+
* @param previews - The ledger of the package this run belongs to; a run read
|
|
76
|
+
* on its own charges its previews to no package
|
|
74
77
|
* @returns Parsed Run object
|
|
75
78
|
*/
|
|
76
|
-
declare function parseRun(node: XmlElement, _styles: StyleMap | null, theme: document_d_exports.Theme | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null, rootXmlns?: Record<string, string
|
|
79
|
+
declare function parseRun(node: XmlElement, _styles: StyleMap | null, theme: document_d_exports.Theme | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null, rootXmlns?: Record<string, string>, previews?: PreviewLedger): document_d_exports.Run;
|
|
77
80
|
/**
|
|
78
81
|
* Get plain text from a run
|
|
79
82
|
*
|