@stll/folio-core 0.47.7 → 0.49.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 +565 -121
- package/dist/ai-edits/minimal-replacement.d.ts +64 -0
- package/dist/ai-edits/minimal-replacement.js +282 -0
- 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 +70 -18
- 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 +68 -11
- package/dist/display-list/build/tablePrimitives.js +10 -6
- package/dist/display-list/build/textBoxPrimitives.js +1 -1
- package/dist/display-list/build/unsupported.d.ts +2 -2
- package/dist/display-list/build/unsupported.js +0 -0
- package/dist/display-list/dom/renderDisplayListToDom.js +0 -1
- package/dist/docx/attributeRemainder.js +10 -2
- package/dist/docx/blockContentParser.d.ts +2 -0
- package/dist/docx/blockContentParser.js +79 -64
- package/dist/docx/bulletMarkers.d.ts +18 -2
- package/dist/docx/bulletMarkers.js +27 -2
- 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/drawingGroupChildren.d.ts +60 -0
- package/dist/docx/drawingGroupChildren.js +176 -0
- package/dist/docx/drawingUtils.js +3 -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 +9 -2
- package/dist/docx/groupDrawingParser.js +125 -37
- 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/packageParts.d.ts +45 -1
- package/dist/docx/packageParts.js +93 -2
- package/dist/docx/paraIdAttribute.d.ts +3 -2
- package/dist/docx/paragraphParser.d.ts +5 -1
- package/dist/docx/paragraphParser.js +468 -365
- 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 +143 -10
- 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 +182 -184
- package/dist/docx/sdtProperties.js +87 -84
- package/dist/docx/sectionParser.js +169 -160
- package/dist/docx/selectiveSaveFlags.d.ts +10 -3
- package/dist/docx/selectiveSaveFlags.js +1 -1
- package/dist/docx/selectiveXmlPatch.d.ts +56 -34
- package/dist/docx/selectiveXmlPatch.js +222 -115
- package/dist/docx/serializer/groupTextBoxWriteBack.d.ts +12 -0
- package/dist/docx/serializer/groupTextBoxWriteBack.js +101 -0
- package/dist/docx/serializer/paragraphSerializer.js +47 -42
- package/dist/docx/serializer/runSerializer.d.ts +5 -1
- package/dist/docx/serializer/runSerializer.js +4 -3
- package/dist/docx/serializer/settingsSerializer.js +19 -1
- package/dist/docx/settingsParser.js +8 -0
- package/dist/docx/shapeAlternateContent.d.ts +25 -0
- package/dist/docx/shapeAlternateContent.js +52 -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 +18 -5
- package/dist/docx/textBoxParser.js +12 -6
- 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/headlessRevisionResolution.js +50 -13
- 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 +284 -39
- 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 +102 -14
- 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 +15 -6
- package/dist/layout-engine/keep-together.js +43 -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 +50 -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 +46 -10
- package/dist/layout-engine/measure/measureContainer.js +51 -8
- package/dist/layout-engine/measure/measureHelpers.d.ts +15 -3
- package/dist/layout-engine/measure/measureHelpers.js +34 -8
- package/dist/layout-engine/measure/measureParagraph.js +143 -101
- package/dist/layout-engine/measure/measureTypes.d.ts +5 -0
- package/dist/layout-engine/measure/smallCapsCasing.d.ts +56 -0
- package/dist/layout-engine/measure/smallCapsCasing.js +88 -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 +12 -1
- package/dist/layout-engine/paginator.js +18 -2
- package/dist/layout-engine/paragraphSpacing.d.ts +4 -2
- package/dist/layout-engine/paragraphSpacing.js +2 -1
- package/dist/layout-engine/tableRowBreak.d.ts +8 -1
- package/dist/layout-engine/tableRowBreak.js +25 -2
- package/dist/layout-engine/types.d.ts +108 -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 +75 -26
- package/dist/layout-painter/renderTable.js +26 -13
- package/dist/layout-painter/renderTextBox.d.ts +12 -2
- package/dist/layout-painter/renderTextBox.js +26 -2
- package/dist/prosemirror/alternateContentAttrs.d.ts +9 -0
- package/dist/prosemirror/alternateContentAttrs.js +35 -0
- package/dist/prosemirror/attrs/index.d.ts +9 -9
- package/dist/prosemirror/attrs/index.js +133 -11
- package/dist/prosemirror/commands/comments.js +51 -41
- package/dist/prosemirror/contentControlRevisions.d.ts +43 -0
- package/dist/prosemirror/contentControlRevisions.js +84 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +54 -23
- package/dist/prosemirror/conversion/markInterner.d.ts +21 -0
- package/dist/prosemirror/conversion/markInterner.js +90 -0
- package/dist/prosemirror/conversion/toProseDoc.js +117 -58
- package/dist/prosemirror/extensions/core/DocExtension.js +2 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.d.ts +7 -7
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -7
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +6 -2
- package/dist/prosemirror/extensions/marks/markUtils.js +39 -51
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +6 -3
- package/dist/prosemirror/extensions/nodes/SdtExtension.js +9 -2
- package/dist/prosemirror/extensions/nodes/ShapeExtension.js +1 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +5 -1
- package/dist/prosemirror/listMarker.d.ts +1 -0
- package/dist/prosemirror/listMarker.js +4 -2
- package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
- package/dist/prosemirror/listRenderingAttrs.js +3 -0
- package/dist/prosemirror/paragraphDirection.d.ts +29 -2
- package/dist/prosemirror/paragraphDirection.js +21 -2
- package/dist/prosemirror/plugins/suggestionMode.js +37 -8
- package/dist/prosemirror/rejoinRunCarriers.d.ts +27 -0
- package/dist/prosemirror/rejoinRunCarriers.js +66 -0
- package/dist/prosemirror/runIdentityAcrossRevisions.d.ts +10 -0
- package/dist/prosemirror/runIdentityAcrossRevisions.js +90 -0
- package/dist/prosemirror/schema/nodes.d.ts +50 -6
- package/dist/prosemirror/textBoxHostParagraph.d.ts +13 -0
- package/dist/prosemirror/textBoxHostParagraph.js +21 -0
- package/dist/prosemirror/validation.js +91 -80
- package/dist/types/content.d.ts +2 -2
- 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
- package/dist/layout-engine/justifiedLineFit.d.ts +0 -7
- package/dist/layout-engine/justifiedLineFit.js +0 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NO_MODELLED_ATTRIBUTES, attributeRemainder } from "./attributeRemainder.js";
|
|
2
2
|
import { parseBorderSpec } from "./borderParser.js";
|
|
3
|
-
import { CAPTURE,
|
|
3
|
+
import { CAPTURE, dispatchChildrenWithContext, keptUnless, sequencePositions } from "./containerChildren.js";
|
|
4
4
|
import { parseFooterReference, parseHeaderReference } from "./headerFooterRefParser.js";
|
|
5
5
|
import { parseEndnoteProperties, parseFootnoteProperties } from "./notePropertiesParser.js";
|
|
6
6
|
import { NumberFormatSchema, TextDirectionSchema, narrowEnum } from "./parserEnums.js";
|
|
@@ -67,6 +67,165 @@ function parseLineNumberRestart(restart) {
|
|
|
67
67
|
default: return;
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
+
const SECTION_PROPERTY_HANDLERS = {
|
|
71
|
+
headerReference: (child, { headerRefs, context }) => {
|
|
72
|
+
const reference = parseHeaderReference(child, context);
|
|
73
|
+
if (reference) headerRefs.push(reference);
|
|
74
|
+
},
|
|
75
|
+
footerReference: (child, { footerRefs, context }) => {
|
|
76
|
+
const reference = parseFooterReference(child, context);
|
|
77
|
+
if (reference) footerRefs.push(reference);
|
|
78
|
+
},
|
|
79
|
+
footnotePr: (child, { props }) => {
|
|
80
|
+
const footnotePr = parseFootnoteProperties(child);
|
|
81
|
+
if (Object.keys(footnotePr).length > 0) {
|
|
82
|
+
props.footnotePr = footnotePr;
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
return CAPTURE;
|
|
86
|
+
},
|
|
87
|
+
endnotePr: (child, { props }) => {
|
|
88
|
+
const endnotePr = parseEndnoteProperties(child);
|
|
89
|
+
if (Object.keys(endnotePr).length > 0) {
|
|
90
|
+
props.endnotePr = endnotePr;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
return CAPTURE;
|
|
94
|
+
},
|
|
95
|
+
type: (child, { props }) => {
|
|
96
|
+
const sectionStart = parseSectionStart(getAttribute(child, "w", "val"));
|
|
97
|
+
if (sectionStart) props.sectionStart = sectionStart;
|
|
98
|
+
return keptUnless(sectionStart !== void 0);
|
|
99
|
+
},
|
|
100
|
+
pgSz: (child, { props }) => {
|
|
101
|
+
const width = parseNumericAttribute(child, "w", "w");
|
|
102
|
+
if (width !== void 0) props.pageWidth = Math.min(width, MAX_PAGE_DIMENSION_TWIPS);
|
|
103
|
+
const height = parseNumericAttribute(child, "w", "h");
|
|
104
|
+
if (height !== void 0) props.pageHeight = Math.min(height, MAX_PAGE_DIMENSION_TWIPS);
|
|
105
|
+
const orientation = parseOrientation(getAttribute(child, "w", "orient"));
|
|
106
|
+
if (orientation) props.orientation = orientation;
|
|
107
|
+
return keptUnless(width !== void 0 || height !== void 0 || orientation !== void 0);
|
|
108
|
+
},
|
|
109
|
+
pgMar: (child, { props }) => {
|
|
110
|
+
const margins = [
|
|
111
|
+
["top", "marginTop"],
|
|
112
|
+
["bottom", "marginBottom"],
|
|
113
|
+
["left", "marginLeft"],
|
|
114
|
+
["right", "marginRight"],
|
|
115
|
+
["header", "headerDistance"],
|
|
116
|
+
["footer", "footerDistance"],
|
|
117
|
+
["gutter", "gutter"]
|
|
118
|
+
];
|
|
119
|
+
let taken = false;
|
|
120
|
+
for (const [attribute, field] of margins) {
|
|
121
|
+
const value = parseNumericAttribute(child, "w", attribute);
|
|
122
|
+
if (value !== void 0) {
|
|
123
|
+
props[field] = value;
|
|
124
|
+
taken = true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return keptUnless(taken);
|
|
128
|
+
},
|
|
129
|
+
paperSrc: (child, { props }) => {
|
|
130
|
+
const first = parseNumericAttribute(child, "w", "first");
|
|
131
|
+
if (first !== void 0) props.paperSrcFirst = first;
|
|
132
|
+
const other = parseNumericAttribute(child, "w", "other");
|
|
133
|
+
if (other !== void 0) props.paperSrcOther = other;
|
|
134
|
+
return keptUnless(first !== void 0 || other !== void 0);
|
|
135
|
+
},
|
|
136
|
+
pgBorders: (child, { props, context }) => keptUnless(readPageBorders(props, child, context)),
|
|
137
|
+
lnNumType: (child, { props }) => {
|
|
138
|
+
const lineNumbers = {};
|
|
139
|
+
for (const [attribute, field] of [
|
|
140
|
+
["start", "start"],
|
|
141
|
+
["countBy", "countBy"],
|
|
142
|
+
["distance", "distance"]
|
|
143
|
+
]) {
|
|
144
|
+
const value = parseNumericAttribute(child, "w", attribute);
|
|
145
|
+
if (value !== void 0) lineNumbers[field] = value;
|
|
146
|
+
}
|
|
147
|
+
const restart = parseLineNumberRestart(getAttribute(child, "w", "restart"));
|
|
148
|
+
if (restart) lineNumbers.restart = restart;
|
|
149
|
+
if (Object.keys(lineNumbers).length === 0) return CAPTURE;
|
|
150
|
+
props.lineNumbers = lineNumbers;
|
|
151
|
+
},
|
|
152
|
+
pgNumType: (child, { props }) => {
|
|
153
|
+
const pageNumbering = {};
|
|
154
|
+
const format = narrowEnum(getAttribute(child, "w", "fmt"), NumberFormatSchema);
|
|
155
|
+
if (format) pageNumbering.format = format;
|
|
156
|
+
const start = parseNumericAttribute(child, "w", "start");
|
|
157
|
+
if (start !== void 0) pageNumbering.start = start;
|
|
158
|
+
const chapterStyle = parseNumericAttribute(child, "w", "chapStyle");
|
|
159
|
+
if (chapterStyle !== void 0) pageNumbering.chapterStyle = chapterStyle;
|
|
160
|
+
const chapterSeparator = getAttribute(child, "w", "chapSep");
|
|
161
|
+
if (chapterSeparator) pageNumbering.chapterSeparator = chapterSeparator;
|
|
162
|
+
if (Object.keys(pageNumbering).length === 0) return CAPTURE;
|
|
163
|
+
props.pageNumbering = pageNumbering;
|
|
164
|
+
},
|
|
165
|
+
cols: (child, { props }) => keptUnless(readColumns(props, child)),
|
|
166
|
+
formProt: (child, { props, context }) => {
|
|
167
|
+
props.formProtection = parseBooleanElement(child, "w", context);
|
|
168
|
+
},
|
|
169
|
+
vAlign: (child, { props }) => {
|
|
170
|
+
const verticalAlign = parseVerticalAlign(getAttribute(child, "w", "val"));
|
|
171
|
+
if (verticalAlign) props.verticalAlign = verticalAlign;
|
|
172
|
+
return keptUnless(verticalAlign !== void 0);
|
|
173
|
+
},
|
|
174
|
+
noEndnote: (child, { props, context }) => {
|
|
175
|
+
props.noEndnote = parseBooleanElement(child, "w", context);
|
|
176
|
+
},
|
|
177
|
+
titlePg: (child, { props, context }) => {
|
|
178
|
+
props.titlePg = parseBooleanElement(child, "w", context);
|
|
179
|
+
},
|
|
180
|
+
textDirection: (child, { props }) => {
|
|
181
|
+
const textDirection = narrowEnum(getAttribute(child, "w", "val"), TextDirectionSchema);
|
|
182
|
+
if (textDirection) props.textDirection = textDirection;
|
|
183
|
+
return keptUnless(textDirection !== void 0);
|
|
184
|
+
},
|
|
185
|
+
bidi: (child, { props, context }) => {
|
|
186
|
+
props.bidi = parseBooleanElement(child, "w", context);
|
|
187
|
+
},
|
|
188
|
+
rtlGutter: (child, { props, context }) => {
|
|
189
|
+
props.rtlGutter = parseBooleanElement(child, "w", context);
|
|
190
|
+
},
|
|
191
|
+
docGrid: (child, { props }) => {
|
|
192
|
+
const docGrid = {};
|
|
193
|
+
const gridType = getAttribute(child, "w", "type");
|
|
194
|
+
if (gridType === "default" || gridType === "lines" || gridType === "linesAndChars" || gridType === "snapToChars") docGrid.type = gridType;
|
|
195
|
+
const linePitch = parseNumericAttribute(child, "w", "linePitch");
|
|
196
|
+
if (linePitch !== void 0) docGrid.linePitch = linePitch;
|
|
197
|
+
const charSpace = parseNumericAttribute(child, "w", "charSpace");
|
|
198
|
+
if (charSpace !== void 0) docGrid.charSpace = charSpace;
|
|
199
|
+
props.docGrid = docGrid;
|
|
200
|
+
},
|
|
201
|
+
printerSettings: (child, { props }) => {
|
|
202
|
+
const relationshipId = getAttribute(child, "r", "id");
|
|
203
|
+
if (relationshipId) props.printerSettingsRelationshipId = relationshipId;
|
|
204
|
+
return keptUnless(Boolean(relationshipId));
|
|
205
|
+
},
|
|
206
|
+
sectPrChange: (child, { propertyChanges }) => {
|
|
207
|
+
const previousSectPr = findChild(child, "w", "sectPr");
|
|
208
|
+
const change = {
|
|
209
|
+
type: "sectionPropertyChange",
|
|
210
|
+
info: parsePropertyChangeInfo(child)
|
|
211
|
+
};
|
|
212
|
+
if (previousSectPr) change.previousProperties = parseSectionProperties(previousSectPr);
|
|
213
|
+
const previousReferences = parseSectionReferenceHistory(child);
|
|
214
|
+
if (previousReferences !== void 0) change.previousReferences = previousReferences;
|
|
215
|
+
propertyChanges.push(change);
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const SECTION_PROPERTY_UNDECLARED = {
|
|
219
|
+
background: (child, { props, context }) => keptUnless(readBackground(props, child, context)),
|
|
220
|
+
evenAndOddHeaders: (child, { props, context }) => {
|
|
221
|
+
props.evenAndOddHeaders = parseBooleanElement(child, "w", context);
|
|
222
|
+
},
|
|
223
|
+
footnoteColumns: (child, { props }) => {
|
|
224
|
+
const columns = parseNumericAttribute(child, "w", "val");
|
|
225
|
+
if (columns !== void 0) props.footnoteColumns = columns;
|
|
226
|
+
return keptUnless(columns !== void 0);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
70
229
|
/**
|
|
71
230
|
* Parse section properties (w:sectPr)
|
|
72
231
|
*
|
|
@@ -79,168 +238,18 @@ function parseSectionProperties(sectPr, context) {
|
|
|
79
238
|
const headerRefs = [];
|
|
80
239
|
const footerRefs = [];
|
|
81
240
|
const propertyChanges = [];
|
|
82
|
-
const preserved =
|
|
241
|
+
const preserved = dispatchChildrenWithContext({
|
|
83
242
|
element: sectPr,
|
|
84
243
|
container: "section-properties",
|
|
85
|
-
handlers:
|
|
86
|
-
headerReference: (child) => {
|
|
87
|
-
const reference = parseHeaderReference(child, context);
|
|
88
|
-
if (reference) headerRefs.push(reference);
|
|
89
|
-
},
|
|
90
|
-
footerReference: (child) => {
|
|
91
|
-
const reference = parseFooterReference(child, context);
|
|
92
|
-
if (reference) footerRefs.push(reference);
|
|
93
|
-
},
|
|
94
|
-
footnotePr: (child) => {
|
|
95
|
-
const footnotePr = parseFootnoteProperties(child);
|
|
96
|
-
if (Object.keys(footnotePr).length > 0) {
|
|
97
|
-
props.footnotePr = footnotePr;
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
return CAPTURE;
|
|
101
|
-
},
|
|
102
|
-
endnotePr: (child) => {
|
|
103
|
-
const endnotePr = parseEndnoteProperties(child);
|
|
104
|
-
if (Object.keys(endnotePr).length > 0) {
|
|
105
|
-
props.endnotePr = endnotePr;
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
return CAPTURE;
|
|
109
|
-
},
|
|
110
|
-
type: (child) => {
|
|
111
|
-
const sectionStart = parseSectionStart(getAttribute(child, "w", "val"));
|
|
112
|
-
if (sectionStart) props.sectionStart = sectionStart;
|
|
113
|
-
return keptUnless(sectionStart !== void 0);
|
|
114
|
-
},
|
|
115
|
-
pgSz: (child) => {
|
|
116
|
-
const width = parseNumericAttribute(child, "w", "w");
|
|
117
|
-
if (width !== void 0) props.pageWidth = Math.min(width, MAX_PAGE_DIMENSION_TWIPS);
|
|
118
|
-
const height = parseNumericAttribute(child, "w", "h");
|
|
119
|
-
if (height !== void 0) props.pageHeight = Math.min(height, MAX_PAGE_DIMENSION_TWIPS);
|
|
120
|
-
const orientation = parseOrientation(getAttribute(child, "w", "orient"));
|
|
121
|
-
if (orientation) props.orientation = orientation;
|
|
122
|
-
return keptUnless(width !== void 0 || height !== void 0 || orientation !== void 0);
|
|
123
|
-
},
|
|
124
|
-
pgMar: (child) => {
|
|
125
|
-
const margins = [
|
|
126
|
-
["top", "marginTop"],
|
|
127
|
-
["bottom", "marginBottom"],
|
|
128
|
-
["left", "marginLeft"],
|
|
129
|
-
["right", "marginRight"],
|
|
130
|
-
["header", "headerDistance"],
|
|
131
|
-
["footer", "footerDistance"],
|
|
132
|
-
["gutter", "gutter"]
|
|
133
|
-
];
|
|
134
|
-
let taken = false;
|
|
135
|
-
for (const [attribute, field] of margins) {
|
|
136
|
-
const value = parseNumericAttribute(child, "w", attribute);
|
|
137
|
-
if (value !== void 0) {
|
|
138
|
-
props[field] = value;
|
|
139
|
-
taken = true;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return keptUnless(taken);
|
|
143
|
-
},
|
|
144
|
-
paperSrc: (child) => {
|
|
145
|
-
const first = parseNumericAttribute(child, "w", "first");
|
|
146
|
-
if (first !== void 0) props.paperSrcFirst = first;
|
|
147
|
-
const other = parseNumericAttribute(child, "w", "other");
|
|
148
|
-
if (other !== void 0) props.paperSrcOther = other;
|
|
149
|
-
return keptUnless(first !== void 0 || other !== void 0);
|
|
150
|
-
},
|
|
151
|
-
pgBorders: (child) => keptUnless(readPageBorders(props, child, context)),
|
|
152
|
-
lnNumType: (child) => {
|
|
153
|
-
const lineNumbers = {};
|
|
154
|
-
for (const [attribute, field] of [
|
|
155
|
-
["start", "start"],
|
|
156
|
-
["countBy", "countBy"],
|
|
157
|
-
["distance", "distance"]
|
|
158
|
-
]) {
|
|
159
|
-
const value = parseNumericAttribute(child, "w", attribute);
|
|
160
|
-
if (value !== void 0) lineNumbers[field] = value;
|
|
161
|
-
}
|
|
162
|
-
const restart = parseLineNumberRestart(getAttribute(child, "w", "restart"));
|
|
163
|
-
if (restart) lineNumbers.restart = restart;
|
|
164
|
-
if (Object.keys(lineNumbers).length === 0) return CAPTURE;
|
|
165
|
-
props.lineNumbers = lineNumbers;
|
|
166
|
-
},
|
|
167
|
-
pgNumType: (child) => {
|
|
168
|
-
const pageNumbering = {};
|
|
169
|
-
const format = narrowEnum(getAttribute(child, "w", "fmt"), NumberFormatSchema);
|
|
170
|
-
if (format) pageNumbering.format = format;
|
|
171
|
-
const start = parseNumericAttribute(child, "w", "start");
|
|
172
|
-
if (start !== void 0) pageNumbering.start = start;
|
|
173
|
-
const chapterStyle = parseNumericAttribute(child, "w", "chapStyle");
|
|
174
|
-
if (chapterStyle !== void 0) pageNumbering.chapterStyle = chapterStyle;
|
|
175
|
-
const chapterSeparator = getAttribute(child, "w", "chapSep");
|
|
176
|
-
if (chapterSeparator) pageNumbering.chapterSeparator = chapterSeparator;
|
|
177
|
-
if (Object.keys(pageNumbering).length === 0) return CAPTURE;
|
|
178
|
-
props.pageNumbering = pageNumbering;
|
|
179
|
-
},
|
|
180
|
-
cols: (child) => keptUnless(readColumns(props, child)),
|
|
181
|
-
formProt: (child) => {
|
|
182
|
-
props.formProtection = parseBooleanElement(child, "w", context);
|
|
183
|
-
},
|
|
184
|
-
vAlign: (child) => {
|
|
185
|
-
const verticalAlign = parseVerticalAlign(getAttribute(child, "w", "val"));
|
|
186
|
-
if (verticalAlign) props.verticalAlign = verticalAlign;
|
|
187
|
-
return keptUnless(verticalAlign !== void 0);
|
|
188
|
-
},
|
|
189
|
-
noEndnote: (child) => {
|
|
190
|
-
props.noEndnote = parseBooleanElement(child, "w", context);
|
|
191
|
-
},
|
|
192
|
-
titlePg: (child) => {
|
|
193
|
-
props.titlePg = parseBooleanElement(child, "w", context);
|
|
194
|
-
},
|
|
195
|
-
textDirection: (child) => {
|
|
196
|
-
const textDirection = narrowEnum(getAttribute(child, "w", "val"), TextDirectionSchema);
|
|
197
|
-
if (textDirection) props.textDirection = textDirection;
|
|
198
|
-
return keptUnless(textDirection !== void 0);
|
|
199
|
-
},
|
|
200
|
-
bidi: (child) => {
|
|
201
|
-
props.bidi = parseBooleanElement(child, "w", context);
|
|
202
|
-
},
|
|
203
|
-
rtlGutter: (child) => {
|
|
204
|
-
props.rtlGutter = parseBooleanElement(child, "w", context);
|
|
205
|
-
},
|
|
206
|
-
docGrid: (child) => {
|
|
207
|
-
const docGrid = {};
|
|
208
|
-
const gridType = getAttribute(child, "w", "type");
|
|
209
|
-
if (gridType === "default" || gridType === "lines" || gridType === "linesAndChars" || gridType === "snapToChars") docGrid.type = gridType;
|
|
210
|
-
const linePitch = parseNumericAttribute(child, "w", "linePitch");
|
|
211
|
-
if (linePitch !== void 0) docGrid.linePitch = linePitch;
|
|
212
|
-
const charSpace = parseNumericAttribute(child, "w", "charSpace");
|
|
213
|
-
if (charSpace !== void 0) docGrid.charSpace = charSpace;
|
|
214
|
-
props.docGrid = docGrid;
|
|
215
|
-
},
|
|
216
|
-
printerSettings: (child) => {
|
|
217
|
-
const relationshipId = getAttribute(child, "r", "id");
|
|
218
|
-
if (relationshipId) props.printerSettingsRelationshipId = relationshipId;
|
|
219
|
-
return keptUnless(Boolean(relationshipId));
|
|
220
|
-
},
|
|
221
|
-
sectPrChange: (child) => {
|
|
222
|
-
const previousSectPr = findChild(child, "w", "sectPr");
|
|
223
|
-
const change = {
|
|
224
|
-
type: "sectionPropertyChange",
|
|
225
|
-
info: parsePropertyChangeInfo(child)
|
|
226
|
-
};
|
|
227
|
-
if (previousSectPr) change.previousProperties = parseSectionProperties(previousSectPr);
|
|
228
|
-
const previousReferences = parseSectionReferenceHistory(child);
|
|
229
|
-
if (previousReferences !== void 0) change.previousReferences = previousReferences;
|
|
230
|
-
propertyChanges.push(change);
|
|
231
|
-
}
|
|
232
|
-
},
|
|
244
|
+
handlers: SECTION_PROPERTY_HANDLERS,
|
|
233
245
|
capturePosition: sequencePositions("section-properties", sectPr),
|
|
234
|
-
undeclared:
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
if (columns !== void 0) props.footnoteColumns = columns;
|
|
242
|
-
return keptUnless(columns !== void 0);
|
|
243
|
-
}
|
|
246
|
+
undeclared: SECTION_PROPERTY_UNDECLARED,
|
|
247
|
+
context: {
|
|
248
|
+
props,
|
|
249
|
+
headerRefs,
|
|
250
|
+
footerRefs,
|
|
251
|
+
propertyChanges,
|
|
252
|
+
context
|
|
244
253
|
}
|
|
245
254
|
});
|
|
246
255
|
if (preserved) props.preserved = preserved;
|
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Selective Save Feature Flags
|
|
4
4
|
*
|
|
5
|
-
* Operational controls for the selective save path.
|
|
6
|
-
*
|
|
5
|
+
* Operational controls for the selective save path. Selective save is on by
|
|
6
|
+
* default: every save attempts it first and falls back to a full repack
|
|
7
|
+
* whenever the patch-safety checks refuse (structural changes, untracked
|
|
8
|
+
* changes, oversized buffers, or an unmodelled part). Hosts that need the
|
|
9
|
+
* previous behavior can opt back into full repacking on every save.
|
|
7
10
|
*
|
|
8
11
|
* - `selectiveSave` — gate the selective branch entirely.
|
|
9
12
|
* - `selectiveSaveTripwire` — run selective + full and compare bytes for CI
|
|
@@ -13,7 +16,11 @@
|
|
|
13
16
|
* the dominant cost.
|
|
14
17
|
*/
|
|
15
18
|
type FolioSelectiveSaveFlags = {
|
|
16
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Enable the selective save path. Default: true. A save always succeeds:
|
|
21
|
+
* when the patch-safety checks refuse, the caller falls back to a full
|
|
22
|
+
* repack automatically. Set to `false` to always full-repack.
|
|
23
|
+
*/
|
|
17
24
|
selectiveSave?: boolean;
|
|
18
25
|
/**
|
|
19
26
|
* Run selective save and full repack on every save, compare bytes, and emit
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const DEFAULT_SELECTIVE_SAVE_MAX_BYTES = 100 * 1024 * 1024;
|
|
3
3
|
function resolveSelectiveSaveFlags(flags) {
|
|
4
4
|
return {
|
|
5
|
-
selectiveSave: flags?.selectiveSave ??
|
|
5
|
+
selectiveSave: flags?.selectiveSave ?? true,
|
|
6
6
|
selectiveSaveTripwire: flags?.selectiveSaveTripwire ?? false,
|
|
7
7
|
selectiveSaveMaxBytes: flags?.selectiveSaveMaxBytes ?? 104857600
|
|
8
8
|
};
|
|
@@ -54,22 +54,48 @@ type ParagraphOffsets = {
|
|
|
54
54
|
* function would return null.
|
|
55
55
|
*/
|
|
56
56
|
declare function buildParagraphOffsetIndex(xml: string): Map<string, ParagraphOffsets>;
|
|
57
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* The containers a `<w:p>` sits in, as far as a splice has to care.
|
|
59
|
+
*
|
|
60
|
+
* A paragraph is addressed inside one *story*: the main flow of the part (its
|
|
61
|
+
* body, table cells and block-level content controls included), or the text
|
|
62
|
+
* of a text box (`w:txbxContent`, DrawingML or VML). The two are separate
|
|
63
|
+
* ordinal spaces, because the model can legitimately represent a text box
|
|
64
|
+
* differently from the source (a VML box read as DrawingML, a box it cannot
|
|
65
|
+
* read at all) without that saying anything about the main flow.
|
|
66
|
+
*
|
|
67
|
+
* `mc:Fallback` is a copy of its `mc:Choice` for consumers that cannot read
|
|
68
|
+
* the Choice. The model reads the Choice and owns nothing in the Fallback, so
|
|
69
|
+
* a Fallback paragraph is never addressed: it is neither a splice target nor
|
|
70
|
+
* an ordinal, which is also the rule `ensureParaIds` stamps by.
|
|
71
|
+
*/
|
|
72
|
+
type ParagraphContainer = {
|
|
73
|
+
/** Inside `mc:Fallback`. */
|
|
74
|
+
inFallback: boolean;
|
|
75
|
+
/** Inside `mc:AlternateContent`, whose Fallback repeats this paragraph. */
|
|
76
|
+
inAlternateContent: boolean;
|
|
77
|
+
/** How many text-box stories (`w:txbxContent`) enclose the paragraph. */
|
|
78
|
+
textBoxDepth: number;
|
|
79
|
+
/** How many table cells (`w:tc`) enclose the paragraph. */
|
|
80
|
+
tableDepth: number;
|
|
81
|
+
};
|
|
82
|
+
/** One `<w:p>` of a part: its byte range, the paraId its open tag carries, and where it sits. */
|
|
58
83
|
type ScannedParagraph = ParagraphOffsets & {
|
|
59
84
|
paraId: string | undefined;
|
|
85
|
+
container: ParagraphContainer;
|
|
60
86
|
};
|
|
61
87
|
/**
|
|
62
88
|
* Every `<w:p>` element of `xml`, in the document order of its opening tags,
|
|
63
|
-
* with the `w14:paraId` that tag carries.
|
|
89
|
+
* with the `w14:paraId` that tag carries and the containers around it.
|
|
64
90
|
*
|
|
65
|
-
* Document order is what makes the array an ordinal space:
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* {@link countParagraphElements} counts it
|
|
71
|
-
*
|
|
72
|
-
*
|
|
91
|
+
* Document order is what makes the array an ordinal space: within one story
|
|
92
|
+
* (see {@link ParagraphContainer}), the *n*th paragraph of the source part and
|
|
93
|
+
* the *n*th paragraph of the model's serialization name the same paragraph,
|
|
94
|
+
* which is the only way to address a paragraph the producer gave no id. A
|
|
95
|
+
* `<w:p>` nested inside another (inside `mc:AlternateContent`, a text box) is
|
|
96
|
+
* one entry of its own, exactly as {@link countParagraphElements} counts it.
|
|
97
|
+
* An unterminated paragraph keeps `end === start`: it occupies its ordinal but
|
|
98
|
+
* no splice can be built from it.
|
|
73
99
|
*/
|
|
74
100
|
declare function scanParagraphs(xml: string): ScannedParagraph[];
|
|
75
101
|
/**
|
|
@@ -85,32 +111,26 @@ type PatchValidationResult = {
|
|
|
85
111
|
safe: boolean;
|
|
86
112
|
reason?: string;
|
|
87
113
|
};
|
|
88
|
-
type PatchSafetyOptions = {
|
|
89
|
-
/**
|
|
90
|
-
* Require the original and serialized XML to hold the same number of `<w:p>`
|
|
91
|
-
* elements. Guards document.xml against structural drift. Notes disable it:
|
|
92
|
-
* the model only retains the normal notes, so a serialized note part
|
|
93
|
-
* legitimately has fewer paragraphs than the original (which still carries
|
|
94
|
-
* the separator notes). See {@link buildPatchedNoteXml}.
|
|
95
|
-
*/
|
|
96
|
-
checkParagraphCount?: boolean;
|
|
97
|
-
};
|
|
98
114
|
/**
|
|
99
|
-
* Validate that a selective patch can be safely applied
|
|
115
|
+
* Validate that a selective patch can be safely applied: every changed
|
|
116
|
+
* paragraph routes to exactly one region of the original part (see
|
|
117
|
+
* {@link routeChangedParagraphs} for what is refused and why).
|
|
100
118
|
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* - Paragraph count matches between original and serialized (unless disabled)
|
|
119
|
+
* The rest of the part does not have to match the model's serialization. The
|
|
120
|
+
* splice keeps every unchanged byte of the source, so a paragraph the model
|
|
121
|
+
* represents differently elsewhere (a text box it re-reads, a Fallback it
|
|
122
|
+
* does not own) is simply kept as the source wrote it.
|
|
106
123
|
*/
|
|
107
|
-
declare function validatePatchSafety(originalXml: string, serializedXml: string, changedIds: Set<string
|
|
124
|
+
declare function validatePatchSafety(originalXml: string, serializedXml: string, changedIds: Set<string>): PatchValidationResult;
|
|
108
125
|
/**
|
|
109
126
|
* Build a patched document.xml by splicing new paragraph XML into
|
|
110
127
|
* the original at the correct offsets. Only changed paragraphs
|
|
111
128
|
* are replaced; everything else is preserved byte-for-byte.
|
|
112
129
|
*
|
|
113
|
-
* Returns null
|
|
130
|
+
* Returns null when a changed paragraph cannot be routed (see
|
|
131
|
+
* {@link validatePatchSafety}) or {@link spliceXml} refuses the result; the
|
|
132
|
+
* caller then falls back to a full repack, whose parts are all re-serialized
|
|
133
|
+
* from one model.
|
|
114
134
|
*/
|
|
115
135
|
declare function buildPatchedDocumentXml(originalXml: string, serializedXml: string, changedIds: Set<string>): string | null;
|
|
116
136
|
/**
|
|
@@ -118,11 +138,13 @@ declare function buildPatchedDocumentXml(originalXml: string, serializedXml: str
|
|
|
118
138
|
* splicing edited note paragraphs into the original, preserving unchanged
|
|
119
139
|
* content byte-for-byte.
|
|
120
140
|
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
141
|
+
* The routing is the document's: the model only retains the normal notes, so
|
|
142
|
+
* the serialized note XML omits the separator / continuationSeparator
|
|
143
|
+
* paragraphs the original part still carries, and splicing by `paraId` keeps
|
|
144
|
+
* those separators and every unedited note byte-exact while replacing only the
|
|
145
|
+
* edited ones. (An id-less note paragraph does not route here, because the
|
|
146
|
+
* separators misalign its story's ordinals; {@link buildPatchedNotePartXml}
|
|
147
|
+
* addresses it by note instead.)
|
|
126
148
|
*
|
|
127
149
|
* Returns null if any changed id is missing or ambiguous in either input, so
|
|
128
150
|
* the caller can fall back to preserving the original part verbatim.
|
|
@@ -241,4 +263,4 @@ declare const patchNumberingDefinitions: ({ originalXml, baselineXml, currentXml
|
|
|
241
263
|
*/
|
|
242
264
|
declare function appendNumberingDefs(xml: string, currentXml: string, added: ChangedNumberingDefs): string | null;
|
|
243
265
|
//#endregion
|
|
244
|
-
export { ChangedNumberingDefs, NotePartPatch, NotePartPatchRefusal,
|
|
266
|
+
export { ChangedNumberingDefs, NotePartPatch, NotePartPatchRefusal, ParagraphContainer, ParagraphOffsets, PatchValidationResult, ScannedParagraph, XmlSplice, appendNumberingDefs, buildParagraphOffsetIndex, buildPatchedDocumentXml, buildPatchedNotePartXml, buildPatchedNoteXml, buildPatchedNumberingXml, collectAddedNumberingDefs, collectChangedNoteParaIds, collectChangedNumberingDefs, collectParaIds, countParagraphElements, extractParagraphXml, findParagraphOffsets, isXmlNameBoundary, patchNumberingDefinitions, scanParagraphs, spliceXml, validatePatchSafety };
|